fullscreen episodes

pull/262/head
okjack 2 years ago
parent 7579c1e239
commit 1fe106b4a8
  1. 15
      app/src/leanback/java/com/fongmi/android/tv/ui/activity/VideoActivity.java
  2. 173
      app/src/leanback/java/com/fongmi/android/tv/ui/dialog/EpisodeDialog.java
  3. 34
      app/src/leanback/res/layout/dialog_episode.xml
  4. 14
      app/src/leanback/res/layout/view_control_vod.xml
  5. 1
      app/src/main/res/values-zh-rCN/strings.xml
  6. 1
      app/src/main/res/values-zh-rTW/strings.xml
  7. 1
      app/src/main/res/values/strings.xml

@ -69,6 +69,7 @@ import com.fongmi.android.tv.ui.base.BaseActivity;
import com.fongmi.android.tv.ui.custom.CustomKeyDownVod;
import com.fongmi.android.tv.ui.custom.CustomMovement;
import com.fongmi.android.tv.ui.dialog.DescDialog;
import com.fongmi.android.tv.ui.dialog.EpisodeDialog;
import com.fongmi.android.tv.ui.dialog.TrackDialog;
import com.fongmi.android.tv.ui.presenter.ArrayPresenter;
import com.fongmi.android.tv.ui.presenter.EpisodePresenter;
@ -347,6 +348,7 @@ public class VideoActivity extends BaseActivity implements CustomKeyDownVod.List
mBinding.control.danmu.setOnClickListener(view -> onDanmu());
mBinding.control.next.setOnClickListener(view -> checkNext());
mBinding.control.prev.setOnClickListener(view -> checkPrev());
mBinding.control.episodes.setOnClickListener(view -> showEpisodes());
mBinding.control.scale.setOnClickListener(view -> onScale());
mBinding.control.speed.setOnClickListener(view -> onSpeed());
mBinding.control.reset.setOnClickListener(view -> onReset());
@ -376,7 +378,7 @@ public class VideoActivity extends BaseActivity implements CustomKeyDownVod.List
mBinding.array.addOnChildViewHolderSelectedListener(new OnChildViewHolderSelectedListener() {
@Override
public void onChildViewHolderSelected(@NonNull RecyclerView parent, @Nullable RecyclerView.ViewHolder child, int position, int subposition) {
if (mEpisodeAdapter.size() > getGroupSize() && position > 1) setEpisodeSelectedPosition((position - 2) * getGroupSize() + 1);
if (mEpisodeAdapter.size() > getGroupSize() && position > 1) setEpisodeSelectedPosition((position - 2) * getGroupSize());
}
});
}
@ -637,7 +639,7 @@ public class VideoActivity extends BaseActivity implements CustomKeyDownVod.List
else if (episodeNameLength > 15) numColumns = 3;
else if (episodeNameLength > 10) numColumns = 4;
else if (episodeNameLength > 6) numColumns = 6;
else if (episodeNameLength > 2) numColumns = 8;
else if (episodeNameLength > 4) numColumns = 8;
int rowNum = (int) Math.ceil((double) size / (double) numColumns);
int width = ResUtil.getScreenWidth() - ResUtil.dp2px(48);
ViewGroup.LayoutParams params = mBinding.episodeVert.getLayoutParams();
@ -667,7 +669,7 @@ public class VideoActivity extends BaseActivity implements CustomKeyDownVod.List
}
}
private void setEpisodeActivated(Episode item) {
public void setEpisodeActivated(Episode item) {
if (shouldEnterFullscreen(item)) return;
setCurrentFlag(mBinding.flag.getSelectedPosition());
for (int i = 0; i < mFlagAdapter.size(); i++) ((Flag) mFlagAdapter.get(i)).toggle(getCurrentFlag() == i, item);
@ -841,6 +843,10 @@ public class VideoActivity extends BaseActivity implements CustomKeyDownVod.List
else mBinding.danmaku.hide();
}
private void showEpisodes() {
EpisodeDialog.create().episodes(getFlag().getEpisodes()).show(this);
}
private void checkNext() {
if (mHistory.isRevPlay()) onPrev();
else onNext();
@ -1486,7 +1492,7 @@ public class VideoActivity extends BaseActivity implements CustomKeyDownVod.List
this.background = background;
}
private boolean isFullscreen() {
public boolean isFullscreen() {
return fullscreen;
}
@ -1560,6 +1566,7 @@ public class VideoActivity extends BaseActivity implements CustomKeyDownVod.List
@Override
public boolean dispatchKeyEvent(KeyEvent event) {
if (!isFullscreen() && KeyUtil.isMenuKey(event)) showEpisodes();
if (isFullscreen() && KeyUtil.isMenuKey(event)) onToggle();
if (isVisible(mBinding.control.getRoot())) setR1Callback();
if (isVisible(mBinding.control.getRoot())) mFocus2 = getCurrentFocus();

@ -0,0 +1,173 @@
package com.fongmi.android.tv.ui.dialog;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity;
import androidx.leanback.widget.ArrayObjectAdapter;
import androidx.leanback.widget.ItemBridgeAdapter;
import androidx.leanback.widget.OnChildViewHolderSelectedListener;
import androidx.recyclerview.widget.RecyclerView;
import androidx.viewbinding.ViewBinding;
import com.fongmi.android.tv.bean.Episode;
import com.fongmi.android.tv.databinding.DialogEpisodeBinding;
import com.fongmi.android.tv.ui.activity.VideoActivity;
import com.fongmi.android.tv.ui.presenter.ArrayPresenter;
import com.fongmi.android.tv.ui.presenter.EpisodePresenter;
import com.fongmi.android.tv.utils.ResUtil;
import com.google.android.material.bottomsheet.BottomSheetDialogFragment;
import java.util.ArrayList;
import java.util.List;
public class EpisodeDialog extends BaseDialog implements ArrayPresenter.OnClickListener {
private DialogEpisodeBinding binding;
private VideoActivity activity;
private View mFocus1;
private List<Episode> episodes;
private EpisodePresenter mEpisodePresenter;
private ArrayObjectAdapter mEpisodeAdapter;
private ArrayObjectAdapter mArrayAdapter;
private ArrayPresenter mArrayPresenter;
private int groupSize;
public static EpisodeDialog create() {
return new EpisodeDialog();
}
@Override
protected ViewBinding getBinding(@NonNull LayoutInflater inflater, @Nullable ViewGroup container) {
return binding = DialogEpisodeBinding.inflate(inflater, container, false);
}
public EpisodeDialog() {
}
public EpisodeDialog episodes(List<Episode> episodes) {
this.episodes = episodes;
return this;
}
public void show(FragmentActivity activity) {
for (Fragment f : activity.getSupportFragmentManager().getFragments()) if (f instanceof BottomSheetDialogFragment) return;
show(activity.getSupportFragmentManager(), null);
this.activity = (VideoActivity) activity;
}
@Override
protected void initView() {
this.binding.array.setHorizontalSpacing(ResUtil.dp2px(8));
this.binding.array.setRowHeight(ViewGroup.LayoutParams.WRAP_CONTENT);
this.binding.array.setAdapter(new ItemBridgeAdapter(mArrayAdapter = new ArrayObjectAdapter(mArrayPresenter = new ArrayPresenter(this))));
this.binding.episodeVert.setVerticalSpacing(ResUtil.dp2px(8));
this.binding.episodeVert.setHorizontalSpacing(ResUtil.dp2px(8));
this.binding.episodeVert.setAdapter(new ItemBridgeAdapter(mEpisodeAdapter = new ArrayObjectAdapter(mEpisodePresenter = new EpisodePresenter(this::setEpisodeActivated))));
setEpisodeAdapter(episodes);
}
@Override
protected void initEvent() {
this.binding.array.addOnChildViewHolderSelectedListener(new OnChildViewHolderSelectedListener() {
@Override
public void onChildViewHolderSelected(@NonNull RecyclerView parent, @Nullable RecyclerView.ViewHolder child, int position, int subposition) {
if (mEpisodeAdapter.size() > getGroupSize()) setEpisodeSelectedPosition(position * getGroupSize());
}
});
this.binding.episodeVert.addOnChildViewHolderSelectedListener(new OnChildViewHolderSelectedListener() {
@Override
public void onChildViewHolderSelected(@NonNull RecyclerView parent, @Nullable RecyclerView.ViewHolder child, int position, int subposition) {
if (child != null ) mFocus1 = child.itemView;
}
});
}
private void setEpisodeSelectedPosition(int position) {
this.binding.episodeVert.setSelectedPosition(position);
}
private int getEpisodePosition() {
for (int i = 0; i < mEpisodeAdapter.size(); i++) if (((Episode) mEpisodeAdapter.get(i)).isActivated()) return i;
return 0;
}
public int getGroupSize() {
return groupSize;
}
public void setGroupSize(int size) {
groupSize = size;
}
private void setEpisodeAdapter(List<Episode> items) {
this.binding.episodeVert.setVisibility(items.isEmpty() ? View.GONE : View.VISIBLE);
mEpisodePresenter.setNextFocusUp(this.binding.array.getId());
mArrayPresenter.setNextFocusDown(this.binding.episodeVert.getId());
setEpisodeView(items);
setArrayAdapter(items.size());
mEpisodeAdapter.setItems(items, null);
this.binding.episodeVert.postDelayed(() -> {
int position = getEpisodePosition();
setEpisodeSelectedPosition(position);
}, 1000);
}
private void setArrayAdapter(int size) {
if (size > 200) setGroupSize(100);
else if (size > 100) setGroupSize(40);
else setGroupSize(20);
List<String> items = new ArrayList<>();
this.binding.array.setVisibility(size > 1 ? View.VISIBLE : View.GONE);
for (int i = 0; i < size; i += getGroupSize()) items.add((i + 1) + "-" + Math.min(i + getGroupSize(), size));
mArrayAdapter.setItems(items, null);
}
private void setEpisodeView(List<Episode> items) {
int size = items.size();
int episodeNameLength = items.isEmpty() ? 0 : items.get(0).getName().length();
for (int i = 0; i < size; i++) {
items.get(i).setIndex(i);
int length = items.get(i).getName() == null ? 0 : items.get(i).getName().length();
if (length > episodeNameLength) episodeNameLength = length;
}
int numColumns = 10;
if (episodeNameLength > 30) numColumns = 2;
else if (episodeNameLength > 15) numColumns = 3;
else if (episodeNameLength > 10) numColumns = 4;
else if (episodeNameLength > 6) numColumns = 6;
else if (episodeNameLength > 4) numColumns = 8;
int rowNum = (int) Math.ceil((double) size / (double) numColumns);
int width = ResUtil.getScreenWidth() - ResUtil.dp2px(48);
this.binding.episodeVert.setNumColumns(numColumns);
this.binding.episodeVert.setColumnWidth((width - ((numColumns - 1) * ResUtil.dp2px(8))) / numColumns);
this.binding.episodeVert.setWindowAlignmentOffsetPercent(10f);
ViewGroup.LayoutParams params = this.binding.getRoot().getLayoutParams();
params.height = ResUtil.getScreenHeight() * 3 / 4;
this.binding.getRoot().setLayoutParams(params);
mEpisodePresenter.setNumColumns(numColumns);
mEpisodePresenter.setNumRows(rowNum);
}
private void setEpisodeActivated(Episode item) {
if (!this.activity.isFullscreen() || !item.isActivated()) this.activity.setEpisodeActivated(item);
this.dismiss();
}
@Override
public void onRevSort() {
}
@Override
public void onRevPlay(TextView view) {
}
}

@ -0,0 +1,34 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<com.fongmi.android.tv.ui.custom.CustomHorizontalGridView
android:id="@+id/array"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clipChildren="false"
android:clipToPadding="false"
android:layout_marginTop="12dp"
android:paddingStart="24dp"
android:paddingEnd="24dp"
android:visibility="gone" />
<androidx.leanback.widget.VerticalGridView
android:id="@+id/episodeVert"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clipChildren="false"
android:clipToPadding="false"
android:layout_marginTop="12dp"
android:layout_marginBottom="12dp"
android:paddingStart="24dp"
android:paddingEnd="24dp"
android:focusable="false"
app:focusOutEnd="true"
app:focusOutFront="true"
android:visibility="gone" />
</LinearLayout>

@ -61,6 +61,20 @@
android:textColor="@color/white"
android:textSize="14sp" />
<TextView
android:id="@+id/episodes"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="12dp"
android:background="@drawable/selector_text"
android:focusable="true"
android:focusableInTouchMode="true"
android:nextFocusDown="@id/timeBar"
android:text="@string/play_episodes"
android:textColor="@color/white"
android:textSize="14sp"
tools:text="選集" />
<TextView
android:id="@+id/reset"
android:layout_width="wrap_content"

@ -33,6 +33,7 @@
<string name="play_ed">片尾</string>
<string name="play_next">下集</string>
<string name="play_prev">上集</string>
<string name="play_episodes">选集</string>
<string name="play_loop">循环</string>
<string name="play_timer">定时</string>
<string name="play_time">时间</string>

@ -33,6 +33,7 @@
<string name="play_ed">片尾</string>
<string name="play_next">下集</string>
<string name="play_prev">上集</string>
<string name="play_episodes">選集</string>
<string name="play_loop">循環</string>
<string name="play_timer">定時</string>
<string name="play_time">時間</string>

@ -33,6 +33,7 @@
<string name="play_ed">ED</string>
<string name="play_next">Next</string>
<string name="play_prev">Prev</string>
<string name="play_episodes">Episodes</string>
<string name="play_loop">Loop</string>
<string name="play_timer">Timer</string>
<string name="play_time">Time</string>

Loading…
Cancel
Save