[leanback] support multi view type

pull/137/head
FongMi 3 years ago
parent f36e6b569c
commit 1ecff571ff
  1. 25
      app/src/leanback/java/com/fongmi/android/tv/Product.java
  2. 16
      app/src/leanback/java/com/fongmi/android/tv/ui/base/BaseVodHolder.java
  3. 5
      app/src/leanback/java/com/fongmi/android/tv/ui/base/ViewType.java
  4. 30
      app/src/leanback/java/com/fongmi/android/tv/ui/fragment/VodFragment.java
  5. 5
      app/src/leanback/java/com/fongmi/android/tv/ui/holder/VodFolderHolder.java
  6. 29
      app/src/leanback/java/com/fongmi/android/tv/ui/holder/VodFullHolder.java
  7. 11
      app/src/leanback/java/com/fongmi/android/tv/ui/holder/VodGridHolder.java
  8. 35
      app/src/leanback/java/com/fongmi/android/tv/ui/holder/VodOvalHolder.java
  9. 41
      app/src/leanback/java/com/fongmi/android/tv/ui/presenter/VodPresenter.java
  10. 4
      app/src/leanback/res/drawable/selector_vod_oval.xml
  11. 9
      app/src/leanback/res/drawable/shape_vod_oval_focused.xml
  12. 25
      app/src/leanback/res/layout/adapter_vod_full.xml
  13. 45
      app/src/leanback/res/layout/adapter_vod_oval.xml
  14. 4
      app/src/mobile/java/com/fongmi/android/tv/ui/holder/VodGridHolder.java
  15. 4
      app/src/mobile/java/com/fongmi/android/tv/ui/holder/VodOvalHolder.java
  16. 0
      app/src/mobile/res/drawable/shape_vod_oval.xml
  17. 2
      app/src/mobile/res/layout/adapter_vod_oval.xml

