奇怪的Android RecyclerView(GridLayoutManager)焦点行为

时间:2015-01-23 04:19:38

标签: android android-tv recycler-adapter

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

enter image description here

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

enter image description here

我的网格视图适配器是:

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);
        }
    }
}

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

2 个答案:

答案 0 :(得分:2)

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

  

我向AOSP问题跟踪器报告了此错误:issue 190526

     

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

     

My workaround for this issue.

答案 1 :(得分:0)

我想出了一个黑客的答案。 它不会让你滚动除非新行被充气(所以它等待新行被充气。)但它通常需要不到50~100 ms。 所以我们同意这种行为是可以接受的。

只需获取onFocusSearchFailed即可返回null。这是一个例子。

/ **  *由sylversphere于15-04-22创建。  * / 公共类DelayedNaviGridLayoutManager扩展了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;
}}