Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/asp.net/35.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android recyclerView findViewHolderForAdapterPosition返回null_Android_Android Recyclerview - Fatal编程技术网

Android recyclerView findViewHolderForAdapterPosition返回null

Android recyclerView findViewHolderForAdapterPosition返回null,android,android-recyclerview,Android,Android Recyclerview,我想以编程方式单击recyclerView中的项目,我发现可以这样做: 但它对我不起作用,findViewHolderForAdapterPosition只返回null 我的代码中遗漏了什么吗 HistoryListAdapter: public class HistoryListAdapter extends RecyclerView.Adapter<HistoryListAdapter.ViewHolder> { private static ArrayList<Recor

我想以编程方式单击recyclerView中的项目,我发现可以这样做:

但它对我不起作用,findViewHolderForAdapterPosition只返回null

我的代码中遗漏了什么吗

HistoryListAdapter:

public class HistoryListAdapter extends RecyclerView.Adapter<HistoryListAdapter.ViewHolder> {
private static ArrayList<RecordItem> recordItems;
private static FragmentActivity activity;
private static RecordList recordList;

public HistoryListAdapter(ArrayList<RecordItem> recordItems, FragmentActivity FA, RecordList FRL) {
    this.recordItems = recordItems;
    this.activity = FA;
    this.recordList = FRL;
}

@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    // create a new view
    View itemLayoutView = LayoutInflater.from(parent.getContext()).inflate(R.layout.recorditem, parent, false);
    return new ViewHolder(itemLayoutView);
}

@Override
public void onBindViewHolder(final ViewHolder viewHolder, final int position) {
    // TextView setText ...
}

// Return the size of the itemsData (invoked by the layout manager)
@Override
public int getItemCount() {
    return recordItems.size();
}

// inner class to hold a reference to each item of RecyclerView
public static class ViewHolder extends RecyclerView.ViewHolder{
    public TextView result, datetime;

    public ViewHolder(View itemLayoutView) {
        super(itemLayoutView);
        itemLayoutView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (activity != null) {
                    // do something...
                }
            }
        });
        result = (TextView) itemLayoutView.findViewById(R.id.result);
        heartrate = (TextView) itemLayoutView.findViewById(R.id.heartrate);
        datetime = (TextView) itemLayoutView.findViewById(R.id.datetime);
    }
}
}
我省略了一些代码,但它不应影响代码的整体结构。

根据:

如果已调用notifyDataSetChanged(),但新布局没有 尚未计算,自新的 在计算布局之前,视图的位置是未知的

使用
findViewHolderForAdapterPosition()
是不安全的


当您在
listView.swapAdapter(listadapter,false)之后调用此方法时
结果总是会得到一个
null
,因为将调用
notifyDataSetChanged()

嘿,我用这种方法解决了这个问题:

public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {

private TextView mTotalSum;
protected int mSum;
protected ArrayList<BasketRVAdapter.ViewHolder> mViewHolders;

public BasketRVAdapter(JSONArray recyclerItems, Context context, TextView totalSum) {
    super(recyclerItems, context);
    mTotalSum = totalSum;
    mViewHolders = new ArrayList<>();
}

@Override
public RecyclerView.ViewHolder onCreateSwipeViewHolder(ViewGroup parent, int i) {
    View view = LayoutInflater.from(parent.getContext())
            .inflate(R.layout.view_basket_rv_item, parent, true);

    return new ViewHolder(view);
}

@Override
public void onBindSwipeViewHolder(final RecyclerView.ViewHolder viewHolder, int position) {
    final BasketRVAdapter.ViewHolder holder = (BasketRVAdapter.ViewHolder) viewHolder;

    JSONObject object;
    try {
        object = mRecyclerItems.getJSONObject(position);
        final int priceValue = object.getInt("price");
        final int quantityValue = object.getInt("quantity");

        holder.setId(object.getInt("id"));
        holder.title.setText(object.getString("title"));
        holder.price.setText(String.format(mContext.getString(R.string.price), priceValue));
        holder.quantity.setText(String.valueOf(quantityValue));
        holder.sum.setText(String.valueOf(priceValue * quantityValue));

        holder.quantity.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {

            }

            @Override
            public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {

            }

            @Override
            public void afterTextChanged(Editable editable) {
                String value = holder.quantity.getText().toString();

                if (value.equals("")) {
                    return;
                }

                if (value.equals("0")) {
                    Toast.makeText(mContext, R.string.null_value_error, Toast.LENGTH_SHORT).show();
                    return;
                }
                holder.sum.setText(String.valueOf(priceValue * Integer.valueOf(value)));
                setTotalSum();
            }

        });

        mViewHolders.add(holder);
        mSum += priceValue * quantityValue;

        if (position == getItemCount() - 1) {
            mTotalSum.setText(String.format(mContext.getString(R.string.total_sum), mSum));
        }
    } catch (JSONException e) {
        e.printStackTrace();
    }
}

