RecyclerViewAnimationsTest.java revision 11b7cfea15306c0d6e4ed7da09f7698df01695df
1d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase/* 2d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * Copyright (C) 2014 The Android Open Source Project 3d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * 4d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * Licensed under the Apache License, Version 2.0 (the "License"); 5d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * you may not use this file except in compliance with the License. 6d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * You may obtain a copy of the License at 7d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * 8d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * http://www.apache.org/licenses/LICENSE-2.0 9d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * 10d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * Unless required by applicable law or agreed to in writing, software 11d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * distributed under the License is distributed on an "AS IS" BASIS, 12d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * See the License for the specific language governing permissions and 14d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase * limitations under the License. 15d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase */ 16d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase 17d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haasepackage android.support.v7.widget; 18d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase 19b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyarimport android.content.Context; 20888c70abaa77e15458c366b8d27835d176dcc546Yigit Boyarimport android.graphics.Canvas; 21b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyarimport android.util.AttributeSet; 22b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyarimport android.util.Log; 23b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyarimport android.view.View; 24b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar 2511b7cfea15306c0d6e4ed7da09f7698df01695dfYigit Boyarimport java.util.ArrayList; 2611b7cfea15306c0d6e4ed7da09f7698df01695dfYigit Boyarimport java.util.HashSet; 2711b7cfea15306c0d6e4ed7da09f7698df01695dfYigit Boyarimport java.util.List; 2811b7cfea15306c0d6e4ed7da09f7698df01695dfYigit Boyarimport java.util.Map; 2911b7cfea15306c0d6e4ed7da09f7698df01695dfYigit Boyarimport java.util.Set; 30888c70abaa77e15458c366b8d27835d176dcc546Yigit Boyarimport java.util.concurrent.CountDownLatch; 31d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haaseimport java.util.concurrent.TimeUnit; 32d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase 33d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haasepublic class RecyclerViewAnimationsTest extends BaseRecyclerViewInstrumentationTest { 34d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase 35b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar private static final boolean DEBUG = false; 36b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar 37b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar private static final String TAG = "RecyclerViewAnimationsTest"; 38b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar 39b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar Throwable mainThreadException; 40b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar 41b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar AnimationLayoutManager mLayoutManager; 42b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar 43b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar TestAdapter mTestAdapter; 44b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar 45b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar public RecyclerViewAnimationsTest() { 46b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar super(DEBUG); 47b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar } 48b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar 49b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar @Override 50b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar protected void setUp() throws Exception { 51b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar super.setUp(); 52b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar } 53b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar 54b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar void checkForMainThreadException() throws Throwable { 55b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar if (mainThreadException != null) { 56b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar throw mainThreadException; 57b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar } 58b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar } 59b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar 60b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar RecyclerView setupBasic(int itemCount) throws Throwable { 61b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar return setupBasic(itemCount, 0, itemCount); 62b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar } 63b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar 64b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar RecyclerView setupBasic(int itemCount, int firstLayoutStartIndex, int firstLayoutItemCount) 65b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar throws Throwable { 6611b7cfea15306c0d6e4ed7da09f7698df01695dfYigit Boyar return setupBasic(itemCount, firstLayoutStartIndex, firstLayoutItemCount, null); 6711b7cfea15306c0d6e4ed7da09f7698df01695dfYigit Boyar } 6811b7cfea15306c0d6e4ed7da09f7698df01695dfYigit Boyar 6911b7cfea15306c0d6e4ed7da09f7698df01695dfYigit Boyar RecyclerView setupBasic(int itemCount, int firstLayoutStartIndex, int firstLayoutItemCount, 7011b7cfea15306c0d6e4ed7da09f7698df01695dfYigit Boyar TestAdapter testAdapter) 7111b7cfea15306c0d6e4ed7da09f7698df01695dfYigit Boyar throws Throwable { 72888c70abaa77e15458c366b8d27835d176dcc546Yigit Boyar final TestRecyclerView recyclerView = new TestRecyclerView(getActivity()); 73b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar recyclerView.setHasFixedSize(true); 7411b7cfea15306c0d6e4ed7da09f7698df01695dfYigit Boyar if (testAdapter == null) { 7511b7cfea15306c0d6e4ed7da09f7698df01695dfYigit Boyar mTestAdapter = new TestAdapter(itemCount); 7611b7cfea15306c0d6e4ed7da09f7698df01695dfYigit Boyar } else { 7711b7cfea15306c0d6e4ed7da09f7698df01695dfYigit Boyar mTestAdapter = testAdapter; 7811b7cfea15306c0d6e4ed7da09f7698df01695dfYigit Boyar } 79b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar recyclerView.setAdapter(mTestAdapter); 80b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar mLayoutManager = new AnimationLayoutManager(); 81b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar recyclerView.setLayoutManager(mLayoutManager); 82b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar mLayoutManager.mOnLayoutCallbacks.mLayoutMin = firstLayoutStartIndex; 83b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar mLayoutManager.mOnLayoutCallbacks.mLayoutItemCount = firstLayoutItemCount; 84b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar 85b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar mLayoutManager.expectLayouts(1); 86888c70abaa77e15458c366b8d27835d176dcc546Yigit Boyar recyclerView.expectDraw(1); 87b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar setRecyclerView(recyclerView); 88b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar mLayoutManager.waitForLayout(2); 89888c70abaa77e15458c366b8d27835d176dcc546Yigit Boyar recyclerView.waitForDraw(1); 90888c70abaa77e15458c366b8d27835d176dcc546Yigit Boyar mLayoutManager.mOnLayoutCallbacks.reset(); 91b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar return recyclerView; 92b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar } 93b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar 9411b7cfea15306c0d6e4ed7da09f7698df01695dfYigit Boyar public void getItemForDeletedViewTest() throws Throwable { 9511b7cfea15306c0d6e4ed7da09f7698df01695dfYigit Boyar testGetItemForDeletedView(false); 9611b7cfea15306c0d6e4ed7da09f7698df01695dfYigit Boyar testGetItemForDeletedView(true); 9711b7cfea15306c0d6e4ed7da09f7698df01695dfYigit Boyar } 9811b7cfea15306c0d6e4ed7da09f7698df01695dfYigit Boyar 9911b7cfea15306c0d6e4ed7da09f7698df01695dfYigit Boyar public void testGetItemForDeletedView(boolean stableIds) throws Throwable { 10011b7cfea15306c0d6e4ed7da09f7698df01695dfYigit Boyar final Set<Integer> itemViewTypeQueries = new HashSet<Integer>(); 10111b7cfea15306c0d6e4ed7da09f7698df01695dfYigit Boyar final Set<Integer> itemIdQueries = new HashSet<Integer>(); 10211b7cfea15306c0d6e4ed7da09f7698df01695dfYigit Boyar TestAdapter adapter = new TestAdapter(10) { 10311b7cfea15306c0d6e4ed7da09f7698df01695dfYigit Boyar @Override 10411b7cfea15306c0d6e4ed7da09f7698df01695dfYigit Boyar public int getItemViewType(int position) { 10511b7cfea15306c0d6e4ed7da09f7698df01695dfYigit Boyar itemViewTypeQueries.add(position); 10611b7cfea15306c0d6e4ed7da09f7698df01695dfYigit Boyar return super.getItemViewType(position); 10711b7cfea15306c0d6e4ed7da09f7698df01695dfYigit Boyar } 10811b7cfea15306c0d6e4ed7da09f7698df01695dfYigit Boyar 10911b7cfea15306c0d6e4ed7da09f7698df01695dfYigit Boyar @Override 11011b7cfea15306c0d6e4ed7da09f7698df01695dfYigit Boyar public long getItemId(int position) { 11111b7cfea15306c0d6e4ed7da09f7698df01695dfYigit Boyar itemIdQueries.add(position); 11211b7cfea15306c0d6e4ed7da09f7698df01695dfYigit Boyar return mItems.get(position).mId; 11311b7cfea15306c0d6e4ed7da09f7698df01695dfYigit Boyar } 11411b7cfea15306c0d6e4ed7da09f7698df01695dfYigit Boyar }; 11511b7cfea15306c0d6e4ed7da09f7698df01695dfYigit Boyar adapter.setHasStableIds(stableIds); 11611b7cfea15306c0d6e4ed7da09f7698df01695dfYigit Boyar setupBasic(10, 0, 10, adapter); 11711b7cfea15306c0d6e4ed7da09f7698df01695dfYigit Boyar assertEquals("getItemViewType for all items should be called", 10, 11811b7cfea15306c0d6e4ed7da09f7698df01695dfYigit Boyar itemViewTypeQueries.size()); 11911b7cfea15306c0d6e4ed7da09f7698df01695dfYigit Boyar if (adapter.hasStableIds()) { 12011b7cfea15306c0d6e4ed7da09f7698df01695dfYigit Boyar assertEquals("getItemId should be called when adapter has stable ids", 10, 12111b7cfea15306c0d6e4ed7da09f7698df01695dfYigit Boyar itemIdQueries.size()); 12211b7cfea15306c0d6e4ed7da09f7698df01695dfYigit Boyar } else { 12311b7cfea15306c0d6e4ed7da09f7698df01695dfYigit Boyar assertEquals("getItemId should not be called when adapter does not have stable ids", 0, 12411b7cfea15306c0d6e4ed7da09f7698df01695dfYigit Boyar itemIdQueries.size()); 12511b7cfea15306c0d6e4ed7da09f7698df01695dfYigit Boyar } 12611b7cfea15306c0d6e4ed7da09f7698df01695dfYigit Boyar itemViewTypeQueries.clear(); 12711b7cfea15306c0d6e4ed7da09f7698df01695dfYigit Boyar itemIdQueries.clear(); 12811b7cfea15306c0d6e4ed7da09f7698df01695dfYigit Boyar mLayoutManager.expectLayouts(2); 12911b7cfea15306c0d6e4ed7da09f7698df01695dfYigit Boyar // delete last two 13011b7cfea15306c0d6e4ed7da09f7698df01695dfYigit Boyar final int deleteStart = 8; 13111b7cfea15306c0d6e4ed7da09f7698df01695dfYigit Boyar final int deleteCount = adapter.getItemCount() - deleteStart; 13211b7cfea15306c0d6e4ed7da09f7698df01695dfYigit Boyar adapter.deleteAndNotify(deleteStart, deleteCount); 13311b7cfea15306c0d6e4ed7da09f7698df01695dfYigit Boyar mLayoutManager.waitForLayout(2); 13411b7cfea15306c0d6e4ed7da09f7698df01695dfYigit Boyar for (int i = 0; i < deleteStart; i++) { 13511b7cfea15306c0d6e4ed7da09f7698df01695dfYigit Boyar assertTrue("getItemViewType for existing item " + i + " should be called", 13611b7cfea15306c0d6e4ed7da09f7698df01695dfYigit Boyar itemViewTypeQueries.contains(i)); 13711b7cfea15306c0d6e4ed7da09f7698df01695dfYigit Boyar if (adapter.hasStableIds()) { 13811b7cfea15306c0d6e4ed7da09f7698df01695dfYigit Boyar assertTrue("getItemId for existing item " + i 13911b7cfea15306c0d6e4ed7da09f7698df01695dfYigit Boyar + " should be called when adapter has stable ids", 14011b7cfea15306c0d6e4ed7da09f7698df01695dfYigit Boyar itemIdQueries.contains(i)); 14111b7cfea15306c0d6e4ed7da09f7698df01695dfYigit Boyar } 14211b7cfea15306c0d6e4ed7da09f7698df01695dfYigit Boyar } 14311b7cfea15306c0d6e4ed7da09f7698df01695dfYigit Boyar for (int i = deleteStart; i < deleteStart + deleteCount; i++) { 14411b7cfea15306c0d6e4ed7da09f7698df01695dfYigit Boyar assertFalse("getItemViewType for deleted item " + i + " SHOULD NOT be called", 14511b7cfea15306c0d6e4ed7da09f7698df01695dfYigit Boyar itemViewTypeQueries.contains(i)); 14611b7cfea15306c0d6e4ed7da09f7698df01695dfYigit Boyar if (adapter.hasStableIds()) { 14711b7cfea15306c0d6e4ed7da09f7698df01695dfYigit Boyar assertTrue("getItemId for deleted item " + i + " SHOULD NOT be called", 14811b7cfea15306c0d6e4ed7da09f7698df01695dfYigit Boyar itemIdQueries.contains(i)); 14911b7cfea15306c0d6e4ed7da09f7698df01695dfYigit Boyar } 15011b7cfea15306c0d6e4ed7da09f7698df01695dfYigit Boyar } 15111b7cfea15306c0d6e4ed7da09f7698df01695dfYigit Boyar } 15211b7cfea15306c0d6e4ed7da09f7698df01695dfYigit Boyar 153b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar public void testAddInvisibleAndVisible() throws Throwable { 154b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar setupBasic(10, 1, 7); 155b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar mLayoutManager.expectLayouts(2); 156b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar mLayoutManager.mOnLayoutCallbacks.setExpectedItemCounts(10, 12); 157b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar mTestAdapter.addAndNotify(0, 1);// add a new item 0 // invisible 158b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar mTestAdapter.addAndNotify(7, 1);// add a new item after 5th (old 5, new 6) 159b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar mLayoutManager.waitForLayout(2); 160b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar } 161b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar 162b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar public void testAddInvisible() throws Throwable { 163b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar setupBasic(10, 1, 7); 164b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar mLayoutManager.expectLayouts(1); 165b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar mLayoutManager.mOnLayoutCallbacks.setExpectedItemCounts(10, 12); 166b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar mTestAdapter.addAndNotify(0, 1);// add a new item 0 167b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar mTestAdapter.addAndNotify(8, 1);// add a new item after 6th (old 6, new 7) 168b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar mLayoutManager.waitForLayout(2); 169b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar } 170b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar 171b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar public void testBasicAdd() throws Throwable { 172b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar setupBasic(10); 173b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar mLayoutManager.expectLayouts(2); 174b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar setExpectedItemCounts(10, 13); 175b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar mTestAdapter.addAndNotify(2, 3); 176b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar mLayoutManager.waitForLayout(2); 177b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar } 178b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar 179888c70abaa77e15458c366b8d27835d176dcc546Yigit Boyar public TestRecyclerView getTestRecyclerView() { 180888c70abaa77e15458c366b8d27835d176dcc546Yigit Boyar return (TestRecyclerView) mRecyclerView; 181888c70abaa77e15458c366b8d27835d176dcc546Yigit Boyar } 182888c70abaa77e15458c366b8d27835d176dcc546Yigit Boyar 183888c70abaa77e15458c366b8d27835d176dcc546Yigit Boyar public void testRemoveScrapInvalidate() throws Throwable { 184888c70abaa77e15458c366b8d27835d176dcc546Yigit Boyar setupBasic(10); 185888c70abaa77e15458c366b8d27835d176dcc546Yigit Boyar TestRecyclerView testRecyclerView = getTestRecyclerView(); 186888c70abaa77e15458c366b8d27835d176dcc546Yigit Boyar mLayoutManager.expectLayouts(1); 187888c70abaa77e15458c366b8d27835d176dcc546Yigit Boyar testRecyclerView.expectDraw(1); 188888c70abaa77e15458c366b8d27835d176dcc546Yigit Boyar runTestOnUiThread(new Runnable() { 189888c70abaa77e15458c366b8d27835d176dcc546Yigit Boyar @Override 190888c70abaa77e15458c366b8d27835d176dcc546Yigit Boyar public void run() { 191888c70abaa77e15458c366b8d27835d176dcc546Yigit Boyar mTestAdapter.mItems.clear(); 192888c70abaa77e15458c366b8d27835d176dcc546Yigit Boyar mTestAdapter.notifyDataSetChanged(); 193888c70abaa77e15458c366b8d27835d176dcc546Yigit Boyar } 194888c70abaa77e15458c366b8d27835d176dcc546Yigit Boyar }); 195888c70abaa77e15458c366b8d27835d176dcc546Yigit Boyar mLayoutManager.waitForLayout(2); 196888c70abaa77e15458c366b8d27835d176dcc546Yigit Boyar testRecyclerView.waitForDraw(2); 197888c70abaa77e15458c366b8d27835d176dcc546Yigit Boyar } 198888c70abaa77e15458c366b8d27835d176dcc546Yigit Boyar 199b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar public void testDeleteVisibleAndInvisible() throws Throwable { 200b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar setupBasic(11, 3, 5); //layout items 3 4 5 6 7 201b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar mLayoutManager.expectLayouts(2); 202b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar setLayoutRange(3, 6); //layout previously invisible child 10 from end of the list 203b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar setExpectedItemCounts(9, 8); 204b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar mTestAdapter.deleteAndNotify(new int[]{4, 1}, new int[]{7, 2});// delete items 4, 8, 9 205b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar mLayoutManager.waitForLayout(2); 206b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar } 207b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar 208b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar private void setLayoutRange(int start, int count) { 209b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar mLayoutManager.mOnLayoutCallbacks.mLayoutMin = start; 210b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar mLayoutManager.mOnLayoutCallbacks.mLayoutItemCount = count; 211b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar } 212b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar 213b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar private void setExpectedItemCounts(int preLayout, int postLayout) { 214b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar mLayoutManager.mOnLayoutCallbacks.setExpectedItemCounts(preLayout, postLayout); 215b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar } 216b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar 217b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar public void testDeleteInvisible() throws Throwable { 218b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar setupBasic(10, 1, 7); 219b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar mLayoutManager.expectLayouts(1); 220b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar mLayoutManager.mOnLayoutCallbacks.setExpectedItemCounts(8, 8); 221b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar mTestAdapter.deleteAndNotify(0, 1);// delete item id 0 222b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar mTestAdapter.deleteAndNotify(7, 1);// delete item id 8 223b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar mLayoutManager.waitForLayout(2); 224b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar } 225b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar 226b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar public void testBasicDelete() throws Throwable { 227b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar setupBasic(10); 228b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar final OnLayoutCallbacks callbacks = new OnLayoutCallbacks() { 229d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase @Override 230b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar public void postDispatchLayout() { 231b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar // verify this only in first layout 232b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar assertEquals("deleted views should still be children of RV", 233b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar mLayoutManager.getChildCount() + mDeletedViewCount 234b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar , mRecyclerView.getChildCount()); 235b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar } 236d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase 237b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar @Override 238b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar void afterPreLayout(RecyclerView.Recycler recycler, 239b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar AnimationLayoutManager layoutManager, 240b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar RecyclerView.State state) { 241b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar super.afterPreLayout(recycler, layoutManager, state); 242b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar mLayoutItemCount = 3; 243b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar mLayoutMin = 0; 244d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase } 245d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase }; 246b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar callbacks.mLayoutItemCount = 10; 247b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar callbacks.setExpectedItemCounts(10, 3); 248b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar mLayoutManager.setOnLayoutCallbacks(callbacks); 249b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar 250b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar mLayoutManager.expectLayouts(2); 251b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar mTestAdapter.deleteAndNotify(0, 7); 252b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar mLayoutManager.waitForLayout(2); 253b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar callbacks.reset();// when animations end another layout will happen 254b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar } 255b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar 256b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar 257b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar class AnimationLayoutManager extends TestLayoutManager { 258b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar 259b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar OnLayoutCallbacks mOnLayoutCallbacks = new OnLayoutCallbacks() { 260b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar }; 261b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar 262b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar @Override 263b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar public boolean supportsItemAnimations() { 264b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar return true; 265b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar } 266b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar 267b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar @Override 268b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar public void expectLayouts(int count) { 269b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar super.expectLayouts(count); 270b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar mOnLayoutCallbacks.mLayoutCount = 0; 271b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar } 272b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar 273b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar public void setOnLayoutCallbacks(OnLayoutCallbacks onLayoutCallbacks) { 274b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar mOnLayoutCallbacks = onLayoutCallbacks; 275b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar } 276b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar 277b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar @Override 278b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar public final void onLayoutChildren(RecyclerView.Recycler recycler, 279b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar RecyclerView.State state) { 280b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar try { 281b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar mOnLayoutCallbacks.onLayoutChildren(recycler, this, state); 282b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar } finally { 283b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar layoutLatch.countDown(); 284d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase } 285b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar } 286b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar 287b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar 288b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar public void onPostDispatchLayout() { 289b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar mOnLayoutCallbacks.postDispatchLayout(); 290b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar } 291b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar 292b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar @Override 293b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar public void waitForLayout(long timeout, TimeUnit timeUnit) throws Throwable { 294b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar super.waitForLayout(timeout, timeUnit); 295b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar checkForMainThreadException(); 296b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar } 297d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase } 298d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase 299b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar abstract class OnLayoutCallbacks { 300b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar 301b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar int mLayoutMin = Integer.MIN_VALUE; 302b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar 303b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar int mLayoutItemCount = Integer.MAX_VALUE; 304b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar 305b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar int expectedPreLayoutItemCount = -1; 306b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar 307b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar int expectedPostLayoutItemCount = -1; 308b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar 309b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar private int mLayoutCount; 310b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar 311b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar int mDeletedViewCount; 312b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar 313b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar void setExpectedItemCounts(int preLayout, int postLayout) { 314b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar expectedPreLayoutItemCount = preLayout; 315b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar expectedPostLayoutItemCount = postLayout; 316b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar } 317b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar 318b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar void reset() { 319b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar mLayoutCount = 0; 320b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar mLayoutMin = Integer.MIN_VALUE; 321b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar mLayoutItemCount = Integer.MAX_VALUE; 322b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar expectedPreLayoutItemCount = -1; 323b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar expectedPostLayoutItemCount = -1; 324b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar } 325b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar 326b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar void beforePreLayout(RecyclerView.Recycler recycler, 327b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar AnimationLayoutManager lm, RecyclerView.State state) { 328b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar mDeletedViewCount = 0; 329b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar for (int i = 0; i < lm.getChildCount(); i++) { 330b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar View v = lm.getChildAt(i); 331b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar if (lm.getLp(v).isItemRemoved()) { 332b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar mDeletedViewCount++; 333b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar } 334b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar } 335b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar } 336b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar 337b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar void doLayout(RecyclerView.Recycler recycler, AnimationLayoutManager lm, 338b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar RecyclerView.State state) { 339b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar if (DEBUG) { 340b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar Log.d(TAG, "item count " + state.getItemCount()); 341b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar } 342b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar lm.detachAndScrapAttachedViews(recycler); 343b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar final int start = mLayoutMin == Integer.MIN_VALUE ? 0 : mLayoutMin; 344b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar final int count = mLayoutItemCount 345b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar == Integer.MAX_VALUE ? state.getItemCount() : mLayoutItemCount; 346b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar lm.layoutRange(recycler, start, start + count); 347b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar assertEquals("correct # of children should be laid out", 348b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar count - (inPreLayout() ? mDeletedViewCount : 0), lm.getChildCount()); 349b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar if (!inPreLayout()) { // may not be the correct check 350b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar lm.assertVisibleItemPositions(); 351b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar } 352b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar } 353b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar 354b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar void onLayoutChildren(RecyclerView.Recycler recycler, AnimationLayoutManager lm, 355b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar RecyclerView.State state) { 356b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar 357b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar if (mLayoutCount == 0) { 358b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar if (expectedPreLayoutItemCount != -1) { 359b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar assertEquals("on pre layout, state should return abstracted adapter size", 360b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar expectedPreLayoutItemCount, state.getItemCount()); 361b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar } 362b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar beforePreLayout(recycler, lm, state); 363b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar } else if (mLayoutCount == 1) { 364b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar if (expectedPostLayoutItemCount != -1) { 365b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar assertEquals("on post layout, state should return real adapter size", 366b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar expectedPostLayoutItemCount, state.getItemCount()); 367b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar } 368b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar beforePostLayout(recycler, lm, state); 369b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar } 370b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar doLayout(recycler, lm, state); 371b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar if (mLayoutCount == 0) { 372b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar afterPreLayout(recycler, lm, state); 373b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar } else if (mLayoutCount == 1) { 374b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar afterPostLayout(recycler, lm, state); 375b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar } 376b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar mLayoutCount++; 377b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar } 378b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar 379b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar void afterPreLayout(RecyclerView.Recycler recycler, AnimationLayoutManager layoutManager, 380b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar RecyclerView.State state) { 381b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar } 382b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar 383b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar void beforePostLayout(RecyclerView.Recycler recycler, AnimationLayoutManager layoutManager, 384b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar RecyclerView.State state) { 385b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar } 386b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar 387b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar void afterPostLayout(RecyclerView.Recycler recycler, AnimationLayoutManager layoutManager, 388b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar RecyclerView.State state) { 389b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar } 390b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar 391b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar void postDispatchLayout() { 392b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar } 393b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar 394b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar boolean inPreLayout() { 395b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar return mLayoutCount == 0; 396b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar } 397b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar } 398b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar 399b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar class TestRecyclerView extends RecyclerView { 40011b7cfea15306c0d6e4ed7da09f7698df01695dfYigit Boyar 401888c70abaa77e15458c366b8d27835d176dcc546Yigit Boyar CountDownLatch drawLatch; 402b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar 403b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar public TestRecyclerView(Context context) { 404b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar super(context); 405b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar } 406b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar 407b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar public TestRecyclerView(Context context, AttributeSet attrs) { 408b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar super(context, attrs); 409b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar } 410b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar 411b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar public TestRecyclerView(Context context, AttributeSet attrs, int defStyle) { 412b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar super(context, attrs, defStyle); 413b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar } 414b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar 415888c70abaa77e15458c366b8d27835d176dcc546Yigit Boyar public void expectDraw(int count) { 416888c70abaa77e15458c366b8d27835d176dcc546Yigit Boyar drawLatch = new CountDownLatch(count); 417888c70abaa77e15458c366b8d27835d176dcc546Yigit Boyar } 418888c70abaa77e15458c366b8d27835d176dcc546Yigit Boyar 419888c70abaa77e15458c366b8d27835d176dcc546Yigit Boyar public void waitForDraw(long timeout) throws Throwable { 420888c70abaa77e15458c366b8d27835d176dcc546Yigit Boyar drawLatch.await(timeout * (DEBUG ? 100 : 1), TimeUnit.SECONDS); 421888c70abaa77e15458c366b8d27835d176dcc546Yigit Boyar assertEquals("all expected draws should happen at the expected time frame", 422888c70abaa77e15458c366b8d27835d176dcc546Yigit Boyar 0, drawLatch.getCount()); 423888c70abaa77e15458c366b8d27835d176dcc546Yigit Boyar } 424888c70abaa77e15458c366b8d27835d176dcc546Yigit Boyar 425888c70abaa77e15458c366b8d27835d176dcc546Yigit Boyar @Override 426888c70abaa77e15458c366b8d27835d176dcc546Yigit Boyar protected void dispatchDraw(Canvas canvas) { 427888c70abaa77e15458c366b8d27835d176dcc546Yigit Boyar super.dispatchDraw(canvas); 428888c70abaa77e15458c366b8d27835d176dcc546Yigit Boyar if (drawLatch != null) { 429888c70abaa77e15458c366b8d27835d176dcc546Yigit Boyar drawLatch.countDown(); 430888c70abaa77e15458c366b8d27835d176dcc546Yigit Boyar } 431888c70abaa77e15458c366b8d27835d176dcc546Yigit Boyar } 432888c70abaa77e15458c366b8d27835d176dcc546Yigit Boyar 433b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar @Override 434b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar void dispatchLayout() { 435b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar try { 436b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar super.dispatchLayout(); 437b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar if (getLayoutManager() instanceof AnimationLayoutManager) { 438b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar ((AnimationLayoutManager) getLayoutManager()).onPostDispatchLayout(); 439b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar } 440b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar } catch (Throwable t) { 441b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar postExceptionToInstrumentation(t); 442b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar } 443b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar 444b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar } 445b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar 446b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar private void postExceptionToInstrumentation(Throwable t) { 447b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar if (DEBUG) { 448b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar Log.e(TAG, "captured exception on main thread", t); 449b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar } 450b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar mainThreadException = t; 451b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar if (mLayoutManager instanceof TestLayoutManager) { 452b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar TestLayoutManager lm = mLayoutManager; 453b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar // finish all layouts so that we get the correct exception 454b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar while (lm.layoutLatch.getCount() > 0) { 455b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar lm.layoutLatch.countDown(); 456b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar } 457b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar } 458b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar } 459b5f8b4fecb531aee6b359b4968409410aba90817Yigit Boyar } 460d7d27e9ebe5c7325e67e1a8af265378bd2056cadChet Haase} 461