Support epg - part 6

pull/362/head
FongMi 2 years ago
parent d33a31d2a2
commit 981ed04f1e
  1. 8
      app/src/leanback/java/com/fongmi/android/tv/ui/activity/CastActivity.java
  2. 51
      app/src/leanback/java/com/fongmi/android/tv/ui/activity/LiveActivity.java
  3. 16
      app/src/leanback/java/com/fongmi/android/tv/ui/activity/VideoActivity.java
  4. 59
      app/src/leanback/java/com/fongmi/android/tv/ui/custom/CustomLeftRightView.java
  5. 6
      app/src/leanback/java/com/fongmi/android/tv/ui/custom/CustomLiveListView.java
  6. 26
      app/src/leanback/java/com/fongmi/android/tv/ui/custom/CustomUpDownView.java
  7. 3
      app/src/leanback/java/com/fongmi/android/tv/ui/presenter/ChannelPresenter.java
  8. 56
      app/src/leanback/java/com/fongmi/android/tv/ui/presenter/EpgDataPresenter.java
  9. 7
      app/src/leanback/res/color/chip.xml
  10. 6
      app/src/leanback/res/color/epg.xml
  11. 4
      app/src/leanback/res/drawable/selector_epg.xml
  12. 11
      app/src/leanback/res/drawable/shape_epg_focused.xml
  13. 4
      app/src/leanback/res/layout/adapter_channel.xml
  14. 37
      app/src/leanback/res/layout/adapter_epg_data.xml
  15. 20
      app/src/leanback/res/layout/view_widget_live.xml
  16. 5
      app/src/main/java/com/fongmi/android/tv/bean/Epg.java
  17. 6
      app/src/mobile/java/com/fongmi/android/tv/ui/activity/LiveActivity.java

