Movatterモバイル変換


[0]ホーム

URL:


Skip to content
Search Gists
Sign in Sign up

Instantly share code, notes, and snippets.

@RareScrap
CreatedJune 15, 2017 02:51
    • Star(0)You must be signed in to star a gist
    • Fork(0)You must be signed in to fork a gist

    Select an option

    Save RareScrap/a720ffe4b9abeaf031ad9aab0e9d6d14 to your computer and use it in GitHub Desktop.
    DefaultItemAnimator с подробным описанием (дополняется время от времени)
    /*
    * Copyright (C) 2014 The Android Open Source Project
    *
    * Licensed under the Apache License, Version 2.0 (the "License");
    * you may not use this file except in compliance with the License.
    * You may obtain a copy of the License at
    *
    * http://www.apache.org/licenses/LICENSE-2.0
    *
    * Unless required by applicable law or agreed to in writing, software
    * distributed under the License is distributed on an "AS IS" BASIS,
    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    * See the License for the specific language governing permissions and
    * limitations under the License.
    */
    packagecom.webtrust.tennosushi;
    importandroid.support.annotation.NonNull;
    importandroid.support.v4.animation.AnimatorCompatHelper;
    importandroid.support.v4.view.ViewCompat;
    importandroid.support.v4.view.ViewPropertyAnimatorCompat;
    importandroid.support.v4.view.ViewPropertyAnimatorListener;
    importandroid.support.v7.widget.CardView;
    importandroid.support.v7.widget.RecyclerView.ViewHolder;
    importandroid.support.v7.widget.SimpleItemAnimator;
    importandroid.view.View;
    importjava.util.ArrayList;
    importjava.util.List;
    /**
    * This implementation of {@link RecyclerView.ItemAnimator} provides basic
    * animations on remove, add, and move events that happen to the items in
    * a RecyclerView. RecyclerView uses a DefaultItemAnimator by default.
    *
    * @see RecyclerView#setItemAnimator(RecyclerView.ItemAnimator)
    */
    publicclassDefaultItemAnimatorextendsSimpleItemAnimator {
    privatestaticfinalbooleanDEBUG =false;
    privateArrayList<ViewHolder>mPendingRemovals =newArrayList<>();
    privateArrayList<ViewHolder>mPendingAdditions =newArrayList<>();
    privateArrayList<MoveInfo>mPendingMoves =newArrayList<>();
    privateArrayList<ChangeInfo>mPendingChanges =newArrayList<>();
    ArrayList<ArrayList<ViewHolder>>mAdditionsList =newArrayList<>();
    ArrayList<ArrayList<MoveInfo>>mMovesList =newArrayList<>();
    ArrayList<ArrayList<ChangeInfo>>mChangesList =newArrayList<>();
    ArrayList<ViewHolder>mAddAnimations =newArrayList<>();
    ArrayList<ViewHolder>mMoveAnimations =newArrayList<>();
    ArrayList<ViewHolder>mRemoveAnimations =newArrayList<>();
    ArrayList<ViewHolder>mChangeAnimations =newArrayList<>();
    privatestaticclassMoveInfo {
    publicViewHolderholder;
    publicintfromX,fromY,toX,toY;
    MoveInfo(ViewHolderholder,intfromX,intfromY,inttoX,inttoY) {
    this.holder =holder;
    this.fromX =fromX;
    this.fromY =fromY;
    this.toX =toX;
    this.toY =toY;
    }
    }
    privatestaticclassChangeInfo {
    publicViewHolderoldHolder,newHolder;
    publicintfromX,fromY,toX,toY;
    privateChangeInfo(ViewHolderoldHolder,ViewHoldernewHolder) {
    this.oldHolder =oldHolder;
    this.newHolder =newHolder;
    }
    ChangeInfo(ViewHolderoldHolder,ViewHoldernewHolder,
    intfromX,intfromY,inttoX,inttoY) {
    this(oldHolder,newHolder);
    this.fromX =fromX;
    this.fromY =fromY;
    this.toX =toX;
    this.toY =toY;
    }
    @Override
    publicStringtoString() {
    return"ChangeInfo{" +
    "oldHolder=" +oldHolder +
    ", newHolder=" +newHolder +
    ", fromX=" +fromX +
    ", fromY=" +fromY +
    ", toX=" +toX +
    ", toY=" +toY +
    '}';
    }
    }
    @Override
    publicvoidrunPendingAnimations() {
    booleanremovalsPending = !mPendingRemovals.isEmpty();
    booleanmovesPending = !mPendingMoves.isEmpty();
    booleanchangesPending = !mPendingChanges.isEmpty();
    booleanadditionsPending = !mPendingAdditions.isEmpty();
    if (!removalsPending && !movesPending && !additionsPending && !changesPending) {
    // nothing to animate
    return;
    }
    // First, remove stuff
    for (ViewHolderholder :mPendingRemovals) {
    animateRemoveImpl(holder);
    }
    mPendingRemovals.clear();
    // Next, move stuff
    if (movesPending) {
    finalArrayList<MoveInfo>moves =newArrayList<>();
    moves.addAll(mPendingMoves);
    mMovesList.add(moves);
    mPendingMoves.clear();
    Runnablemover =newRunnable() {
    @Override
    publicvoidrun() {
    for (MoveInfomoveInfo :moves) {
    animateMoveImpl(moveInfo.holder,moveInfo.fromX,moveInfo.fromY,
    moveInfo.toX,moveInfo.toY);
    }
    moves.clear();
    mMovesList.remove(moves);
    }
    };
    if (removalsPending) {
    Viewview =moves.get(0).holder.itemView;
    ViewCompat.postOnAnimationDelayed(view,mover,getRemoveDuration());
    }else {
    mover.run();
    }
    }
    // Next, change stuff, to run in parallel with move animations
    if (changesPending) {
    finalArrayList<ChangeInfo>changes =newArrayList<>();
    changes.addAll(mPendingChanges);
    mChangesList.add(changes);
    mPendingChanges.clear();
    Runnablechanger =newRunnable() {
    @Override
    publicvoidrun() {
    for (ChangeInfochange :changes) {
    animateChangeImpl(change);
    }
    changes.clear();
    mChangesList.remove(changes);
    }
    };
    if (removalsPending) {
    ViewHolderholder =changes.get(0).oldHolder;
    ViewCompat.postOnAnimationDelayed(holder.itemView,changer,getRemoveDuration());
    }else {
    changer.run();
    }
    }
    // Next, add stuff
    if (additionsPending) {
    finalArrayList<ViewHolder>additions =newArrayList<>();
    additions.addAll(mPendingAdditions);
    mAdditionsList.add(additions);
    mPendingAdditions.clear();
    Runnableadder =newRunnable() {
    @Override
    publicvoidrun() {
    for (ViewHolderholder :additions) {
    animateAddImpl(holder);
    }
    additions.clear();
    mAdditionsList.remove(additions);
    }
    };
    if (removalsPending ||movesPending ||changesPending) {
    longremoveDuration =removalsPending ?getRemoveDuration() :0;
    longmoveDuration =movesPending ?getMoveDuration() :0;
    longchangeDuration =changesPending ?getChangeDuration() :0;
    longtotalDelay =removeDuration +Math.max(moveDuration,changeDuration);
    Viewview =additions.get(0).itemView;
    ViewCompat.postOnAnimationDelayed(view,adder,totalDelay);
    }else {
    adder.run();
    }
    }
    }
    // Отвечает за анимацию исчезаия "полного удаления" элемента
    @Override
    publicbooleananimateRemove(finalViewHolderholder) {
    resetAnimation(holder);
    mPendingRemovals.add(holder);
    returntrue;
    }
    privatevoidanimateRemoveImpl(finalViewHolderholder) {
    finalViewview =holder.itemView;
    finalViewPropertyAnimatorCompatanimation =ViewCompat.animate(view);
    mRemoveAnimations.add(holder);
    animation.setDuration(getRemoveDuration())
    .alpha(0).setListener(newVpaListenerAdapter() {
    @Override
    publicvoidonAnimationStart(Viewview) {
    dispatchRemoveStarting(holder);
    }
    @Override
    publicvoidonAnimationEnd(Viewview) {
    animation.setListener(null);
    ViewCompat.setAlpha(view,1);
    dispatchRemoveFinished(holder);
    mRemoveAnimations.remove(holder);
    dispatchFinishedWhenDone();
    }
    }).start();
    }
    @Override
    publicbooleananimateAdd(finalViewHolderholder) {
    resetAnimation(holder);
    ViewCompat.setAlpha(holder.itemView,0);
    mPendingAdditions.add(holder);
    returntrue;
    }
    voidanimateAddImpl(finalViewHolderholder) {
    finalViewview =holder.itemView;
    finalViewPropertyAnimatorCompatanimation =ViewCompat.animate(view);
    mAddAnimations.add(holder);
    animation.alpha(1).setDuration(getAddDuration()).
    setListener(newVpaListenerAdapter() {
    @Override
    publicvoidonAnimationStart(Viewview) {
    dispatchAddStarting(holder);
    }
    @Override
    publicvoidonAnimationCancel(Viewview) {
    ViewCompat.setAlpha(view,1);
    }
    @Override
    publicvoidonAnimationEnd(Viewview) {
    animation.setListener(null);
    dispatchAddFinished(holder);
    mAddAnimations.remove(holder);
    dispatchFinishedWhenDone();
    }
    }).start();
    }
    // Отвечает за изменение высоты красного фона при свайпе, но не вызывается, если в списке всего один элемент
    @Override
    publicbooleananimateMove(finalViewHolderholder,intfromX,intfromY,
    inttoX,inttoY) {
    finalViewview =holder.itemView;
    fromX +=ViewCompat.getTranslationX(holder.itemView);
    fromY +=ViewCompat.getTranslationY(holder.itemView);
    resetAnimation(holder);
    intdeltaX =toX -fromX;
    intdeltaY =toY -fromY;
    if (deltaX ==0 &&deltaY ==0) {
    dispatchMoveFinished(holder);
    returnfalse;
    }
    if (deltaX !=0) {
    ViewCompat.setTranslationX(view, -deltaX);
    }
    if (deltaY !=0) {
    ViewCompat.setTranslationY(view, -deltaY);
    }
    mPendingMoves.add(newMoveInfo(holder,fromX,fromY,toX,toY));
    returntrue;
    }
    voidanimateMoveImpl(finalViewHolderholder,intfromX,intfromY,inttoX,inttoY) {
    finalViewview =holder.itemView;
    finalintdeltaX =toX -fromX;
    finalintdeltaY =toY -fromY;
    if (deltaX !=0) {
    ViewCompat.animate(view).translationX(0);
    }
    if (deltaY !=0) {
    ViewCompat.animate(view).translationY(0);
    }
    // TODO: make EndActions end listeners instead, since end actions aren't called when
    // vpas are canceled (and can't end them. why?)
    // need listener functionality in VPACompat for this. Ick.
    finalViewPropertyAnimatorCompatanimation =ViewCompat.animate(view);
    mMoveAnimations.add(holder);
    animation.setDuration(getMoveDuration()).setListener(newVpaListenerAdapter() {
    @Override
    publicvoidonAnimationStart(Viewview) {
    dispatchMoveStarting(holder);
    }
    @Override
    publicvoidonAnimationCancel(Viewview) {
    if (deltaX !=0) {
    ViewCompat.setTranslationX(view,0);
    }
    if (deltaY !=0) {
    ViewCompat.setTranslationY(view,0);
    }
    }
    @Override
    publicvoidonAnimationEnd(Viewview) {
    animation.setListener(null);
    dispatchMoveFinished(holder);
    mMoveAnimations.remove(holder);
    dispatchFinishedWhenDone();
    }
    }).start();
    }
    /**
    * В проекте TennoSushi Отвечает за анимацию "выдвижения" кнопки Undo (и, возможно, за что-то еще)
    * @param oldHolder Элемент списка, который подвергся изменению
    * @param newHolder Элемент списка, который получился из-за произошедших изменений
    * @param fromX Левый край oldHolder
    * @param fromY Вверхий край oldHolder
    * @param toX Левый край newHolder
    * @param toY Вверхий край newHolder
    * @return True, если позже ожидается (запрашивается) вызов {@link #runPendingAnimations()}, иначе - false
    */
    @Override
    publicbooleananimateChange(ViewHolderoldHolder,ViewHoldernewHolder,
    intfromX,intfromY,inttoX,inttoY) {
    if (oldHolder ==newHolder) {
    // Don't know how to run change animations when the same view holder is re-used.
    // run a move animation to handle position changes.
    returnanimateMove(oldHolder,fromX,fromY,toX,toY);
    }
    // by RareScrap
    ( (CardView)oldHolder.itemView.findViewById(R.id.root_card_view)).setCardElevation(0);
    ( (CardView)newHolder.itemView.findViewById(R.id.root_card_view)).setCardElevation(0);
    finalfloatprevTranslationX =ViewCompat.getTranslationX(oldHolder.itemView);
    finalfloatprevTranslationY =ViewCompat.getTranslationY(oldHolder.itemView);
    finalfloatprevAlpha =ViewCompat.getAlpha(oldHolder.itemView);
    resetAnimation(oldHolder);
    intdeltaX = (int) (toX -fromX -prevTranslationX);
    intdeltaY = (int) (toY -fromY -prevTranslationY);
    // recover prev translation state after ending animation
    ViewCompat.setTranslationX(oldHolder.itemView,prevTranslationX);
    ViewCompat.setTranslationY(oldHolder.itemView,prevTranslationY);
    ViewCompat.setAlpha(oldHolder.itemView,prevAlpha);
    if (newHolder !=null) {
    // carry over translation values
    resetAnimation(newHolder);
    ViewCompat.setTranslationX(newHolder.itemView, -deltaX);
    ViewCompat.setTranslationY(newHolder.itemView, -deltaY);
    ViewCompat.setAlpha(newHolder.itemView,0);
    }
    mPendingChanges.add(newChangeInfo(oldHolder,newHolder,fromX,fromY,toX,toY));
    returntrue;
    }
    voidanimateChangeImpl(finalChangeInfochangeInfo) {
    finalViewHolderholder =changeInfo.oldHolder;
    finalViewview =holder ==null ?null :holder.itemView;
    finalViewHoldernewHolder =changeInfo.newHolder;
    finalViewnewView =newHolder !=null ?newHolder.itemView :null;
    if (view !=null) {
    finalViewPropertyAnimatorCompatoldViewAnim =ViewCompat.animate(view).setDuration(
    getChangeDuration());
    mChangeAnimations.add(changeInfo.oldHolder);
    oldViewAnim.translationX(changeInfo.toX -changeInfo.fromX);
    oldViewAnim.translationY(changeInfo.toY -changeInfo.fromY);
    oldViewAnim.alpha(0).setListener(newVpaListenerAdapter() {
    @Override
    publicvoidonAnimationStart(Viewview) {
    dispatchChangeStarting(changeInfo.oldHolder,true);
    }
    @Override
    publicvoidonAnimationEnd(Viewview) {
    oldViewAnim.setListener(null);
    ViewCompat.setAlpha(view,1);
    ViewCompat.setTranslationX(view,0);
    ViewCompat.setTranslationY(view,0);
    dispatchChangeFinished(changeInfo.oldHolder,true);
    mChangeAnimations.remove(changeInfo.oldHolder);
    dispatchFinishedWhenDone();
    }
    }).start();
    }
    if (newView !=null) {
    finalViewPropertyAnimatorCompatnewViewAnimation =ViewCompat.animate(newView);
    mChangeAnimations.add(changeInfo.newHolder);
    newViewAnimation.translationX(0).translationY(0).setDuration(getChangeDuration()).
    alpha(1).setListener(newVpaListenerAdapter() {
    @Override
    publicvoidonAnimationStart(Viewview) {
    dispatchChangeStarting(changeInfo.newHolder,false);
    }
    @Override
    publicvoidonAnimationEnd(Viewview) {
    newViewAnimation.setListener(null);
    ViewCompat.setAlpha(newView,1);
    ViewCompat.setTranslationX(newView,0);
    ViewCompat.setTranslationY(newView,0);
    dispatchChangeFinished(changeInfo.newHolder,false);
    mChangeAnimations.remove(changeInfo.newHolder);
    dispatchFinishedWhenDone();
    }
    }).start();
    }
    }
    privatevoidendChangeAnimation(List<ChangeInfo>infoList,ViewHolderitem) {
    for (inti =infoList.size() -1;i >=0;i--) {
    ChangeInfochangeInfo =infoList.get(i);
    if (endChangeAnimationIfNecessary(changeInfo,item)) {
    if (changeInfo.oldHolder ==null &&changeInfo.newHolder ==null) {
    infoList.remove(changeInfo);
    }
    }
    }
    }
    privatevoidendChangeAnimationIfNecessary(ChangeInfochangeInfo) {
    if (changeInfo.oldHolder !=null) {
    endChangeAnimationIfNecessary(changeInfo,changeInfo.oldHolder);
    }
    if (changeInfo.newHolder !=null) {
    endChangeAnimationIfNecessary(changeInfo,changeInfo.newHolder);
    }
    }
    privatebooleanendChangeAnimationIfNecessary(ChangeInfochangeInfo,ViewHolderitem) {
    booleanoldItem =false;
    if (changeInfo.newHolder ==item) {
    changeInfo.newHolder =null;
    }elseif (changeInfo.oldHolder ==item) {
    changeInfo.oldHolder =null;
    oldItem =true;
    }else {
    returnfalse;
    }
    ViewCompat.setAlpha(item.itemView,1);
    ViewCompat.setTranslationX(item.itemView,0);
    ViewCompat.setTranslationY(item.itemView,0);
    dispatchChangeFinished(item,oldItem);
    returntrue;
    }
    @Override
    publicvoidendAnimation(ViewHolderitem) {
    finalViewview =item.itemView;
    // this will trigger end callback which should set properties to their target values.
    ViewCompat.animate(view).cancel();
    // TODO if some other animations are chained to end, how do we cancel them as well?
    for (inti =mPendingMoves.size() -1;i >=0;i--) {
    MoveInfomoveInfo =mPendingMoves.get(i);
    if (moveInfo.holder ==item) {
    ViewCompat.setTranslationY(view,0);
    ViewCompat.setTranslationX(view,0);
    dispatchMoveFinished(item);
    mPendingMoves.remove(i);
    }
    }
    endChangeAnimation(mPendingChanges,item);
    if (mPendingRemovals.remove(item)) {
    ViewCompat.setAlpha(view,1);
    dispatchRemoveFinished(item);
    }
    if (mPendingAdditions.remove(item)) {
    ViewCompat.setAlpha(view,1);
    dispatchAddFinished(item);
    }
    for (inti =mChangesList.size() -1;i >=0;i--) {
    ArrayList<ChangeInfo>changes =mChangesList.get(i);
    endChangeAnimation(changes,item);
    if (changes.isEmpty()) {
    mChangesList.remove(i);
    }
    }
    for (inti =mMovesList.size() -1;i >=0;i--) {
    ArrayList<MoveInfo>moves =mMovesList.get(i);
    for (intj =moves.size() -1;j >=0;j--) {
    MoveInfomoveInfo =moves.get(j);
    if (moveInfo.holder ==item) {
    ViewCompat.setTranslationY(view,0);
    ViewCompat.setTranslationX(view,0);
    dispatchMoveFinished(item);
    moves.remove(j);
    if (moves.isEmpty()) {
    mMovesList.remove(i);
    }
    break;
    }
    }
    }
    for (inti =mAdditionsList.size() -1;i >=0;i--) {
    ArrayList<ViewHolder>additions =mAdditionsList.get(i);
    if (additions.remove(item)) {
    ViewCompat.setAlpha(view,1);
    dispatchAddFinished(item);
    if (additions.isEmpty()) {
    mAdditionsList.remove(i);
    }
    }
    }
    // animations should be ended by the cancel above.
    //noinspection PointlessBooleanExpression,ConstantConditions
    if (mRemoveAnimations.remove(item) &&DEBUG) {
    thrownewIllegalStateException("after animation is cancelled, item should not be in "
    +"mRemoveAnimations list");
    }
    //noinspection PointlessBooleanExpression,ConstantConditions
    if (mAddAnimations.remove(item) &&DEBUG) {
    thrownewIllegalStateException("after animation is cancelled, item should not be in "
    +"mAddAnimations list");
    }
    //noinspection PointlessBooleanExpression,ConstantConditions
    if (mChangeAnimations.remove(item) &&DEBUG) {
    thrownewIllegalStateException("after animation is cancelled, item should not be in "
    +"mChangeAnimations list");
    }
    //noinspection PointlessBooleanExpression,ConstantConditions
    if (mMoveAnimations.remove(item) &&DEBUG) {
    thrownewIllegalStateException("after animation is cancelled, item should not be in "
    +"mMoveAnimations list");
    }
    dispatchFinishedWhenDone();
    }
    privatevoidresetAnimation(ViewHolderholder) {
    AnimatorCompatHelper.clearInterpolator(holder.itemView);
    endAnimation(holder);
    }
    @Override
    publicbooleanisRunning() {
    return (!mPendingAdditions.isEmpty() ||
    !mPendingChanges.isEmpty() ||
    !mPendingMoves.isEmpty() ||
    !mPendingRemovals.isEmpty() ||
    !mMoveAnimations.isEmpty() ||
    !mRemoveAnimations.isEmpty() ||
    !mAddAnimations.isEmpty() ||
    !mChangeAnimations.isEmpty() ||
    !mMovesList.isEmpty() ||
    !mAdditionsList.isEmpty() ||
    !mChangesList.isEmpty());
    }
    /**
    * Check the state of currently pending and running animations. If there are none
    * pending/running, call {@link #dispatchAnimationsFinished()} to notify any
    * listeners.
    */
    voiddispatchFinishedWhenDone() {
    if (!isRunning()) {
    dispatchAnimationsFinished();
    }
    }
    @Override
    publicvoidendAnimations() {
    intcount =mPendingMoves.size();
    for (inti =count -1;i >=0;i--) {
    MoveInfoitem =mPendingMoves.get(i);
    Viewview =item.holder.itemView;
    ViewCompat.setTranslationY(view,0);
    ViewCompat.setTranslationX(view,0);
    dispatchMoveFinished(item.holder);
    mPendingMoves.remove(i);
    }
    count =mPendingRemovals.size();
    for (inti =count -1;i >=0;i--) {
    ViewHolderitem =mPendingRemovals.get(i);
    dispatchRemoveFinished(item);
    mPendingRemovals.remove(i);
    }
    count =mPendingAdditions.size();
    for (inti =count -1;i >=0;i--) {
    ViewHolderitem =mPendingAdditions.get(i);
    Viewview =item.itemView;
    ViewCompat.setAlpha(view,1);
    dispatchAddFinished(item);
    mPendingAdditions.remove(i);
    }
    count =mPendingChanges.size();
    for (inti =count -1;i >=0;i--) {
    endChangeAnimationIfNecessary(mPendingChanges.get(i));
    }
    mPendingChanges.clear();
    if (!isRunning()) {
    return;
    }
    intlistCount =mMovesList.size();
    for (inti =listCount -1;i >=0;i--) {
    ArrayList<MoveInfo>moves =mMovesList.get(i);
    count =moves.size();
    for (intj =count -1;j >=0;j--) {
    MoveInfomoveInfo =moves.get(j);
    ViewHolderitem =moveInfo.holder;
    Viewview =item.itemView;
    ViewCompat.setTranslationY(view,0);
    ViewCompat.setTranslationX(view,0);
    dispatchMoveFinished(moveInfo.holder);
    moves.remove(j);
    if (moves.isEmpty()) {
    mMovesList.remove(moves);
    }
    }
    }
    listCount =mAdditionsList.size();
    for (inti =listCount -1;i >=0;i--) {
    ArrayList<ViewHolder>additions =mAdditionsList.get(i);
    count =additions.size();
    for (intj =count -1;j >=0;j--) {
    ViewHolderitem =additions.get(j);
    Viewview =item.itemView;
    ViewCompat.setAlpha(view,1);
    dispatchAddFinished(item);
    additions.remove(j);
    if (additions.isEmpty()) {
    mAdditionsList.remove(additions);
    }
    }
    }
    listCount =mChangesList.size();
    for (inti =listCount -1;i >=0;i--) {
    ArrayList<ChangeInfo>changes =mChangesList.get(i);
    count =changes.size();
    for (intj =count -1;j >=0;j--) {
    endChangeAnimationIfNecessary(changes.get(j));
    if (changes.isEmpty()) {
    mChangesList.remove(changes);
    }
    }
    }
    cancelAll(mRemoveAnimations);
    cancelAll(mMoveAnimations);
    cancelAll(mAddAnimations);
    cancelAll(mChangeAnimations);
    dispatchAnimationsFinished();
    }
    voidcancelAll(List<ViewHolder>viewHolders) {
    for (inti =viewHolders.size() -1;i >=0;i--) {
    ViewCompat.animate(viewHolders.get(i).itemView).cancel();
    }
    }
    /**
    * {@inheritDoc}
    * <p>
    * If the payload list is not empty, DefaultItemAnimator returns <code>true</code>.
    * When this is the case:
    * <ul>
    * <li>If you override {@link #animateChange(ViewHolder, ViewHolder, int, int, int, int)}, both
    * ViewHolder arguments will be the same instance.
    * </li>
    * <li>
    * If you are not overriding {@link #animateChange(ViewHolder, ViewHolder, int, int, int, int)},
    * then DefaultItemAnimator will call {@link #animateMove(ViewHolder, int, int, int, int)} and
    * run a move animation instead.
    * </li>
    * </ul>
    */
    @Override
    publicbooleancanReuseUpdatedViewHolder(@NonNullViewHolderviewHolder,
    @NonNullList<Object>payloads) {
    return !payloads.isEmpty() ||super.canReuseUpdatedViewHolder(viewHolder,payloads);
    }
    privatestaticclassVpaListenerAdapterimplementsViewPropertyAnimatorListener {
    VpaListenerAdapter() {
    }
    @Override
    publicvoidonAnimationStart(Viewview) {}
    @Override
    publicvoidonAnimationEnd(Viewview) {}
    @Override
    publicvoidonAnimationCancel(Viewview) {}
    }
    }
    Sign up for freeto join this conversation on GitHub. Already have an account?Sign in to comment

    [8]ページ先頭

    ©2009-2025 Movatter.jp