diff --git a/app/src/main/java/com/fongmi/bear/ui/activity/HomeActivity.java b/app/src/main/java/com/fongmi/bear/ui/activity/HomeActivity.java index 826fbdab1..f4c46d080 100644 --- a/app/src/main/java/com/fongmi/bear/ui/activity/HomeActivity.java +++ b/app/src/main/java/com/fongmi/bear/ui/activity/HomeActivity.java @@ -2,27 +2,37 @@ package com.fongmi.bear.ui.activity; import android.app.Activity; import android.content.Intent; -import android.view.ViewGroup; import androidx.annotation.Nullable; +import androidx.leanback.widget.ArrayObjectAdapter; +import androidx.leanback.widget.ItemBridgeAdapter; +import androidx.leanback.widget.ListRow; import androidx.lifecycle.ViewModelProvider; import androidx.viewbinding.ViewBinding; import com.fongmi.bear.R; import com.fongmi.bear.bean.Func; import com.fongmi.bear.bean.Result; +import com.fongmi.bear.bean.Vod; import com.fongmi.bear.databinding.ActivityHomeBinding; import com.fongmi.bear.model.SiteViewModel; -import com.fongmi.bear.ui.adapter.FuncAdapter; -import com.fongmi.bear.ui.adapter.VodAdapter; +import com.fongmi.bear.ui.custom.CustomSelector; +import com.fongmi.bear.ui.presenter.FuncPresenter; +import com.fongmi.bear.ui.presenter.FuncRowPresenter; +import com.fongmi.bear.ui.presenter.TitlePresenter; +import com.fongmi.bear.ui.presenter.VodPresenter; +import com.fongmi.bear.ui.presenter.VodRowPresenter; import com.fongmi.bear.utils.ResUtil; +import com.fongmi.bear.utils.Utils; + +import java.util.List; public class HomeActivity extends BaseActivity { private ActivityHomeBinding mBinding; private SiteViewModel mSiteViewModel; - private FuncAdapter mFuncAdapter; - private VodAdapter mVodAdapter; + private FuncPresenter mFuncPresenter; + private ArrayObjectAdapter mAdapter; public static void start(Activity activity) { activity.startActivity(new Intent(activity, HomeActivity.class)); @@ -38,38 +48,58 @@ public class HomeActivity extends BaseActivity { protected void initView() { setRecyclerView(); setViewModel(); + setAdapter(); getContent(); } @Override protected void initEvent() { - mFuncAdapter.setOnItemClickListener(this::onFuncClick); + mFuncPresenter.setOnClickListener(this::onFuncClick); } private void setRecyclerView() { - mBinding.func.setAdapter(mFuncAdapter = new FuncAdapter()); - mBinding.func.setRowHeight(ViewGroup.LayoutParams.WRAP_CONTENT); - mBinding.recent.setNumColumns(5); - mBinding.recent.setAdapter(mVodAdapter = new VodAdapter()); - mBinding.recent.setItemSpacing(ResUtil.dp2px(12)); - mBinding.recommend.setNumColumns(5); - mBinding.recommend.setAdapter(mVodAdapter = new VodAdapter()); - mBinding.recommend.setItemSpacing(ResUtil.dp2px(12)); + CustomSelector selector = new CustomSelector(); + selector.addPresenter(String.class, new TitlePresenter()); + selector.addPresenter(ListRow.class, new VodRowPresenter(), VodPresenter.class); + selector.addPresenter(ListRow.class, new FuncRowPresenter(), FuncPresenter.class); + ItemBridgeAdapter adapter = new ItemBridgeAdapter(mAdapter = new ArrayObjectAdapter(selector)); + mBinding.recycler.setVerticalSpacing(ResUtil.dp2px(24)); + mBinding.recycler.setAdapter(adapter); } private void setViewModel() { mSiteViewModel = new ViewModelProvider(this).get(SiteViewModel.class); mSiteViewModel.mResult.observe(this, result -> { - mVodAdapter.addAll(result.getList()); - mBinding.progress.showContent(); + for (List items : Utils.chunkList(result.getList(), 5)) { + ArrayObjectAdapter adapter = new ArrayObjectAdapter(new VodPresenter()); + adapter.addAll(0, items); + mAdapter.add(new ListRow(adapter)); + } }); } + private void setAdapter() { + mAdapter.add(ResUtil.getString(R.string.app_name)); + mAdapter.add(getFuncRow()); + mAdapter.add(ResUtil.getString(R.string.home_recent)); + mAdapter.add(ResUtil.getString(R.string.home_recommend)); + } + private void getContent() { - mBinding.progress.showProgress(); + if (mAdapter.size() > 4) mAdapter.removeItems(4, mAdapter.size() - 4); mSiteViewModel.homeContent(); } + private ListRow getFuncRow() { + ArrayObjectAdapter adapter = new ArrayObjectAdapter(mFuncPresenter = new FuncPresenter()); + adapter.add(Func.create(R.string.home_vod)); + adapter.add(Func.create(R.string.home_live)); + adapter.add(Func.create(R.string.home_search)); + adapter.add(Func.create(R.string.home_push)); + adapter.add(Func.create(R.string.home_setting)); + return new ListRow(adapter); + } + private void onFuncClick(Func item) { switch (item.getResId()) { case R.string.home_vod: diff --git a/app/src/main/java/com/fongmi/bear/ui/adapter/FuncAdapter.java b/app/src/main/java/com/fongmi/bear/ui/adapter/FuncAdapter.java deleted file mode 100644 index ed98b47ce..000000000 --- a/app/src/main/java/com/fongmi/bear/ui/adapter/FuncAdapter.java +++ /dev/null @@ -1,76 +0,0 @@ -package com.fongmi.bear.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.fongmi.bear.R; -import com.fongmi.bear.bean.Func; -import com.fongmi.bear.databinding.AdapterFuncBinding; - -import java.util.ArrayList; -import java.util.List; - -public class FuncAdapter extends RecyclerView.Adapter { - - private OnItemClickListener mListener; - private List mItems; - - public FuncAdapter() { - addAll(); - } - - public interface OnItemClickListener { - void onItemClick(Func item); - } - - public void setOnItemClickListener(OnItemClickListener listener) { - this.mListener = listener; - } - - class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener { - - private final AdapterFuncBinding binding; - - public ViewHolder(@NonNull AdapterFuncBinding binding) { - super(binding.getRoot()); - this.binding = binding; - itemView.setOnClickListener(this); - } - - @Override - public void onClick(View view) { - mListener.onItemClick(mItems.get(getLayoutPosition())); - } - } - - public void addAll() { - mItems = new ArrayList<>(); - mItems.add(Func.create(R.string.home_vod)); - mItems.add(Func.create(R.string.home_live)); - mItems.add(Func.create(R.string.home_search)); - mItems.add(Func.create(R.string.home_push)); - mItems.add(Func.create(R.string.home_setting)); - } - - @Override - public int getItemCount() { - return mItems.size(); - } - - @NonNull - @Override - public FuncAdapter.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { - return new ViewHolder(AdapterFuncBinding.inflate(LayoutInflater.from(parent.getContext()), parent, false)); - } - - @Override - public void onBindViewHolder(@NonNull FuncAdapter.ViewHolder holder, int position) { - Func item = mItems.get(position); - holder.binding.icon.setImageResource(item.getDrawable()); - holder.binding.text.setText(item.getText()); - } -} diff --git a/app/src/main/java/com/fongmi/bear/ui/custom/CustomSelector.java b/app/src/main/java/com/fongmi/bear/ui/custom/CustomSelector.java new file mode 100644 index 000000000..e9c4e9cc1 --- /dev/null +++ b/app/src/main/java/com/fongmi/bear/ui/custom/CustomSelector.java @@ -0,0 +1,66 @@ +package com.fongmi.bear.ui.custom; + +import androidx.collection.ArrayMap; +import androidx.leanback.widget.ListRow; +import androidx.leanback.widget.Presenter; +import androidx.leanback.widget.PresenterSelector; + +import java.util.ArrayList; +import java.util.List; + +public class CustomSelector extends PresenterSelector { + + private final List mPresenters; + private final ArrayMap, Presenter> mSingleMap; + private final ArrayMap, ArrayMap, Presenter>> mClassMap; + + public CustomSelector() { + super(); + mPresenters = new ArrayList<>(); + mSingleMap = new ArrayMap<>(); + mClassMap = new ArrayMap<>(); + } + + public void addPresenter(Class cls, Presenter presenter) { + mSingleMap.put(cls, presenter); + if (!mPresenters.contains(presenter)) { + mPresenters.add(presenter); + } + } + + public void addPresenter(Class cls, Presenter presenter, Class childType) { + ArrayMap, Presenter> classPresenterArrayMap = mClassMap.get(cls); + if (classPresenterArrayMap == null) classPresenterArrayMap = new ArrayMap<>(); + classPresenterArrayMap.put(childType, presenter); + mClassMap.put(cls, classPresenterArrayMap); + if (!mPresenters.contains(presenter)) { + mPresenters.add(presenter); + } + } + + @Override + public Presenter getPresenter(Object item) { + Class cls = item.getClass(); + Presenter presenter; + presenter = mSingleMap.get(cls); + if (presenter != null) return presenter; + ArrayMap, Presenter> presenters = mClassMap.get(cls); + assert presenters != null; + if (presenters.size() == 1) return presenters.valueAt(0); + if (item instanceof ListRow) { + ListRow listRow = (ListRow) item; + Presenter childPresenter = listRow.getAdapter().getPresenter(listRow); + Class childCls = childPresenter.getClass(); + do { + presenter = presenters.get(childCls); + childCls = childCls.getSuperclass(); + } while (presenter == null && childCls != null); + } + return presenter; + } + + @Override + public Presenter[] getPresenters() { + return mPresenters.toArray(new Presenter[]{}); + } +} \ No newline at end of file diff --git a/app/src/main/java/com/fongmi/bear/ui/presenter/FuncPresenter.java b/app/src/main/java/com/fongmi/bear/ui/presenter/FuncPresenter.java new file mode 100644 index 000000000..829a63b0f --- /dev/null +++ b/app/src/main/java/com/fongmi/bear/ui/presenter/FuncPresenter.java @@ -0,0 +1,52 @@ +package com.fongmi.bear.ui.presenter; + +import android.view.LayoutInflater; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.leanback.widget.Presenter; + +import com.fongmi.bear.bean.Func; +import com.fongmi.bear.databinding.AdapterFuncBinding; + +public class FuncPresenter extends Presenter { + + private OnClickListener mListener; + + public interface OnClickListener { + void onItemClick(Func item); + } + + public void setOnClickListener(OnClickListener listener) { + this.mListener = listener; + } + + @Override + public Presenter.ViewHolder onCreateViewHolder(ViewGroup parent) { + return new ViewHolder(AdapterFuncBinding.inflate(LayoutInflater.from(parent.getContext()), parent, false)); + } + + @Override + public void onBindViewHolder(Presenter.ViewHolder viewHolder, Object object) { + Func item = (Func) object; + ViewHolder holder = (ViewHolder) viewHolder; + holder.binding.text.setText(item.getText()); + holder.binding.icon.setImageResource(item.getDrawable()); + setOnClickListener(holder, view -> mListener.onItemClick(item)); + } + + @Override + public void onUnbindViewHolder(Presenter.ViewHolder viewHolder) { + + } + + public static class ViewHolder extends Presenter.ViewHolder { + + private final AdapterFuncBinding binding; + + public ViewHolder(@NonNull AdapterFuncBinding binding) { + super(binding.getRoot()); + this.binding = binding; + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/fongmi/bear/ui/presenter/FuncRowPresenter.java b/app/src/main/java/com/fongmi/bear/ui/presenter/FuncRowPresenter.java new file mode 100644 index 000000000..d1d4d9881 --- /dev/null +++ b/app/src/main/java/com/fongmi/bear/ui/presenter/FuncRowPresenter.java @@ -0,0 +1,27 @@ +package com.fongmi.bear.ui.presenter; + +import android.annotation.SuppressLint; + +import androidx.leanback.widget.HorizontalGridView; +import androidx.leanback.widget.ListRowPresenter; +import androidx.leanback.widget.RowPresenter; + +import com.fongmi.bear.utils.ResUtil; + +public class FuncRowPresenter extends ListRowPresenter { + + public FuncRowPresenter() { + setShadowEnabled(false); + setSelectEffectEnabled(false); + setKeepChildForeground(false); + } + + @Override + @SuppressLint("RestrictedApi") + protected void initializeRowViewHolder(RowPresenter.ViewHolder holder) { + super.initializeRowViewHolder(holder); + ViewHolder vh = (ViewHolder) holder; + vh.getGridView().setItemSpacing(ResUtil.dp2px(16)); + vh.getGridView().setFocusScrollStrategy(HorizontalGridView.FOCUS_SCROLL_ITEM); + } +} \ No newline at end of file diff --git a/app/src/main/java/com/fongmi/bear/ui/presenter/TitlePresenter.java b/app/src/main/java/com/fongmi/bear/ui/presenter/TitlePresenter.java new file mode 100644 index 000000000..52c21c472 --- /dev/null +++ b/app/src/main/java/com/fongmi/bear/ui/presenter/TitlePresenter.java @@ -0,0 +1,37 @@ +package com.fongmi.bear.ui.presenter; + +import android.view.LayoutInflater; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.leanback.widget.Presenter; + +import com.fongmi.bear.databinding.AdapterTitleBinding; + +public class TitlePresenter extends Presenter { + + @Override + public Presenter.ViewHolder onCreateViewHolder(ViewGroup parent) { + return new TitlePresenter.ViewHolder(AdapterTitleBinding.inflate(LayoutInflater.from(parent.getContext()), parent, false)); + } + + @Override + public void onBindViewHolder(Presenter.ViewHolder viewHolder, Object object) { + TitlePresenter.ViewHolder holder = (TitlePresenter.ViewHolder) viewHolder; + holder.binding.header.setText(object.toString()); + } + + @Override + public void onUnbindViewHolder(Presenter.ViewHolder viewHolder) { + } + + public static class ViewHolder extends Presenter.ViewHolder { + + private final AdapterTitleBinding binding; + + public ViewHolder(@NonNull AdapterTitleBinding binding) { + super(binding.getRoot()); + this.binding = binding; + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/fongmi/bear/ui/presenter/VodPresenter.java b/app/src/main/java/com/fongmi/bear/ui/presenter/VodPresenter.java new file mode 100644 index 000000000..b0204a998 --- /dev/null +++ b/app/src/main/java/com/fongmi/bear/ui/presenter/VodPresenter.java @@ -0,0 +1,55 @@ +package com.fongmi.bear.ui.presenter; + +import android.view.LayoutInflater; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.leanback.widget.Presenter; + +import com.fongmi.bear.bean.Func; +import com.fongmi.bear.bean.Vod; +import com.fongmi.bear.databinding.AdapterVodBinding; +import com.fongmi.bear.utils.Utils; + +public class VodPresenter extends Presenter { + + private OnClickListener mListener; + + public interface OnClickListener { + void onItemClick(Func item); + } + + public void setOnClickListener(OnClickListener listener) { + this.mListener = listener; + } + + @Override + public Presenter.ViewHolder onCreateViewHolder(ViewGroup parent) { + return new ViewHolder(AdapterVodBinding.inflate(LayoutInflater.from(parent.getContext()), parent, false)); + } + + @Override + public void onBindViewHolder(Presenter.ViewHolder viewHolder, Object object) { + Vod item = (Vod) object; + ViewHolder holder = (ViewHolder) viewHolder; + holder.binding.name.setText(item.getVodName()); + holder.binding.remark.setText(item.getVodRemarks()); + holder.binding.remark.setVisibility(item.getRemarkVisible()); + Utils.loadImage(item.getVodPic(), holder.binding.image); + } + + @Override + public void onUnbindViewHolder(Presenter.ViewHolder viewHolder) { + + } + + public static class ViewHolder extends Presenter.ViewHolder { + + private final AdapterVodBinding binding; + + public ViewHolder(@NonNull AdapterVodBinding binding) { + super(binding.getRoot()); + this.binding = binding; + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/fongmi/bear/ui/presenter/VodRowPresenter.java b/app/src/main/java/com/fongmi/bear/ui/presenter/VodRowPresenter.java new file mode 100644 index 000000000..04f2bab90 --- /dev/null +++ b/app/src/main/java/com/fongmi/bear/ui/presenter/VodRowPresenter.java @@ -0,0 +1,27 @@ +package com.fongmi.bear.ui.presenter; + +import android.annotation.SuppressLint; + +import androidx.leanback.widget.HorizontalGridView; +import androidx.leanback.widget.ListRowPresenter; +import androidx.leanback.widget.RowPresenter; + +import com.fongmi.bear.utils.ResUtil; + +public class VodRowPresenter extends ListRowPresenter { + + public VodRowPresenter() { + setShadowEnabled(false); + setSelectEffectEnabled(false); + setKeepChildForeground(false); + } + + @Override + @SuppressLint("RestrictedApi") + protected void initializeRowViewHolder(RowPresenter.ViewHolder holder) { + super.initializeRowViewHolder(holder); + ViewHolder vh = (ViewHolder) holder; + vh.getGridView().setItemSpacing(ResUtil.dp2px(16)); + vh.getGridView().setFocusScrollStrategy(HorizontalGridView.FOCUS_SCROLL_ITEM); + } +} \ No newline at end of file diff --git a/app/src/main/java/com/fongmi/bear/utils/Utils.java b/app/src/main/java/com/fongmi/bear/utils/Utils.java index 03ef3a51f..8f6f628a0 100644 --- a/app/src/main/java/com/fongmi/bear/utils/Utils.java +++ b/app/src/main/java/com/fongmi/bear/utils/Utils.java @@ -16,6 +16,9 @@ import com.fongmi.bear.App; import com.fongmi.bear.R; import com.google.android.exoplayer2.util.Util; +import java.util.ArrayList; +import java.util.List; + public class Utils { public static String getString(int resId) { @@ -88,4 +91,12 @@ public class Utils { public static String getUserAgent() { return Util.getUserAgent(App.get(), App.get().getPackageName().concat(".").concat(getUUID())); } + + public static List> chunkList(List list, int chunkSize) { + List> chunkList = new ArrayList<>(list.size() / chunkSize); + for (int i = 0; i < list.size(); i += chunkSize) { + chunkList.add(list.subList(i, i + chunkSize >= list.size() ? list.size() - 1 : i + chunkSize)); + } + return chunkList; + } } diff --git a/app/src/main/res/layout/activity_home.xml b/app/src/main/res/layout/activity_home.xml index c6d67f22e..712c049db 100644 --- a/app/src/main/res/layout/activity_home.xml +++ b/app/src/main/res/layout/activity_home.xml @@ -1,66 +1,15 @@ - + android:orientation="vertical"> - + android:clipChildren="false" + android:clipToPadding="false" + android:padding="24dp" /> - - - - - - - - - - - - - - - - - \ No newline at end of file + \ No newline at end of file diff --git a/app/src/main/res/layout/adapter_func.xml b/app/src/main/res/layout/adapter_func.xml index 8f2f9db0e..b2a7a75c7 100644 --- a/app/src/main/res/layout/adapter_func.xml +++ b/app/src/main/res/layout/adapter_func.xml @@ -3,7 +3,6 @@ xmlns:tools="http://schemas.android.com/tools" android:layout_width="96dp" android:layout_height="96dp" - android:layout_marginEnd="12dp" android:background="@drawable/selector_item" android:focusable="true" android:focusableInTouchMode="true" diff --git a/app/src/main/res/layout/adapter_title.xml b/app/src/main/res/layout/adapter_title.xml new file mode 100644 index 000000000..542af2ebf --- /dev/null +++ b/app/src/main/res/layout/adapter_title.xml @@ -0,0 +1,9 @@ + + \ No newline at end of file diff --git a/app/src/main/res/layout/adapter_vod.xml b/app/src/main/res/layout/adapter_vod.xml index 50e87fde4..715dd1f19 100644 --- a/app/src/main/res/layout/adapter_vod.xml +++ b/app/src/main/res/layout/adapter_vod.xml @@ -1,7 +1,7 @@