@ -1,6 +1,7 @@
package com.fongmi.android.tv;
import com.fongmi.android.tv.ui.activity.LiveActivity;
import com.fongmi.android.tv.ui.base.ViewType;
import com.fongmi.android.tv.utils.ResUtil;
public class Product {
@ -13,10 +14,34 @@ public class Product {
return Math.abs(Setting.getSize() - 7);
}
public static int getColumn(int viewType) {
if (viewType == ViewType.LAND) return getColumn() - 1;
if (viewType == ViewType.FULL) return 3;
return getColumn();
}
public static void bootLive() {
LiveActivity.start(App.activity());
}
public static int[] getSpec(int viewType) {
int column = getColumn(viewType);
int space = ResUtil.dp2px(48) + ResUtil.dp2px(16 * (column - 1));
return getSpec(space, column, viewType);
}
private static int[] getSpec(int space, int column, int viewType) {
int base = ResUtil.getScreenWidth() - space;
int width = base / column;
return new int[]{width, getHeight(viewType, width)};
}
private static int getHeight(int viewType, int value) {
if (viewType == ViewType.LAND) return (int) (value * 0.75f);
if (viewType == ViewType.OVAL) return value;
return (int) (value / 0.75f);
}
public static int getEms() {
return Math.min(ResUtil.getScreenWidth() / ResUtil.sp2px(24), 35);
}

@ -0,0 +1,16 @@
package com.fongmi.android.tv.ui.base;
import android.view.View;
import androidx.leanback.widget.Presenter;
import com.fongmi.android.tv.bean.Vod;
public abstract class BaseVodHolder extends Presenter.ViewHolder {
public BaseVodHolder(View view) {
super(view);
}
public abstract void initView(Vod item);
}

@ -3,5 +3,8 @@ package com.fongmi.android.tv.ui.base;
public class ViewType {
public static final int GRID = 0;
public static final int FOLDER = 1;
public static final int LAND = 1;
public static final int OVAL = 2;
public static final int FULL = 3;
public static final int FOLDER = 99;
}

@ -19,8 +19,10 @@ import androidx.viewbinding.ViewBinding;
import com.fongmi.android.tv.App;
import com.fongmi.android.tv.Product;
import com.fongmi.android.tv.R;
import com.fongmi.android.tv.api.ApiConfig;
import com.fongmi.android.tv.bean.Filter;
import com.fongmi.android.tv.bean.Page;
import com.fongmi.android.tv.bean.Site;
import com.fongmi.android.tv.bean.Vod;
import com.fongmi.android.tv.databinding.FragmentVodBinding;
import com.fongmi.android.tv.model.SiteViewModel;
@ -80,10 +82,18 @@ public class VodFragment extends BaseFragment implements CustomScroller.Callback
return getArguments().getBoolean("folder");
}
private Site getSite() {
return ApiConfig.get().getSite(getKey());
}
private Page getLastPage() {
return mPages.get(mPages.size() - 1);
}
private int getDefaultViewType() {
return isFolder() ? ViewType.FOLDER : getSite().getViewType();
}
@Override
protected ViewBinding getBinding(@NonNull LayoutInflater inflater, @Nullable ViewGroup container) {
return mBinding = FragmentVodBinding.inflate(inflater, container, false);
@ -151,9 +161,9 @@ public class VodFragment extends BaseFragment implements CustomScroller.Callback
private void addVideo(List<Vod> items) {
if (items.isEmpty()) return;
boolean list = items.get(0).isList(isFolder());
if (list) mAdapter.addAll(mAdapter.size(), items);
else addGrid(items);
int viewType = items.get(0).getViewType(getDefaultViewType());
if (viewType == ViewType.FOLDER) mAdapter.addAll(mAdapter.size(), items);
else addGrid(items, viewType);
}
private void checkPosition() {
@ -169,21 +179,21 @@ public class VodFragment extends BaseFragment implements CustomScroller.Callback
getVideo(getTypeId(), String.valueOf(mScroller.addPage()));
}
private boolean checkLastSize(List<Vod> items) {
private boolean checkLastSize(List<Vod> items, int viewType) {
if (mLast == null || items.size() == 0) return false;
int size = Product.getColumn() - mLast.size();
int size = Product.getColumn(viewType) - mLast.size();
if (size == 0) return false;
size = Math.min(size, items.size());
mLast.addAll(mLast.size(), new ArrayList<>(items.subList(0, size)));
addGrid(new ArrayList<>(items.subList(size, items.size())));
addGrid(new ArrayList<>(items.subList(size, items.size())), viewType);
return true;
}
private void addGrid(List<Vod> items) {
if (checkLastSize(items)) return;
private void addGrid(List<Vod> items, int viewType) {
if (checkLastSize(items, viewType)) return;
List<ListRow> rows = new ArrayList<>();
for (List<Vod> part : Lists.partition(items, Product.getColumn())) {
mLast = new ArrayObjectAdapter(new VodPresenter(this));
for (List<Vod> part : Lists.partition(items, Product.getColumn(viewType))) {
mLast = new ArrayObjectAdapter(new VodPresenter(this, viewType));
mLast.setItems(part, null);
rows.add(new ListRow(mLast));
}

@ -3,14 +3,14 @@ package com.fongmi.android.tv.ui.holder;
import android.widget.ImageView;
import androidx.annotation.NonNull;
import androidx.leanback.widget.Presenter;
import com.fongmi.android.tv.bean.Vod;
import com.fongmi.android.tv.databinding.AdapterVodFolderBinding;
import com.fongmi.android.tv.ui.base.BaseVodHolder;
import com.fongmi.android.tv.ui.presenter.VodPresenter;
import com.fongmi.android.tv.utils.ImgUtil;
public class VodFolderHolder extends Presenter.ViewHolder {
public class VodFolderHolder extends BaseVodHolder {
private final VodPresenter.OnClickListener listener;
public final AdapterVodFolderBinding binding;
@ -21,6 +21,7 @@ public class VodFolderHolder extends Presenter.ViewHolder {
this.listener = listener;
}
@Override
public void initView(Vod item) {
binding.name.setText(item.getVodName());
binding.remark.setText(item.getVodRemarks());

@ -0,0 +1,29 @@
package com.fongmi.android.tv.ui.holder;
import androidx.annotation.NonNull;
import com.fongmi.android.tv.bean.Vod;
import com.fongmi.android.tv.databinding.AdapterVodFullBinding;
import com.fongmi.android.tv.ui.base.BaseVodHolder;
import com.fongmi.android.tv.utils.ImgUtil;
public class VodFullHolder extends BaseVodHolder {
public final AdapterVodFullBinding binding;
public VodFullHolder(@NonNull AdapterVodFullBinding binding) {
super(binding.getRoot());
this.binding = binding;
}
public VodFullHolder size(int[] size) {
binding.getRoot().getLayoutParams().width = size[0];
binding.getRoot().getLayoutParams().height = size[1];
return this;
}
@Override
public void initView(Vod item) {
ImgUtil.load(item.getVodPic(), binding.image);
}
}

@ -1,14 +1,14 @@
package com.fongmi.android.tv.ui.holder;
import androidx.annotation.NonNull;
import androidx.leanback.widget.Presenter;
import com.fongmi.android.tv.bean.Vod;
import com.fongmi.android.tv.databinding.AdapterVodGridBinding;
import com.fongmi.android.tv.ui.base.BaseVodHolder;
import com.fongmi.android.tv.ui.presenter.VodPresenter;
import com.fongmi.android.tv.utils.ImgUtil;
public class VodGridHolder extends Presenter.ViewHolder {
public class VodGridHolder extends BaseVodHolder {
private final VodPresenter.OnClickListener listener;
public final AdapterVodGridBinding binding;
@ -19,6 +19,13 @@ public class VodGridHolder extends Presenter.ViewHolder {
this.listener = listener;
}
public VodGridHolder size(int[] size) {
binding.getRoot().getLayoutParams().width = size[0];
binding.getRoot().getLayoutParams().height = size[1];
return this;
}
@Override
public void initView(Vod item) {
binding.name.setText(item.getVodName());
binding.year.setText(item.getVodYear());

@ -0,0 +1,35 @@
package com.fongmi.android.tv.ui.holder;
import androidx.annotation.NonNull;
import com.fongmi.android.tv.bean.Vod;
import com.fongmi.android.tv.databinding.AdapterVodOvalBinding;
import com.fongmi.android.tv.ui.base.BaseVodHolder;
import com.fongmi.android.tv.ui.presenter.VodPresenter;
import com.fongmi.android.tv.utils.ImgUtil;
public class VodOvalHolder extends BaseVodHolder {
private final VodPresenter.OnClickListener listener;
public final AdapterVodOvalBinding binding;
public VodOvalHolder(@NonNull AdapterVodOvalBinding binding, VodPresenter.OnClickListener listener) {
super(binding.getRoot());
this.binding = binding;
this.listener = listener;
}
public VodOvalHolder size(int[] size) {
binding.image.getLayoutParams().width = size[0];
binding.image.getLayoutParams().height = size[1];
return this;
}
@Override
public void initView(Vod item) {
binding.name.setText(item.getVodName());
binding.getRoot().setOnClickListener(v -> listener.onItemClick(item));
binding.getRoot().setOnLongClickListener(v -> listener.onLongClick(item));
ImgUtil.load(item.getVodPic(), binding.image);
}
}

@ -8,17 +8,21 @@ import androidx.leanback.widget.Presenter;
import com.fongmi.android.tv.Product;
import com.fongmi.android.tv.bean.Vod;
import com.fongmi.android.tv.databinding.AdapterVodFolderBinding;
import com.fongmi.android.tv.databinding.AdapterVodFullBinding;
import com.fongmi.android.tv.databinding.AdapterVodGridBinding;
import com.fongmi.android.tv.databinding.AdapterVodOvalBinding;
import com.fongmi.android.tv.ui.base.BaseVodHolder;
import com.fongmi.android.tv.ui.base.ViewType;
import com.fongmi.android.tv.ui.holder.VodFolderHolder;
import com.fongmi.android.tv.ui.holder.VodFullHolder;
import com.fongmi.android.tv.ui.holder.VodGridHolder;
import com.fongmi.android.tv.utils.ResUtil;
import com.fongmi.android.tv.ui.holder.VodOvalHolder;
public class VodPresenter extends Presenter {
private final OnClickListener mListener;
private final int viewType;
private int width, height;
private final int[] size;
public VodPresenter(OnClickListener listener) {
this(listener, ViewType.GRID);
@ -27,7 +31,7 @@ public class VodPresenter extends Presenter {
public VodPresenter(OnClickListener listener, int viewType) {
this.mListener = listener;
this.viewType = viewType;
setLayoutSize();
this.size = Product.getSpec(viewType);
}
public interface OnClickListener {
@ -37,32 +41,23 @@ public class VodPresenter extends Presenter {
boolean onLongClick(Vod item);
}
private void setLayoutSize() {
int space = ResUtil.dp2px(48) + ResUtil.dp2px(16 * (Product.getColumn() - 1));
int base = ResUtil.getScreenWidth() - space;
width = base / Product.getColumn();
height = (int) (width / 0.75f);
}
@Override
public Presenter.ViewHolder onCreateViewHolder(ViewGroup parent) {
if (viewType == ViewType.FOLDER) return new VodFolderHolder(AdapterVodFolderBinding.inflate(LayoutInflater.from(parent.getContext()), parent, false), mListener);
VodGridHolder holder = new VodGridHolder(AdapterVodGridBinding.inflate(LayoutInflater.from(parent.getContext()), parent, false), mListener);
holder.binding.getRoot().getLayoutParams().width = width;
holder.binding.getRoot().getLayoutParams().height = height;
return holder;
switch (viewType) {
case ViewType.FOLDER:
return new VodFolderHolder(AdapterVodFolderBinding.inflate(LayoutInflater.from(parent.getContext()), parent, false), mListener);
case ViewType.FULL:
return new VodFullHolder(AdapterVodFullBinding.inflate(LayoutInflater.from(parent.getContext()), parent, false)).size(size);
case ViewType.OVAL:
return new VodOvalHolder(AdapterVodOvalBinding.inflate(LayoutInflater.from(parent.getContext()), parent, false), mListener).size(size);
default:
return new VodGridHolder(AdapterVodGridBinding.inflate(LayoutInflater.from(parent.getContext()), parent, false), mListener).size(size);
}
}
@Override
public void onBindViewHolder(Presenter.ViewHolder viewHolder, Object object) {
switch (viewType) {
case ViewType.GRID:
((VodGridHolder) viewHolder).initView((Vod) object);
break;
case ViewType.FOLDER:
((VodFolderHolder) viewHolder).initView((Vod) object);
break;
}
((BaseVodHolder) viewHolder).initView((Vod) object);
}
@Override

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/shape_vod_oval_focused" android:state_focused="true" />
</selector>

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval">
<stroke
android:width="1.5dp"
android:color="@color/white" />
</shape>

@ -0,0 +1,25 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="200dp"
android:layout_height="200dp"
android:focusable="true"
android:focusableInTouchMode="true">
<com.google.android.material.imageview.ShapeableImageView
android:id="@+id/image"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/black_20"
android:scaleType="center"
app:shapeAppearanceOverlay="@style/Vod.Grid"
tools:src="@drawable/ic_img_loading" />
<View
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/selector_vod"
android:duplicateParentState="true" />
</RelativeLayout>

@ -0,0 +1,45 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:focusable="true"
android:focusableInTouchMode="true">
<com.google.android.material.imageview.ShapeableImageView
android:id="@+id/image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@color/black_20"
android:scaleType="center"
app:shapeAppearanceOverlay="@style/Vod.Circle"
tools:src="@drawable/ic_img_loading" />
<TextView
android:id="@+id/name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/image"
android:layout_alignStart="@+id/image"
android:layout_alignEnd="@+id/image"
android:layout_marginTop="12dp"
android:ellipsize="marquee"
android:gravity="center"
android:singleLine="true"
android:textColor="@color/white"
android:textSize="16sp"
tools:text="蜘蛛人" />
<FrameLayout
android:id="@+id/frame"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignStart="@+id/image"
android:layout_alignTop="@+id/image"
android:layout_alignEnd="@+id/image"
android:layout_alignBottom="@+id/image"
android:background="@drawable/selector_vod_oval"
android:duplicateParentState="true" />
</RelativeLayout>

@ -20,8 +20,8 @@ public class VodGridHolder extends BaseVodHolder {
}
public VodGridHolder size(int[] size) {
this.itemView.getLayoutParams().width = size[0];
this.itemView.getLayoutParams().height = size[1];
itemView.getLayoutParams().width = size[0];
itemView.getLayoutParams().height = size[1];
return this;
}

@ -20,8 +20,8 @@ public class VodOvalHolder extends BaseVodHolder {
}
public VodOvalHolder size(int[] size) {
this.binding.image.getLayoutParams().width = size[0];
this.binding.image.getLayoutParams().height = size[1];
binding.image.getLayoutParams().width = size[0];
binding.image.getLayoutParams().height = size[1];
return this;
}

@ -11,7 +11,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@color/black_20"
android:foreground="@drawable/shape_vod_circle"
android:foreground="@drawable/shape_vod_oval"
android:scaleType="center"
app:shapeAppearanceOverlay="@style/Vod.Circle"
tools:src="@drawable/ic_img_loading" />

Loading…
Cancel
Save