@Override
public SwipeConfiguration onCreateSwipeConfiguration(Context context, int i) {
    return new SwipeConfiguration.Builder(context)
                                 .setLeftSwipeBehaviour(SwipeConfiguration.SwipeBehaviour.NORMAL_SWIPE)
                                 .setRightSwipeBehaviour(SwipeConfiguration.SwipeBehaviour.NO_SWIPE)
                                 .setLeftBackgroundColorResource(R.color.dt_basket_deleted)
                                 .setLeftUndoDescription(R.string.deleted)
                                 .setDescriptionTextColorResource(R.color.dt_white)
                                 .setLeftUndoable(true)
                                 .build();
}

@Override
public void onSwipe(int i, int i1, RecyclerView.ViewHolder holder) {
    try {
        if (i1 == SWIPE_LEFT) {
            remove(i);
            notifyItemRemoved(i);
            mViewHolders.remove(i);
            setTotalSum();
        }
    } catch (JSONException e) {
        e.printStackTrace();
    }
}

public int getSum() {
    return mSum;
}

public void setTotalSum() {
    int totalSum = 0;

    for (BasketRVAdapter.ViewHolder holder : mViewHolders) {
        totalSum += Integer.valueOf(holder.sum.getText().toString());
    }

    mSum = totalSum;
    mTotalSum.setText(String.format(mContext.getString(R.string.total_sum), totalSum));
}

public static class ViewHolder extends RecyclerView.ViewHolder {

    @Bind(R.id.trade_title)
    public TextView title;
    @Bind(R.id.trade_price)
    public TextView price;
    @Bind(R.id.trade_quantity)
    public EditText quantity;
    @Bind(R.id.sum)
    public TextView sum;

    private int mId;

    public ViewHolder(View itemView) {
        super(itemView);
        ButterKnife.bind(this, itemView);
    }

    public int getId() {
        return mId;
    }

