功能描述: Android TV端通过遥控器控制focus在RecyclerView移动,当焦点处于第一个item,再向上按,则焦点跳至最后一个。同理,在最后一个,再向下按跳至第一个。(RecycleView垂直布局)
解决思路: 1、 跳转时,让RecycleView做smoothScrollToPosition(int position)操作,position为第一个或者最后一个item位置。
2、跳转后,获取当前屏幕第一个可见或最有一个可见view ,请求焦点即可。
部分代码如下:
1.监听上下键,做滚动操作
holder.itemView.setOnKeyListener(new View.OnKeyListener() { @Override public boolean onKey(View v, int keyCode, KeyEvent event) { int action = event.getAction(); switch (keyCode) { case KeyEvent.KEYCODE_DPAD_UP: int positionUp = (int) v.getTag(); if (action == KeyEvent.ACTION_DOWN) { if (positionUp <= 0) { recyclerView.smoothScrollToPosition(getItemCount() - 1); return true; } } break; case KeyEvent.KEYCODE_DPAD_DOWN: int positionDown = (int) v.getTag(); if (action == KeyEvent.ACTION_DOWN) { if (positionDown >= getItemCount() - 1) { recyclerView.smoothScrollToPosition(0); return true; } } break; } });
2.监听滚动。这里需要注意的是,通过RecycleView的getChildAt()获取view可能为空。可以获取RecyleView对应的LayoutManager(这里是LinearLayoutManager),然后通过manager的findFirstCompletelyVisibleItemPosition()获取当前屏幕第一个或者findLastCompletelyVisibleItemPosition()获取当前屏幕的最后一个position。 最后通过position找到view,再requestFocus().
recycleView.setOnScrollListener(new RecyclerView.OnScrollListener() { //向上或者向下滚动 boolean toLast = false; booleantoFirst = false; @Override public void onScrollStateChanged(RecyclerView recyclerView, int newState) { super.onScrollStateChanged(recyclerView, newState); if (newState == RecyclerView.SCROLL_STATE_IDLE) { scroolChange(recyclerView, toFirst, toLast); } } @Override public void onScrolled(RecyclerView recyclerView, int dx, int dy) { super.onScrolled(recyclerView, dx, dy); if (dy > 0) { toLast = true; } else { toFirst = true; } } });public void scroolChange(RecyclerView recyclerView, boolean toFirst, boolean toLast) { LinearLayoutManager manager = (LinearLayoutManager) recyclerView.getLayoutManager(); int lastVisibleItem = manager.findLastCompletelyVisibleItemPosition(); int firstVisibleItem = manager.findFirstCompletelyVisibleItemPosition(); int totalItemCount = manager.getItemCount(); //向下滚动,到底部 if (lastVisibleItem == (totalItemCount - 1) && toLast) { View view = recyclerView.getChildAt(lastVisibleItem); LinearLayoutManager llM = (LinearLayoutManager) recyclerView.getLayoutManager(); if (view != null) { view.requestFocus(); } else if (llM.findViewByPosition(lastVisibleItem) != null) { llM.findViewByPosition(lastVisibleItem).requestFocus(); } else { recyclerView.requestFocus(); } } //向上滚动,到顶部 if (firstVisibleItem == 0 && toFirst) { View view =recyclerView.getChildAt(firstVisibleItem); LinearLayoutManager llM = (LinearLayoutManager) recyclerView.getLayoutManager(); if (view != null) { view.requestFocus(); } else if (llM.findViewByPosition(firstVisibleItem) != null) { llM.findViewByPosition(firstVisibleItem).requestFocus(); } else { recyclerView.requestFocus(); } } }