需求
项目需求:在电视端加载视频列表并播放视频,用遥控器操作每一个menu和子项目的ietm。
问题
- recycleview如何在电视端聚焦
- recycleview聚焦混乱
- 第一个recycleview(菜单栏menu)切换到第二个recycleview(子项Item)
TV开发和手机开发有个不同的就是焦点问题。
在手机端,手指只要一划就可以到后面了,而在TV端,需要用遥控器左右键控制焦点移动。
- 第一个recycleview(菜单栏menu)切换到第二个recycleview(子项Item)
RecyclerView(简称RV)在TV端的应用可以借鉴的案例不多,相比于ListView,RV的很多功能都需要自己实现。诸如,wrap_content自适应问题,选中的背景问题,setSelection()方法等。
menu列表
本项目中的menu采用重写recycleview:
主要解决Recycleview切换到子项item时,返回记住当前选择的menu。如图所示:
- TvRecyclerView属性介绍 :
<attr name="scrollMode"/>
<attr name="focusDrawable" format="reference" />
<attr name="isAutoProcessFocus" format="boolean" />
<attr name="focusScale" format="float" />
(1) scrollMode控制TvRecyclerView的滑动模式, TvRecyclerView的滑动模式有两种:
- ① normalScroll: 默认情况下是这种模式, 当TvRecyclerView是这种模式时, 当焦点滑动到的view是没有全部显示出来的, TvRecyclerView将会向按键的方向滑动屏幕一半的距离.
- ② followScroll: 当TvRecyclerView是这种模式时, 当焦点滑动到view在屏幕当中就一直滑动, 效果与android Tv上的HorizontalGridView差不多.
(2) focusDrawable 设置选择的Drawable, 如图一的白色选择框, 默认是没有设置, 想要这种效果需要设置此属性或在代码中设置.
(3) isAutoProcessFocus 控制焦点处理是由谁来做, 默认焦点由TvRecyclerView来处理.
当isAutoProcessFocus 为false, 子view是可以获得焦点的, 当isAutoProcessFocus为true, 子view获取
不到焦点, 焦点由TvRecyclerView来处理.
(4)focusScale 设置选中view时, view的放大系数. 大于1.0f才生效.
主要代码如下:
public class TvRecyclerView extends RecyclerView {
public static final String TAG = "TvRecyclerView";
private static final float DEFAULT_SELECT_SCALE = 1.04f;
private static final int SCROLL_NORMAL = 0;
private static final int SCROLL_FOLLOW = 1;
private FocusBorderView mFocusBorderView;
private Drawable mDrawableFocus;
public boolean mIsDrawFocusMoveAnim;
private float mSelectedScaleValue;
private float mFocusMoveAnimScale;
private int mSelectedPosition;
private View mNextFocused;
private boolean mInLayout;
private int mFocusFrameLeft;
private int mFocusFrameTop;
private int mFocusFrameRight;
private int mFocusFrameBottom;
private boolean mReceivedInvokeKeyDown;
protected View mSelectedItem;
private OnItemStateListener mItemStateListener;
private Scroller mScrollerFocusMoveAnim;
private boolean mIsFollowScroll;
private int mScreenWidth;
private int mScreenHeight;
private boolean mIsAutoProcessFocus;
private int mOrientation;
private boolean mIsSetItemSelected = false;
private boolean mIsNeedMoveForSelect = false;
public TvRecyclerView(Context context) {
this(context, null);
}
public TvRecyclerView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public TvRecyclerView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
setAttributeSet(attrs);
// 解决问题: 当需要选择的item没有显示在屏幕上, 需要滑动让item显示出来.
// 这时需要调整item的位置, 并且item获取焦点
addOnScrollListener(new OnScrollListener() {
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
if (mIsNeedMoveForSelect) {
mIsNeedMoveForSelect = false;
int firstVisiblePos = getFirstVisiblePosition();
View selectView = getChildAt(mSelectedPosition - firstVisiblePos);
if (selectView != null) {
mSelectedItem = selectView;
adjustSelectOffset(selectView);
}
}
}
});
}
private void init() {
mScrollerFocusMoveAnim = new Scroller(getContext());
mIsDrawFocusMoveAnim = false;
mReceivedInvokeKeyDown = false;
mSelectedPosition = 0;
mNextFocused = null;
mInLayout = false;
mIsFollowScroll = false;
mSelectedScaleValue = DEFAULT_SELECT_SCALE;
mIsAutoProcessFocus = true;
mFocusFrameLeft = 22;
mFocusFrameTop = 22;
mFocusFrameRight = 22;
mFocusFrameBottom = 22;
mOrientation = HORIZONTAL;
mScreenWidth = getContext().getResources().getDisplayMetrics().widthPixels;
mScreenHeight = getContext().getResources().getDisplayMetrics().heightPixels;
}
private void setAttributeSet(AttributeSet attrs) {
if (attrs != null) {
TypedArray typeArray = getContext().obtainStyledAttributes(attrs, R.styleable.TvRecyclerView);
int type = typeArray.getInteger(R.styleable.TvRecyclerView_scrollMode, 0);
if (type == 1) {
mIsFollowScroll = true;
}
final Drawable drawable = typeArray.getDrawable(R.styleable.TvRecyclerView_focusDrawable);
if (drawable != null) {
setFocusDrawable(drawable);
}
mSelectedScaleValue = typeArray.getFloat(R.styleable.TvRecyclerView_focusScale, DEFAULT_SELECT_SCALE);
mIsAutoProcessFocus = typeArray.getBoolean(R.styleable.TvRecyclerView_isAutoProcessFocus, true);
if (!mIsAutoProcessFocus) {
mSelectedScaleValue = 1.0f;
setChildrenDrawingOrderEnabled(true);
}
typeArray.recycle();
}
if (mIsAutoProcessFocus) {
// set TvRecyclerView process Focus
setDescendantFocusability(ViewGroup.FOCUS_BEFORE_DESCENDANTS);
}
}
private void addFlyBorderView(Context context) {
if (mFocusBorderView == null) {
mFocusBorderView = new FocusBorderView(context);
((Activity) context).getWindow().addContentView(mFocusBorderView,
new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
mFocusBorderView.setSelectPadding(mFocusFrameLeft, mFocusFrameTop,
mFocusFrameRight, mFocusFrameBottom);
}
}
public int getFirstVisiblePosition() {
int firstVisiblePos = -1;
LayoutManager layoutManager = getLayoutManager();
if (layoutManager != null) {
if (layoutManager instanceof LinearLayoutManager) {
firstVisiblePos = ((LinearLayoutManager) layoutManager)
.findFirstVisibleItemPosition();
} else if (layoutManager instanceof ModuleLayoutManager) {
firstVisiblePos = ((ModuleLayoutManager) layoutManager)
.findFirstVisibleItemPosition();
}
}
return firstVisiblePos;
}
public int getLastVisiblePosition() {
int lastVisiblePos = -1;
LayoutManager layoutManager = getLayoutManager();
if (layoutManager != null) {
if (layoutManager instanceof LinearLayoutManager) {
lastVisiblePos = ((LinearLayoutManager) layoutManager)
.findLastVisibleItemPosition();
} else if (layoutManager instanceof ModuleLayoutManager) {
lastVisiblePos = ((ModuleLayoutManager) layoutManager)
.findLastVisibleItemPosition();
}
}
return lastVisiblePos;
}
@Override
public void setLayoutManager(LayoutManager layoutManager) {
if (layoutManager instanceof LinearLayoutManager) {
mOrientation = ((LinearLayoutManager) layoutManager).getOrientation();
} else if (layoutManager instanceof ModuleLayoutManager) {
mOrientation = ((ModuleLayoutManager) layoutManager).getOrientation();
}
Log.i(TAG, "setLayoutManager: ====orientation==" + mOrientation);
super.setLayoutManager(layoutManager);
}
/**
* note: if you set the property of isAutoProcessFocus is false, the listener will be invalid
*
* @param listener itemStateListener
*/
public void setOnItemStateListener(OnItemStateListener listener) {
mItemStateListener = listener;
}
public void setSelectedScale(float scale) {
if (scale >= 1.0f) {
mSelectedScaleValue = scale;
}
}
public void setIsAutoProcessFocus(boolean isAuto) {
mIsAutoProcessFocus = isAuto;
if (!isAuto) {
mSelectedScaleValue = 1.0f;
setChildrenDrawingOrderEnabled(true);
} else {
if (mSelectedScaleValue == 1.0f) {
mSelectedScaleValue = DEFAULT_SELECT_SCALE;
}
}
}
public void setFocusDrawable(Drawable focusDrawable) {
mDrawableFocus = focusDrawable;
}
public void setScrollMode(int mode) {
mIsFollowScroll = mode == SCROLL_FOLLOW;
}
/**
* When call this method, you must ensure that the location of the view has been inflate
*
* @param position selected item position
*/
public void setItemSelected(int position) {
if (mSelectedPosition == position) {
return;
}
mIsSetItemSelected = true;
if (position >= getAdapter().getItemCount()) {
position = getAdapter().getItemCount() - 1;
}
mSelectedPosition = position;
requestLayout();
}
/**
* the selected item, there are two cases:
* 1. item is displayed on the screen
* 2. item is not displayed on the screen
*/
private void adjustSelectMode() {
int childCount = getChildCount();
if (mSelectedPosition < childCount) {
mSelectedItem = getChildAt(mSelectedPosition);
adjustSelectOffset(mSelectedItem);
} else {
mIsNeedMoveForSelect = true;
scrollToPosition(mSelectedPosition);
}
}
/**
* adjust the selected item position to half screen location
*/
private void adjustSelectOffset(View selectView) {
if (mIsAutoProcessFocus) {
scrollOffset(selectView);
} else {
scrollOffset(selectView);
selectView.requestFocus();
}
if (mItemStateListener != null) {
mItemStateListener.onItemViewFocusChanged(true, selectView,
mSelectedPosition);
}
}
private void scrollOffset(View selectView) {
int dx;
if (mOrientation == HORIZONTAL) {
dx = selectView.getLeft() + selectView.getWidth() / 2 - mScreenWidth / 2;
scrollBy(dx, 0);
} else {
dx = selectView.getTop() + selectView.getHeight() / 2 - mScreenHeight / 2;
scrollBy(0, dx);
}
}
@Override
public boolean isInTouchMode() {
boolean result = super.isInTouchMode();
// 解决4.4版本抢焦点的问题
if (Build.VERSION.SDK_INT == 19) {
return !(hasFocus() && !result);
} else {
return result;
}
}
/**
* fix issue: not have focus box when change focus
*
* @param child child view
* @param focused the focused view
*/
@Override
public void requestChildFocus(View child, View focused) {
if (mSelectedPosition < 0) {
mSelectedPosition = getChildAdapterPosition(focused);
}
super.requestChildFocus(child, focused);
if (mIsAutoProcessFocus) {
requestFocus();
}
}
@Override
protected void onFinishInflate() {
super.onFinishInflate();
if (mIsAutoProcessFocus) {
addFlyBorderView(getContext());
}
}
@Override
protected void onFocusChanged(boolean gainFocus, int direction, Rect previouslyFocusedRect) {
super.onFocusChanged(gainFocus, direction, previouslyFocusedRect);
if (mItemStateListener != null) {
if (mSelectedItem == null) {
mSelectedItem = getChildAt(mSelectedPosition - getFirstVisiblePosition());
}
mItemStateListener.onItemViewFocusChanged(gainFocus, mSelectedItem,
mSelectedPosition);
}
if (mFocusBorderView == null) {
return;
}
mFocusBorderView.setTvRecyclerView(this);
if (gainFocus) {
mFocusBorderView.bringToFront();
}
if (mSelectedItem != null) {
if (gainFocus) {
mSelectedItem.setSelected(true);
} else {
mSelectedItem.setSelected(false);
}
if (gainFocus && !mInLayout) {
mFocusBorderView.startFocusAnim();
}
}
if (!gainFocus) {
mFocusBorderView.dismissFocus();
}
}
@Override
protected int getChildDrawingOrder(int childCount, int i) {
int focusIndex = indexOfChild(mSelectedItem);
if (focusIndex < 0) {
return i;
}
if (i < focusIndex) {
return i;
} else if (i < childCount - 1) {
return focusIndex + childCount - 1 - i;
} else {
return focusIndex;
}
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
mInLayout = true;
super.onLayout(changed, l, t, r, b);
if (mIsSetItemSelected) {
adjustSelectMode();
mIsSetItemSelected = false;
}
// fix issue: when start anim the FocusView location error in AutoProcessFocus mode
Adapter adapter = getAdapter();
if (adapter != null && mSelectedPosition >= adapter.getItemCount()) {
mSelectedPosition = adapter.getItemCount() - 1;
}
mSelectedItem = getChildAt(mSelectedPosition - getFirstVisiblePosition());
mInLayout = false;
}
@Override
protected void dispatchDraw(Canvas canvas) {
super.dispatchDraw(canvas);
if (mFocusBorderView != null && mFocusBorderView.getTvRecyclerView() != null) {
mFocusBorderView.invalidate();
}
}
@Override
protected void onRestoreInstanceState(Parcelable state) {
Bundle bundle = (Bundle) state;
Parcelable superData = bundle.getParcelable("super_data");
super.onRestoreInstanceState(superData);
setItemSelected(bundle.getInt("select_pos", 0));
}
@Override
protected Parcelable onSaveInstanceState() {
Bundle bundle = new Bundle();
Parcelable superData = super.onSaveInstanceState();
bundle.putParcelable("super_data", superData);
bundle.putInt("select_pos", mSelectedPosition);
return bundle;
}
@Override
public boolean dispatchKeyEvent(KeyEvent event) {
if (event.getAction() == KeyEvent.ACTION_DOWN) {
int keyCode = event.getKeyCode();
if (mSelectedItem == null) {
mSelectedItem = getChildAt(mSelectedPosition);
}
try {
if (keyCode == KeyEvent.KEYCODE_DPAD_LEFT) {
mNextFocused = FocusFinder.getInstance().findNextFocus(this, mSelectedItem, View.FOCUS_LEFT);
} else if (keyCode == KEYCODE_DPAD_RIGHT) {
mNextFocused = FocusFinder.getInstance().findNextFocus(this, mSelectedItem, View.FOCUS_RIGHT);
} else if (keyCode == KeyEvent.KEYCODE_DPAD_UP) {
mNextFocused = FocusFinder.getInstance().findNextFocus(this, mSelectedItem, View.FOCUS_UP);
} else if (keyCode == KeyEvent.KEYCODE_DPAD_DOWN) {
mNextFocused = FocusFinder.getInstance().findNextFocus(this, mSelectedItem, View.FOCUS_DOWN);
}
} catch (Exception e) {
Log.i(TAG, "dispatchKeyEvent: get next focus item error: " + e.getMessage());
mNextFocused = null;
}
if (!mIsAutoProcessFocus) {
processMoves(event.getKeyCode());
if (mNextFocused != null) {
mSelectedItem = mNextFocused;
} else {
mSelectedItem = getFocusedChild();
}
mSelectedPosition = getChildAdapterPosition(mSelectedItem);
}
}
return super.dispatchKeyEvent(event);
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
switch (keyCode) {
case KeyEvent.KEYCODE_DPAD_LEFT:
case KeyEvent.KEYCODE_DPAD_UP:
case KEYCODE_DPAD_RIGHT:
case KeyEvent.KEYCODE_DPAD_DOWN:
if (processMoves(keyCode)) {
return true;
}
break;
case KeyEvent.KEYCODE_DPAD_CENTER:
case KeyEvent.KEYCODE_ENTER:
mReceivedInvokeKeyDown = true;
break;
default:
break;
}
return super.onKeyDown(keyCode, event);
}
@Override
public boolean onKeyUp(int keyCode, KeyEvent event) {
switch (keyCode) {
case KeyEvent.KEYCODE_DPAD_CENTER:
case KeyEvent.KEYCODE_ENTER: {
if (mReceivedInvokeKeyDown) {
if ((getAdapter() != null) && (mSelectedItem != null)) {
if (mItemStateListener != null) {
if (mFocusBorderView != null) {
mFocusBorderView.startClickAnim();
}
mItemStateListener.onItemViewClick(mSelectedItem,
getChildAdapterPosition(mSelectedItem));
}
}
}
mReceivedInvokeKeyDown = false;
return true;
}
}
return super.onKeyUp(keyCode, event);
}
@Override
public void computeScroll() {
if (mScrollerFocusMoveAnim.computeScrollOffset()) {
if (mIsDrawFocusMoveAnim) {
mFocusMoveAnimScale = ((float) (mScrollerFocusMoveAnim.getCurrX())) / 100;
}
postInvalidate();
} else {
if (mIsDrawFocusMoveAnim) {
if (mNextFocused != null) {
mSelectedItem = mNextFocused;
mSelectedPosition = getChildAdapterPosition(mSelectedItem);
}
mIsDrawFocusMoveAnim = false;
setLayerType(View.LAYER_TYPE_SOFTWARE, null);
postInvalidate();
if (mItemStateListener != null) {
mItemStateListener.onItemViewFocusChanged(true, mSelectedItem,
mSelectedPosition);
}
}
}
}
private boolean processMoves(int keycode) {
if (mNextFocused == null || !hasFocus()) {
return false;
} else {
if (mIsDrawFocusMoveAnim) {
return true;
}
if (!mIsFollowScroll) {
boolean isVisible = isVisibleChild(mNextFocused);
boolean isHalfVisible = isHalfVisibleChild(mNextFocused);
if (isHalfVisible || !isVisible) {
smoothScrollView(keycode);
}
} else {
boolean isOver = isOverHalfScreen(mNextFocused, keycode);
if (isOver) {
smoothScrollView(keycode);
}
}
if (mIsAutoProcessFocus) {
startFocusMoveAnim();
} else {
invalidate();
}
return true;
}
}
private void smoothScrollView(int keycode) {
int scrollDistance = getScrollDistance(keycode);
if ((keycode == KEYCODE_DPAD_RIGHT || keycode == KeyEvent.KEYCODE_DPAD_LEFT)
&& mOrientation == HORIZONTAL) {
smoothScrollBy(scrollDistance, 0);
} else if ((keycode == KeyEvent.KEYCODE_DPAD_UP || keycode == KeyEvent.KEYCODE_DPAD_DOWN)
&& mOrientation == VERTICAL) {
smoothScrollBy(0, scrollDistance);
}
}
private int getScrollDistance(int keyCode) {
int distance = 0;
switch (keyCode) {
case KeyEvent.KEYCODE_DPAD_RIGHT:
distance = mNextFocused.getLeft() +
mNextFocused.getWidth() / 2 - mScreenWidth / 2;
break;
case KeyEvent.KEYCODE_DPAD_LEFT:
distance = mNextFocused.getLeft()
- mScreenWidth / 2 + mNextFocused.getWidth() / 2;
break;
case KeyEvent.KEYCODE_DPAD_UP:
distance = mNextFocused.getBottom() -
mNextFocused.getHeight() / 2 - mScreenHeight / 2;
break;
case KeyEvent.KEYCODE_DPAD_DOWN:
distance = mNextFocused.getTop() +
mNextFocused.getHeight() / 2 - mScreenHeight / 2;
break;
default:
break;
}
return distance;
}
private boolean isHalfVisibleChild(View child) {
if (child != null) {
Rect ret = new Rect();
boolean isVisible = child.getLocalVisibleRect(ret);
if (mOrientation == HORIZONTAL) {
return isVisible && (ret.width() < child.getWidth());
} else {
return isVisible && (ret.height() < child.getHeight());
}
}
return false;
}
private boolean isVisibleChild(View child) {
if (child != null) {
Rect ret = new Rect();
return child.getLocalVisibleRect(ret);
}
return false;
}
private boolean isOverHalfScreen(View child, int keycode) {
Rect ret = new Rect();
boolean visibleRect = child.getGlobalVisibleRect(ret);
if (visibleRect && keycode == KEYCODE_DPAD_RIGHT) {
if (ret.right > mScreenWidth / 2) {
return true;
}
} else if (visibleRect && keycode == KeyEvent.KEYCODE_DPAD_LEFT) {
if (ret.left < mScreenWidth / 2) {
return true;
}
} else if (visibleRect && keycode == KeyEvent.KEYCODE_DPAD_UP) {
if (ret.top < mScreenHeight / 2) {
return true;
}
} else if (visibleRect && keycode == KeyEvent.KEYCODE_DPAD_DOWN) {
if (ret.bottom > mScreenHeight / 2) {
return true;
}
}
return false;
}
private void startFocusMoveAnim() {
setLayerType(View.LAYER_TYPE_NONE, null);
mIsDrawFocusMoveAnim = true;
if (mItemStateListener != null) {
mItemStateListener.onItemViewFocusChanged(false, mSelectedItem,
mSelectedPosition);
}
mScrollerFocusMoveAnim.startScroll(0, 0, 100, 100, 200);
invalidate();
}
/**
* When the TvRecyclerView width is determined, the returned position is correct
*
* @return selected view position
*/
public int getSelectedPosition() {
return mSelectedPosition;
}
View getSelectedView() {
return mSelectedItem;
}
public float getSelectedScaleValue() {
return mSelectedScaleValue;
}
public Drawable getDrawableFocus() {
return mDrawableFocus;
}
public View getNextFocusView() {
return mNextFocused;
}
public float getFocusMoveAnimScale() {
return mFocusMoveAnimScale;
}
public void setSelectPadding(int left, int top, int right, int bottom) {
mFocusFrameLeft = left;
mFocusFrameTop = top;
mFocusFrameRight = right;
mFocusFrameBottom = bottom;
if (mFocusBorderView != null) {
mFocusBorderView.setSelectPadding(mFocusFrameLeft, mFocusFrameTop,
mFocusFrameRight, mFocusFrameBottom);
}
}
public interface OnItemStateListener {
void onItemViewClick(View view, int position);
void onItemViewFocusChanged(boolean gainFocus, View view, int position);
}
}
xml.文件如下:
<RecyclerViewEx.TvRecyclerView
android:id="@+id/title_list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:divider="@null"
android:fastScrollEnabled="false"
android:footerDividersEnabled="false"
android:headerDividersEnabled="false"
app:focusDrawable="@drawable/bg_item_focused" />
注: app:focusDrawable="@drawable/bg_item_focused" 主要是当前menu中的item聚焦的效果。
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="@color/bg_btn"></solid>
<stroke
android:width="1dp"
android:color="@color/darkgray" />
<corners android:radius="@dimen/x1" />
</shape>
问题 三
本项目中的右侧item采用原生的recycleview,
项目中最大的问题是左侧menu按下遥控器右键切换到右侧子项item时,(如果当前右侧的数据源不低于4个)会默认选择第二列的第一个数据源,如图标注所示:
项目需求: 当menu切换的时候,按下遥控器右键,切换到右侧子item的时候默认选择第一列的第一个数据源。
解决方案:在xml文件布局中,recycleview的外边套着一层布局,让当前布局可聚焦,具体如下:
<LinearLayout
android:id="@+id/ll_content"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="8"
android:background="@color/white"
android:focusable="true"
android:orientation="vertical"
android:padding="@dimen/x2">
<android.support.v7.widget.RecyclerView
android:id="@+id/content_list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:divider="@null"
android:fastScrollEnabled="false"
android:focusable="false"
android:footerDividersEnabled="false"
android:headerDividersEnabled="false" />
</LinearLayout>
设置外层的LinearLayout的android:focusable="true"
,RecyclerView的android:focusable="false"
。
最后在acticity的设置LinearLayout的聚焦监听器:
mLayoutContent.setOnFocusChangeListener(new View.OnFocusChangeListener() {
@Override
public void onFocusChange(View v, boolean hasFocus) {
if (hasFocus) {
if (mListViewContent.getChildCount() > 0) {
mListViewContent.getChildAt(0).requestFocus();
}
}
}
});
mListViewContent为RecycleView。
最后每次切换menu的时候,自动让右侧的items滚动到最上面,附上方法:
mListViewMenu.setOnItemStateListener(new TvRecyclerView.OnItemStateListener() {
@Override
public void onItemViewClick(View view, int position) {
// mAdapterMenu.setSelectPosition(position);
// mAdapterContent.setData(mVideoBeans.get(position).getList(), false);
}
@Override
public void onItemViewFocusChanged(boolean gainFocus, View view, int position) {
if (position < 0) return;
if (gainFocus) {
mAdapterMenu.setSelectPosition(position);
//为右侧recycleview设置数据源
mAdapterContent.setData(mVideoBeans.get(position).getList(), false);
//
if (mCurPosition != position) {
if (mListViewContent.getAdapter().getItemCount() > 0) {
//设置右侧的recycleview滚动到最上面
mListViewContent.scrollToPosition(0);
mCurPosition = position;
}
}
}
}
});
mListViewMenu为重写的TvRecycleView。