Dicas para uso profissional do RecyclerView. Parte 2

Dicas para uso profissional do RecyclerView. Parte 2


Continuando o artigo anterior , discutirei sobre ItemDecoration e ItemAnimator e tentarei explicar o princípio de seu trabalho no RecyclerView usando um exemplo de aplicativo simples disponível no Github .


1. ItemDecoration


ItemDecoration usado para decorar itens da lista em um RecyclerView .


Com o ItemDecoration você pode adicionar divisórias entre os componentes da view , alinhá-los ou dividi-los em intervalos iguais. Para adicionar um separador simples entre os componentes de view , use a classe DividerItemDecoration , que pode ser encontrada na biblioteca de suporte versão 25.1.0 e superior. O seguinte fragmento de código demonstra sua implementação:


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

A melhor maneira de criar seu próprio separador é estender a classe RecyclerView.ItemDecoration . No aplicativo de exemplo, usei o GridLayoutManager e apliquei CharacterItemDecoration ao RecyclerView :


 recyclerView.addItemDecoration(new CharacterItemDecoration(50)); 

Aqui CharacterItemDecoration define o deslocamento ( eng. Deslocamento) para 50 pixels em seu construtor e substitui getItemOffsets(...) . Dentro do método getItemOffsets() , cada campo outRects determina o número de pixels que devem ser configurados para cada componente de view , semelhante ao recuo e recuo. Como usei o GridLayoutManager e desejei definir distâncias iguais entre os elementos da grade, defino o recuo à direita em 25 pixels (isto é, offset / 2) para cada elemento par e o recuo à esquerda em 25 pixels para cada elemento ímpar, mantendo o recuo superior o mesmo para todos os elementos.


Recuo da grade


2. ItemAnimator


ItemAnimator usado para animar elementos ou view componentes dentro de um RecyclerView .


Animar itens em uma lista


Vamos tornar nosso aplicativo semelhante ao Instagram estendendo o DefaultItemAnimator e substituindo vários métodos.


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

O canReuseUpdatedViewHolder(...) determina se o mesmo ViewHolder usado para animação se os dados desse elemento forem alterados. Se retornar false , os dois ViewHolders - antigos e atualizados - são passados ​​para o 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 chama o recordPreLayoutInformation(...) para iniciar a renderização do layout . ItemAnimator deve registrar as informações necessárias sobre o componente de view antes de ser substituído, movido ou excluído. Os dados retornados por esse método serão transferidos para o método de animação correspondente (no nosso caso, isso é 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 chama o animateChange(...) quando o elemento do adaptador está presente antes e depois da renderização após chamar o notifyItemChanged(int) . Este método também pode ser usado ao chamar notifyDataSetChanged() , se o adaptador usar identificadores estáveis. Isso é necessário para que o RecyclerView possa reutilizar os componentes de view nos mesmos ViewHolders . Observe que esse método usa como argumentos: (ViewHolder oldHolder, ViewHolder newHolder, ItemHolderInfo preInfo, ItemHolderInfo postInfo) . Como estamos reutilizando o ViewHolder , oldHolder e newHolder são os mesmos.


Sempre que o usuário clica duas vezes em qualquer item, o seguinte método é chamado:


 notifyItemChanged(position, ACTION_LIKE_IMAGE_DOUBLE_CLICKED); 

Isso inicia toda a cadeia de chamadas: canReuseUpdatedViewHolder(...) , recordPreLayoutInformation(...) e, finalmente, animateChange(...) no ItemAnimator , que, por sua vez, anima o item da lista e o ícone de coração nesse elemento ( exemplo no GIF acima).


Esta é a segunda parte de uma série de artigos sobre o RecyclerView . Se você perdeu a primeira parte, leia aqui .


Mais alguns bons artigos sobre o RecyclerView :



← Dicas para uso profissional RecyclerView. Parte 1

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


All Articles