【问题标题】:Strange Android RecyclerView (GridLayoutManager) focus behavior奇怪的 Android RecyclerView (GridLayoutManager) 焦点行为
【发布时间】:2015-03-22 02:00:42
【问题描述】:

我有一个带有 GridLayoutManager 的 RecyclerView,每行有 2 列。因为开发是针对 Android TV 的,所以我需要专注于导航。

如果我使用向下键导航到任何可见项目,那也没关系。例如,项目 1 -> 项目 3 -> 项目 5 -> 项目 7(仅部分可见。)。但是当我再次按下键时,焦点将移动到第 10 项而不是第 9 项。

我的网格视图适配器是:

public class GridAdapter extends RecyclerView.Adapter<GridAdapter.ViewHolder> {    
    private ArrayList<String> mDataset;

    public GridAdapter(ArrayList<String> myDataset) {
        mDataset = myDataset;
    }

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
        View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.grid_item, viewGroup, false);
        ViewHolder vh = new ViewHolder(v);
        return vh;
    }

    @Override
    public void onBindViewHolder(ViewHolder holder, int position) {
        holder.txtTitle.setText(mDataset.get(position));    
    }

    @Override
    public int getItemCount() {
        return mDataset.size();
    }

    public static class ViewHolder extends RecyclerView.ViewHolder {

        public TextView txtTitle;
        public ViewHolder(View v) {
            super(v);
            txtTitle = (TextView) v.findViewById(R.id.title);
        }
    }
}

知道如何解决这个问题吗?谢谢。

【问题讨论】:

  • 你最终解决了这个问题吗?在过去的一两个月里,这一直困扰着我的生活。
  • 不,我还没有找到任何解决方案。但它在我的应用程序中并不是很重要,所以我只是把它放在那里。希望有一天有人能解决这个问题。
  • 导航文档这样说“Android 框架会根据布局中可聚焦元素的相对位置自动应用定向导航方案。”你能以某种方式在你的适配器中设置 nextFocusDown、nextFocusUp 等吗?

标签: android android-tv android-recyclerview


【解决方案1】:

查看this related postVganin's answer 以解决您的问题。

我将此错误报告给 AOSP 问题跟踪器:issue 190526

正如我从源代码中看到的那样,问题是因为 GridLayoutManager 使用 LinearLayoutManager 的 onFocusSearchFailed() 实现是 当焦点接近 RecyclerView 的内部边界时调用。 LinearLayoutManager 的实现只提供第一个/最后一个(取决于 在滚动方向上)元素。因此焦点跳转到第一个/最后一个 新行的元素。

My workaround for this issue.

【讨论】:

    【解决方案2】:

    我想出了一个破解答案。 它不会让你滚动,除非新行被充气(所以它会等待新行被充气。)但它通常需要不到 50~100 毫秒。 所以我们一致认为这种行为是可以接受的。

    只要让 onFocusSearchFailed 返回 null。这是一个例子。

    /**
     * Created by sylversphere on 15-04-22.
     */
    public class DelayedNaviGridLayoutManager extends GridLayoutManager{
    
        private final Context context;
    
        public SomeGridLayoutManager(Context context, int spanCount) {
            super(context, spanCount);
            this.context = context;
        }
    
        public SomeGridLayoutManager(Context context, int spanCount, int orientation, boolean reverseLayout) {
            super(context, spanCount, orientation, reverseLayout);
            this.context = context;
        }
    
        @Override
        public View onFocusSearchFailed(View focused, int focusDirection, RecyclerView.Recycler recycler, RecyclerView.State state) {
            return null;
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-02-28
      • 2013-07-17
      相关资源
      最近更新 更多