From 136ed7d36f3ff664337822ddf19bc0aeca368fae Mon Sep 17 00:00:00 2001 From: FongMi Date: Tue, 16 Jan 2024 18:54:03 +0800 Subject: [PATCH] Add episode view switch --- .../tv/ui/activity/SettingPlayerActivity.java | 9 ++ .../android/tv/ui/activity/VideoActivity.java | 107 +++++++++++------- .../android/tv/ui/adapter/QualityAdapter.java | 16 +-- .../tv/ui/presenter/PartPresenter.java | 8 +- .../res/layout/activity_setting_player.xml | 29 +++++ .../leanback/res/layout/activity_video.xml | 14 ++- app/src/leanback/res/layout/adapter_array.xml | 2 - .../leanback/res/layout/adapter_episode.xml | 2 - app/src/leanback/res/layout/adapter_flag.xml | 1 - app/src/leanback/res/layout/adapter_part.xml | 1 - .../leanback/res/layout/adapter_quality.xml | 1 - .../java/com/fongmi/android/tv/Setting.java | 12 +- app/src/main/res/values-zh-rCN/strings.xml | 6 + app/src/main/res/values-zh-rTW/strings.xml | 6 + app/src/main/res/values/strings.xml | 6 + 15 files changed, 152 insertions(+), 68 deletions(-) diff --git a/app/src/leanback/java/com/fongmi/android/tv/ui/activity/SettingPlayerActivity.java b/app/src/leanback/java/com/fongmi/android/tv/ui/activity/SettingPlayerActivity.java index ffe1accda..30961ad8c 100644 --- a/app/src/leanback/java/com/fongmi/android/tv/ui/activity/SettingPlayerActivity.java +++ b/app/src/leanback/java/com/fongmi/android/tv/ui/activity/SettingPlayerActivity.java @@ -30,6 +30,7 @@ public class SettingPlayerActivity extends BaseActivity implements UaCallback, B private ActivitySettingPlayerBinding mBinding; private String[] danmuSpeed; private String[] caption; + private String[] episode; private String[] player; private String[] render; private String[] scale; @@ -64,6 +65,7 @@ public class SettingPlayerActivity extends BaseActivity implements UaCallback, B mBinding.scaleText.setText((scale = ResUtil.getStringArray(R.array.select_scale))[Setting.getScale()]); mBinding.playerText.setText((player = ResUtil.getStringArray(R.array.select_player))[Setting.getPlayer()]); mBinding.renderText.setText((render = ResUtil.getStringArray(R.array.select_render))[Setting.getRender()]); + mBinding.episodeText.setText((episode = ResUtil.getStringArray(R.array.select_episode))[Setting.getEpisode()]); mBinding.captionText.setText((caption = ResUtil.getStringArray(R.array.select_caption))[Setting.isCaption() ? 1 : 0]); mBinding.danmuSpeedText.setText((danmuSpeed = ResUtil.getStringArray(R.array.select_danmu_speed))[Setting.getDanmuSpeed()]); } @@ -78,6 +80,7 @@ public class SettingPlayerActivity extends BaseActivity implements UaCallback, B mBinding.player.setOnClickListener(this::setPlayer); mBinding.render.setOnClickListener(this::setRender); mBinding.tunnel.setOnClickListener(this::setTunnel); + mBinding.episode.setOnClickListener(this::setEpisode); mBinding.caption.setOnClickListener(this::setCaption); mBinding.subtitle.setOnClickListener(this::onSubtitle); mBinding.caption.setOnLongClickListener(this::onCaption); @@ -150,6 +153,12 @@ public class SettingPlayerActivity extends BaseActivity implements UaCallback, B mBinding.tunnelText.setText(getSwitch(Setting.isTunnel())); } + private void setEpisode(View view) { + int index = Setting.getEpisode(); + Setting.putEpisode(index = index == episode.length - 1 ? 0 : ++index); + mBinding.episodeText.setText(episode[index]); + } + private void setCaption(View view) { Setting.putCaption(!Setting.isCaption()); mBinding.captionText.setText(caption[Setting.isCaption() ? 1 : 0]); diff --git a/app/src/leanback/java/com/fongmi/android/tv/ui/activity/VideoActivity.java b/app/src/leanback/java/com/fongmi/android/tv/ui/activity/VideoActivity.java index 3c90d9a80..3cba76a39 100644 --- a/app/src/leanback/java/com/fongmi/android/tv/ui/activity/VideoActivity.java +++ b/app/src/leanback/java/com/fongmi/android/tv/ui/activity/VideoActivity.java @@ -23,6 +23,7 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.fragment.app.FragmentActivity; import androidx.leanback.widget.ArrayObjectAdapter; +import androidx.leanback.widget.BaseGridView; import androidx.leanback.widget.ItemBridgeAdapter; import androidx.leanback.widget.OnChildViewHolderSelectedListener; import androidx.lifecycle.ViewModelProvider; @@ -276,6 +277,10 @@ public class VideoActivity extends BaseActivity implements CustomKeyDownVod.List return mBinding.ijk; } + private BaseGridView getEpisodeView() { + return Setting.getEpisode() == 0 ? mBinding.episodeHori : mBinding.episodeVert; + } + private boolean isReplay() { return Setting.getReset() == 1; } @@ -302,6 +307,7 @@ public class VideoActivity extends BaseActivity implements CustomKeyDownVod.List mR3 = this::showEmpty; setBackground(false); setRecyclerView(); + setEpisodeView(); setVideoView(); setDanmuView(); setViewModel(); @@ -352,7 +358,7 @@ public class VideoActivity extends BaseActivity implements CustomKeyDownVod.List if (mFlagAdapter.size() > 0) setFlagActivated((Flag) mFlagAdapter.get(position)); } }); - mBinding.episode.addOnChildViewHolderSelectedListener(new OnChildViewHolderSelectedListener() { + getEpisodeView().addOnChildViewHolderSelectedListener(new OnChildViewHolderSelectedListener() { @Override public void onChildViewHolderSelected(@NonNull RecyclerView parent, @Nullable RecyclerView.ViewHolder child, int position, int subposition) { if (child != null && mBinding.video != mFocus1) mFocus1 = child.itemView; @@ -361,7 +367,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() > 20 && position > 1) mBinding.episode.setSelectedPosition((position - 2) * 20); + if (mEpisodeAdapter.size() > 20 && position > 1) getEpisodeView().setSelectedPosition((position - 2) * 20); } }); } @@ -370,9 +376,6 @@ public class VideoActivity extends BaseActivity implements CustomKeyDownVod.List mBinding.flag.setHorizontalSpacing(ResUtil.dp2px(8)); mBinding.flag.setRowHeight(ViewGroup.LayoutParams.WRAP_CONTENT); mBinding.flag.setAdapter(new ItemBridgeAdapter(mFlagAdapter = new ArrayObjectAdapter(mFlagPresenter = new FlagPresenter(this::setFlagActivated)))); - mBinding.episode.setVerticalSpacing(ResUtil.dp2px(8)); - mBinding.episode.setHorizontalSpacing(ResUtil.dp2px(8)); - mBinding.episode.setAdapter(new ItemBridgeAdapter(mEpisodeAdapter = new ArrayObjectAdapter(mEpisodePresenter = new EpisodePresenter(this::setEpisodeActivated)))); mBinding.quality.setHorizontalSpacing(ResUtil.dp2px(8)); mBinding.quality.setRowHeight(ViewGroup.LayoutParams.WRAP_CONTENT); mBinding.quality.setAdapter(mQualityAdapter = new QualityAdapter(this::setQualityActivated)); @@ -391,6 +394,13 @@ public class VideoActivity extends BaseActivity implements CustomKeyDownVod.List mParseAdapter.setItems(VodConfig.get().getParses(), null); } + private void setEpisodeView() { + getEpisodeView().setHorizontalSpacing(ResUtil.dp2px(8)); + getEpisodeView().setAdapter(new ItemBridgeAdapter(mEpisodeAdapter = new ArrayObjectAdapter(mEpisodePresenter = new EpisodePresenter(this::setEpisodeActivated)))); + if (Setting.getEpisode() == 0) mBinding.episodeHori.setRowHeight(ViewGroup.LayoutParams.WRAP_CONTENT); + else mBinding.episodeVert.setVerticalSpacing(ResUtil.dp2px(8)); + } + private void setVideoView() { mPlayers.set(getExo(), getIjk()); getExo().getSubtitleView().setStyle(ExoUtil.getCaptionStyle()); @@ -589,6 +599,14 @@ public class VideoActivity extends BaseActivity implements CustomKeyDownVod.List } private void setEpisodeAdapter(List items) { + getEpisodeView().setVisibility(items.isEmpty() ? View.GONE : View.VISIBLE); + if (items.size() > 0 && Setting.getEpisode() == 1) setEpisodeView(items); + mEpisodeAdapter.setItems(items, null); + setArrayAdapter(items.size()); + updateFocus(); + } + + private void setEpisodeView(List items) { int size = items.size(); for (int i = 0; i < size; i++) items.get(i).setIndex(i); int episodeNameLength = items.isEmpty() ? 0 : items.get(0).getName().length(); @@ -600,18 +618,14 @@ public class VideoActivity extends BaseActivity implements CustomKeyDownVod.List if (size < numColumns) numColumns = size; int rowNum = (int) Math.ceil((double) size / (double) numColumns); int width = ResUtil.getScreenWidth() - ResUtil.dp2px(48); - mBinding.episode.setNumColumns(numColumns); - mBinding.episode.setColumnWidth((width - ((numColumns - 1) * ResUtil.dp2px(8))) / numColumns); - ViewGroup.LayoutParams layoutParams = mBinding.episode.getLayoutParams(); - layoutParams.width = ResUtil.getScreenWidth(); - layoutParams.height = rowNum > 6 ? ResUtil.dp2px(300) : ResUtil.dp2px(rowNum * 50); - mBinding.episode.setLayoutParams(layoutParams); - mBinding.episode.setVisibility(items.isEmpty() ? View.GONE : View.VISIBLE); + ViewGroup.LayoutParams params = mBinding.episodeVert.getLayoutParams(); + params.width = ResUtil.getScreenWidth(); + params.height = rowNum > 6 ? ResUtil.dp2px(300) : ResUtil.dp2px(rowNum * 50); + mBinding.episodeVert.setNumColumns(numColumns); + mBinding.episodeVert.setColumnWidth((width - ((numColumns - 1) * ResUtil.dp2px(8))) / numColumns); + mBinding.episodeVert.setLayoutParams(params); mEpisodePresenter.setNumColumns(numColumns); mEpisodePresenter.setNumRows(rowNum); - mEpisodeAdapter.setItems(items, null); - setArray(size); - updateFocus(); } private void seamless(Flag flag) { @@ -620,8 +634,8 @@ public class VideoActivity extends BaseActivity implements CustomKeyDownVod.List if (episode == null || episode.isActivated()) return; if (Setting.getFlag() == 1) { episode.setActivated(true); - mBinding.episode.requestFocus(); - mBinding.episode.setSelectedPosition(getEpisodePosition()); + getEpisodeView().requestFocus(); + getEpisodeView().setSelectedPosition(getEpisodePosition()); episode.setActivated(false); } else { mHistory.setVodRemarks(episode.getName()); @@ -634,24 +648,16 @@ public class VideoActivity extends BaseActivity implements CustomKeyDownVod.List if (shouldEnterFullscreen(item)) return; setCurrentFlag(mBinding.flag.getSelectedPosition()); for (int i = 0; i < mFlagAdapter.size(); i++) ((Flag) mFlagAdapter.get(i)).toggle(getCurrentFlag() == i, item); - mBinding.episode.setSelectedPosition(getEpisodePosition()); - notifyItemChanged(mBinding.episode, mEpisodeAdapter); + getEpisodeView().setSelectedPosition(getEpisodePosition()); + notifyItemChanged(getEpisodeView(), mEpisodeAdapter); if (mEpisodeAdapter.size() == 0) return; if (isFullscreen()) Notify.show(getString(R.string.play_ready, item.getName())); onRefresh(); } private void setQualityVisible(boolean visible) { - mArrayPresenter.setNextFocusDown(isVisible(mBinding.episode) ? R.id.episode : R.id.part); - mFlagPresenter.setNextFocusDown(visible ? R.id.quality : R.id.array); mBinding.quality.setVisibility(visible ? View.VISIBLE : View.GONE); - mArrayPresenter.setNextFocusUp(visible ? R.id.quality : R.id.flag); - mEpisodePresenter.setNextFocusUp(R.id.array); - mQualityAdapter.setNextFocusDown(R.id.array); - mQualityAdapter.setNextFocusUp(R.id.flag); - notifyItemChanged(mBinding.episode, mEpisodeAdapter); - notifyItemChanged(mBinding.array, mArrayAdapter); - notifyItemChanged(mBinding.flag, mFlagAdapter); + updateFocus(); } private void setQualityActivated(Result result) { @@ -668,7 +674,7 @@ public class VideoActivity extends BaseActivity implements CustomKeyDownVod.List private void reverseEpisode(boolean scroll) { for (int i = 0; i < mFlagAdapter.size(); i++) Collections.reverse(((Flag) mFlagAdapter.get(i)).getEpisodes()); setEpisodeAdapter(getFlag().getEpisodes()); - if (scroll) mBinding.episode.setSelectedPosition(getEpisodePosition()); + if (scroll) getEpisodeView().setSelectedPosition(getEpisodePosition()); } private void setParseActivated(Parse item) { @@ -677,7 +683,7 @@ public class VideoActivity extends BaseActivity implements CustomKeyDownVod.List onRefresh(); } - private void setArray(int size) { + private void setArrayAdapter(int size) { List items = new ArrayList<>(); items.add(getString(R.string.play_reverse)); items.add(getString(mHistory.getRevPlayText())); @@ -688,10 +694,27 @@ public class VideoActivity extends BaseActivity implements CustomKeyDownVod.List } private void updateFocus() { - mPartPresenter.setNextFocusUp(isVisible(mBinding.episode) ? R.id.episode : R.id.array); - mEpisodePresenter.setNextFocusDown(isVisible(mBinding.part) ? R.id.part : R.id.flag); - notifyItemChanged(mBinding.episode, mEpisodeAdapter); + if (Setting.getEpisode() == 0) { + mArrayPresenter.setNextFocusUp(R.id.episodeHori); + mQualityAdapter.setNextFocusDown(R.id.episodeHori); + mArrayPresenter.setNextFocusDown(isVisible(mBinding.part) ? R.id.part : R.id.quick); + mEpisodePresenter.setNextFocusDown(isVisible(mBinding.array) ? R.id.array : R.id.part); + mEpisodePresenter.setNextFocusUp(isVisible(mBinding.quality) ? R.id.quality : R.id.flag); + mPartPresenter.setNextFocusUp(isVisible(mBinding.array) ? R.id.array : R.id.episodeHori); + mFlagPresenter.setNextFocusDown(isVisible(mBinding.quality) ? R.id.quality : R.id.episodeHori); + } else { + mArrayPresenter.setNextFocusDown(R.id.episodeVert); + mEpisodePresenter.setNextFocusDown(isVisible(mBinding.part) ? R.id.part : R.id.quick); + mArrayPresenter.setNextFocusUp(isVisible(mBinding.quality) ? R.id.quality : R.id.flag); + mQualityAdapter.setNextFocusDown(isVisible(mBinding.array) ? R.id.array : R.id.episodeVert); + mEpisodePresenter.setNextFocusUp(isVisible(mBinding.array) ? R.id.array : isVisible(mBinding.quality) ? R.id.quality : R.id.flag); + mFlagPresenter.setNextFocusDown(isVisible(mBinding.quality) ? R.id.quality : isVisible(mBinding.array) ? R.id.array : R.id.episodeVert); + mPartPresenter.setNextFocusUp(isVisible(mBinding.episodeVert) ? R.id.episodeVert : isVisible(mBinding.quality) ? R.id.quality : R.id.flag); + } + notifyItemChanged(getEpisodeView(), mEpisodeAdapter); + notifyItemChanged(mBinding.array, mArrayAdapter); notifyItemChanged(mBinding.part, mPartAdapter); + notifyItemChanged(mBinding.flag, mFlagAdapter); } @Override @@ -1055,25 +1078,23 @@ public class VideoActivity extends BaseActivity implements CustomKeyDownVod.List public void onResponse(@NonNull Call call, @NonNull Response response) throws IOException { List items = Part.get(response.body().string()); if (!items.contains(source)) items.add(0, source); - App.post(() -> { - mBinding.part.setVisibility(View.VISIBLE); - mPartAdapter.setItems(items, null); - updateFocus(); - }); + App.post(() -> setPartAdapter(items)); } @Override public void onFailure(@NonNull Call call, @NonNull IOException e) { List items = List.of(source); - App.post(() -> { - mBinding.part.setVisibility(View.VISIBLE); - mPartAdapter.setItems(items, null); - updateFocus(); - }); + App.post(() -> setPartAdapter(items)); } }); } + private void setPartAdapter(List items) { + mBinding.part.setVisibility(View.VISIBLE); + mPartAdapter.setItems(items, null); + updateFocus(); + } + private void checkFlag(Vod item) { boolean empty = item.getVodFlags().isEmpty(); mBinding.flag.setVisibility(empty ? View.GONE : View.VISIBLE); diff --git a/app/src/leanback/java/com/fongmi/android/tv/ui/adapter/QualityAdapter.java b/app/src/leanback/java/com/fongmi/android/tv/ui/adapter/QualityAdapter.java index 0665c2fe8..96d6882fd 100644 --- a/app/src/leanback/java/com/fongmi/android/tv/ui/adapter/QualityAdapter.java +++ b/app/src/leanback/java/com/fongmi/android/tv/ui/adapter/QualityAdapter.java @@ -12,10 +12,9 @@ import com.fongmi.android.tv.databinding.AdapterQualityBinding; public class QualityAdapter extends RecyclerView.Adapter { private final OnClickListener mListener; + private int nextFocusDown; private Result mResult; private int position; - private int nextFocusUp; - private int nextFocusDown; public QualityAdapter(OnClickListener listener) { this.mListener = listener; @@ -27,18 +26,14 @@ public class QualityAdapter extends RecyclerView.Adapter onItemClick(position)); diff --git a/app/src/leanback/java/com/fongmi/android/tv/ui/presenter/PartPresenter.java b/app/src/leanback/java/com/fongmi/android/tv/ui/presenter/PartPresenter.java index 0a25a4d59..15c28185a 100644 --- a/app/src/leanback/java/com/fongmi/android/tv/ui/presenter/PartPresenter.java +++ b/app/src/leanback/java/com/fongmi/android/tv/ui/presenter/PartPresenter.java @@ -12,7 +12,7 @@ import com.fongmi.android.tv.databinding.AdapterPartBinding; public class PartPresenter extends Presenter { private final OnClickListener mListener; - private int nextFocus; + private int nextFocusUp; public PartPresenter(OnClickListener listener) { this.mListener = listener; @@ -22,8 +22,8 @@ public class PartPresenter extends Presenter { void onItemClick(String item); } - public void setNextFocusUp(int nextFocus) { - this.nextFocus = nextFocus; + public void setNextFocusUp(int nextFocusUp) { + this.nextFocusUp = nextFocusUp; } @Override @@ -37,7 +37,7 @@ public class PartPresenter extends Presenter { ViewHolder holder = (ViewHolder) viewHolder; holder.binding.text.setText(text); holder.binding.text.setMaxEms(Product.getEms()); - holder.binding.text.setNextFocusUpId(nextFocus); + holder.binding.text.setNextFocusUpId(nextFocusUp); setOnClickListener(holder, view -> mListener.onItemClick(text)); } diff --git a/app/src/leanback/res/layout/activity_setting_player.xml b/app/src/leanback/res/layout/activity_setting_player.xml index 4310662e2..60af0a1a9 100644 --- a/app/src/leanback/res/layout/activity_setting_player.xml +++ b/app/src/leanback/res/layout/activity_setting_player.xml @@ -291,6 +291,35 @@ + + + + + + + + + + \ No newline at end of file diff --git a/app/src/leanback/res/layout/adapter_episode.xml b/app/src/leanback/res/layout/adapter_episode.xml index 26861fb8a..42bd7f847 100644 --- a/app/src/leanback/res/layout/adapter_episode.xml +++ b/app/src/leanback/res/layout/adapter_episode.xml @@ -9,8 +9,6 @@ android:focusable="true" android:focusableInTouchMode="true" android:gravity="center" - android:nextFocusUp="@id/flag" - android:nextFocusDown="@id/array" android:singleLine="true" android:textColor="@color/text" android:textSize="16sp" diff --git a/app/src/leanback/res/layout/adapter_flag.xml b/app/src/leanback/res/layout/adapter_flag.xml index 2efba1661..cc8698372 100644 --- a/app/src/leanback/res/layout/adapter_flag.xml +++ b/app/src/leanback/res/layout/adapter_flag.xml @@ -8,7 +8,6 @@ android:focusable="true" android:focusableInTouchMode="true" android:gravity="center" - android:nextFocusDown="@id/episode" android:textColor="@color/text" android:textSize="16sp" tools:text="泥巴" /> \ No newline at end of file diff --git a/app/src/leanback/res/layout/adapter_part.xml b/app/src/leanback/res/layout/adapter_part.xml index 196533688..c568c6ede 100644 --- a/app/src/leanback/res/layout/adapter_part.xml +++ b/app/src/leanback/res/layout/adapter_part.xml @@ -9,7 +9,6 @@ android:focusable="true" android:focusableInTouchMode="true" android:gravity="center" - android:nextFocusUp="@id/array" android:singleLine="true" android:textColor="@color/white" android:textSize="16sp" diff --git a/app/src/leanback/res/layout/adapter_quality.xml b/app/src/leanback/res/layout/adapter_quality.xml index 1aa9b8ddb..fa189df46 100644 --- a/app/src/leanback/res/layout/adapter_quality.xml +++ b/app/src/leanback/res/layout/adapter_quality.xml @@ -10,7 +10,6 @@ android:focusableInTouchMode="true" android:gravity="center" android:nextFocusUp="@id/flag" - android:nextFocusDown="@id/episode" android:singleLine="true" android:textColor="@color/text" android:textSize="16sp" diff --git a/app/src/main/java/com/fongmi/android/tv/Setting.java b/app/src/main/java/com/fongmi/android/tv/Setting.java index 205e68941..7ec60b619 100644 --- a/app/src/main/java/com/fongmi/android/tv/Setting.java +++ b/app/src/main/java/com/fongmi/android/tv/Setting.java @@ -173,8 +173,16 @@ public class Setting { return Prefers.getInt("flag"); } - public static void putFlag(int mode) { - Prefers.put("flag", mode); + public static void putFlag(int flag) { + Prefers.put("flag", flag); + } + + public static int getEpisode() { + return Prefers.getInt("episode"); + } + + public static void putEpisode(int episode) { + Prefers.put("episode", episode); } public static int getBackground() { diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index 22c1adebc..47153a13b 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -89,6 +89,7 @@ 弹幕行数 后台播放 线路播放 + 选集样式 隧道模式 连线方式 缓冲时间 @@ -192,6 +193,11 @@ 手动 + + 单列 + 多列 + + 预设 系统 diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index afb750012..53e705865 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -89,6 +89,7 @@ 彈幕行數 背景播放 線路播放 + 選集樣式 隧道模式 連線方式 緩衝時間 @@ -192,6 +193,11 @@ 手動 + + 單列 + 多列 + + 預設 系統 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index dea04a735..849c6e445 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -89,6 +89,7 @@ Danmu line Background play Flag play + Episode style Tunnel mode HTTP method Buffer time @@ -197,6 +198,11 @@ Manual + + Single + Multiple + + Default System