diff --git a/app/src/leanback/java/com/fongmi/android/tv/ui/activity/CollectActivity.java b/app/src/leanback/java/com/fongmi/android/tv/ui/activity/CollectActivity.java index faea35f93..c27b8cdaa 100644 --- a/app/src/leanback/java/com/fongmi/android/tv/ui/activity/CollectActivity.java +++ b/app/src/leanback/java/com/fongmi/android/tv/ui/activity/CollectActivity.java @@ -158,7 +158,7 @@ public class CollectActivity extends BaseActivity { if (child == null) return; mOldView = child.itemView; mOldView.setActivated(true); - App.post(mRunnable, 200); + App.post(mRunnable, 100); } private final Runnable mRunnable = new Runnable() { diff --git a/app/src/leanback/java/com/fongmi/android/tv/ui/activity/VodActivity.java b/app/src/leanback/java/com/fongmi/android/tv/ui/activity/VodActivity.java index bcda2a45e..e85ddd5a9 100644 --- a/app/src/leanback/java/com/fongmi/android/tv/ui/activity/VodActivity.java +++ b/app/src/leanback/java/com/fongmi/android/tv/ui/activity/VodActivity.java @@ -26,7 +26,7 @@ import com.fongmi.android.tv.bean.Result; import com.fongmi.android.tv.bean.Site; import com.fongmi.android.tv.databinding.ActivityVodBinding; import com.fongmi.android.tv.ui.base.BaseActivity; -import com.fongmi.android.tv.ui.fragment.VodFragment; +import com.fongmi.android.tv.ui.fragment.TypeFragment; import com.fongmi.android.tv.ui.presenter.TypePresenter; import com.fongmi.android.tv.utils.KeyUtil; import com.fongmi.android.tv.utils.ResUtil; @@ -41,7 +41,6 @@ public class VodActivity extends BaseActivity implements TypePresenter.OnClickLi private ActivityVodBinding mBinding; private ArrayObjectAdapter mAdapter; private PageAdapter mPageAdapter; - private boolean coolDown; private View mOldView; public static void start(Activity activity, Result result) { @@ -146,13 +145,8 @@ public class VodActivity extends BaseActivity implements TypePresenter.OnClickLi mAdapter.notifyArrayItemRangeChanged(0, mAdapter.size()); } - private VodFragment getFragment() { - return (VodFragment) mPageAdapter.instantiateItem(mBinding.pager, mBinding.pager.getCurrentItem()); - } - - private void setCoolDown() { - App.post(() -> coolDown = false, 2000); - coolDown = true; + private TypeFragment getFragment() { + return (TypeFragment) mPageAdapter.instantiateItem(mBinding.pager, mBinding.pager.getCurrentItem()); } @Override @@ -168,16 +162,15 @@ public class VodActivity extends BaseActivity implements TypePresenter.OnClickLi @Override public boolean dispatchKeyEvent(KeyEvent event) { if (KeyUtil.isMenuKey(event)) updateFilter((Class) mAdapter.get(mBinding.pager.getCurrentItem())); - if (KeyUtil.isBackKey(event) && event.isLongPress() && getFragment().goRoot()) setCoolDown(); return super.dispatchKeyEvent(event); } @Override protected void onBackInvoked() { Class item = (Class) mAdapter.get(mBinding.pager.getCurrentItem()); - if (item.getFilter() != null && item.getFilter()) updateFilter(item); + if (item != null && item.getFilter() != null && item.getFilter()) updateFilter(item); else if (getFragment().canBack()) getFragment().goBack(); - else if (!coolDown) super.onBackInvoked(); + else super.onBackInvoked(); } class PageAdapter extends FragmentStatePagerAdapter { @@ -190,7 +183,7 @@ public class VodActivity extends BaseActivity implements TypePresenter.OnClickLi @Override public Fragment getItem(int position) { Class type = (Class) mAdapter.get(position); - return VodFragment.newInstance(getKey(), type.getTypeId(), type.getStyle(), type.getExtend(false), "1".equals(type.getTypeFlag())); + return TypeFragment.newInstance(getKey(), type.getTypeId(), type.getStyle(), type.getExtend(false), "1".equals(type.getTypeFlag())); } @Override diff --git a/app/src/leanback/java/com/fongmi/android/tv/ui/base/BaseFragment.java b/app/src/leanback/java/com/fongmi/android/tv/ui/base/BaseFragment.java index f00529fec..a506737ed 100644 --- a/app/src/leanback/java/com/fongmi/android/tv/ui/base/BaseFragment.java +++ b/app/src/leanback/java/com/fongmi/android/tv/ui/base/BaseFragment.java @@ -14,8 +14,6 @@ public abstract class BaseFragment extends Fragment { protected abstract ViewBinding getBinding(@NonNull LayoutInflater inflater, @Nullable ViewGroup container); - private boolean init; - @Nullable @Override public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { @@ -25,29 +23,12 @@ public abstract class BaseFragment extends Fragment { @Override public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { initView(); + initEvent(); } protected void initView() { } - protected void initData() { - } - - private void onVisible() { - if (init) return; - initData(); - init = true; - } - - @Override - public void setUserVisibleHint(boolean isVisibleToUser) { - super.setUserVisibleHint(isVisibleToUser); - if (isVisibleToUser) if (isResumed()) onVisible(); - } - - @Override - public void onResume() { - super.onResume(); - if (getUserVisibleHint()) onVisible(); + protected void initEvent() { } } diff --git a/app/src/leanback/java/com/fongmi/android/tv/ui/custom/CustomVerticalGridView.java b/app/src/leanback/java/com/fongmi/android/tv/ui/custom/CustomVerticalGridView.java index 577ab0c1f..cbdee5fd7 100644 --- a/app/src/leanback/java/com/fongmi/android/tv/ui/custom/CustomVerticalGridView.java +++ b/app/src/leanback/java/com/fongmi/android/tv/ui/custom/CustomVerticalGridView.java @@ -64,6 +64,11 @@ public class CustomVerticalGridView extends VerticalGridView { if (views != null) for (View view : views) view.setVisibility(View.VISIBLE); } + public boolean isHeaderVisible() { + if (views != null) for (View view : views) if (view.getId() == R.id.recycler && view.getVisibility() == View.VISIBLE) return true; + return false; + } + @Override public boolean dispatchKeyEvent(KeyEvent event) { if (event.getAction() != KeyEvent.ACTION_DOWN) return super.dispatchKeyEvent(event); diff --git a/app/src/leanback/java/com/fongmi/android/tv/ui/fragment/CollectFragment.java b/app/src/leanback/java/com/fongmi/android/tv/ui/fragment/CollectFragment.java index 7c319c5ec..7c02eb469 100644 --- a/app/src/leanback/java/com/fongmi/android/tv/ui/fragment/CollectFragment.java +++ b/app/src/leanback/java/com/fongmi/android/tv/ui/fragment/CollectFragment.java @@ -69,6 +69,7 @@ public class CollectFragment extends BaseFragment implements CustomScroller.Call protected void initView() { setRecyclerView(); setViewModel(); + addVideo(mCollect); } private void setRecyclerView() { @@ -88,13 +89,8 @@ public class CollectFragment extends BaseFragment implements CustomScroller.Call }); } - @Override - protected void initData() { - if (mCollect != null) addVideo(mCollect.getList()); - } - private boolean checkLastSize(List items) { - if (mLast == null || items.size() == 0) return false; + if (mLast == null || items.isEmpty()) return false; int size = Product.getColumn() - mLast.size(); if (size == 0) return false; size = Math.min(size, items.size()); @@ -103,8 +99,12 @@ public class CollectFragment extends BaseFragment implements CustomScroller.Call return true; } + private void addVideo(Collect collect) { + if (collect != null) addVideo(collect.getList()); + } + public void addVideo(List items) { - if (checkLastSize(items) || requireActivity() == null || requireActivity().isFinishing()) return; + if (checkLastSize(items) || getActivity() == null || requireActivity().isFinishing()) return; List rows = new ArrayList<>(); for (List part : Lists.partition(items, Product.getColumn())) { mLast = new ArrayObjectAdapter(new VodPresenter(this)); @@ -132,10 +132,4 @@ public class CollectFragment extends BaseFragment implements CustomScroller.Call mViewModel.searchContent(mCollect.getSite(), getKeyword(), page); mScroller.setLoading(true); } - - @Override - public void setUserVisibleHint(boolean isVisibleToUser) { - super.setUserVisibleHint(isVisibleToUser); - if (mBinding != null && !isVisibleToUser) mBinding.recycler.moveToTop(); - } } diff --git a/app/src/leanback/java/com/fongmi/android/tv/ui/fragment/TypeFragment.java b/app/src/leanback/java/com/fongmi/android/tv/ui/fragment/TypeFragment.java new file mode 100644 index 000000000..468052c4d --- /dev/null +++ b/app/src/leanback/java/com/fongmi/android/tv/ui/fragment/TypeFragment.java @@ -0,0 +1,90 @@ +package com.fongmi.android.tv.ui.fragment; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.FragmentTransaction; +import androidx.viewbinding.ViewBinding; + +import com.fongmi.android.tv.R; +import com.fongmi.android.tv.bean.Style; +import com.fongmi.android.tv.databinding.FragmentFolderBinding; +import com.fongmi.android.tv.ui.base.BaseFragment; + +import java.util.HashMap; + +public class TypeFragment extends BaseFragment { + + public static TypeFragment newInstance(String key, String typeId, Style style, HashMap extend, boolean folder) { + Bundle args = new Bundle(); + args.putString("key", key); + args.putString("typeId", typeId); + args.putBoolean("folder", folder); + args.putParcelable("style", style); + args.putSerializable("extend", extend); + TypeFragment fragment = new TypeFragment(); + fragment.setArguments(args); + return fragment; + } + + private String getKey() { + return getArguments().getString("key"); + } + + private String getTypeId() { + return getArguments().getString("typeId"); + } + + private boolean getFolder() { + return getArguments().getBoolean("folder"); + } + + private Style getStyle() { + return getArguments().getParcelable("style"); + } + + private HashMap getExtend() { + return (HashMap) getArguments().getSerializable("extend"); + } + + @Override + protected ViewBinding getBinding(@NonNull LayoutInflater inflater, @Nullable ViewGroup container) { + return FragmentFolderBinding.inflate(inflater, container, false); + } + + @Override + protected void initView() { + getChildFragmentManager().beginTransaction().replace(R.id.container, VodFragment.newInstance(getKey(), getTypeId(), getStyle(), getExtend(), getFolder())).commit(); + } + + public void openFolder(String typeId) { + VodFragment next = VodFragment.newInstance(getKey(), typeId, getStyle(), getExtend(), getFolder()); + VodFragment current = (VodFragment) getChildFragmentManager().findFragmentById(R.id.container); + FragmentTransaction ft = getChildFragmentManager().beginTransaction(); + if (current != null) ft.hide(current); + ft.add(R.id.container, next); + ft.addToBackStack(null); + ft.commit(); + } + + public void toggleFilter(boolean visible) { + VodFragment current = (VodFragment) getChildFragmentManager().findFragmentById(R.id.container); + if (current != null) current.toggleFilter(visible); + } + + public void onRefresh() { + VodFragment current = (VodFragment) getChildFragmentManager().findFragmentById(R.id.container); + if (current != null) current.onRefresh(); + } + + public boolean canBack() { + return getChildFragmentManager().getBackStackEntryCount() > 0; + } + + public void goBack() { + getChildFragmentManager().popBackStack(); + } +} diff --git a/app/src/leanback/java/com/fongmi/android/tv/ui/fragment/VodFragment.java b/app/src/leanback/java/com/fongmi/android/tv/ui/fragment/VodFragment.java index 49f3eee70..e2af082e6 100644 --- a/app/src/leanback/java/com/fongmi/android/tv/ui/fragment/VodFragment.java +++ b/app/src/leanback/java/com/fongmi/android/tv/ui/fragment/VodFragment.java @@ -3,7 +3,6 @@ package com.fongmi.android.tv.ui.fragment; import android.annotation.SuppressLint; import android.os.Bundle; import android.view.LayoutInflater; -import android.view.View; import android.view.ViewGroup; import androidx.annotation.NonNull; @@ -21,7 +20,6 @@ import com.fongmi.android.tv.Product; import com.fongmi.android.tv.R; import com.fongmi.android.tv.api.config.VodConfig; import com.fongmi.android.tv.bean.Filter; -import com.fongmi.android.tv.bean.Page; import com.fongmi.android.tv.bean.Result; import com.fongmi.android.tv.bean.Site; import com.fongmi.android.tv.bean.Style; @@ -42,7 +40,6 @@ import com.fongmi.android.tv.utils.ResUtil; import com.github.catvod.utils.Prefers; import com.google.common.collect.Lists; -import java.io.Serializable; import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -56,9 +53,8 @@ public class VodFragment extends BaseFragment implements CustomScroller.Callback private CustomScroller mScroller; private SiteViewModel mViewModel; private List mFilters; - private List mPages; - private boolean mOpen; - private Page mPage; + private boolean headerVisible; + private boolean filterVisible; public static VodFragment newInstance(String key, String typeId, Style style, HashMap extend, boolean folder) { Bundle args = new Bundle(); @@ -77,32 +73,31 @@ public class VodFragment extends BaseFragment implements CustomScroller.Callback } private String getTypeId() { - return mPages.isEmpty() ? getArguments().getString("typeId") : getLastPage().getVodId(); - } - - private List getFilter() { - return Filter.arrayFrom(Prefers.getString("filter_" + getKey() + "_" + getTypeId())); + return getArguments().getString("typeId"); } private HashMap getExtend() { - Serializable extend = getArguments().getSerializable("extend"); - return extend == null ? new HashMap<>() : (HashMap) extend; + return (HashMap) getArguments().getSerializable("extend"); } private boolean isFolder() { return getArguments().getBoolean("folder"); } + private Style getStyle() { + return isFolder() ? Style.list() : getSite().getStyle(getArguments().getParcelable("style")); + } + private Site getSite() { return VodConfig.get().getSite(getKey()); } - private Page getLastPage() { - return mPages.get(mPages.size() - 1); + private List getFilter() { + return Filter.arrayFrom(Prefers.getString("filter_" + getKey() + "_" + getTypeId())); } - private Style getStyle() { - return isFolder() ? Style.list() : getSite().getStyle(mPages.isEmpty() ? getArguments().getParcelable("style") : getLastPage().getStyle()); + private TypeFragment getParent() { + return ((TypeFragment) getParentFragment()); } @Override @@ -112,16 +107,11 @@ public class VodFragment extends BaseFragment implements CustomScroller.Callback @Override protected void initView() { - mPages = new ArrayList<>(); mExtends = getExtend(); mFilters = getFilter(); setRecyclerView(); setViewModel(); setFilters(); - } - - @Override - protected void initData() { getVideo(); } @@ -143,11 +133,10 @@ public class VodFragment extends BaseFragment implements CustomScroller.Callback mViewModel.result.observe(getViewLifecycleOwner(), result -> { boolean first = mScroller.first(); int size = result.getList().size(); + mBinding.progressLayout.showContent(first, size); if (size > 0) addVideo(result); mScroller.endLoading(result); - checkPosition(first); checkMore(size); - hideProgress(); }); } @@ -176,7 +165,7 @@ public class VodFragment extends BaseFragment implements CustomScroller.Callback boolean first = "1".equals(page); if (first) mLast = null; if (first) showProgress(); - int filterSize = mOpen ? mFilters.size() : 0; + int filterSize = filterVisible ? mFilters.size() : 0; boolean clear = first && mAdapter.size() > filterSize; if (clear) mAdapter.removeItems(filterSize, mAdapter.size() - filterSize); mViewModel.categoryContent(getKey(), typeId, page, true, mExtends); @@ -188,14 +177,6 @@ public class VodFragment extends BaseFragment implements CustomScroller.Callback else addGrid(result.getList(), style); } - private void checkPosition(boolean first) { - if (mPage != null && mPage.getPosition() > 0) mBinding.recycler.hideHeader(); - if (mPage != null && mPage.getPosition() < 1) mBinding.recycler.showHeader(); - if (mPage != null) mBinding.recycler.setSelectedPosition(mPage.getPosition()); - else if (first && !mOpen) mBinding.recycler.moveToTop(); - mPage = null; - } - private void checkMore(int count) { if (mScroller.isDisable() || count == 0 || mAdapter.size() >= 5) return; getVideo(getTypeId(), String.valueOf(mScroller.addPage())); @@ -231,11 +212,7 @@ public class VodFragment extends BaseFragment implements CustomScroller.Callback } private void showProgress() { - if (!mOpen) mBinding.progress.getRoot().setVisibility(View.VISIBLE); - } - - private void hideProgress() { - mBinding.progress.getRoot().setVisibility(View.GONE); + if (!filterVisible) mBinding.progressLayout.showProgress(); } private void showFilter() { @@ -243,48 +220,29 @@ public class VodFragment extends BaseFragment implements CustomScroller.Callback for (Filter filter : mFilters) rows.add(getRow(filter)); App.post(() -> mBinding.recycler.scrollToPosition(0), 48); mAdapter.addAll(0, rows); - hideProgress(); } private void hideFilter() { mAdapter.removeItems(0, mFilters.size()); } - public void toggleFilter(boolean open) { - if (open) showFilter(); + public void toggleFilter(boolean visible) { + this.filterVisible = visible; + if (visible) showFilter(); else hideFilter(); - mOpen = open; } public void onRefresh() { getVideo(); } - public boolean canBack() { - return !mPages.isEmpty(); - } - - public void goBack() { - if (mPages.size() == 1) mBinding.recycler.setMoveTop(true); - mPages.remove(mPage = getLastPage()); - onRefresh(); - } - - public boolean goRoot() { - if (mPages.isEmpty()) return false; - mPages.clear(); - getVideo(); - return true; - } - @Override public void onItemClick(Vod item) { if (item.isAction()) { mViewModel.action(getKey(), item.getAction()); } else if (item.isFolder()) { - mPages.add(Page.get(item, mBinding.recycler.getSelectedPosition())); - mBinding.recycler.setMoveTop(false); - getVideo(item.getVodId(), "1"); + getParent().openFolder(item.getVodId()); + headerVisible = mBinding.recycler.isHeaderVisible(); } else { if (getSite().isIndex()) CollectActivity.start(requireActivity(), item.getVodName()); else VideoActivity.start(requireActivity(), getKey(), item.getVodId(), item.getVodName(), item.getVodPic(), isFolder() ? item.getVodName() : null); @@ -303,9 +261,16 @@ public class VodFragment extends BaseFragment implements CustomScroller.Callback getVideo(getTypeId(), page); } + @Override - public void setUserVisibleHint(boolean isVisibleToUser) { - super.setUserVisibleHint(isVisibleToUser); - if (mBinding != null && !isVisibleToUser) mBinding.recycler.moveToTop(); + public void onHiddenChanged(boolean hidden) { + super.onHiddenChanged(hidden); + if (hidden) { + mBinding.recycler.showHeader(); + } else { + if (headerVisible) mBinding.recycler.showHeader(); + else mBinding.recycler.hideHeader(); + mBinding.recycler.requestFocus(); + } } } diff --git a/app/src/leanback/res/layout/fragment_folder.xml b/app/src/leanback/res/layout/fragment_folder.xml new file mode 100644 index 000000000..beba12a85 --- /dev/null +++ b/app/src/leanback/res/layout/fragment_folder.xml @@ -0,0 +1,11 @@ + + + + + + \ No newline at end of file diff --git a/app/src/leanback/res/layout/fragment_vod.xml b/app/src/leanback/res/layout/fragment_vod.xml index 8681257d6..724c3b4c8 100644 --- a/app/src/leanback/res/layout/fragment_vod.xml +++ b/app/src/leanback/res/layout/fragment_vod.xml @@ -1,6 +1,7 @@ - @@ -17,9 +18,4 @@ app:focusOutEnd="true" app:focusOutFront="true" /> - - - \ No newline at end of file + \ No newline at end of file