@ -106,10 +106,10 @@ public class CastActivity extends BaseActivity implements CustomKeyDownCast.List
@SuppressLint("ClickableViewAccessibility")
protected void initEvent() {
mBinding.control.seek.setListener(mPlayers);
mBinding.control.text.setAddListener(this::onTextAdd);
mBinding.control.text.setSubListener(this::onTextSub);
mBinding.control.speed.setAddListener(this::onSpeedAdd);
mBinding.control.speed.setSubListener(this::onSpeedSub);
mBinding.control.text.setUpListener(this::onTextAdd);
mBinding.control.text.setDownListener(this::onTextSub);
mBinding.control.speed.setUpListener(this::onSpeedAdd);
mBinding.control.speed.setDownListener(this::onSpeedSub);
mBinding.control.text.setOnClickListener(this::onTrack);
mBinding.control.audio.setOnClickListener(this::onTrack);
mBinding.control.video.setOnClickListener(this::onTrack);

@ -30,6 +30,7 @@ import com.fongmi.android.tv.Setting;
import com.fongmi.android.tv.api.config.LiveConfig;
import com.fongmi.android.tv.bean.Channel;
import com.fongmi.android.tv.bean.Epg;
import com.fongmi.android.tv.bean.EpgData;
import com.fongmi.android.tv.bean.Group;
import com.fongmi.android.tv.bean.Keep;
import com.fongmi.android.tv.bean.Live;
@ -55,6 +56,7 @@ import com.fongmi.android.tv.ui.dialog.PassDialog;
import com.fongmi.android.tv.ui.dialog.SubtitleDialog;
import com.fongmi.android.tv.ui.dialog.TrackDialog;
import com.fongmi.android.tv.ui.presenter.ChannelPresenter;
import com.fongmi.android.tv.ui.presenter.EpgDataPresenter;
import com.fongmi.android.tv.ui.presenter.GroupPresenter;
import com.fongmi.android.tv.utils.Biometric;
import com.fongmi.android.tv.utils.Clock;
@ -73,10 +75,11 @@ import java.util.List;
import tv.danmaku.ijk.media.player.ui.IjkVideoView;
public class LiveActivity extends BaseActivity implements GroupPresenter.OnClickListener, ChannelPresenter.OnClickListener, CustomKeyDownLive.Listener, CustomLiveListView.Callback, TrackDialog.Listener, Biometric.Callback, PassCallback, LiveCallback, SubtitleCallback {
public class LiveActivity extends BaseActivity implements GroupPresenter.OnClickListener, ChannelPresenter.OnClickListener, EpgDataPresenter.OnClickListener, CustomKeyDownLive.Listener, CustomLiveListView.Callback, TrackDialog.Listener, Biometric.Callback, PassCallback, LiveCallback, SubtitleCallback {
private ActivityLiveBinding mBinding;
private ArrayObjectAdapter mChannelAdapter;
private ArrayObjectAdapter mEpgDataAdapter;
private ArrayObjectAdapter mGroupAdapter;
private CustomKeyDownLive mKeyDown;
private LiveViewModel mViewModel;
@ -188,8 +191,10 @@ public class LiveActivity extends BaseActivity implements GroupPresenter.OnClick
private void setRecyclerView() {
mBinding.group.setItemAnimator(null);
mBinding.channel.setItemAnimator(null);
mBinding.widget.epgData.setItemAnimator(null);
mBinding.group.setAdapter(new ItemBridgeAdapter(mGroupAdapter = new ArrayObjectAdapter(new GroupPresenter(this))));
mBinding.channel.setAdapter(new ItemBridgeAdapter(mChannelAdapter = new ArrayObjectAdapter(new ChannelPresenter(this))));
mBinding.widget.epgData.setAdapter(new ItemBridgeAdapter(mEpgDataAdapter = new ArrayObjectAdapter(new EpgDataPresenter(this))));
}
private void setPlayerView() {
@ -289,6 +294,14 @@ public class LiveActivity extends BaseActivity implements GroupPresenter.OnClick
return group;
}
private void setWidth(Epg epg) {
int padding = ResUtil.dp2px(48);
if (epg.getList().isEmpty()) return;
int minWidth = ResUtil.getTextWidth(epg.getList().get(0).getTime(), 16);
if (epg.getWidth() == 0) for (EpgData item : epg.getList()) epg.setWidth(Math.max(epg.getWidth(), ResUtil.getTextWidth(item.getTitle(), 16)));
mBinding.widget.epgData.getLayoutParams().width = epg.getWidth() == 0 ? 0 : Math.min(Math.max(epg.getWidth(), minWidth) + padding, ResUtil.getScreenWidth() / 3);
}
private void setPosition(int[] position) {
if (position[0] == -1) return;
if (mGroupAdapter.size() == 1) return;
@ -414,11 +427,27 @@ public class LiveActivity extends BaseActivity implements GroupPresenter.OnClick
setPosition();
}
private void showUI() {
@Override
public void showUI() {
if (isVisible(mBinding.recycler)) return;
mBinding.recycler.setVisibility(View.VISIBLE);
mBinding.channel.requestFocus();
setPosition();
setUITimer();
hideEpg();
}
@Override
public void showEpg() {
if (mChannel == null || mChannel.getData().getList().isEmpty() || mEpgDataAdapter.size() == 0) return;
mBinding.widget.epgData.setSelectedPosition(mChannel.getData().getIndex());
mBinding.widget.epg.setVisibility(View.VISIBLE);
mBinding.widget.epg.requestFocus();
hideUI();
}
private void hideEpg() {
mBinding.widget.epg.setVisibility(View.GONE);
}
private void showProgress() {
@ -450,6 +479,7 @@ public class LiveActivity extends BaseActivity implements GroupPresenter.OnClick
view.requestFocus();
setR1Callback();
hideInfo();
hideEpg();
}
private void hideControl() {
@ -548,6 +578,11 @@ public class LiveActivity extends BaseActivity implements GroupPresenter.OnClick
return true;
}
@Override
public void onItemClick(EpgData item) {
}
private void addKeep(Channel item) {
getKeep().add(item);
Keep keep = new Keep();
@ -582,13 +617,16 @@ public class LiveActivity extends BaseActivity implements GroupPresenter.OnClick
mBinding.control.line.setText(mChannel.getLineText());
mBinding.widget.line.setVisibility(mChannel.getLineVisible());
mBinding.control.line.setVisibility(mChannel.getLineVisible());
hideEpg();
setEpg();
}
private void setEpg() {
String epg = mChannel.getData().getEpg();
mBinding.widget.name.setMaxEms(epg.isEmpty() ? mChannel.getName().length() : 12);
mEpgDataAdapter.setItems(mChannel.getData().getList(), null);
mBinding.widget.play.setText(epg);
setWidth(mChannel.getData());
setMetadata();
}
@ -605,7 +643,11 @@ public class LiveActivity extends BaseActivity implements GroupPresenter.OnClick
}
private void resetAdapter() {
mBinding.widget.epgData.getLayoutParams().width = 0;
mBinding.channel.getLayoutParams().width = 0;
mBinding.group.getLayoutParams().width = 0;
mBinding.divide.setVisibility(View.GONE);
mEpgDataAdapter.clear();
mChannelAdapter.clear();
mGroupAdapter.clear();
mHides.clear();
@ -842,7 +884,7 @@ public class LiveActivity extends BaseActivity implements GroupPresenter.OnClick
@Override
public boolean dispatch(boolean check) {
return !check || isGone(mBinding.recycler) && isGone(mBinding.control.getRoot());
return !check || isGone(mBinding.recycler) && isGone(mBinding.control.getRoot()) && isGone(mBinding.widget.epg);
}
@Override
@ -912,6 +954,7 @@ public class LiveActivity extends BaseActivity implements GroupPresenter.OnClick
@Override
public void onDoubleTap() {
if (isVisible(mBinding.recycler)) hideUI();
else if (isVisible(mBinding.widget.epg)) hideEpg();
else if (isVisible(mBinding.control.getRoot())) hideControl();
else onMenu();
}
@ -942,6 +985,8 @@ public class LiveActivity extends BaseActivity implements GroupPresenter.OnClick
hideControl();
} else if (isVisible(mBinding.widget.bottom)) {
hideInfo();
} else if (isVisible(mBinding.widget.epg)) {
hideEpg();
} else if (isVisible(mBinding.recycler)) {
hideUI();
} else if (!confirm) {

@ -322,14 +322,14 @@ public class VideoActivity extends BaseActivity implements CustomKeyDownVod.List
mBinding.control.text.setOnClickListener(this::onTrack);
mBinding.control.audio.setOnClickListener(this::onTrack);
mBinding.control.video.setOnClickListener(this::onTrack);
mBinding.control.text.setAddListener(this::onTextAdd);
mBinding.control.text.setSubListener(this::onTextSub);
mBinding.control.speed.setAddListener(this::onSpeedAdd);
mBinding.control.speed.setSubListener(this::onSpeedSub);
mBinding.control.ending.setAddListener(this::onEndingAdd);
mBinding.control.ending.setSubListener(this::onEndingSub);
mBinding.control.opening.setAddListener(this::onOpeningAdd);
mBinding.control.opening.setSubListener(this::onOpeningSub);
mBinding.control.text.setUpListener(this::onTextAdd);
mBinding.control.text.setDownListener(this::onTextSub);
mBinding.control.speed.setUpListener(this::onSpeedAdd);
mBinding.control.speed.setDownListener(this::onSpeedSub);
mBinding.control.ending.setUpListener(this::onEndingAdd);
mBinding.control.ending.setDownListener(this::onEndingSub);
mBinding.control.opening.setUpListener(this::onOpeningAdd);
mBinding.control.opening.setDownListener(this::onOpeningSub);
mBinding.control.loop.setOnClickListener(view -> onLoop());
mBinding.control.danmu.setOnClickListener(view -> onDanmu());
mBinding.control.next.setOnClickListener(view -> checkNext());

@ -0,0 +1,59 @@
package com.fongmi.android.tv.ui.custom;
import android.content.Context;
import android.util.AttributeSet;
import android.view.KeyEvent;
import android.widget.LinearLayout;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.fongmi.android.tv.utils.KeyUtil;
public class CustomLeftRightView extends LinearLayout {
private LeftListener leftListener;
private RightListener rightListener;
public CustomLeftRightView(@NonNull Context context) {
super(context);
}
public CustomLeftRightView(@NonNull Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
}
public void setLeftListener(LeftListener leftListener) {
this.leftListener = leftListener;
}
public void setRightListener(RightListener rightListener) {
this.rightListener = rightListener;
}
private boolean hasEvent(KeyEvent event) {
return event.getAction() == KeyEvent.ACTION_DOWN && ((leftListener != null && KeyUtil.isLeftKey(event)) || (rightListener != null && KeyUtil.isRightKey(event)));
}
@Override
public boolean dispatchKeyEvent(KeyEvent event) {
if (hasEvent(event)) return onKeyDown(event);
else return super.dispatchKeyEvent(event);
}
private boolean onKeyDown(KeyEvent event) {
if (leftListener != null && KeyUtil.isLeftKey(event)) leftListener.onLeft();
if (rightListener != null && KeyUtil.isRightKey(event)) rightListener.onRight();
return true;
}
public interface LeftListener {
void onLeft();
}
public interface RightListener {
void onRight();
}
}

@ -35,21 +35,21 @@ public class CustomLiveListView extends VerticalGridView {
private boolean onKeyDown() {
if (getSelectedPosition() != getAdapter().getItemCount() - 1) return false;
if (getId() == R.id.channel) setSelectedPosition(0);
else listener.nextGroup(false);
else if (listener != null) listener.nextGroup(false);
return true;
}
private boolean onKeyUp() {
if (getSelectedPosition() != 0) return false;
if (getId() == R.id.channel) setSelectedPosition(getAdapter().getItemCount());
else listener.prevGroup(false);
else if (listener != null) listener.prevGroup(false);
return true;
}
@Override
public boolean dispatchKeyEvent(@NonNull KeyEvent event) {
if (getVisibility() == View.GONE || event.getAction() != KeyEvent.ACTION_DOWN) return super.dispatchKeyEvent(event);
if (getVisibility() == View.VISIBLE) listener.setUITimer();
if (getVisibility() == View.VISIBLE && listener != null) listener.setUITimer();
if (KeyUtil.isDownKey(event)) return onKeyDown();
if (KeyUtil.isUpKey(event)) return onKeyUp();
return super.dispatchKeyEvent(event);

@ -12,8 +12,8 @@ import com.fongmi.android.tv.utils.KeyUtil;
public class CustomUpDownView extends AppCompatTextView {
private AddListener addListener;
private SubListener subListener;
private UpListener upListener;
private DownListener downListener;
public CustomUpDownView(@NonNull Context context) {
super(context);
@ -23,16 +23,16 @@ public class CustomUpDownView extends AppCompatTextView {
super(context, attrs);
}
public void setAddListener(AddListener addListener) {
this.addListener = addListener;
public void setUpListener(UpListener upListener) {
this.upListener = upListener;
}
public void setSubListener(SubListener subListener) {
this.subListener = subListener;
public void setDownListener(DownListener downListener) {
this.downListener = downListener;
}
private boolean hasEvent(KeyEvent event) {
return event.getAction() == KeyEvent.ACTION_DOWN && (KeyUtil.isUpKey(event) || KeyUtil.isDownKey(event));
return event.getAction() == KeyEvent.ACTION_DOWN && ((upListener != null && KeyUtil.isUpKey(event)) || (downListener != null && KeyUtil.isDownKey(event)));
}
@Override
@ -42,18 +42,18 @@ public class CustomUpDownView extends AppCompatTextView {
}
private boolean onKeyDown(KeyEvent event) {
if (KeyUtil.isUpKey(event)) addListener.onAdd();
if (KeyUtil.isDownKey(event)) subListener.onSud();
if (upListener != null && KeyUtil.isUpKey(event)) upListener.onUp();
if (downListener != null && KeyUtil.isDownKey(event)) downListener.onDown();
return true;
}
public interface AddListener {
public interface UpListener {
void onAdd();
void onUp();
}
public interface SubListener {
public interface DownListener {
void onSud();
void onDown();
}
}

@ -19,6 +19,8 @@ public class ChannelPresenter extends Presenter {
public interface OnClickListener {
void showEpg();
void onItemClick(Channel item);
boolean onLongClick(Channel item);
@ -37,6 +39,7 @@ public class ChannelPresenter extends Presenter {
holder.binding.name.setText(item.getName());
holder.binding.number.setText(item.getNumber());
holder.binding.getRoot().setSelected(item.isSelected());
holder.binding.getRoot().setRightListener(mListener::showEpg);
setOnClickListener(holder, view -> mListener.onItemClick(item));
holder.view.setOnLongClickListener(view -> mListener.onLongClick(item));
}

@ -0,0 +1,56 @@
package com.fongmi.android.tv.ui.presenter;
import android.view.LayoutInflater;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.leanback.widget.Presenter;
import com.fongmi.android.tv.bean.EpgData;
import com.fongmi.android.tv.databinding.AdapterEpgDataBinding;
public class EpgDataPresenter extends Presenter {
private final OnClickListener mListener;
public EpgDataPresenter(OnClickListener listener) {
this.mListener = listener;
}
public interface OnClickListener {
void showUI();
void onItemClick(EpgData item);
}
@Override
public Presenter.ViewHolder onCreateViewHolder(ViewGroup parent) {
return new ViewHolder(AdapterEpgDataBinding.inflate(LayoutInflater.from(parent.getContext()), parent, false));
}
@Override
public void onBindViewHolder(Presenter.ViewHolder viewHolder, Object object) {
EpgData item = (EpgData) object;
ViewHolder holder = (ViewHolder) viewHolder;
holder.binding.time.setText(item.getTime());
holder.binding.title.setText(item.getTitle());
holder.binding.getRoot().setSelected(item.isInRange());
holder.binding.getRoot().setLeftListener(mListener::showUI);
setOnClickListener(holder, view -> mListener.onItemClick(item));
}
@Override
public void onUnbindViewHolder(Presenter.ViewHolder viewHolder) {
}
public static class ViewHolder extends Presenter.ViewHolder {
private final AdapterEpgDataBinding binding;
public ViewHolder(@NonNull AdapterEpgDataBinding binding) {
super(binding.getRoot());
this.binding = binding;
}
}
}

@ -1,7 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="@color/grey_800" android:state_checked="true" android:state_focused="true" />
<item android:color="@color/grey_600" android:state_checked="true" />
<item android:color="@color/grey_800" android:state_focused="true" />
<item android:color="@color/grey_600" />
</selector>

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="@color/yellow_500" android:state_focused="true" android:state_selected="true" />
<item android:color="@color/yellow_500" android:state_selected="true" />
<item android:color="@color/white" />
</selector>

@ -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_epg_focused" android:state_focused="true" />
</selector>

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

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
<com.fongmi.android.tv.ui.custom.CustomLeftRightView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="wrap_content"
android:layout_height="56dp"
@ -42,4 +42,4 @@
android:textStyle="bold"
tools:text="CNN" />
</LinearLayout>
</com.fongmi.android.tv.ui.custom.CustomLeftRightView>

@ -0,0 +1,37 @@
<?xml version="1.0" encoding="utf-8"?>
<com.fongmi.android.tv.ui.custom.CustomLeftRightView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/selector_epg"
android:focusable="true"
android:focusableInTouchMode="true"
android:orientation="vertical"
android:paddingStart="20dp"
android:paddingTop="12dp"
android:paddingEnd="20dp"
android:paddingBottom="12dp">
<TextView
android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:duplicateParentState="true"
android:ellipsize="marquee"
android:singleLine="true"
android:textColor="@color/epg"
android:textSize="16sp"
tools:text="七龍珠" />
<TextView
android:id="@+id/time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:duplicateParentState="true"
android:ellipsize="marquee"
android:singleLine="true"
android:textColor="@color/epg"
android:textSize="14sp"
tools:text="18:00 ~ 19:00" />
</com.fongmi.android.tv.ui.custom.CustomLeftRightView>

@ -241,4 +241,24 @@
tools:text="16:50" />
</LinearLayout>
<LinearLayout
android:id="@+id/epg"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:background="@drawable/shape_live_list"
android:orientation="vertical"
android:visibility="gone"
tools:visibility="visible">
<androidx.leanback.widget.VerticalGridView
android:id="@+id/epg_data"
android:layout_width="0dp"
android:layout_height="match_parent"
android:clipChildren="false"
android:clipToPadding="false"
tools:itemCount="5"
tools:listitem="@layout/adapter_epg_data" />
</LinearLayout>
</FrameLayout>

@ -76,6 +76,11 @@ public class Epg {
}
}
public int getIndex() {
for (int i = 0; i < getList().size(); i++) if (getList().get(i).isInRange()) return i;
return -1;
}
public String getEpg() {
for (EpgData item : getList()) if (item.isInRange()) return item.format();
return "";

@ -323,7 +323,7 @@ public class LiveActivity extends BaseActivity implements CustomKeyDownLive.List
private void setWidth(Epg epg) {
int padding = ResUtil.dp2px(40);
if (epg.getList().isEmpty()) return;
int minWidth = ResUtil.getTextWidth(epg.getList().get(0).getTime(), 12);
int minWidth = ResUtil.getTextWidth(epg.getList().get(0).getTime(), 14);
if (epg.getWidth() == 0) for (EpgData item : epg.getList()) epg.setWidth(Math.max(epg.getWidth(), ResUtil.getTextWidth(item.getTitle(), 14)));
mBinding.widget.epgData.getLayoutParams().width = epg.getWidth() == 0 ? 0 : Math.min(Math.max(epg.getWidth(), minWidth) + padding, ResUtil.getScreenWidth() / 3);
}
@ -668,6 +668,7 @@ public class LiveActivity extends BaseActivity implements CustomKeyDownLive.List
mBinding.widget.line.setVisibility(mChannel.getLineVisible());
mBinding.control.action.line.setText(mBinding.widget.line.getText());
mBinding.control.action.line.setVisibility(mBinding.widget.line.getVisibility());
hideEpg();
setEpg();
}
@ -708,6 +709,9 @@ public class LiveActivity extends BaseActivity implements CustomKeyDownLive.List
}
private void resetAdapter() {
mBinding.widget.epgData.getLayoutParams().width = 0;
mBinding.channel.getLayoutParams().width = 0;
mBinding.group.getLayoutParams().width = 0;
mBinding.divide.setVisibility(View.GONE);
mEpgDataAdapter.clear();
mChannelAdapter.clear();

Loading…
Cancel
Save