From c20ac50892f4fbfda388a2a46b9da34deba8174e Mon Sep 17 00:00:00 2001 From: raoqian <506411586@qq.com> Date: Sat, 20 Sep 2025 16:07:16 +0800 Subject: [PATCH] =?UTF-8?q?1.=E5=AE=8C=E6=88=90=E6=90=9C=E7=B4=A2=E7=95=8C?= =?UTF-8?q?=E9=9D=A2=E6=8E=A5=E5=8F=A3=E6=8E=A5=E5=85=A5=202.=E5=AE=8C?= =?UTF-8?q?=E6=88=90=E6=94=B6=E8=97=8F=E3=80=81=E6=92=AD=E6=94=BE=E5=8E=86?= =?UTF-8?q?=E5=8F=B2=E6=8E=A5=E5=8F=A3=E6=8E=A5=E5=85=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../er/nebuluxe/app/basics/BaseActivity.kt | 17 +- .../er/nebuluxe/app/basics/BaseFragment.kt | 25 ++ .../nebuluxe/app/home/InputResultAdapter.java | 18 +- .../nebuluxe/app/home/SaveFavoritesAdapter.kt | 34 +-- .../nebuluxe/app/home/SaveHistoryAdapter.kt | 50 ++-- .../jia/er/nebuluxe/app/home/SavedFragment.kt | 277 +++++++++--------- .../er/nebuluxe/app/home/SearchActivity.kt | 207 ++++++++----- .../jia/er/nebuluxe/app/net/MainViewModel.kt | 13 +- .../jia/er/nebuluxe/app/utils/DialogUtils.kt | 42 ++- .../com/jia/er/nebuluxe/app/utils/Memory.kt | 4 + .../jia/er/nebuluxe/app/utils/StringUtil.java | 10 + .../er/nebuluxe/app/utils/TextViewUtil.java | 4 +- app/src/main/res/layout/activity_search.xml | 60 ++-- app/src/main/res/layout/fragment_saved.xml | 31 +- app/src/main/res/layout/item_saved_favory.xml | 20 +- .../main/res/layout/item_saved_history.xml | 11 +- app/src/main/res/values/strings.xml | 5 + 17 files changed, 498 insertions(+), 330 deletions(-) create mode 100644 app/src/main/java/com/jia/er/nebuluxe/app/utils/StringUtil.java diff --git a/app/src/main/java/com/jia/er/nebuluxe/app/basics/BaseActivity.kt b/app/src/main/java/com/jia/er/nebuluxe/app/basics/BaseActivity.kt index aad71ec..a017d48 100644 --- a/app/src/main/java/com/jia/er/nebuluxe/app/basics/BaseActivity.kt +++ b/app/src/main/java/com/jia/er/nebuluxe/app/basics/BaseActivity.kt @@ -2,6 +2,7 @@ package com.jia.er.nebuluxe.app.basics import android.app.Dialog import android.content.Context +import android.content.Intent import android.content.pm.ActivityInfo import android.graphics.Color import android.graphics.drawable.ColorDrawable @@ -21,6 +22,7 @@ import androidx.core.view.WindowInsetsCompat import androidx.viewbinding.ViewBinding import com.blankj.utilcode.util.BarUtils import com.jia.er.nebuluxe.app.R +import com.jia.er.nebuluxe.app.utils.singleClick abstract class BaseActivity : AppCompatActivity() { lateinit var binding: BV @@ -68,6 +70,11 @@ abstract class BaseActivity : AppCompatActivity() { BarUtils.transparentStatusBar(this) BarUtils.setStatusBarLightMode(this, false) requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT + if (findViewById(R.id.example_iv_back) != null) { + findViewById(R.id.example_iv_back)?.setOnClickListener { + finish() + } + } top() center() if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.VANILLA_ICE_CREAM) { @@ -79,7 +86,13 @@ abstract class BaseActivity : AppCompatActivity() { } } } - + protected fun skip2Activity(clazz: Class>) { + singleClick { + startActivity( + Intent(this, clazz) + ) + } + } protected abstract fun top() protected abstract fun center() protected abstract fun getViewBinding(): BV @@ -98,7 +111,7 @@ abstract class BaseActivity : AppCompatActivity() { networkErrorView?.visibility = View.INVISIBLE } - fun showNoDrama(){ + fun showNoDrama() { noDramaView?.visibility = View.VISIBLE } diff --git a/app/src/main/java/com/jia/er/nebuluxe/app/basics/BaseFragment.kt b/app/src/main/java/com/jia/er/nebuluxe/app/basics/BaseFragment.kt index c687b90..50c6ea6 100644 --- a/app/src/main/java/com/jia/er/nebuluxe/app/basics/BaseFragment.kt +++ b/app/src/main/java/com/jia/er/nebuluxe/app/basics/BaseFragment.kt @@ -13,6 +13,8 @@ import androidx.appcompat.widget.AppCompatTextView import androidx.fragment.app.Fragment import androidx.viewbinding.ViewBinding import com.jia.er.nebuluxe.app.R +import com.jia.er.nebuluxe.app.utils.LOG +import com.jia.er.nebuluxe.app.utils.singleClick abstract class BaseFragment : Fragment() { lateinit var binding: VB @@ -53,6 +55,29 @@ abstract class BaseFragment : Fragment() { protected open fun onRetry() { } + @Deprecated(message = "Use onPageResume() instead") + override fun onResume() { + super.onResume() + resume() + } + + fun resume() { + singleClick { + onPageResume() + } + } + + open fun onPageResume() { + LOG.d("BaseFragment", this::class.java.simpleName + ".onResume") + } + + override fun onHiddenChanged(hidden: Boolean) { + super.onHiddenChanged(hidden) + if (!hidden) { + resume() + } + } + fun showNetError() { networkErrorView?.visibility = View.VISIBLE } diff --git a/app/src/main/java/com/jia/er/nebuluxe/app/home/InputResultAdapter.java b/app/src/main/java/com/jia/er/nebuluxe/app/home/InputResultAdapter.java index be0f3d8..a40fb39 100644 --- a/app/src/main/java/com/jia/er/nebuluxe/app/home/InputResultAdapter.java +++ b/app/src/main/java/com/jia/er/nebuluxe/app/home/InputResultAdapter.java @@ -2,22 +2,32 @@ package com.jia.er.nebuluxe.app.home; import android.content.Context; import android.view.ViewGroup; +import android.widget.ImageView; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import com.blankj.utilcode.util.StringUtils; +import com.bumptech.glide.Glide; import com.chad.library.adapter4.BaseQuickAdapter; import com.chad.library.adapter4.viewholder.QuickViewHolder; import com.jia.er.nebuluxe.app.R; +import com.jia.er.nebuluxe.app.data.VideoListDataRes; +import com.jia.er.nebuluxe.app.utils.StringUtil; import com.jia.er.nebuluxe.app.utils.TextViewUtil; -public class InputResultAdapter extends BaseQuickAdapter { +import java.net.IDN; + +public class InputResultAdapter extends BaseQuickAdapter { String keyword; @Override - protected void onBindViewHolder(@NonNull QuickViewHolder quickAdapterHelper, int i, @Nullable String s) { - quickAdapterHelper.setText(R.id.tv_con, s); - quickAdapterHelper.setText(R.id.tv_title, TextViewUtil.getTextColor(s, keyword, R.color.text_color_pink_dark)); + protected void onBindViewHolder(@NonNull QuickViewHolder holder, int i, @Nullable VideoListDataRes.VideoListData item) { + holder.setText(R.id.tv_tip, item.getCategoryList().get(0).getName()); + holder.setText(R.id.tv_title, TextViewUtil.getTextColor(item.getName(), keyword, R.color.text_color_pink_dark)); + holder.setText(R.id.tv_num, StringUtil.getWatchNum(item.getWatch_total())); + holder.setText(R.id.tv_con, item.getDescription()); + Glide.with(getContext()).load(item.getImage_url()).into((ImageView) holder.getView(R.id.iv)); } diff --git a/app/src/main/java/com/jia/er/nebuluxe/app/home/SaveFavoritesAdapter.kt b/app/src/main/java/com/jia/er/nebuluxe/app/home/SaveFavoritesAdapter.kt index a9f939f..47037e6 100644 --- a/app/src/main/java/com/jia/er/nebuluxe/app/home/SaveFavoritesAdapter.kt +++ b/app/src/main/java/com/jia/er/nebuluxe/app/home/SaveFavoritesAdapter.kt @@ -16,34 +16,28 @@ import com.chad.library.adapter4.viewholder.QuickViewHolder import com.google.android.material.imageview.ShapeableImageView import com.google.android.material.shape.RelativeCornerSize import com.jia.er.nebuluxe.app.R +import com.jia.er.nebuluxe.app.data.CollectionRes.CollectionData import com.jia.er.nebuluxe.app.data.HomeBannerBean class SaveFavoritesAdapter : - BaseQuickAdapter() { + BaseQuickAdapter() { var currentPosition = 0 override fun onBindViewHolder( holder: QuickViewHolder, position: Int, - item: String? + item: CollectionData? ) { - holder.getView(R.id.progress_bar).setProgress(position * 13) -// val view = holder.getView(R.id.example_iv_icon_ceo) -// Glide.with(context).load(item?.image_url).placeholder(R.drawable.iv_placeholder_v) -// .into(view) -// view.scaleType = ImageView.ScaleType.CENTER_CROP -// view.shapeAppearanceModel = view.shapeAppearanceModel -// .toBuilder() -// .setAllCornerSizes(RelativeCornerSize(0.5f)) -// .build() -// view.elevation = 0f -// view.clipToOutline = true -// view.outlineProvider = object : ViewOutlineProvider() { -// override fun getOutline(view: View, outline: Outline) { -// val size = minOf(view.width, view.height) -// outline.setOval(0, 0, size, size) -// } -// } -// + val view = holder.getView(R.id.iv) + Glide.with(context).load(item?.image_url).placeholder(R.drawable.iv_placeholder_v) + .into(view) + holder.getView(R.id.sk_play_progress).progress = + if (item != null) { + val current = item.current_episode + val total = item.episode_total.takeIf { it > 0 } ?: 100 + current * 100 / total + } else { + 0 + } // if (currentPosition == position) { // holder.setVisible(R.id.view, false) // } else { diff --git a/app/src/main/java/com/jia/er/nebuluxe/app/home/SaveHistoryAdapter.kt b/app/src/main/java/com/jia/er/nebuluxe/app/home/SaveHistoryAdapter.kt index 712153e..3e32461 100644 --- a/app/src/main/java/com/jia/er/nebuluxe/app/home/SaveHistoryAdapter.kt +++ b/app/src/main/java/com/jia/er/nebuluxe/app/home/SaveHistoryAdapter.kt @@ -9,53 +9,43 @@ import android.view.ViewGroup import android.view.ViewOutlineProvider import android.widget.ImageView import android.widget.SeekBar +import androidx.appcompat.widget.AppCompatSeekBar import com.bumptech.glide.Glide import com.chad.library.adapter4.BaseQuickAdapter import com.chad.library.adapter4.viewholder.QuickViewHolder import com.google.android.material.imageview.ShapeableImageView import com.google.android.material.shape.RelativeCornerSize import com.jia.er.nebuluxe.app.R +import com.jia.er.nebuluxe.app.data.HistoryDataRes import com.jia.er.nebuluxe.app.data.HomeBannerBean +import com.jia.er.nebuluxe.app.utils.LOG class SaveHistoryAdapter : - BaseQuickAdapter() { - var currentPosition = 0 + BaseQuickAdapter() { override fun onBindViewHolder( holder: QuickViewHolder, position: Int, - item: String? + item: HistoryDataRes.Data? ) { holder.getView(R.id.line).visibility = if (position == 0) View.GONE else View.VISIBLE - holder.getView(R.id.progress_bar).setProgress(position * 10) - holder.setSelected(R.id.iv_star, position % 2 == 0) - holder.setText(R.id.tv_name, "Name " + position) - holder.setText(R.id.tv_con, "Content " + position) + holder.setSelected(R.id.iv_star, item?.is_collect == 1) + holder.setText(R.id.tv_name, item?.name) + val progress = if (item != null) { + val current = item.current_episode + val total = item.episode_total.takeIf { it > 0 } ?: 1 + current * 100 / total + } else { + 0 + } + holder.getView(R.id.progress_bar).progress = progress + holder.setText(R.id.tv_con, item?.category.let { it?.joinToString(", ") ?: "" }) holder.setText( R.id.tv_viewed, - String.format(context.getString(R.string.viewed_format), position.toString()) + String.format(context.getString(R.string.viewed_format), progress.toString()) ) -// val view = holder.getView(R.id.example_iv_icon_ceo) -// Glide.with(context).load(item?.image_url).placeholder(R.drawable.iv_placeholder_v) -// .into(view) -// view.scaleType = ImageView.ScaleType.CENTER_CROP -// view.shapeAppearanceModel = view.shapeAppearanceModel -// .toBuilder() -// .setAllCornerSizes(RelativeCornerSize(0.5f)) -// .build() -// view.elevation = 0f -// view.clipToOutline = true -// view.outlineProvider = object : ViewOutlineProvider() { -// override fun getOutline(view: View, outline: Outline) { -// val size = minOf(view.width, view.height) -// outline.setOval(0, 0, size, size) -// } -// } -// -// if (currentPosition == position) { -// holder.setVisible(R.id.view, false) -// } else { -// holder.setVisible(R.id.view, true) -// } + val view = holder.getView(R.id.iv) + Glide.with(context).load(item?.image_url).placeholder(R.drawable.iv_placeholder_v) + .into(view) } override fun onCreateViewHolder( diff --git a/app/src/main/java/com/jia/er/nebuluxe/app/home/SavedFragment.kt b/app/src/main/java/com/jia/er/nebuluxe/app/home/SavedFragment.kt index 9f87f4d..a368a5e 100644 --- a/app/src/main/java/com/jia/er/nebuluxe/app/home/SavedFragment.kt +++ b/app/src/main/java/com/jia/er/nebuluxe/app/home/SavedFragment.kt @@ -1,179 +1,173 @@ package com.jia.er.nebuluxe.app.home import android.content.Intent -import android.graphics.Color import android.view.View import androidx.lifecycle.ViewModelProvider import androidx.recyclerview.widget.LinearLayoutManager -import com.jia.er.nebuluxe.app.data.CollectionRes +import com.blankj.utilcode.util.GsonUtils import com.blankj.utilcode.util.NetworkUtils +import com.chad.library.adapter4.BaseQuickAdapter import com.chad.library.adapter4.layoutmanager.QuickGridLayoutManager import com.jia.er.nebuluxe.app.R import com.jia.er.nebuluxe.app.basics.BaseFragment +import com.jia.er.nebuluxe.app.basics.Constants +import com.jia.er.nebuluxe.app.data.CollectionRes.CollectionData +import com.jia.er.nebuluxe.app.data.HistoryDataRes import com.jia.er.nebuluxe.app.databinding.FragmentSavedBinding import com.jia.er.nebuluxe.app.net.MainViewModel import com.jia.er.nebuluxe.app.utils.DialogUtils +import com.jia.er.nebuluxe.app.utils.LOG import com.jia.er.nebuluxe.app.utils.singleClick import com.jia.er.nebuluxe.app.utils.toast +import com.jia.er.nebuluxe.app.video.PlayerDetailActivity class SavedFragment : BaseFragment() { private var page: Int = 1 - // private var myListAdapter: MyListAdapter? = null + private var favorAdapter: SaveFavoritesAdapter? = null + private var historyAdapter: SaveHistoryAdapter? = null private var edit = false + private var mode = 0//0-收藏 1-历史 private var current: Int = 0 private val mViewModel by lazy { ViewModelProvider(this)[MainViewModel::class.java] } override fun top() { + showLoading() binding.btnFavor.isSelected = true binding.btnFavor.setOnClickListener { binding.btnFavor.isSelected = true binding.btnHistory.isSelected = false binding.rvFavor.visibility = View.VISIBLE binding.rvHistory.visibility = View.GONE + mode = 0 + onPageResume() } binding.btnHistory.setOnClickListener { binding.btnFavor.isSelected = false binding.btnHistory.isSelected = true binding.rvFavor.visibility = View.GONE binding.rvHistory.visibility = View.VISIBLE + mode = 1 + onPageResume() } val layoutManager = QuickGridLayoutManager(requireContext(), 3) binding.rvFavor.layoutManager = layoutManager - val adapter = SaveFavoritesAdapter() - binding.rvFavor.adapter = adapter - val debug = listOf( - "a", - "b", - "c", - "d", - "e", - "f" - ) - adapter.items = debug + favorAdapter = SaveFavoritesAdapter() + binding.rvFavor.adapter = favorAdapter val layoutManager1 = LinearLayoutManager(requireContext()) binding.rvHistory.layoutManager = layoutManager1 - val adapter1 = SaveHistoryAdapter() - binding.rvHistory.adapter = adapter1 - adapter1.items = debug - adapter.addOnItemChildClickListener(R.id.iv_favorites_delete, { adapter, view, position -> - DialogUtils.showDoubleBtnDialog( - requireContext(), - "Remove from Favorites?", - "This drama will be removed from your favorites.", - "Remove", - "Cancel", - R.drawable.ic_star_remove, - object : DialogUtils.DialogOnClickListener { - - override fun onConfirmClick() { - toast("确认移除接口") - } - - override fun onCancelClick() { - } - }) + historyAdapter = SaveHistoryAdapter() + binding.rvHistory.adapter = historyAdapter + favorAdapter?.addOnItemChildClickListener( + R.id.iv_favorites_delete, { adapter, view, position -> + val item = adapter.getItem(position) as CollectionData + current = position + showRemoveDialog(item.short_play_id, item.short_play_video_id) + }) + favorAdapter?.addOnItemChildClickListener( + R.id.item_pan, { adapter, view, position -> + val item = adapter.getItem(position) as CollectionData + skip2Detail(item.short_play_id) + }) + historyAdapter?.addOnItemChildClickListener( + R.id.iv_star, { adapter, view, position -> + val item = adapter.getItem(position) as HistoryDataRes.Data + current = position + if (item.is_collect == 0) { + mViewModel.doCollect(item.short_play_id, item.short_play_video_id) + } else { + showRemoveDialog(item.short_play_id, item.short_play_video_id) + } + }) + historyAdapter?.addOnItemChildClickListener(R.id.item_pan, { adapter, view, position -> + val item = adapter.getItem(position) as HistoryDataRes.Data + skip2Detail(item.short_play_id) }) -// if (NetworkUtils.isConnected()) { -// showLoading() -// mViewModel.getCollections(page) -// } else { -// showNetError() -// } -// binding?.srMyList?.setOnRefreshListener { -// page = 1 -// mViewModel.getCollections(page) -// } -// binding?.srMyList?.setOnLoadMoreListener { -// page++ -// mViewModel.getCollections(page) -// } -// binding?.exampleIvEditMyFavorites?.setOnClickListener { -// if (!edit) { -// edit = true -// binding?.exampleIvEditMyFavorites?.setImageResource(R.drawable.iv_edit_favorites_complete) -// myListAdapter?.eidt = true -// binding?.tvTitle?.text = "Delete" -// binding.tvTitle.background = context?.getDrawable(R.drawable.iv_list_title_bg_h) -// myListAdapter?.notifyDataSetChanged() -// } else { -// edit = false -// binding?.exampleIvEditMyFavorites?.setImageResource(R.drawable.iv_edit_favorites) -// binding.tvTitle.background = context?.getDrawable(R.drawable.iv_list_title_bg) -// myListAdapter?.eidt = false -// binding?.tvTitle?.text = "Favorites" -// myListAdapter?.notifyDataSetChanged() -// } -// } -// binding.ivHis.setOnClickListener { -// startActivity( -// Intent( -// requireContext(), -// HistoryActivity::class.java -// )) -// } + mViewModel.collectionsData.observe(this) { + if (it != null) { + if (page == 1) { + favorAdapter?.submitList(it.data?.list) + hideLoading() + hideNetError() + } else if (it.data?.list?.isNotEmpty() == true) { + favorAdapter?.addAll(it.data.list) + hideLoading() + hideNetError() + } else { + hideLoading() + toast(getString(R.string.no_more_data)) + } + } + } + mViewModel.historysData.observe(this) { + if (it != null) { + if (page == 1) { + historyAdapter?.submitList(it.data?.list) + hideLoading() + hideNetError() + } else if (it.data?.list?.isNotEmpty() == true) { + historyAdapter?.addAll(it.data.list) + hideLoading() + hideNetError() + } + } + } + mViewModel.collectData.observe(this) { + if (it != null) { + toast(getString(R.string.success)) + val item = historyAdapter?.getItem(current) as HistoryDataRes.Data + item.is_collect = 1 - item.is_collect + historyAdapter?.notifyItemChanged(current) + } + } + mViewModel.cancelCollectData.observe(this) { + if (it != null) { + toast(getString(R.string.success)) + if (mode == 0) { + favorAdapter?.removeAt(current) + } else { + val item = historyAdapter?.getItem(current) as HistoryDataRes.Data + item.is_collect = 1 - item.is_collect + historyAdapter?.notifyItemChanged(current) + } + } else { + toast(R.string.network_error) + } + } + binding.srMyList.setOnRefreshListener { + onPageResume() + } + binding.srMyList.setOnLoadMoreListener { + page++ + mViewModel.getCollections(page) + } + } + + fun skip2Detail(shortPlayId: Int) { + startActivity( + Intent(requireContext(), PlayerDetailActivity::class.java).apply { + putExtra( + Constants.CONSTANTS_short_play_id, + shortPlayId + ) + }) + } + + override fun onPageResume() { + super.onPageResume() + if (NetworkUtils.isConnected()) { + page = 1 + if (mode == 0) { + mViewModel.getCollections(page) + } else { + mViewModel.myHistorys(page) + } + } else { + showNetError() + } } override fun center() { -// mViewModel.collectionsData.observe(this) { -// if (it != null) { -// if (page == 1) { -// myListAdapter = MyListAdapter() -// val manager = QuickGridLayoutManager(requireContext(), 3) -// binding?.rvMyList?.layoutManager = manager -// binding?.rvMyList?.adapter = myListAdapter -// myListAdapter?.submitList(it.data?.list) -// myListAdapter?.isStateViewEnable = true -// myListAdapter?.setStateViewLayout(requireContext(), R.layout.layout_emptyview) -// myListAdapter?.addOnItemChildClickListener(R.id.iv_favorites_delete) { adapter, view, position -> -// current = position -// val collectionData = -// adapter.getItem(position) as CollectionRes.CollectionData -// DialogUtils.unFavoriteDialog( -// requireContext(), -// collectionData.short_play_id, -// collectionData.short_play_video_id, -// mViewModel -// ) -// } -// myListAdapter?.setOnItemClickListener { adapter, view, position -> -// val data = adapter.getItem(position) as CollectionRes.CollectionData -// startActivity( -// Intent( -// requireContext(), -// PlayerDetailActivity::class.java -// ).apply { -// putExtra( -// Constants.CONSTANTS_short_play_id, -// data.short_play_id -// ) -// }) -// } -// } else { -// if (it.data?.list?.isNotEmpty() == true) { -// myListAdapter?.addAll(it.data.list) -// } else { -// toast(getString(R.string.no_more_data)) -// } -// } -// hideLoading() -// hideNetError() -// } else { -// hideLoading() -// toast(R.string.network_error) -// } -// binding?.srMyList?.finishRefresh() -// binding?.srMyList?.finishLoadMore() -// } -// -// mViewModel.cancelCollectData.observe(this) { -// if (it != null) { -// toast(getString(R.string.success)) -// myListAdapter?.removeAt(current) -// myListAdapter?.notifyDataSetChanged() -// } else { -// toast(R.string.network_error) -// } -// } + } override fun getViewBinding(): FragmentSavedBinding { @@ -193,4 +187,23 @@ class SavedFragment : BaseFragment() { } } + private fun showRemoveDialog(shortPlayId: Int, shortPlayVideoId: Int) { + DialogUtils.showDoubleBtnDialog( + requireContext(), + R.string.dialog_title_remove_favorites, + R.string.dialog_content_remove_favorites, + R.string.dialog_confirm_btn_remove_favorites, + R.string.dialog_cancel_btn_remove_favorites, + R.drawable.ic_star_remove, + object : DialogUtils.DialogOnClickListener { + + override fun onConfirmClick() { + mViewModel.doCancelCollect(shortPlayId, shortPlayVideoId) + } + + override fun onCancelClick() { + } + }) + } } + diff --git a/app/src/main/java/com/jia/er/nebuluxe/app/home/SearchActivity.kt b/app/src/main/java/com/jia/er/nebuluxe/app/home/SearchActivity.kt index 6564637..2bcf991 100644 --- a/app/src/main/java/com/jia/er/nebuluxe/app/home/SearchActivity.kt +++ b/app/src/main/java/com/jia/er/nebuluxe/app/home/SearchActivity.kt @@ -1,85 +1,142 @@ -package com.jia.er.nebuluxe.app.home; +package com.jia.er.nebuluxe.app.home -import static com.blankj.utilcode.util.KeyboardUtils.hideSoftInput; +import android.content.Intent +import android.text.TextUtils +import android.view.KeyEvent +import android.view.View +import android.view.inputmethod.EditorInfo +import android.widget.TextView +import androidx.lifecycle.ViewModelProvider +import androidx.recyclerview.widget.LinearLayoutManager +import com.blankj.utilcode.util.KeyboardUtils +import com.bumptech.glide.Glide +import com.jia.er.nebuluxe.app.R +import com.jia.er.nebuluxe.app.basics.BaseActivity +import com.jia.er.nebuluxe.app.basics.Constants +import com.jia.er.nebuluxe.app.data.ExampleKeywordDataRes +import com.jia.er.nebuluxe.app.databinding.ActivitySearchBinding +import com.jia.er.nebuluxe.app.net.MainViewModel +import com.jia.er.nebuluxe.app.utils.Memory +import com.jia.er.nebuluxe.app.utils.toast +import com.jia.er.nebuluxe.app.video.PlayerDetailActivity -import android.text.TextUtils; -import android.view.KeyEvent; -import android.view.View; -import android.view.inputmethod.EditorInfo; -import android.widget.TextView; +class SearchActivity : BaseActivity() { + var searchResultAdapter: InputResultAdapter? = null + private val mViewModel by lazy { ViewModelProvider(this)[MainViewModel::class.java] } -import androidx.annotation.NonNull; -import androidx.recyclerview.widget.LinearLayoutManager; -import androidx.viewbinding.ViewBinding; - -import com.jia.er.nebuluxe.app.basics.BaseActivity; -import com.jia.er.nebuluxe.app.databinding.ActivityMainBinding; -import com.jia.er.nebuluxe.app.databinding.ActivitySearchBinding; -import com.jia.er.nebuluxe.app.utils.AppUtil; -import com.jia.er.nebuluxe.app.utils.LOG; - -import java.util.ArrayList; -import java.util.List; - -public class SearchActivity extends BaseActivity { - InputResultAdapter adapter2; - - @Override - protected void top() { - InputHistoryAdapter adapter = new InputHistoryAdapter(); - LinearLayoutManager manager = new LinearLayoutManager(this); - manager.setOrientation(LinearLayoutManager.HORIZONTAL); - binding.rvInputHistory.setLayoutManager(manager); - binding.rvInputHistory.setAdapter(adapter); - - LinearLayoutManager manager2 = new LinearLayoutManager(this); - manager2.setOrientation(LinearLayoutManager.VERTICAL); - adapter2 = new InputResultAdapter(); - binding.rvResult.setLayoutManager(manager2); - binding.rvResult.setAdapter(adapter2); - List debug = new ArrayList<>(); - debug.add("Love"); - debug.add("CEO"); - debug.add("Recersal Of Fate"); - adapter.setItems(debug); - binding.tvInput.setOnEditorActionListener((textView, actionId, keyEvent) -> { - String input = binding.tvInput.getText() == null ? "" : binding.tvInput.getText().toString(); - LOG.d("SearchActivity.actionId", String.valueOf(actionId)); - LOG.d("SearchActivity.input", input); - if (actionId == EditorInfo.IME_ACTION_SEARCH || actionId == EditorInfo.IME_ACTION_SEND) { - if (TextUtils.isEmpty(input)) { - binding.emptyPan.setVisibility(View.VISIBLE); - binding.resultPan.setVisibility(View.GONE); - } else { - binding.emptyPan.setVisibility(View.GONE); - binding.resultPan.setVisibility(View.VISIBLE); - onSearch(input); - } - return true; - } - return false; - }); - } - - private void onSearch(String input) { - adapter2.setKeyword(input); - List debug = new ArrayList<>(); - for (int i = 0; i < input.length(); i++) { - debug.add(input + " : DEBUG " + i); + override fun top() { + val adapter = InputHistoryAdapter() + val manager = LinearLayoutManager(this) + manager.setOrientation(LinearLayoutManager.HORIZONTAL) + binding.rvInputHistory.setLayoutManager(manager) + binding.rvInputHistory.setAdapter(adapter) + val manager2 = LinearLayoutManager(this) + manager2.setOrientation(LinearLayoutManager.VERTICAL) + searchResultAdapter = InputResultAdapter() + binding.rvResult.setLayoutManager(manager2) + binding.rvResult.setAdapter(searchResultAdapter) + val searchHistory: MutableList = Memory.getSearch() + val hasHistory = !searchHistory.isEmpty() + binding.btnDelete.visibility = if (hasHistory) View.VISIBLE else View.GONE + binding.rvInputHistory.visibility = if (hasHistory) View.VISIBLE else View.GONE + adapter.items = searchHistory + adapter.setOnItemClickListener { adapter, view, position -> + val data = adapter.getItem(position) as String + binding.tvInput.setText(data) + onSearch(data) } - adapter2.setItems(debug); - adapter2.notifyDataSetChanged(); - hideSoftInput(this); + binding.btnDelete.setOnClickListener { + Memory.clearSearchHistory() + binding.rvInputHistory.visibility = View.GONE + binding.btnDelete.visibility = View.GONE + } + binding.tvInput.setOnEditorActionListener({ textView: TextView?, actionId: Int, keyEvent: KeyEvent? -> + val input = + if (binding.tvInput.getText() == null) "" else binding.tvInput.getText().toString() + if (actionId == EditorInfo.IME_ACTION_SEARCH || actionId == EditorInfo.IME_ACTION_SEND) { + if (!TextUtils.isEmpty(input)) { + onSearch(input) + } + true + } + false + }) + searchResultAdapter?.setOnItemClickListener() { adapter, view, position -> + val data = adapter.getItem(position) + data?.short_play_id?.let { id -> + openDetail(id) + } + } + val itemClickListener: View.OnClickListener = View.OnClickListener { v -> + if (v.getTag() is ExampleKeywordDataRes.KeywordData) { + val data = v.getTag() as ExampleKeywordDataRes.KeywordData + openDetail(data.short_play_id) + } + } + binding.ivEmpty1.setOnClickListener(itemClickListener) + binding.ivEmpty2.setOnClickListener(itemClickListener) + binding.ivEmpty3.setOnClickListener(itemClickListener) + binding.ivEmpty4.setOnClickListener(itemClickListener) + binding.ivEmpty5.setOnClickListener(itemClickListener) + binding.btnMore.setOnClickListener { skip2Activity(HotActivity::class.java) } + mViewModel.hotsData.observe(this) { + val lists = it.data?.list.orEmpty().take(5) // 限制最多5个元素 + lists.size.let { position -> + binding.ivEmpty1.visibility = if (position >= 1) View.VISIBLE else View.GONE + binding.ivEmpty2.visibility = if (position >= 2) View.VISIBLE else View.GONE + binding.ivEmpty3.visibility = if (position >= 3) View.VISIBLE else View.GONE + binding.ivEmpty4.visibility = if (position >= 4) View.VISIBLE else View.GONE + binding.ivEmpty5.visibility = if (position >= 5) View.VISIBLE else View.GONE + binding.ivEmpty1.setTag(it.data?.list[0]) + binding.ivEmpty2.setTag(it.data?.list[1]) + binding.ivEmpty3.setTag(it.data?.list[2]) + binding.ivEmpty4.setTag(it.data?.list[3]) + binding.ivEmpty5.setTag(it.data?.list[4]) + Glide.with(this).load(it.data?.list[0]?.image_url).into(binding.ivEmpty1) + Glide.with(this).load(it.data?.list[1]?.image_url).into(binding.ivEmpty2) + Glide.with(this).load(it.data?.list[2]?.image_url).into(binding.ivEmpty3) + Glide.with(this).load(it.data?.list[3]?.image_url).into(binding.ivEmpty4) + Glide.with(this).load(it.data?.list[4]?.image_url).into(binding.ivEmpty5) + + } + } + mViewModel.searchData.observe(this) { + searchResultAdapter?.items = it?.data?.list.orEmpty() + if (it?.data?.list.isNullOrEmpty()) { + toast(R.string.toast_no_result_of_keyword) + binding.emptyPan.visibility = View.VISIBLE + binding.resultPan.visibility = View.GONE + } else { + binding.emptyPan.visibility = View.GONE + binding.resultPan.visibility = View.VISIBLE + } + searchResultAdapter?.notifyDataSetChanged() + } + mViewModel.hots() } - @Override - protected void center() { - + private fun openDetail(id: Int) { + startActivity( + Intent( + this, PlayerDetailActivity::class.java + ).apply { + putExtra( + Constants.CONSTANTS_short_play_id, id + ) + }) } - @NonNull - @Override - protected ActivitySearchBinding getViewBinding() { - return ActivitySearchBinding.inflate(getLayoutInflater()); + private fun onSearch(input: String) { + Memory.saveSearchString(input) + mViewModel.searchDataByInput(input) + searchResultAdapter!!.setKeyword(input) + KeyboardUtils.hideSoftInput(this) + } + + override fun center() { + } + + override fun getViewBinding(): ActivitySearchBinding { + return ActivitySearchBinding.inflate(getLayoutInflater()) } } diff --git a/app/src/main/java/com/jia/er/nebuluxe/app/net/MainViewModel.kt b/app/src/main/java/com/jia/er/nebuluxe/app/net/MainViewModel.kt index dee5ef1..98cb6e8 100644 --- a/app/src/main/java/com/jia/er/nebuluxe/app/net/MainViewModel.kt +++ b/app/src/main/java/com/jia/er/nebuluxe/app/net/MainViewModel.kt @@ -33,7 +33,6 @@ import com.jia.er.nebuluxe.app.data.UploadHistoryReq import com.jia.er.nebuluxe.app.data.UserInfoRes import com.jia.er.nebuluxe.app.data.UserRegisterRes import com.jia.er.nebuluxe.app.data.VideoListDataRes -import com.jia.er.nebuluxe.app.net.MainRequest class MainViewModel : ViewModel() { private val userRegisterLiveData = MutableLiveData>() @@ -100,15 +99,23 @@ class MainViewModel : ViewModel() { private val searchLiveData = MutableLiveData>() val searchData: MutableLiveData> get() = searchLiveData - fun getVideoList(search: String) { + fun searchDataByInput(search: String) { MainRequest.getVideoList(search).observeForever { result -> searchLiveData.value = result.getOrNull() } } +// private val hotsLiveData = MutableLiveData>() +// val hotsData: MutableLiveData> get() = hotsLiveData +// fun hots() { +// MainRequest.hots().observeForever { result -> +// hotsLiveData.value = result.getOrNull() +// } +// } + private val videoListLiveData = MutableLiveData>() val videoListData: MutableLiveData> get() = videoListLiveData - fun getVideoList(current_page: Int, category_id: Int) { + fun searchDataByInput(current_page: Int, category_id: Int) { MainRequest.getVideoList(current_page, category_id).observeForever { result -> videoListLiveData.value = result.getOrNull() } diff --git a/app/src/main/java/com/jia/er/nebuluxe/app/utils/DialogUtils.kt b/app/src/main/java/com/jia/er/nebuluxe/app/utils/DialogUtils.kt index ccf5fcb..1b33bb4 100644 --- a/app/src/main/java/com/jia/er/nebuluxe/app/utils/DialogUtils.kt +++ b/app/src/main/java/com/jia/er/nebuluxe/app/utils/DialogUtils.kt @@ -1,20 +1,12 @@ package com.jia.er.nebuluxe.app.utils import android.content.Context -import android.graphics.Color -import android.text.Spannable -import android.text.SpannableString -import android.text.SpannedString -import android.text.style.ForegroundColorSpan -import android.util.Log -import android.widget.TextView import androidx.appcompat.widget.AppCompatImageView import androidx.appcompat.widget.AppCompatTextView import com.jia.er.nebuluxe.app.R import com.jia.er.nebuluxe.app.basics.CommonDialog import com.jia.er.nebuluxe.app.net.MainViewModel import com.jia.er.nebuluxe.app.ui.UnFavoriteDialog -import com.jia.er.nebuluxe.app.utils.singleClick object DialogUtils { @@ -43,20 +35,40 @@ object DialogUtils { fun onCancelClick() } - fun showDoubleBtnDialog( + fun showDoubleBtnDialog( context: Context, - title: String, - content: String, - confirmStr: String, - cancelStr: String, + t: T, + c: T, + confirmBtnStr: T, + cancelBtnStr: T, iconRes: Int, listener: DialogOnClickListener ) { + val title = when (t) { + is String -> t + is Int -> context.getString(t) + else -> "" + } + val content = when (c) { + is String -> c + is Int -> context.getString(c) + else -> "" + } + val confirm = when (confirmBtnStr) { + is String -> confirmBtnStr + is Int -> context.getString(confirmBtnStr) + else -> "" + } + val cancel = when (cancelBtnStr) { + is String -> cancelBtnStr + is Int -> context.getString(cancelBtnStr) + else -> "" + } singleClick { val dialog = CommonDialog( CommonDialog.Builder(context).title(title).content(content).centerIcon(iconRes) - .addString(R.id.dialog_confirm, confirmStr) - .addString(R.id.dialog_cancel, cancelStr) + .addString(R.id.dialog_confirm, confirm) + .addString(R.id.dialog_cancel, cancel) .addOnClick({ commonDialog, vId -> commonDialog.dismiss() if (vId == R.id.dialog_confirm) { diff --git a/app/src/main/java/com/jia/er/nebuluxe/app/utils/Memory.kt b/app/src/main/java/com/jia/er/nebuluxe/app/utils/Memory.kt index d647cc9..27b15ee 100644 --- a/app/src/main/java/com/jia/er/nebuluxe/app/utils/Memory.kt +++ b/app/src/main/java/com/jia/er/nebuluxe/app/utils/Memory.kt @@ -34,6 +34,10 @@ object Memory { return Gson().fromJson(string, UserInfoRes::class.java) } + fun clearSearchHistory() { + getMMKV().putString(CONSTANTS_SEARCH_STRINGExample, "[]") + } + fun saveSearchString(search: String) { val strings = getSearch() if (!strings.contains(search)) { diff --git a/app/src/main/java/com/jia/er/nebuluxe/app/utils/StringUtil.java b/app/src/main/java/com/jia/er/nebuluxe/app/utils/StringUtil.java new file mode 100644 index 0000000..f7c38bd --- /dev/null +++ b/app/src/main/java/com/jia/er/nebuluxe/app/utils/StringUtil.java @@ -0,0 +1,10 @@ +package com.jia.er.nebuluxe.app.utils; + +public class StringUtil { + public static String getWatchNum(long num) { + if (num < 1000) { + return num + ""; + } + return num / 1000 + "." + num % 1000 / 100 + "k"; + } +} diff --git a/app/src/main/java/com/jia/er/nebuluxe/app/utils/TextViewUtil.java b/app/src/main/java/com/jia/er/nebuluxe/app/utils/TextViewUtil.java index adc68bb..5cab271 100644 --- a/app/src/main/java/com/jia/er/nebuluxe/app/utils/TextViewUtil.java +++ b/app/src/main/java/com/jia/er/nebuluxe/app/utils/TextViewUtil.java @@ -93,10 +93,11 @@ public class TextViewUtil { LOG.e("TextViewUtil", " tv = " + con + " \nlight = " + light); return ""; } + LOG.d("TextViewUtil.96", con + "->" + light); SpannableString spannableString = new SpannableString(con); ForegroundColorSpan colorSpan = new ForegroundColorSpan(MyApplication.context.getResources() .getColor(color)); - int start = con.indexOf(light); + int start = con.toLowerCase().indexOf(light.toLowerCase()); int end = start + light.length(); spannableString.setSpan(colorSpan, start, end, Spanned.SPAN_INCLUSIVE_EXCLUSIVE); return spannableString; @@ -125,7 +126,6 @@ public class TextViewUtil { // public static CharSequence get123(String bigAndColor, String color, String normal) { // return getTextColorSize(bigAndColor + color + normal, bigAndColor + color, bigAndColor, R.color.text_color_black, 1.6F); // } - public static CharSequence getTextColorSize(String con, String change, int color, float colorSizeRate) { return getTextColorSize(con, change, change, color, colorSizeRate); diff --git a/app/src/main/res/layout/activity_search.xml b/app/src/main/res/layout/activity_search.xml index 7acaa1b..3594a1a 100644 --- a/app/src/main/res/layout/activity_search.xml +++ b/app/src/main/res/layout/activity_search.xml @@ -1,6 +1,7 @@ @@ -80,6 +81,7 @@ android:layout_height="@dimen/padding_40px" android:padding="@dimen/padding_11px" android:src="@drawable/ic_delete_gray" + android:visibility="gone" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent" /> @@ -87,6 +89,7 @@ android:id="@+id/rv_input_history" android:layout_width="0dp" android:layout_height="@dimen/padding_40px" + android:visibility="gone" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toLeftOf="@id/btn_delete" app:layout_constraintTop_toTopOf="parent" /> @@ -96,7 +99,8 @@ android:layout_height="wrap_content" android:background="@drawable/bg_conner_20px_black_light" android:padding="@dimen/padding_10px" - app:layout_constraintTop_toBottomOf="@id/rv_input_history"> + app:layout_constraintTop_toBottomOf="@id/rv_input_history" + tools:visibility="gone"> @@ -198,11 +209,13 @@ + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintTop_toBottomOf="@id/search_pan" + tools:visibility="visible"> \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_saved.xml b/app/src/main/res/layout/fragment_saved.xml index 55c17f5..01e1409 100644 --- a/app/src/main/res/layout/fragment_saved.xml +++ b/app/src/main/res/layout/fragment_saved.xml @@ -40,17 +40,28 @@ - + android:layout_height="wrap_content"> - + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_saved_favory.xml b/app/src/main/res/layout/item_saved_favory.xml index 6a06051..cb8c366 100644 --- a/app/src/main/res/layout/item_saved_favory.xml +++ b/app/src/main/res/layout/item_saved_favory.xml @@ -2,12 +2,13 @@ + app:layout_constraintTop_toBottomOf="@id/iv" /> + android:layout_width="@dimen/padding_30px" + android:layout_height="@dimen/padding_30px" + android:padding="@dimen/padding_6px" + android:src="@drawable/ic_star_select" + app:layout_constraintRight_toRightOf="@id/iv" + app:layout_constraintTop_toTopOf="@id/iv" /> \ No newline at end of file diff --git a/app/src/main/res/layout/item_saved_history.xml b/app/src/main/res/layout/item_saved_history.xml index 1114e98..4d143ad 100644 --- a/app/src/main/res/layout/item_saved_history.xml +++ b/app/src/main/res/layout/item_saved_history.xml @@ -2,6 +2,7 @@ @@ -69,7 +70,7 @@ android:textColor="@color/text_color_gray_DF" android:textSize="@dimen/text_size_10px" app:layout_constraintBottom_toBottomOf="parent" - app:layout_constraintLeft_toRightOf="@id/example_iv_icon_ceo" /> + app:layout_constraintLeft_toRightOf="@id/iv" /> What Everyone’s Watching Join the trend Search Results + Remove from Favorites? + This drama will be removed from your favorites. + Remove + Cancel + 未搜索到结果 \ No newline at end of file