1 /* 2 * Copyright 2018 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package androidx.recyclerview.widget; 18 19 import androidx.annotation.NonNull; 20 21 import java.util.ArrayList; 22 import java.util.List; 23 import java.util.concurrent.CountDownLatch; 24 import java.util.concurrent.TimeUnit; 25 26 public class LoggingItemAnimator extends DefaultItemAnimator { 27 28 final ArrayList<RecyclerView.ViewHolder> mAddVHs = new ArrayList<RecyclerView.ViewHolder>(); 29 30 final ArrayList<RecyclerView.ViewHolder> mRemoveVHs = new ArrayList<RecyclerView.ViewHolder>(); 31 32 final ArrayList<RecyclerView.ViewHolder> mMoveVHs = new ArrayList<RecyclerView.ViewHolder>(); 33 34 final ArrayList<RecyclerView.ViewHolder> mChangeOldVHs = new ArrayList<RecyclerView.ViewHolder>(); 35 36 final ArrayList<RecyclerView.ViewHolder> mChangeNewVHs = new ArrayList<RecyclerView.ViewHolder>(); 37 38 List<BaseRecyclerViewAnimationsTest.AnimateAppearance> mAnimateAppearanceList = new ArrayList<>(); 39 List<BaseRecyclerViewAnimationsTest.AnimateDisappearance> mAnimateDisappearanceList = new ArrayList<>(); 40 List<BaseRecyclerViewAnimationsTest.AnimatePersistence> mAnimatePersistenceList = new ArrayList<>(); 41 List<BaseRecyclerViewAnimationsTest.AnimateChange> mAnimateChangeList = new ArrayList<>(); 42 43 CountDownLatch mWaitForPendingAnimations; 44 45 public boolean contains(RecyclerView.ViewHolder viewHolder, 46 List<? extends BaseRecyclerViewAnimationsTest.AnimateLogBase> list) { 47 for (BaseRecyclerViewAnimationsTest.AnimateLogBase log : list) { 48 if (log.viewHolder == viewHolder) { 49 return true; 50 } 51 if (log instanceof BaseRecyclerViewAnimationsTest.AnimateChange) { 52 if (((BaseRecyclerViewAnimationsTest.AnimateChange) log).newHolder == viewHolder) { 53 return true; 54 } 55 } 56 } 57 return false; 58 } 59 60 @NonNull 61 @Override 62 public ItemHolderInfo recordPreLayoutInformation(@NonNull RecyclerView.State state, 63 @NonNull RecyclerView.ViewHolder viewHolder, 64 @AdapterChanges int changeFlags, @NonNull List<Object> payloads) { 65 BaseRecyclerViewAnimationsTest.LoggingInfo 66 loggingInfo = new BaseRecyclerViewAnimationsTest.LoggingInfo(viewHolder, changeFlags, payloads); 67 return loggingInfo; 68 } 69 70 @NonNull 71 @Override 72 public ItemHolderInfo recordPostLayoutInformation(@NonNull RecyclerView.State state, 73 @NonNull RecyclerView.ViewHolder viewHolder) { 74 BaseRecyclerViewAnimationsTest.LoggingInfo 75 loggingInfo = new BaseRecyclerViewAnimationsTest.LoggingInfo(viewHolder, 0, null); 76 return loggingInfo; 77 } 78 79 80 @Override 81 public boolean animateDisappearance(@NonNull RecyclerView.ViewHolder viewHolder, 82 @NonNull ItemHolderInfo preLayoutInfo, ItemHolderInfo postLayoutInfo) { 83 mAnimateDisappearanceList 84 .add(new BaseRecyclerViewAnimationsTest.AnimateDisappearance(viewHolder, 85 (BaseRecyclerViewAnimationsTest.LoggingInfo) preLayoutInfo, 86 (BaseRecyclerViewAnimationsTest.LoggingInfo) postLayoutInfo)); 87 return super.animateDisappearance(viewHolder, preLayoutInfo, postLayoutInfo); 88 } 89 90 @Override 91 public boolean animateAppearance(@NonNull RecyclerView.ViewHolder viewHolder, 92 ItemHolderInfo preLayoutInfo, 93 @NonNull ItemHolderInfo postLayoutInfo) { 94 mAnimateAppearanceList 95 .add(new BaseRecyclerViewAnimationsTest.AnimateAppearance(viewHolder, 96 (BaseRecyclerViewAnimationsTest.LoggingInfo) preLayoutInfo, 97 (BaseRecyclerViewAnimationsTest.LoggingInfo) postLayoutInfo)); 98 return super.animateAppearance(viewHolder, preLayoutInfo, postLayoutInfo); 99 } 100 101 @Override 102 public boolean animatePersistence(@NonNull RecyclerView.ViewHolder viewHolder, 103 @NonNull ItemHolderInfo preInfo, 104 @NonNull ItemHolderInfo postInfo) { 105 mAnimatePersistenceList 106 .add(new BaseRecyclerViewAnimationsTest.AnimatePersistence(viewHolder, 107 (BaseRecyclerViewAnimationsTest.LoggingInfo) preInfo, 108 (BaseRecyclerViewAnimationsTest.LoggingInfo) postInfo)); 109 return super.animatePersistence(viewHolder, preInfo, postInfo); 110 } 111 112 @Override 113 public boolean animateChange(@NonNull RecyclerView.ViewHolder oldHolder, 114 @NonNull RecyclerView.ViewHolder newHolder, @NonNull ItemHolderInfo preInfo, 115 @NonNull ItemHolderInfo postInfo) { 116 mAnimateChangeList 117 .add(new BaseRecyclerViewAnimationsTest.AnimateChange(oldHolder, newHolder, 118 (BaseRecyclerViewAnimationsTest.LoggingInfo) preInfo, 119 (BaseRecyclerViewAnimationsTest.LoggingInfo) postInfo)); 120 return super.animateChange(oldHolder, newHolder, preInfo, postInfo); 121 } 122 123 @Override 124 public void runPendingAnimations() { 125 if (mWaitForPendingAnimations != null) { 126 mWaitForPendingAnimations.countDown(); 127 } 128 super.runPendingAnimations(); 129 } 130 131 public void expectRunPendingAnimationsCall(int count) { 132 mWaitForPendingAnimations = new CountDownLatch(count); 133 } 134 135 public void waitForPendingAnimationsCall(int seconds) throws InterruptedException { 136 mWaitForPendingAnimations.await(seconds, TimeUnit.SECONDS); 137 } 138 139 @Override 140 public boolean animateAdd(RecyclerView.ViewHolder holder) { 141 mAddVHs.add(holder); 142 return super.animateAdd(holder); 143 } 144 145 @Override 146 public boolean animateRemove(RecyclerView.ViewHolder holder) { 147 mRemoveVHs.add(holder); 148 return super.animateRemove(holder); 149 } 150 151 @Override 152 public boolean animateMove(RecyclerView.ViewHolder holder, int fromX, int fromY, 153 int toX, int toY) { 154 mMoveVHs.add(holder); 155 return super.animateMove(holder, fromX, fromY, toX, toY); 156 } 157 158 @Override 159 public boolean animateChange(RecyclerView.ViewHolder oldHolder, 160 RecyclerView.ViewHolder newHolder, int fromX, int fromY, int toX, int toY) { 161 if (oldHolder != null) { 162 mChangeOldVHs.add(oldHolder); 163 } 164 if (newHolder != null) { 165 mChangeNewVHs.add(newHolder); 166 } 167 return super.animateChange(oldHolder, newHolder, fromX, fromY, toX, toY); 168 } 169 170 public void reset() { 171 mAddVHs.clear(); 172 mRemoveVHs.clear(); 173 mMoveVHs.clear(); 174 mChangeOldVHs.clear(); 175 mChangeNewVHs.clear(); 176 mAnimateChangeList.clear(); 177 mAnimatePersistenceList.clear(); 178 mAnimateAppearanceList.clear(); 179 mAnimateDisappearanceList.clear(); 180 } 181 }