2

私はRecyclerViewの変更アニメーションを作成しています。前のビューホールダーを保持するためにcanReuseUpdatedViewHolder()を返信してtrueを返すようにしました。 animateChange()でアニメーションを開始し、終了するとすぐにdispatchAnimationFinished()に電話します。パラメータoldHoldernewHolderは、animateChange()の同じインスタンスです。ItemAnimator.canReuseUpdatedViewHolder()がtrueを返す場合でも、OnCreateViewHolderが呼び出されます。

その後、アニメーションが開始されるとすぐに、RecyclerViewのonBindViewHolder()がリスト内のすべての子に対して呼び出されます。驚いたことに、アニメーションアイテムについてのみ、新しいViewHolderがonCreateViewHolder()に生成されていますが、これは正しい動作ではありません。他のすべての子に対して、古いViewHolderはonBindViewHolder()にバインドされています。

アニメーションが終了する前に、onBindViewHolder()があまりにも早く呼び出されます。アニメーションが終了した後にdispatchAnimationFinished(holder)が呼び出された場合でも

ここにItemAnimatorサブクラスがあります。

public class CustomItemAnimator extends DefaultItemAnimator { 


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

    @Override 
    public boolean canReuseUpdatedViewHolder(@NonNull RecyclerView.ViewHolder viewHolder, @NonNull List<Object> payloads) { 
     return true; 
    } 

    @Override 
    public boolean animateChange(@NonNull RecyclerView.ViewHolder oldHolder, @NonNull RecyclerView.ViewHolder newHolder, @NonNull ItemHolderInfo preLayoutInfo, @NonNull ItemHolderInfo postLayoutInfo) { 
     CustomHolder holder = (CustomHolder) newHolder; 
     CustomView customView = holder.customView; 
     Animator animator = customView.revealAnimation(); 
     animator.addListener(new AnimatorListenerAdapter() { 
      @Override 
      public void onAnimationEnd(Animator animation) { 
       dispatchAnimationFinished(holder); 
      } 
     }); 
     animator.start(); 
     return false; 
    } 
} 

、ここでは、カスタムビューのアニメーションコードです:

CustomView.java

public Animator revealAnimation() { 
    return circularRevealView(visibleView, hiddenView); 
} 

@TargetApi(Build.VERSION_CODES.LOLLIPOP) 
private Animator circularRevealView(View visibleView, View invisibleView) { 

    // get the center for the clipping circle 
    int cx = visibleView.getWidth()/2; 
    int cy = visibleView.getHeight()/2; 

    // get the final radius for the clipping circle 
    float finalRadius = (float) Math.hypot(cx, cy); 

    // create the animator for this view (the start radius is zero) 
    Animator anim = 
      ViewAnimationUtils.createCircularReveal(invisibleView, cx, cy, 0, finalRadius); 

    visibleView.setVisibility(INVISIBLE); 
    invisibleView.setVisibility(View.VISIBLE); 

    // return the animation for later use 
    return anim; 
} 

感謝。

答えて

1

animateChange(...)は(notifyDataSetChanged後に呼び出される)、それはonBindViewHolderは()animateChange(...)の前に行く。とホルダーの状態がすでにこの

それを行うことができますchanged.maybeたことを意味
animator.addListener(new AnimatorListenerAdapter() { 
      @Override 
      public void onAnimationStart(Animator animation) { 
       visibleView.setVisibility(INVISIBLE); 
       invisibleView.setVisibility(View.VISIBLE); 
      } 

      @Override 
      public void onAnimationEnd(Animator animation) { 
       dispatchAnimationFinished(holder); 
      } 
     }); 
関連する問題