【问题标题】:RecyclerView scroll to position and get that viewRecyclerView 滚动到位置并获取该视图
【发布时间】:2015-10-30 18:38:08
【问题描述】:

我想在我的回收站视图中将列表项自动滚动到顶部(firstVisible 项)并获取该位置的视图,以便我可以从我的片段中突出显示它。

所以,这是我的片段代码的要点:

    private void activateNewListItem(int position) {

       mLayoutManager().scrollToPositionWithOffset(position, 0);
       RecyclerView.ViewHolder viewHolder = mRecyclerView.findViewHolderForLayoutPosition(position);

       View view = viewHolder.getItemView();
       view.setBackgroundColor(getResources().getColor(R.color.esr_light_grey));
}

如果position1234 等,mRecyclerView.findViewHolderForPosition(position) 返回一个有效的 ViewHolder, 因为我猜 RecyclerView 已经为 dataSet 中的那些索引绘制了 ViewHolders。

但是,如果我传入position,如 25mRecyclerView.findViewHolderForPosition(position) 返回 null,因为我假设它还没有被绘制,即使我在它上面调用了 mLayoutManager.scrollToPositionWithOffset(position, 0) .

我可以做些什么来实现这两个目标?

  1. 将dataSet索引position的列表项滚动到firstVisibleItem。

  2. 获取该 listItem 的 View 或 ViewHolder 对象,以便我可以更改背景或其他任何内容。

【问题讨论】:

    标签: android-fragments android-recyclerview android-viewholder android-scroll linearlayoutmanager


    【解决方案1】:

    不要在其他地方访问 ViewHolder,而是在适配器项目布局 xml 文件中使用自定义选择器背景,将适配器中的位置跟踪为选定位置,并在滚动后调用 notifydatasetchanged()/notifyItemRangeChanged() 以突出显示它完全的。你已经有了 scrollToPosition() 方法,有一个滚动监听器来跟踪滚动状态。

    选择器背景示例:item_selector.xml

    <?xml version="1.0" encoding="utf-8"?>
    <selector xmlns:android=
          "http://schemas.android.com/apk/res/android">
       <item android:state_activated="true"
             android:drawable="@color/primary_dark" />
       <item android:drawable="@android:color/transparent" />
    </selector>
    

    将其设置为您的项目 xml 的背景

    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/container_list_item"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@drawable/item_selector">
        <--- Your layout items here --->
    </RelativeLayout>
    

    您的适配器代码:

    public class SampleAdapter extends RecyclerView.Adapter<SampleAdapter.ViewHolder> {
    
        private final String[] list;
        private int lastCheckedPosition = -1;
    
        public SampleAdapter(String[] list) {
            this.list = list;
        }
    
        @Override
        public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            View view = View.inflate(parent.getContext(), R.layout.sample_layout, null);
            ViewHolder holder = new ViewHolder(view);
            return holder;
        }
    
        @Override
        public void onBindViewHolder(ViewHolder holder, int position) {
            holder.choiceName.setText(list[position]);
            holder.containerView.setSelected(position == lastCheckedPosition);
        }
    
        @Override
        public int getItemCount() {
            return list.length;
        }
    
        public class ViewHolder extends RecyclerView.ViewHolder {
            @Bind(R.id.choice_name)
            TextView choiceName;
            @Bind(R.id. container_list_item)
            View containerView;
    
            public ViewHolder(View itemView) {
                super(itemView);
                ButterKnife.bind(this, itemView);
                itemView.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        lastCheckedPosition = getAdapterPosition();
                        notifyItemRangeChanged(0, list.length);
    
                    }
                });
            }
        }
    }
    

    滚动到任意位置:

    recyclerview.scrollToPosition(position)
    

    如果这有帮助,请告诉我。

    【讨论】:

    • 谢谢,试试看。
    【解决方案2】:

    更新 ViewHolder 信息需要几秒钟的时间。只需滚动并延迟mRecyclerView.findViewHolderForLayoutPosition 调用几毫秒(100 毫秒听起来很合理)

    【讨论】:

    【解决方案3】:

    将此代码放入您要滚动到第一个 RecyclerView 项目的片段中:

    RecyclerView.ViewHolder holder = mRecyclerView
                    .findViewHolderForAdapterPosition(0);
    while (holder == null) {
        int firstVisiblePosition = mLayoutManager()
                    .findFirstCompletelyVisibleItemPosition();
        RecyclerView.ViewHolder firstVisibleHolder = mRecyclerView
                    .findViewHolderForAdapterPosition(firstVisiblePosition);
    
        View v = firstVisibleHolder.getItemView();
        if (v != null) mRecyclerView.scrollBy(0, (int) v.getY());
        else break;
        holder = mRecyclerView.findViewHolderForAdapterPosition(0);
    }
    
    View view = null;
    if (holder != null) view = holder.getItemView();
    if (view != null) mRecyclerView.scrollBy(0, (int) view.getY());
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-11-02
      • 2015-01-13
      • 1970-01-01
      • 2023-03-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多