获取特定位置的 ViewHolder - RecyclerView

Posted

技术标签:

【中文标题】获取特定位置的 ViewHolder - RecyclerView【英文标题】:Get ViewHolder for specific position - RecyclerView 【发布时间】:2017-08-11 21:56:13 【问题描述】:

我需要获取特定位置的视图,但我收到此错误:

java.lang.NullPointerException:尝试从字段中读取 'android.view.View android.support.v7.widget.RecyclerView$ViewHolder.itemView' 为空 对象引用

这是我的适配器:

public class ConciergeAdapter extends RecyclerView.Adapter<ConciergeAdapter.MyViewHolder> 

    private Context context;
    private ArrayList<String> items;

    public class MyViewHolder extends RecyclerView.ViewHolder
    
        public TextView text;
        public RelativeLayout maincon;

        public MyViewHolder(View view) 
            super(view);
            this.text = (TextView) view.findViewById(R.id.text);
            this.maincon = (RelativeLayout) view.findViewById(R.id.maincon);
        
    

    public ConciergeAdapter(Context context, ArrayList<String> items)
    
        this.context = context;
        this.items = items;
    

    @Override
    public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType)
    
        View itemView = LayoutInflater.from(parent.getContext())
                .inflate(R.layout.fragment_concierge_top_items, parent, false);

        return new MyViewHolder(itemView);
    


    @Override
    public void onBindViewHolder(ConciergeAdapter.MyViewHolder holder, int position)
    
        Random rnd = new Random();
        int color = Color.argb(255, rnd.nextInt(256), rnd.nextInt(256), rnd.nextInt(256));
        holder.maincon.setBackgroundColor(color);
    

    @Override
    public int getItemCount() 
        return items.size();
    

这是我调用适配器并尝试获取 ViewHolder 的代码:

final LinearLayoutManager layoutManager= new LinearLayoutManager(getActivity(),LinearLayoutManager.HORIZONTAL, false);
        mRecyclerView = (RecyclerView) view.findViewById(R.id.recycler_view);
        mRecyclerView.setLayoutManager(layoutManager);

        ArrayList<String> itemslist = new ArrayList<String>();
        itemslist.add("1");
        itemslist.add("1");
        itemslist.add("1");
        itemslist.add("1");
        itemslist.add("1");
        itemslist.add("1");
        itemslist.add("1");
        itemslist.add("1");
        itemslist.add("1");
        itemslist.add("1");
        itemslist.add("1");

        ConciergeAdapter adapter = new ConciergeAdapter(getActivity(),itemslist);
        mRecyclerView.setAdapter(adapter);

        //RecyclerView.ViewHolder viewholder =  mRecyclerView.findViewHolderForAdapterPosition(1); 

        View holder = layoutManager.getChildAt(0);

        RelativeLayout middle = (RelativeLayout) holder.findViewById(R.id.maincon);
        middle.getLayoutParams().height = 200;

【问题讨论】:

重复***.com/questions/32836844/… 这不是同一个问题。他的问题是 swapAdapter @student 他使用swapAdapter,你使用setAdapter,但是底层的工作实际上是相同的,并且你没有通知你的数据集已经改变。我想你会发现,如果你仔细研究这个问题,它会解决你的问题。 @student 你解决了吗? 【参考方案1】:

我的想法是将 ViewHolders 存储在一个数组中,因为它们出现在适配器中。

尝试像这样扩展 RecyclerView.Adapter:

public class MyRecyclerViewAdapter extends RecyclerView.Adapter<...> 

 ...
 // array of ViewHolders at specific positions
 private ViewHolder[] viewHolders;

 // constructor
 public MyRecyclerViewAdapter(List items) 
     ...
     viewHolders = new ViewHolder[items.size()];
     ...
 

 @Override
 public void onBindViewHolder(final ViewHolder holder, int position) 
     ...
     viewHolders[position] = holder;
     ...
 

 // call this function from outside of the adapter
 public ViewHolder getViewHolder(int position) 
    return viewHolders[position];
 

【讨论】:

【参考方案2】:

这是因为 RecyclerView 尚未填充。我建议您在适配器的onBindViewHolder 内进行预期的布局操作:

 @Override
public void onBindViewHolder(ConciergeAdapter.MyViewHolder holder, int position) 
    if (position == 0)  
        RelativeLayout middle = (RelativeLayout) holder.container(R.id.maincon);
        middle.getLayoutParams().height = 200;
    

    Random rnd = new Random();
    int color = Color.argb(255, rnd.nextInt(256), rnd.nextInt(256), rnd.nextInt(256));
    holder.maincon.setBackgroundColor(color);

你的MyViewHolder

public class MyViewHolder extends RecyclerView.ViewHolder 
    public View container;
    public TextView text;
    public RelativeLayout maincon;

    public MyViewHolder(View view) 
        super(view);
        container = view;
        this.text = (TextView) view.findViewById(R.id.text);
        this.maincon = (RelativeLayout) view.findViewById(R.id.maincon);
    

【讨论】:

您好,感谢您的回答。这仅适用于一个职位,我不想仅限于一个职位。我希望能够从适配器外部选择任何视图。

以上是关于获取特定位置的 ViewHolder - RecyclerView的主要内容,如果未能解决你的问题,请参考以下文章

关于recyclerView中ViewHolder中的几种不同方式获取position有什么区别

关于recyclerView中ViewHolder中的几种不同方式获取position有什么区别

回收站视图滚动到特定位置

在 RecyclerView 中使用多个视图类型时如何将项目添加到所需的 ViewHolder 位置?

从ViewHolder类更新项目数据

android RecyclerView获得单个Item的ViewHolder