    public void setId(int id) {
        mId = id;
    }
}}
公共类MyAdapter扩展了RecyclerView.Adapter{ 私有文本视图mTotalSum; 受保护的内部mSum; 受保护的ArrayList多视图文件夹; public BasketrAdapter(JSONArray recyclerItems、上下文、TextView totalSum){ 超级(循环使用,上下文); mTotalSum=总和; mViewHolders=newarraylist(); } @凌驾 public RecyclerView.ViewHolder onCreateSwipeViewHolder(视图组父级,int i){ View=LayoutInflater.from(parent.getContext()) .充气(右布局、视图、篮子、房车项目、父项、真实); 返回新的ViewHolder(视图); } @凌驾 BindSwipeViewHolder上的公共无效(最终RecyclerView.ViewHolder ViewHolder,内部位置){ final basketrAdapter.ViewHolder=(basketrAdapter.ViewHolder)ViewHolder; JSONObject对象; 试一试{ object=mRecyclerItems.getJSONObject(位置); final int priceValue=object.getInt(“价格”); final int quantityValue=object.getInt(“数量”); holder.setId(object.getInt(“id”)); holder.title.setText(object.getString(“title”); holder.price.setText(String.format(mContext.getString(R.String.price),priceValue)); holder.quantity.setText(String.valueOf(quantityValue)); holder.sum.setText(String.valueOf(priceValue*quantityValue)); holder.quantity.addTextChangedListener(新的TextWatcher(){ @凌驾 更改前的公共无效(CharSequence CharSequence,int i,int i1,int i2){ } @凌驾 public void onTextChanged(CharSequence CharSequence,int i,int i1,int i2){ } @凌驾 public void PostTextChanged(可编辑){ 字符串值=holder.quantity.getText().toString(); if(值等于(“”){ 返回; } if(值等于(“0”)){ Toast.makeText(mContext,R.string.null_value_error,Toast.LENGTH_SHORT).show(); 返回; } holder.sum.setText(String.valueOf(priceValue*Integer.valueOf(value)); setTotalSum(); } }); mViewHolders.add(holder); mSum+=价格值*数量值; if(position==getItemCount()-1){ setText(String.format(mContext.getString(R.String.total_sum),mSum)); } }捕获(JSONException e){ e、 printStackTrace(); } } @凌驾 公共SwipeConfiguration onCreateSwipeConfiguration(上下文,int i){ 返回新的swipConfiguration.Builder(上下文) .SetLeftSwipeBehavior(SwipeConfiguration.SwipeBehavior.NORMAL_SWIPE) .SetRightSwipeBehavior(SwipeConfiguration.SwipeBehavior.NO_SWIPE) .setLeftBackgroundColorResource(R.color.dt_已删除) .setLeftUndoDescription(R.string.deleted) .setDescriptionTextColorResource(R.color.dt_白色) .setLeftUndoable(真) .build(); } @凌驾 公共void onswip(int i、int i1、RecyclerView.ViewHolder){ 试一试{ 如果(i1==向左滑动){ 删除(i); (i)删去第(i)款; 删除(i)项; setTotalSum(); } }捕获(JSONException e){ e、 printStackTrace(); } } 公共整数getSum(){ 返回mSum; } 公共无效setTotalSum(){ 整数总和=0; 用于(BasketrAdapter.ViewHolder:mViewHolders){ totalSum+=Integer.valueOf(holder.sum.getText().toString()); } mSum=总和; setText(String.format(mContext.getString(R.String.total_sum),totalSum)); } 公共静态类ViewHolder扩展了RecyclerView.ViewHolder{ @绑定(R.id.trade_title) 公共文本视图标题; @绑定(R.id.交易价格) 公共文本视图价格; @绑定(R.id.trade\u数量) 公共编辑文本数量; @绑定(R.id.sum) 公共文本视图和; 私人int mId; 公共视图持有者(视图项视图){ 超级(项目视图); ButterKnife.bind(这个,itemView); } 公共int getId(){ 中途返回; } 公共无效集合id(内部id){ mId=id; } }}
  • 在类中添加了ArrayList mViewholders字段
  • 将每个viewholder实例添加到onBindSwipeViewHolder方法内的mViewHolders arraylist中
  • 在setTotalSum方法中使用MVIEWolders arraylist而不是FindViewWolderforAdapterPosition方法
  • 您可以这样做:

       listView.postDelayed(new Runnable()
                {
                    @Override
                    public void run()
                    {
                        if(listView.findViewHolderForAdapterPosition(0)!=null )
                        {
    
                            listView.findViewHolderForAdapterPosition(0).itemView.performClick();
                        }
                    }
                },50);
    
    postAndNotifyAdapter(new Handler(),mRecyclerView);
    
    
    
    protected void postAndNotifyAdapter(final Handler handler, final RecyclerView recyclerView) {
        handler.post(new Runnable() {
            @Override
            public void run() {
                if ( recyclerView.findViewHolderForLayoutPosition(0)!=null) {
                    // This will call first item by calling "performClick()" of view.
                    recyclerView.findViewHolderForLayoutPosition(0).itemView.performClick();
                } else {
                    //   
                    postAndNotifyAdapter(handler, recyclerView);
                }
            }
        });
    }
    

    我不建议使用后期延迟。虽然它可以工作,但时间是任意的

    使用recyclerview上的OnPreDrawListener,计时将与下一个绘图周期对齐,并且可以访问可见项目。

    您可以执行以下操作:

       listView.postDelayed(new Runnable()
                {
                    @Override
                    public void run()
                    {
                        if(listView.findViewHolderForAdapterPosition(0)!=null )
                        {
    
                            listView.findViewHolderForAdapterPosition(0).itemView.performClick();
                        }
                    }
                },50);
    
    postAndNotifyAdapter(new Handler(),mRecyclerView);
    
    
    
    protected void postAndNotifyAdapter(final Handler handler, final RecyclerView recyclerView) {
        handler.post(new Runnable() {
            @Override
            public void run() {
                if ( recyclerView.findViewHolderForLayoutPosition(0)!=null) {
                    // This will call first item by calling "performClick()" of view.
                    recyclerView.findViewHolderForLayoutPosition(0).itemView.performClick();
                } else {
                    //   
                    postAndNotifyAdapter(handler, recyclerView);
                }
            }
        });
    }
    

    我知道这已经很晚了,但可能对Kotlin时代的其他人有帮助:

     binding.recycler.post {
         val view = binding.recycler.findViewHolderForAdapterPosition(position)?.itemView?.performClick()
     }