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 org.jspecify.annotations.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 contains(RecyclerView.ViewHolder viewHolder, List<? extends BaseRecyclerViewAnimationsTest.AnimateLogBase> list)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 @Override recordPreLayoutInformation(RecyclerView.@onNull State state, RecyclerView.@NonNull ViewHolder viewHolder, @AdapterChanges int changeFlags, @NonNull List<Object> payloads)61 public @NonNull ItemHolderInfo recordPreLayoutInformation(RecyclerView.@NonNull State state, 62 RecyclerView.@NonNull ViewHolder viewHolder, 63 @AdapterChanges int changeFlags, @NonNull List<Object> payloads) { 64 BaseRecyclerViewAnimationsTest.LoggingInfo 65 loggingInfo = new BaseRecyclerViewAnimationsTest.LoggingInfo(viewHolder, changeFlags, payloads); 66 return loggingInfo; 67 } 68 69 @Override recordPostLayoutInformation(RecyclerView.@onNull State state, RecyclerView.@NonNull ViewHolder viewHolder)70 public @NonNull ItemHolderInfo recordPostLayoutInformation(RecyclerView.@NonNull State state, 71 RecyclerView.@NonNull ViewHolder viewHolder) { 72 BaseRecyclerViewAnimationsTest.LoggingInfo 73 loggingInfo = new BaseRecyclerViewAnimationsTest.LoggingInfo(viewHolder, 0, null); 74 return loggingInfo; 75 } 76 77 78 @Override animateDisappearance(RecyclerView.@onNull ViewHolder viewHolder, @NonNull ItemHolderInfo preLayoutInfo, ItemHolderInfo postLayoutInfo)79 public boolean animateDisappearance(RecyclerView.@NonNull ViewHolder viewHolder, 80 @NonNull ItemHolderInfo preLayoutInfo, ItemHolderInfo postLayoutInfo) { 81 mAnimateDisappearanceList 82 .add(new BaseRecyclerViewAnimationsTest.AnimateDisappearance(viewHolder, 83 (BaseRecyclerViewAnimationsTest.LoggingInfo) preLayoutInfo, 84 (BaseRecyclerViewAnimationsTest.LoggingInfo) postLayoutInfo)); 85 return super.animateDisappearance(viewHolder, preLayoutInfo, postLayoutInfo); 86 } 87 88 @Override animateAppearance(RecyclerView.@onNull ViewHolder viewHolder, ItemHolderInfo preLayoutInfo, @NonNull ItemHolderInfo postLayoutInfo)89 public boolean animateAppearance(RecyclerView.@NonNull ViewHolder viewHolder, 90 ItemHolderInfo preLayoutInfo, 91 @NonNull ItemHolderInfo postLayoutInfo) { 92 mAnimateAppearanceList 93 .add(new BaseRecyclerViewAnimationsTest.AnimateAppearance(viewHolder, 94 (BaseRecyclerViewAnimationsTest.LoggingInfo) preLayoutInfo, 95 (BaseRecyclerViewAnimationsTest.LoggingInfo) postLayoutInfo)); 96 return super.animateAppearance(viewHolder, preLayoutInfo, postLayoutInfo); 97 } 98 99 @Override animatePersistence(RecyclerView.@onNull ViewHolder viewHolder, @NonNull ItemHolderInfo preLayoutInfo, @NonNull ItemHolderInfo postLayoutInfo)100 public boolean animatePersistence(RecyclerView.@NonNull ViewHolder viewHolder, 101 @NonNull ItemHolderInfo preLayoutInfo, 102 @NonNull ItemHolderInfo postLayoutInfo) { 103 mAnimatePersistenceList 104 .add(new BaseRecyclerViewAnimationsTest.AnimatePersistence(viewHolder, 105 (BaseRecyclerViewAnimationsTest.LoggingInfo) preLayoutInfo, 106 (BaseRecyclerViewAnimationsTest.LoggingInfo) postLayoutInfo)); 107 return super.animatePersistence(viewHolder, preLayoutInfo, postLayoutInfo); 108 } 109 110 @Override animateChange(RecyclerView.@onNull ViewHolder oldHolder, RecyclerView.@NonNull ViewHolder newHolder, @NonNull ItemHolderInfo preLayoutInfo, @NonNull ItemHolderInfo postLayoutInfo)111 public boolean animateChange(RecyclerView.@NonNull ViewHolder oldHolder, 112 RecyclerView.@NonNull ViewHolder newHolder, @NonNull ItemHolderInfo preLayoutInfo, 113 @NonNull ItemHolderInfo postLayoutInfo) { 114 mAnimateChangeList 115 .add(new BaseRecyclerViewAnimationsTest.AnimateChange(oldHolder, newHolder, 116 (BaseRecyclerViewAnimationsTest.LoggingInfo) preLayoutInfo, 117 (BaseRecyclerViewAnimationsTest.LoggingInfo) postLayoutInfo)); 118 return super.animateChange(oldHolder, newHolder, preLayoutInfo, postLayoutInfo); 119 } 120 121 @Override runPendingAnimations()122 public void runPendingAnimations() { 123 if (mWaitForPendingAnimations != null) { 124 mWaitForPendingAnimations.countDown(); 125 } 126 super.runPendingAnimations(); 127 } 128 expectRunPendingAnimationsCall(int count)129 public void expectRunPendingAnimationsCall(int count) { 130 mWaitForPendingAnimations = new CountDownLatch(count); 131 } 132 waitForPendingAnimationsCall(int seconds)133 public void waitForPendingAnimationsCall(int seconds) throws InterruptedException { 134 mWaitForPendingAnimations.await(seconds, TimeUnit.SECONDS); 135 } 136 137 @Override animateAdd(RecyclerView.@onNull ViewHolder holder)138 public boolean animateAdd(RecyclerView.@NonNull ViewHolder holder) { 139 mAddVHs.add(holder); 140 return super.animateAdd(holder); 141 } 142 143 @Override animateRemove(RecyclerView.@onNull ViewHolder holder)144 public boolean animateRemove(RecyclerView.@NonNull ViewHolder holder) { 145 mRemoveVHs.add(holder); 146 return super.animateRemove(holder); 147 } 148 149 @Override animateMove(RecyclerView.@onNull ViewHolder holder, int fromX, int fromY, int toX, int toY)150 public boolean animateMove(RecyclerView.@NonNull ViewHolder holder, int fromX, int fromY, 151 int toX, int toY) { 152 mMoveVHs.add(holder); 153 return super.animateMove(holder, fromX, fromY, toX, toY); 154 } 155 156 @Override animateChange(RecyclerView.@onNull ViewHolder oldHolder, RecyclerView.ViewHolder newHolder, int fromLeft, int fromTop, int toLeft, int toTop)157 public boolean animateChange(RecyclerView.@NonNull ViewHolder oldHolder, 158 RecyclerView.ViewHolder newHolder, int fromLeft, int fromTop, int toLeft, int toTop) { 159 if (oldHolder != null) { 160 mChangeOldVHs.add(oldHolder); 161 } 162 if (newHolder != null) { 163 mChangeNewVHs.add(newHolder); 164 } 165 return super.animateChange(oldHolder, newHolder, fromLeft, fromTop, toLeft, toTop); 166 } 167 reset()168 public void reset() { 169 mAddVHs.clear(); 170 mRemoveVHs.clear(); 171 mMoveVHs.clear(); 172 mChangeOldVHs.clear(); 173 mChangeNewVHs.clear(); 174 mAnimateChangeList.clear(); 175 mAnimatePersistenceList.clear(); 176 mAnimateAppearanceList.clear(); 177 mAnimateDisappearanceList.clear(); 178 } 179 }