viewholder update studio recyclerview recycler practices custom best android android-recyclerview android-viewholder

android - update - RecyclerView.getChild(índice) muestra nulo cuando la lista se desplaza(el índice se arruina)



update recyclerview (3)

He estado utilizando SwipeableRecyclerView para mi aplicación de Android para habilitar los golpes para mi recyclerView. RecyclerView contiene una lista de cardViews.

Estaba intentando implementar la funcionalidad de deshacer para las tarjetas que se borrarán cuando deslice hacia la izquierda (el primer deslizamiento muestra deshacer, el siguiente desliza desencadena eliminar)

Estoy intentando el siguiente código (parcialmente, supongo)

SwipeableRecyclerViewTouchListener srvTouchListner = new SwipeableRecyclerViewTouchListener(rvTimerList, new SwipeableRecyclerViewTouchListener.SwipeListener(){ @Override public boolean canSwipe(int i) { return true; } @Override public void onDismissedBySwipeLeft(RecyclerView recyclerView, int[] ints) { for(int position : ints){ View view = recyclerView.getChildAt(position); if (view.getTag(R.string.card_undo) == null) { if(viewStack == null) { saveToViewStack(position, view); final ViewGroup viewGroup = (ViewGroup) view.findViewById(R.id.time_card2); view.setTag(R.string.card_undo, "true"); viewGroup.addView(view.inflate(TimerSummary.this, R.layout.timeslot_card_undo, null)); } } else { Log.d(TAG, "Removing Item"); deleteTimeSlot(timerInstanceList.get(position)); Toast.makeText(TimerSummary.this, "Deleted!", Toast.LENGTH_SHORT).show(); timerInstanceList.remove(position); finalSummaryAdapter.notifyItemRemoved(position); } } finalSummaryAdapter.notifyDataSetChanged(); } @Override public void onDismissedBySwipeRight(RecyclerView recyclerView, int[] ints) { for (int position:ints){ View view = recyclerView.getChildAt(position); if(view.getTag(R.string.card_undo) != null && view.getTag(R.string.card_undo).equals("true")){ viewStack = null; recyclerView.setAdapter(finalSummaryAdapter); } } } });

cuando los artículos son más (necesita desplazamiento)

View view = recyclerView.getChildAt(position);

devuelve una referencia nula que causa un bloqueo de la aplicación.

Dudo que esté usando el método incorrecto para tomar una decisión. Debería estar usando algo relacionado con el espectador, en realidad estoy un poco confundido acerca de cómo obtener la vista que desea del visitante.

Si alguien puede compartir algo que ayude, ¡será genial! Estaré feliz de proporcionar más informaciones si alguien lo quiere,


Como no tengo suficientes puntos de reputación para comentar la respuesta de @ yigit, pensé que podría dar una forma de recuperar todos los viewfolders de un RecyclerView independientemente de lo que se encuentre actualmente en el viewGroup. Incluso con findViewHolderForAdapterPosition y ForLayoutPosition aún podemos obtener una instancia nula de ViewHolder en RecyclerView.

Para evitar esto, podemos usar findViewHolderForItemId [ 1 ] y pasar el ID del viewHolder en el adaptador usando RecyclerView.Adapter # getItemId (int position) [ 2 ]

for (int i = 0; i < mAdapter.getItemCount(); i++) { RecyclerView.ViewHolder holder = mRecyclerView.findViewHolderForItemId(mAdapter.getItemId(i)); }

  1. https://developer.android.com/reference/android/support/v7/widget/RecyclerView.html#findViewHolderForItemId(int)
  2. https://developer.android.com/reference/android/support/v7/widget/RecyclerView.Adapter.html#getItemId(int)


Utilice los métodos findFirstCompletelyVisibleItemPosition () y findLastVisibleItemPosition () en LayoutManager de su RecyclerView para descubrir que el niño que está buscando es visible o no. Si está visible, entonces puede usar getChild (índice) para obtener la instancia de ViewHolder de ese niño en particular y no sería nulo, de lo contrario podría ser nulo (si el niño no está en él). En caso de que su hijo no sea visible, simplemente realice cambios en su posición específica. Objeto de lista, la próxima vez que sea visible tendrá una interfaz de usuario actualizada.

if (selectedPosition >= linearLayoutManager.findFirstVisibleItemPosition() && selectedPosition <= linearLayoutManager.findLastVisibleItemPosition()){ linearLayoutManager.getChildAt(selectedPosition).setBackgroundResource(0); }