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.
- RecyclerView - Obtener una vista en posición particular
- Cómo hacer Zoom en todo el contenido de RecyclerView?
- Pausar un video en un recicladorVer cuando hay un cierto porcentaje en la pantalla
- Cómo implementar coverflow con recyclerview
- Soporte RecyclerView no muestra nada hasta que se toca
¿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.
- Android reciclerview no muestra elementos
- Recycleview muestra diferentes tipos de vistas
- RecyclerView no se muestra
- RecylcerView se desplaza a la parte superior del elemento eliminado
- Android - ¿Cómo cambiar la altura de Recyclerview dinámicamente?
- Recyclerview - Superposición de artículos de abajo hacia arriba
- Cómo obtener la altura del elemento recyclerview en "onBindViewHolder"
- Crear menú de opciones para RecyclerView-Item
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; } }}
- Se agregó el campo mViewholders de ArrayList dentro de la clase
- Agregó cada instancia del espectador a mViewHolders arraylist dentro del método onBindSwipeViewHolder
- Utilizado mViewholders arraylist en lugar de findViewHolderForadapterposition método dentro de método setTotalSum
- Eliminar un sms de la bandeja de entrada
- ¿Cómo ocurre esta extraña condición cuando se muestra el ítem del ítem de menú en el menú de desbordamiento de la barra de herramientas?