RecyclerViewをプロが使用するためのヒント。 パート2

RecyclerViewをプロが使用するためのヒント。パート2


前の記事を続けて、この記事ではItemDecorationItemAnimatorについて説明し、 Githubで利用可能な単純なアプリケーションの例を使用して、 RecyclerViewでのそれらの動作の原理を説明します。


1. ItemDecoration


ItemDecorationRecyclerViewリストアイテムを装飾するために使用されます。


ItemDecorationを使用すると、 viewコンポーネント間に仕切りを追加したり、配置したり、等間隔で分割したりできます。 viewコンポーネント間に単純なセパレーターを追加するには、サポートライブラリバージョン25.1.0以降にあるDividerItemDecorationクラスを使用します。 次のコードフラグメントは、その実装を示しています。


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

独自のセパレータを作成する最良の方法は、 RecyclerView.ItemDecorationクラスを拡張することです。 サンプルアプリケーションでは、 GridLayoutManagerを使用し、 CharacterItemDecorationRecyclerView適用しました。


 recyclerView.addItemDecoration(new CharacterItemDecoration(50)); 

ここで、 CharacterItemDecorationは、コンストラクターでオフセット( getItemOffsets(...) )を50ピクセルに設定し、 getItemOffsets(...)をオーバーライドします。 getItemOffsets()メソッド内で、各outRectsフィールドは、内部および外部マージンと同様に、各viewコンポーネントに設定する必要があるピクセル数を決定します。 GridLayoutManagerを使用し、グリッド要素間の等距離を設定するため、各偶数要素に対して右側のインデントを25ピクセル(つまり、オフセット/ 2)に設定し、奇数要素ごとに左側のインデントを25ピクセルに設定します。すべての要素に対して。


グリッドのインデント


2. ItemAnimator


ItemAnimatorRecyclerView内の要素のアニメーション化またはコンポーネントのview使用されます。


リストアイテムのアニメーション化


DefaultItemAnimatorを拡張し、いくつかのメソッドをオーバーライドすることにより、アプリケーションを「Instagramライク」にしましょう。


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

canReuseUpdatedViewHolder(...)メソッドは、この要素のデータが変更された場合に同じViewHolderをアニメーションに使用するかどうかを決定します。 false返す場合、 ViewHolders (古いものと更新されたもの)の両方が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は、 layoutレンダリングが開始される前にrecordPreLayoutInformation(...)メソッドを呼び出します。 ItemAnimatorは、上書き、移動、または削除する前に、 viewコンポーネントに関する必要な情報を記録する必要があります。 このメソッドによって返されるデータは、対応するアニメーションメソッドに転送されます(この場合、これは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(); } 

notifyItemChanged(int)メソッドを呼び出した後、レンダリングの前後にアダプター要素が存在する場合、 RecyclerViewanimateChange(...)メソッドを呼び出します。 このメソッドは、アダプターが安定した識別子を使用する場合にnotifyDataSetChanged()呼び出すときにも使用できます。 これは、 RecyclerViewが同じViewHoldersviewコンポーネントを再利用できるようにするために必要ViewHolders 。 このメソッドは引数として受け取ることに注意してください(ViewHolder oldHolder、ViewHolder newHolder、ItemHolderInfo preInfo、ItemHolderInfo postInfo)ViewHolderを再利用しているViewHolder 、oldHolderとnewHolderは同じです。


ユーザーがアイテムをダブルクリックするたびに、次のメソッドが呼び出されます。


 notifyItemChanged(position, ACTION_LIKE_IMAGE_DOUBLE_CLICKED); 

これにより、コールチェーン全体が開始されますcanReuseUpdatedViewHolder(...)recordPreLayoutInformation(...) 、そして最終的にItemAnimator animateChange(...)は、リスト要素とその要素のハートアイコンをアニメーション化しますanimateChange(...)上記のgifの例)。


これは、 RecyclerViewに関する一連の記事の第2部です。 最初の部分を見逃した場合は、 ここで読んでください


RecyclerViewに関するさらに良い記事:



←プロユースのRecyclerViewのヒント。 パート1



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


All Articles