2

我想在我的回收站视图中将列表项自动滚动到顶部(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 中的那些索引绘制了 ViewHolder。

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

我能做些什么来实现这两件事?

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

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

4

3 回答 3

1

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

于 2016-07-21T09:38:05.310 回答
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)

让我知道这是否有帮助。

于 2016-07-21T10:25:15.053 回答
0

将此代码放在您将滚动到第一个 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());
于 2016-11-18T11:16:59.900 回答