studio recyclerview ejemplo cardview android android-recyclerview

android - ejemplo - RecyclerView no recicla vistas si el recuento de vistas es pequeño



cardview android ejemplo (1)

He estado tratando con un comportamiento extraño en Recycler View, si el recuento de vistas en el adaptador es pequeño, en mi caso con el tamaño 5, las vistas no se reciclan y onBindViewHolder no se llama cuando la vista se desplaza de nuevo a la pantalla. Si aumente el tamaño a 10 vistas, por ejemplo, entonces el reciclaje comienza a funcionar y se llama a OnBindViewHolder cada vez que una vista ingresa a la pantalla.

XML

<android.support.v4.widget.SwipeRefreshLayout android:id="@+id/swipeRefresh" android:layout_width="wrap_content" android:layout_height="wrap_content"> <!-- RECYCLER VIEW --> <android.support.v7.widget.RecyclerView android:id="@+id/eventsList" android:layout_width="match_parent" android:layout_height="match_parent" /> </android.support.v4.widget.SwipeRefreshLayout>

Inicialización de vista de reciclador

LinearLayoutManager llm = new LinearLayoutManager(getActivity()); llm.setOrientation(LinearLayoutManager.VERTICAL); eventsList.setLayoutManager(llm); //Sets endless listener scrollListener = new EndlessRecyclerOnScrollListener(llm,3,mLastDownloadedPage) { @Override public void onLoadMore(int current_page) { Timber.d("Loading date for page: " + current_page); mLastDownloadedPage = current_page; //If it''s showing cached don''t download if(showingCached) return; //Shows snackbar loading view showSnackbarLoadingView(); //Gets events getEvents(false); } }; //eventsList.addOnScrollListener(scrollListener); //Set the adapter mAdapter = new EventListAdapter(this,getActivity().getApplicationContext()); eventsList.setAdapter(mAdapter);

El adaptador

@Override public EventHolder onCreateViewHolder(ViewGroup viewGroup, int i) { Timber.d("Create view holder pos: "+i); View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.list_events_row, viewGroup, false); return new EventHolder(v,mListener); } @Override public void onBindViewHolder(EventHolder eventHolder, int i) { if(mBindListener != null) mBindListener.onBind(eventHolder,i); Timber.d("Bind view holder pos "+i); Event event = eventList.get(i); eventHolder.bindEvent(event); //Sets the date setDate(eventHolder.date, event); //Sets the location setLocation(eventHolder.distance,event); }

En la pantalla solo hay 3 vistas visibles, con un tamaño de 5, cuando me createViewHolder puedo ver que se llama a createViewHolder y bindViewHolder para la posición 4 y 5, pero cuando me desplazo hacia arriba no se reciclan al salir de la pantalla . Puedo confirmar eso porque anulando

@Override public void onViewRecycled(EventHolder holder) { super.onViewRecycled(holder); Timber.d("onViewRecycled: "+holder.name); }

no se registra ningún mensaje Sin embargo, si el recuento de vistas se incrementa, por ejemplo, con el tamaño 10, todo funciona bien, las vistas se reciclan y se llama a onBindViewHolder para cada posición.

¿Es este comportamiento normal? Si es cómo puedo guardar el estado de una vista de artículo, por ejemplo, estado activado, solía guardar la posición activa en una variable y luego usar esta línea para activar la vista cuando ingresa a la pantalla usando el método de vinculación

holder.itemView.setActivated(pos == lastSelectedPos);


Es un comportamiento normal, pero puede modificarlo con:

recyclerView.setItemViewCacheSize(int);

Sobre la segunda parte de la pregunta, ¡tienes razón! Almacene la posición "activada" como una variable en su adaptador. En onBindViewHolder () haga algo como:

holder.itemView.setActivated(holder.getAdapterPosition() == lastSelectedPos);