前の記事を続けて、この記事ではItemDecoration
とItemAnimator
について説明し、 Githubで利用可能な単純なアプリケーションの例を使用して、 RecyclerView
でのそれらの動作の原理を説明します。
1. ItemDecoration
ItemDecoration
、 RecyclerView
リストアイテムを装飾するために使用されます。
ItemDecoration
を使用すると、 view
コンポーネント間に仕切りを追加したり、配置したり、等間隔で分割したりできます。 view
コンポーネント間に単純なセパレーターを追加するには、サポートライブラリバージョン25.1.0以降にあるDividerItemDecoration
クラスを使用します。 次のコードフラグメントは、その実装を示しています。
mDividerItemDecoration = new DividerItemDecoration(recyclerView.getContext(), mLayoutManager.getOrientation()); recyclerView.addItemDecoration(mDividerItemDecoration);
独自のセパレータを作成する最良の方法は、 RecyclerView.ItemDecoration
クラスを拡張することです。 サンプルアプリケーションでは、 GridLayoutManager
を使用し、 CharacterItemDecoration
をRecyclerView
適用しました。
recyclerView.addItemDecoration(new CharacterItemDecoration(50));
ここで、 CharacterItemDecoration
は、コンストラクターでオフセット( getItemOffsets(...)
)を50ピクセルに設定し、 getItemOffsets(...)
をオーバーライドします。 getItemOffsets()
メソッド内で、各outRects
フィールドは、内部および外部マージンと同様に、各view
コンポーネントに設定する必要があるピクセル数を決定します。 GridLayoutManager
を使用し、グリッド要素間の等距離を設定するため、各偶数要素に対して右側のインデントを25ピクセル(つまり、オフセット/ 2)に設定し、奇数要素ごとに左側のインデントを25ピクセルに設定します。すべての要素に対して。
2. ItemAnimator
ItemAnimator
、 RecyclerView
内の要素のアニメーション化またはコンポーネントの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)
メソッドを呼び出した後、レンダリングの前後にアダプター要素が存在する場合、 RecyclerView
はanimateChange(...)
メソッドを呼び出します。 このメソッドは、アダプターが安定した識別子を使用する場合にnotifyDataSetChanged()
呼び出すときにも使用できます。 これは、 RecyclerView
が同じViewHolders
でview
コンポーネントを再利用できるようにするために必要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