Consejos para el uso profesional de RecyclerView. Parte 2

Consejos para el uso profesional de RecyclerView. Parte 2


Continuando con el artículo anterior , en este hablaré sobre ItemDecoration y ItemAnimator e intentaré explicar el principio de su trabajo en RecyclerView usando un ejemplo de una aplicación simple que está disponible en Github .


1. Decoración del artículo


ItemDecoration utiliza para decorar elementos de la lista en un RecyclerView .


Con ItemDecoration puede agregar divisores entre los componentes de la view , alinearlos o dividirlos a intervalos iguales. Para agregar un separador simple entre los componentes de la view , use la clase DividerItemDecoration , que se puede encontrar en la biblioteca de soporte versión 25.1.0 y superior. El siguiente fragmento de código demuestra su implementación:


 mDividerItemDecoration = new DividerItemDecoration(recyclerView.getContext(), mLayoutManager.getOrientation()); recyclerView.addItemDecoration(mDividerItemDecoration); 

La mejor manera de crear su propio separador es extender la clase RecyclerView.ItemDecoration . En la aplicación de muestra, utilicé el GridLayoutManager y apliqué CharacterItemDecoration al RecyclerView :


 recyclerView.addItemDecoration(new CharacterItemDecoration(50)); 

Aquí CharacterItemDecoration establece el desplazamiento ( ing. Offset) en 50 píxeles en su constructor y anula getItemOffsets(...) . Dentro del método getItemOffsets() , cada campo outRects determina el número de píxeles que se deben establecer para cada componente de view , de forma similar a la sangría y la sangría. Como utilicé el GridLayoutManager y quería establecer distancias iguales entre los elementos de la cuadrícula, configuré la sangría a la derecha en 25 píxeles (es decir, desplazamiento / 2) para cada elemento par y la sangría a la izquierda en 25 píxeles para cada elemento impar, mientras mantenía la sangría superior igual para todos los elementos


Sangría de rejilla


2. ItemAnimator


ItemAnimator usa para animar elementos o view componentes dentro de un RecyclerView .


Animar elementos en una lista


Hagamos que nuestra aplicación sea similar a Instagram extendiendo el DefaultItemAnimator y anulando varios métodos.


 public boolean canReuseUpdatedViewHolder(@NonNull RecyclerView.ViewHolder viewHolder) { return true; } 

El canReuseUpdatedViewHolder(...) determina si se ViewHolder el mismo ViewHolder para la animación si los datos de este elemento cambian. Si devuelve false , los dos ViewHolders , antiguos y actualizados, se pasan al método animateChange(...) .


 public ItemHolderInfo recordPreLayoutInformation(@NonNull RecyclerView.State state, @NonNull RecyclerView.ViewHolder viewHolder, int changeFlags, @NonNull List<Object> payloads) { if (changeFlags == FLAG_CHANGED) { for (Object payload : payloads) { if (payload instanceof String) { return new CharacterItemHolderInfo((String) payload); } } } return super.recordPreLayoutInformation(state, viewHolder, changeFlags, payloads); } public static class CharacterItemHolderInfo extends ItemHolderInfo { public String updateAction; public CharacterItemHolderInfo(String updateAction) { this.updateAction = updateAction; } } 

RecyclerView llama al recordPreLayoutInformation(...) para comenzar la representación del layout . ItemAnimator debe registrar la información necesaria sobre el componente de view antes de que se sobrescriba, mueva o elimine. Los datos devueltos por este método se transferirán al método de animación correspondiente (en nuestro caso, esto es animateChange(...) ).


 @Override public boolean animateChange(@NonNull RecyclerView.ViewHolder oldHolder, @NonNull RecyclerView.ViewHolder newHolder, @NonNull ItemHolderInfo preInfo, @NonNull ItemHolderInfo postInfo) { if (preInfo instanceof CharacterItemHolderInfo) { CharacterItemHolderInfo recipesItemHolderInfo = (CharacterItemHolderInfo) preInfo; CharacterRVAdapter.CharacterViewHolder holder = (CharacterRVAdapter.CharacterViewHolder) newHolder; if (CharacterRVAdapter.ACTION_LIKE_IMAGE_DOUBLE_CLICKED.equals(recipesItemHolderInfo.updateAction)) { animatePhotoLike(holder); } } return false; } private void animatePhotoLike(final CharacterRVAdapter.CharacterViewHolder holder) { holder.likeIV.setVisibility(View.VISIBLE); holder.likeIV.setScaleY(0.0f); holder.likeIV.setScaleX(0.0f); AnimatorSet animatorSet = new AnimatorSet(); ObjectAnimator scaleLikeIcon = ObjectAnimator.ofPropertyValuesHolder (holder.likeIV, PropertyValuesHolder.ofFloat("scaleX", 0.0f, 2.0f), PropertyValuesHolder.ofFloat("scaleY", 0.0f, 2.0f), PropertyValuesHolder.ofFloat("alpha", 0.0f, 1.0f, 0.0f)); scaleLikeIcon.setInterpolator(DECELERATE_INTERPOLATOR); scaleLikeIcon.setDuration(1000); ObjectAnimator scaleLikeBackground = ObjectAnimator.ofPropertyValuesHolder (holder.characterCV, PropertyValuesHolder.ofFloat("scaleX", 1.0f, 0.95f, 1.0f), PropertyValuesHolder.ofFloat("scaleY", 1.0f, 0.95f, 1.0f)); scaleLikeBackground.setInterpolator(DECELERATE_INTERPOLATOR); scaleLikeBackground.setDuration(600); animatorSet.playTogether(scaleLikeIcon, scaleLikeBackground); animatorSet.start(); } 

RecyclerView llama al animateChange(...) cuando el elemento adaptador está presente tanto antes como después de renderizar después de llamar al notifyItemChanged(int) . Este método también se puede usar al llamar a notifyDataSetChanged() , si el adaptador usa identificadores estables. Esto es necesario para que RecyclerView pueda reutilizar los componentes de view en los mismos ViewHolders . Tenga en cuenta que este método toma como argumentos: (ViewHolder oldHolder, ViewHolder newHolder, ItemHolderInfo preInfo, ItemHolderInfo postInfo) . Como estamos reutilizando ViewHolder , tanto oldHolder como newHolder son iguales.


Cada vez que el usuario hace doble clic en cualquier elemento, se llama al siguiente método:


 notifyItemChanged(position, ACTION_LIKE_IMAGE_DOUBLE_CLICKED); 

Esto inicia toda la cadena de llamadas: canReuseUpdatedViewHolder(...) , recordPreLayoutInformation(...) y, en última instancia, animateChange(...) en ItemAnimator , que, a su vez, anima el elemento de la lista y el ícono del corazón en este elemento ( ejemplo en el GIF anterior).


Esta es la segunda parte de una serie de artículos sobre RecyclerView . Si te perdiste la primera parte, entonces léela aquí .


Algunos buenos artículos más sobre RecyclerView :



← Consejos para uso profesional RecyclerView. Parte 1

Source: https://habr.com/ru/post/es426773/


All Articles