From 991bde743e499142625778b59d20de834fe446a3 Mon Sep 17 00:00:00 2001 From: FongMi Date: Thu, 2 Feb 2023 18:57:18 +0800 Subject: [PATCH] [mobile] support filter - part 1 --- .../android/tv/ui/adapter/FilterAdapter.java | 64 +++++++++++++++++++ .../android/tv/ui/adapter/HistoryAdapter.java | 9 ++- .../android/tv/ui/adapter/TypeAdapter.java | 4 +- .../android/tv/ui/adapter/ValueAdapter.java | 58 +++++++++++++++++ .../android/tv/ui/fragment/VodFragment.java | 23 ++++++- .../tv/ui/fragment/child/TypeFragment.java | 58 +++++++++++++++-- app/src/mobile/res/layout/adapter_filter.xml | 8 +++ app/src/mobile/res/layout/adapter_value.xml | 12 ++++ app/src/mobile/res/layout/fragment_site.xml | 6 +- app/src/mobile/res/layout/fragment_type.xml | 39 ++++++++--- 10 files changed, 257 insertions(+), 24 deletions(-) create mode 100644 app/src/mobile/java/com/fongmi/android/tv/ui/adapter/FilterAdapter.java create mode 100644 app/src/mobile/java/com/fongmi/android/tv/ui/adapter/ValueAdapter.java create mode 100644 app/src/mobile/res/layout/adapter_filter.xml create mode 100644 app/src/mobile/res/layout/adapter_value.xml diff --git a/app/src/mobile/java/com/fongmi/android/tv/ui/adapter/FilterAdapter.java b/app/src/mobile/java/com/fongmi/android/tv/ui/adapter/FilterAdapter.java new file mode 100644 index 000000000..b2acf05c9 --- /dev/null +++ b/app/src/mobile/java/com/fongmi/android/tv/ui/adapter/FilterAdapter.java @@ -0,0 +1,64 @@ +package com.fongmi.android.tv.ui.adapter; + +import android.view.LayoutInflater; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import com.fongmi.android.tv.bean.Filter; +import com.fongmi.android.tv.databinding.AdapterFilterBinding; + +import java.util.ArrayList; +import java.util.List; + +public class FilterAdapter extends RecyclerView.Adapter { + + private final ValueAdapter.OnClickListener mListener; + private final List mItems; + + public FilterAdapter(ValueAdapter.OnClickListener listener) { + this.mListener = listener; + this.mItems = new ArrayList<>(); + } + + static class ViewHolder extends RecyclerView.ViewHolder { + + private final AdapterFilterBinding binding; + + ViewHolder(@NonNull AdapterFilterBinding binding) { + super(binding.getRoot()); + this.binding = binding; + } + } + + public void addAll(List items) { + mItems.addAll(items); + notifyDataSetChanged(); + } + + public void clear() { + mItems.clear(); + notifyDataSetChanged(); + } + + @Override + public int getItemCount() { + return mItems.size(); + } + + @NonNull + @Override + public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + return new ViewHolder(AdapterFilterBinding.inflate(LayoutInflater.from(parent.getContext()), parent, false)); + } + + @Override + public void onBindViewHolder(@NonNull ViewHolder holder, int position) { + Filter item = mItems.get(position); + holder.binding.recycler.setHasFixedSize(true); + holder.binding.recycler.setLayoutManager(new LinearLayoutManager(holder.itemView.getContext(), LinearLayoutManager.HORIZONTAL, false)); + holder.binding.recycler.setAdapter(new ValueAdapter(mListener, item)); + } +} \ No newline at end of file diff --git a/app/src/mobile/java/com/fongmi/android/tv/ui/adapter/HistoryAdapter.java b/app/src/mobile/java/com/fongmi/android/tv/ui/adapter/HistoryAdapter.java index e638a6c81..3fd1b02a0 100644 --- a/app/src/mobile/java/com/fongmi/android/tv/ui/adapter/HistoryAdapter.java +++ b/app/src/mobile/java/com/fongmi/android/tv/ui/adapter/HistoryAdapter.java @@ -1,17 +1,17 @@ package com.fongmi.android.tv.ui.adapter; import android.view.LayoutInflater; +import android.view.View; import android.view.ViewGroup; import androidx.annotation.NonNull; import androidx.recyclerview.widget.RecyclerView; -import com.bumptech.glide.Glide; -import com.fongmi.android.tv.App; import com.fongmi.android.tv.R; import com.fongmi.android.tv.api.ApiConfig; import com.fongmi.android.tv.bean.History; import com.fongmi.android.tv.databinding.AdapterVodBinding; +import com.fongmi.android.tv.utils.ImgUtil; import com.fongmi.android.tv.utils.ResUtil; import java.util.ArrayList; @@ -77,10 +77,13 @@ public class HistoryAdapter extends RecyclerView.Adapter mListener.onItemClick(item)); holder.binding.getRoot().setOnLongClickListener(view -> mListener.onLongClick(item)); - Glide.with(App.get()).load(item.getVodPic()).error(R.drawable.ic_img_error).placeholder(R.drawable.ic_img_loading).into(holder.binding.image); + ImgUtil.loadHistory(item.getVodPic(), holder.binding.image); } } diff --git a/app/src/mobile/java/com/fongmi/android/tv/ui/adapter/TypeAdapter.java b/app/src/mobile/java/com/fongmi/android/tv/ui/adapter/TypeAdapter.java index 4f4cdcfe8..171c2012f 100644 --- a/app/src/mobile/java/com/fongmi/android/tv/ui/adapter/TypeAdapter.java +++ b/app/src/mobile/java/com/fongmi/android/tv/ui/adapter/TypeAdapter.java @@ -29,7 +29,7 @@ public class TypeAdapter extends RecyclerView.Adapter { public interface OnClickListener { - void onItemClick(Class item); + void onItemClick(int position, Class item); } static class ViewHolder extends RecyclerView.ViewHolder { @@ -99,6 +99,6 @@ public class TypeAdapter extends RecyclerView.Adapter { holder.binding.text.setActivated(item.isActivated()); holder.binding.text.setCompoundDrawablePadding(ResUtil.dp2px(4)); holder.binding.text.setCompoundDrawablesRelativeWithIntrinsicBounds(0, 0, item.getIcon(), 0); - holder.binding.getRoot().setOnClickListener(v -> mListener.onItemClick(item)); + holder.binding.getRoot().setOnClickListener(v -> mListener.onItemClick(position, item)); } } \ No newline at end of file diff --git a/app/src/mobile/java/com/fongmi/android/tv/ui/adapter/ValueAdapter.java b/app/src/mobile/java/com/fongmi/android/tv/ui/adapter/ValueAdapter.java new file mode 100644 index 000000000..017a330f0 --- /dev/null +++ b/app/src/mobile/java/com/fongmi/android/tv/ui/adapter/ValueAdapter.java @@ -0,0 +1,58 @@ +package com.fongmi.android.tv.ui.adapter; + +import android.view.LayoutInflater; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.fongmi.android.tv.bean.Filter; +import com.fongmi.android.tv.databinding.AdapterValueBinding; + +import java.util.List; + +public class ValueAdapter extends RecyclerView.Adapter { + + private final OnClickListener mListener; + private final List mItems; + private final String mKey; + + public ValueAdapter(OnClickListener listener, Filter filter) { + this.mListener = listener; + this.mItems = filter.getValue(); + this.mKey = filter.getKey(); + } + + public interface OnClickListener { + void onItemClick(String key, Filter.Value item); + } + + static class ViewHolder extends RecyclerView.ViewHolder { + + private final AdapterValueBinding binding; + + ViewHolder(@NonNull AdapterValueBinding binding) { + super(binding.getRoot()); + this.binding = binding; + } + } + + @Override + public int getItemCount() { + return mItems.size(); + } + + @NonNull + @Override + public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + return new ViewHolder(AdapterValueBinding.inflate(LayoutInflater.from(parent.getContext()), parent, false)); + } + + @Override + public void onBindViewHolder(@NonNull ViewHolder holder, int position) { + Filter.Value item = mItems.get(position); + holder.binding.text.setText(item.getN()); + holder.binding.text.setActivated(item.isActivated()); + holder.binding.getRoot().setOnClickListener(v -> mListener.onItemClick(mKey, item)); + } +} \ No newline at end of file diff --git a/app/src/mobile/java/com/fongmi/android/tv/ui/fragment/VodFragment.java b/app/src/mobile/java/com/fongmi/android/tv/ui/fragment/VodFragment.java index 70c51e0bd..ff1e5beb4 100644 --- a/app/src/mobile/java/com/fongmi/android/tv/ui/fragment/VodFragment.java +++ b/app/src/mobile/java/com/fongmi/android/tv/ui/fragment/VodFragment.java @@ -37,7 +37,7 @@ import org.greenrobot.eventbus.ThreadMode; import java.util.ArrayList; import java.util.List; -public class VodFragment extends BaseFragment implements SiteCallback { +public class VodFragment extends BaseFragment implements SiteCallback, TypeAdapter.OnClickListener { private FragmentVodBinding mBinding; private SiteViewModel mViewModel; @@ -74,8 +74,8 @@ public class VodFragment extends BaseFragment implements SiteCallback { @Override protected void initEvent() { + mTypeAdapter.setListener(this); mBinding.title.setOnClickListener(this::onTitle); - mTypeAdapter.setListener(item -> mBinding.pager.setCurrentItem(mTypeAdapter.setActivated(item))); mBinding.pager.addOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() { @Override public void onPageSelected(int position) { @@ -127,6 +127,21 @@ public class VodFragment extends BaseFragment implements SiteCallback { RefreshEvent.video(); } + @Override + public void onItemClick(int position, Class item) { + if (position == mBinding.pager.getCurrentItem()) { + updateFilter(position, item); + } else { + mBinding.pager.setCurrentItem(mTypeAdapter.setActivated(item)); + } + } + + private void updateFilter(int position, Class item) { + if (item.getFilter() == null) return; + getFragment().toggleFilter(item.toggleFilter()); + mTypeAdapter.notifyItemChanged(position); + } + @Subscribe(threadMode = ThreadMode.MAIN) public void onRefreshEvent(RefreshEvent event) { if (event.getType() == RefreshEvent.Type.VIDEO) homeContent(); @@ -141,6 +156,10 @@ public class VodFragment extends BaseFragment implements SiteCallback { if (!getSite().getKey().isEmpty()) mViewModel.homeContent(); } + private TypeFragment getFragment() { + return (TypeFragment) mPageAdapter.instantiateItem(mBinding.pager, mBinding.pager.getCurrentItem()); + } + class PageAdapter extends FragmentStatePagerAdapter { private Result result; diff --git a/app/src/mobile/java/com/fongmi/android/tv/ui/fragment/child/TypeFragment.java b/app/src/mobile/java/com/fongmi/android/tv/ui/fragment/child/TypeFragment.java index 2cf5c1eb6..de996c5a4 100644 --- a/app/src/mobile/java/com/fongmi/android/tv/ui/fragment/child/TypeFragment.java +++ b/app/src/mobile/java/com/fongmi/android/tv/ui/fragment/child/TypeFragment.java @@ -16,6 +16,8 @@ import com.fongmi.android.tv.bean.Vod; import com.fongmi.android.tv.databinding.FragmentTypeBinding; import com.fongmi.android.tv.model.SiteViewModel; import com.fongmi.android.tv.ui.activity.BaseFragment; +import com.fongmi.android.tv.ui.adapter.FilterAdapter; +import com.fongmi.android.tv.ui.adapter.ValueAdapter; import com.fongmi.android.tv.ui.adapter.VodAdapter; import com.fongmi.android.tv.ui.custom.CustomScroller; import com.fongmi.android.tv.ui.custom.SpaceItemDecoration; @@ -24,15 +26,16 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.List; -public class TypeFragment extends BaseFragment implements CustomScroller.Callback, VodAdapter.OnClickListener { +public class TypeFragment extends BaseFragment implements CustomScroller.Callback, ValueAdapter.OnClickListener, VodAdapter.OnClickListener { private HashMap mExtend; private FragmentTypeBinding mBinding; + private FilterAdapter mFilterAdapter; private CustomScroller mScroller; private SiteViewModel mViewModel; + private VodAdapter mVodAdapter; private List mFilters; private List mTypeIds; - private VodAdapter mAdapter; private boolean mOpen; public static TypeFragment newInstance(String typeId, String filter, boolean folder) { @@ -74,8 +77,10 @@ public class TypeFragment extends BaseFragment implements CustomScroller.Callbac } private void setRecyclerView() { + mBinding.filter.setHasFixedSize(true); + mBinding.filter.setAdapter(mFilterAdapter = new FilterAdapter(this)); mBinding.recycler.setHasFixedSize(true); - mBinding.recycler.setAdapter(mAdapter = new VodAdapter(this)); + mBinding.recycler.setAdapter(mVodAdapter = new VodAdapter(this)); mBinding.recycler.addOnScrollListener(mScroller = new CustomScroller(this)); mBinding.recycler.setLayoutManager(new GridLayoutManager(getContext(), 3)); mBinding.recycler.addItemDecoration(new SpaceItemDecoration(3, 16)); @@ -86,7 +91,7 @@ public class TypeFragment extends BaseFragment implements CustomScroller.Callbac mViewModel.result.observe(getViewLifecycleOwner(), result -> { mBinding.progressLayout.showContent(isFolder(), result.getList().size()); mScroller.endLoading(result.getList().isEmpty()); - mAdapter.addAll(result.getList()); + mVodAdapter.addAll(result.getList()); checkPage(); }); } @@ -97,17 +102,53 @@ public class TypeFragment extends BaseFragment implements CustomScroller.Callbac } private void checkPage() { - if (mScroller.getPage() != 1 || mAdapter.getItemCount() >= 4 || isFolder()) return; + if (mScroller.getPage() != 1 || mVodAdapter.getItemCount() >= 4 || isFolder()) return; if (mScroller.addPage()) getVideo(getTypeId(), "2"); } private void getVideo(String typeId, String page) { if (isFolder()) mTypeIds.add(typeId); if (isFolder() && !mOpen) mBinding.recycler.scrollToPosition(0); - if (page.equals("1")) mAdapter.clear(); + if (page.equals("1")) mVodAdapter.clear(); mViewModel.categoryContent(ApiConfig.get().getHome().getKey(), typeId, page, true, mExtend); } + private void addFilter() { + mFilterAdapter.addAll(mFilters); + } + + private void clearFilter() { + mFilterAdapter.clear(); + } + + /*private void setClick(ArrayObjectAdapter adapter, String key, Filter.Value item) { + for (int i = 0; i < adapter.size(); i++) ((Filter.Value) adapter.get(i)).setActivated(item); + adapter.notifyArrayItemRangeChanged(0, adapter.size()); + mExtend.put(key, item.getV()); + if (isFolder()) refresh(1); + else getVideo(); + }*/ + + private void refresh(int num) { + String typeId = mTypeIds.get(mTypeIds.size() - num); + mTypeIds = mTypeIds.subList(0, mTypeIds.size() - num); + getVideo(typeId, "1"); + } + + public void toggleFilter(boolean open) { + if (open) addFilter(); + else clearFilter(); + mOpen = open; + } + + public boolean canGoBack() { + return mTypeIds.size() > 1; + } + + public void goBack() { + refresh(2); + } + @Override public void onLoadMore(String page) { if (isFolder()) return; @@ -116,8 +157,11 @@ public class TypeFragment extends BaseFragment implements CustomScroller.Callbac } @Override - public void onItemClick(Vod item) { + public void onItemClick(String key, Filter.Value item) { + } + @Override + public void onItemClick(Vod item) { } @Override diff --git a/app/src/mobile/res/layout/adapter_filter.xml b/app/src/mobile/res/layout/adapter_filter.xml new file mode 100644 index 000000000..ad7e1060c --- /dev/null +++ b/app/src/mobile/res/layout/adapter_filter.xml @@ -0,0 +1,8 @@ + + \ No newline at end of file diff --git a/app/src/mobile/res/layout/adapter_value.xml b/app/src/mobile/res/layout/adapter_value.xml new file mode 100644 index 000000000..a8cabf3b5 --- /dev/null +++ b/app/src/mobile/res/layout/adapter_value.xml @@ -0,0 +1,12 @@ + + \ No newline at end of file diff --git a/app/src/mobile/res/layout/fragment_site.xml b/app/src/mobile/res/layout/fragment_site.xml index fb833707c..036699013 100644 --- a/app/src/mobile/res/layout/fragment_site.xml +++ b/app/src/mobile/res/layout/fragment_site.xml @@ -21,7 +21,8 @@ android:id="@+id/history" android:layout_width="match_parent" android:layout_height="wrap_content" - android:layout_marginTop="16dp" /> + android:layout_marginTop="16dp" + android:nestedScrollingEnabled="false" /> + android:layout_height="match_parent" + android:nestedScrollingEnabled="false" /> diff --git a/app/src/mobile/res/layout/fragment_type.xml b/app/src/mobile/res/layout/fragment_type.xml index 246fd5c86..cb1ca6c6d 100644 --- a/app/src/mobile/res/layout/fragment_type.xml +++ b/app/src/mobile/res/layout/fragment_type.xml @@ -1,18 +1,41 @@ - + android:fillViewport="true"> + + + + + + + + \ No newline at end of file