Android recyclerView findViewHolderForAdapterPosition devuelve null

Quiero hacer clic en un elemento en recyclerView programaticamente, encontré una manera de hacerlo:

recyclerView.findViewHolderForAdapterPosition(0).itemView.performClick(); 

Pero no funciona para mí, el findViewHolderForAdapterPosition acaba de devolver null.

¿He extrañado algo en mi código?

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

RecordList:

 RecyclerView listView = (RecyclerView) layoutView.findViewById(R.id.listView); HistoryListAdapter listadapter = new HistoryListAdapter(itemsToShow, getActivity(), RecordList.this); listView.swapAdapter(listadapter, false); listView.findViewHolderForAdapterPosition(0).itemView.performClick(); 

He omitido algún código, pero no debería afectar la estructura general de mi código.

Según la documentación oficial :

Si notifyDataSetChanged () ha sido llamado pero el nuevo diseño no se ha calculado todavía , este método devolverá nulo ya que las nuevas posiciones de vistas son desconocidas hasta que se calcula el diseño.

No es seguro usar findViewHolderForAdapterPosition() .

Mientras llama a este método después de listView.swapAdapter(listadapter, false); Siempre obtendrá un null como resultado porque se notifyDataSetChanged() .

Puedes hacerlo:

  listView.postDelayed(new Runnable() { @Override public void run() { if(listView.findViewHolderForAdapterPosition(0)!=null ) { listView.findViewHolderForAdapterPosition(0).itemView.performClick(); } } },50); 

He resuelto el problema de esta manera:

 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; } }} 
  1. Se agregó el campo mViewholders de ArrayList dentro de la clase
  2. Agregó cada instancia del espectador a mViewHolders arraylist dentro del método onBindSwipeViewHolder
  3. Utilizado mViewholders arraylist en lugar de findViewHolderForadapterposition método dentro de método setTotalSum
  • RecyclerVista la lista con los artículos con los límites en un ángulo, no horizontal
  • RecyclerView ItemDecoration Espaciado y Span
  • Desplazamiento Horizontal Liso de Recyclerview dentro de Scrollview
  • Selección única en RecyclerView
  • Recyclerview notifyDataSetChanged (); no funciona
  • Android - ¿Cómo agregar una línea de separación discontinua / punteada para RecyclerView?
  • Compruebe si RecyclerView es desplazable
  • La barra de desplazamiento de RecyclerView salta de nuevo al principio después del primer elemento
  • Mostrar la vista personalizada bajo el elemento RecyclerView deslizado
  • No se puede usar getLayoutPosition () o getAdapterPosition () en RecyclerView
  • ¿Cómo cambiar el color del elemento Recycler?
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.