14143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar/* 2ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikas * Copyright 2018 The Android Open Source Project 34143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar * 44143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar * Licensed under the Apache License, Version 2.0 (the "License"); 54143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar * you may not use this file except in compliance with the License. 64143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar * You may obtain a copy of the License at 74143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar * 84143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar * http://www.apache.org/licenses/LICENSE-2.0 94143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar * 104143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar * Unless required by applicable law or agreed to in writing, software 114143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar * distributed under the License is distributed on an "AS IS" BASIS, 124143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 134143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar * See the License for the specific language governing permissions and 144143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar * limitations under the License. 154143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar */ 16ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikaspackage androidx.recyclerview.widget; 174143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 186b6a29eea7f6a212447b3cc7b45a081b609ca4b1Yigit Boyarimport static org.hamcrest.CoreMatchers.is; 196b6a29eea7f6a212447b3cc7b45a081b609ca4b1Yigit Boyarimport static org.hamcrest.MatcherAssert.assertThat; 206b6a29eea7f6a212447b3cc7b45a081b609ca4b1Yigit Boyarimport static org.junit.Assert.assertEquals; 216b6a29eea7f6a212447b3cc7b45a081b609ca4b1Yigit Boyarimport static org.junit.Assert.assertNull; 226b6a29eea7f6a212447b3cc7b45a081b609ca4b1Yigit Boyarimport static org.junit.Assert.assertTrue; 236b6a29eea7f6a212447b3cc7b45a081b609ca4b1Yigit Boyar 2429f43aa1bb825a46fd7cf161a0cd1d5353aaf821Yigit Boyarimport android.app.Activity; 254143554adb9b31b700b6876a251a64419e6111e2Yigit Boyarimport android.graphics.Color; 264143554adb9b31b700b6876a251a64419e6111e2Yigit Boyarimport android.graphics.Rect; 274143554adb9b31b700b6876a251a64419e6111e2Yigit Boyarimport android.util.Log; 284143554adb9b31b700b6876a251a64419e6111e2Yigit Boyarimport android.view.Gravity; 294143554adb9b31b700b6876a251a64419e6111e2Yigit Boyarimport android.view.View; 304143554adb9b31b700b6876a251a64419e6111e2Yigit Boyarimport android.view.ViewGroup; 314143554adb9b31b700b6876a251a64419e6111e2Yigit Boyarimport android.widget.TextView; 324143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 33c95a6f1f125ad3a7e1f9f79bccf4b2603bc40ebaAurimas Liutikasimport androidx.annotation.NonNull; 34c95a6f1f125ad3a7e1f9f79bccf4b2603bc40ebaAurimas Liutikasimport androidx.annotation.Nullable; 35c95a6f1f125ad3a7e1f9f79bccf4b2603bc40ebaAurimas Liutikasimport androidx.collection.LongSparseArray; 36c95a6f1f125ad3a7e1f9f79bccf4b2603bc40ebaAurimas Liutikas 37f3844451301cb14ca885e125cb27f108a834c386Yigit Boyarimport org.hamcrest.CoreMatchers; 38959f4c0fac89425a8a9842e82fc180ec736fffacYigit Boyar 394143554adb9b31b700b6876a251a64419e6111e2Yigit Boyarimport java.util.ArrayList; 404143554adb9b31b700b6876a251a64419e6111e2Yigit Boyarimport java.util.Collections; 414143554adb9b31b700b6876a251a64419e6111e2Yigit Boyarimport java.util.List; 424143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 434143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar/** 444143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar * Class to test any generic wrap content behavior. 454143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar * It does so by running the same view scenario twice. Once with match parent setup to record all 464143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar * dimensions and once with wrap_content setup. Then compares all child locations & ids + 474143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar * RecyclerView size. 484143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar */ 494143554adb9b31b700b6876a251a64419e6111e2Yigit Boyarabstract public class BaseWrapContentTest extends BaseRecyclerViewInstrumentationTest { 504143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 514143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar static final boolean DEBUG = false; 524143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar static final String TAG = "WrapContentTest"; 534143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar RecyclerView.LayoutManager mLayoutManager; 544143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 554143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar TestAdapter mTestAdapter; 564143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 574143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar LoggingItemAnimator mLoggingItemAnimator; 584143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 594143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar boolean mIsWrapContent; 604143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 614143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar protected final WrapContentConfig mWrapContentConfig; 624143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 634143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar public BaseWrapContentTest(WrapContentConfig config) { 644143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar mWrapContentConfig = config; 654143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 664143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 674143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar abstract RecyclerView.LayoutManager createLayoutManager(); 684143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 69f3844451301cb14ca885e125cb27f108a834c386Yigit Boyar void unspecifiedWithHintTest(boolean horizontal) throws Throwable { 70f3844451301cb14ca885e125cb27f108a834c386Yigit Boyar final int itemHeight = 20; 71f3844451301cb14ca885e125cb27f108a834c386Yigit Boyar final int itemWidth = 15; 72f3844451301cb14ca885e125cb27f108a834c386Yigit Boyar RecyclerView.LayoutManager layoutManager = createLayoutManager(); 73f3844451301cb14ca885e125cb27f108a834c386Yigit Boyar WrappedRecyclerView rv = createRecyclerView(getActivity()); 74f3844451301cb14ca885e125cb27f108a834c386Yigit Boyar TestAdapter testAdapter = new TestAdapter(20) { 75f3844451301cb14ca885e125cb27f108a834c386Yigit Boyar @Override 768a11e6829c522aa1efcc903afa4c01d337082eabChris Craik public void onBindViewHolder(@NonNull TestViewHolder holder, 77f3844451301cb14ca885e125cb27f108a834c386Yigit Boyar int position) { 78f3844451301cb14ca885e125cb27f108a834c386Yigit Boyar super.onBindViewHolder(holder, position); 79f3844451301cb14ca885e125cb27f108a834c386Yigit Boyar holder.itemView.setLayoutParams(new ViewGroup.LayoutParams(itemWidth, itemHeight)); 80f3844451301cb14ca885e125cb27f108a834c386Yigit Boyar } 81f3844451301cb14ca885e125cb27f108a834c386Yigit Boyar }; 82f3844451301cb14ca885e125cb27f108a834c386Yigit Boyar rv.setLayoutManager(layoutManager); 83f3844451301cb14ca885e125cb27f108a834c386Yigit Boyar rv.setAdapter(testAdapter); 84f3844451301cb14ca885e125cb27f108a834c386Yigit Boyar TestedFrameLayout.FullControlLayoutParams lp = 85f3844451301cb14ca885e125cb27f108a834c386Yigit Boyar new TestedFrameLayout.FullControlLayoutParams(0, 0); 86f3844451301cb14ca885e125cb27f108a834c386Yigit Boyar if (horizontal) { 87f3844451301cb14ca885e125cb27f108a834c386Yigit Boyar lp.wSpec = View.MeasureSpec.makeMeasureSpec(25, View.MeasureSpec.UNSPECIFIED); 88f3844451301cb14ca885e125cb27f108a834c386Yigit Boyar lp.hSpec = View.MeasureSpec.makeMeasureSpec(50, View.MeasureSpec.AT_MOST); 89f3844451301cb14ca885e125cb27f108a834c386Yigit Boyar } else { 90f3844451301cb14ca885e125cb27f108a834c386Yigit Boyar lp.hSpec = View.MeasureSpec.makeMeasureSpec(25, View.MeasureSpec.UNSPECIFIED); 91f3844451301cb14ca885e125cb27f108a834c386Yigit Boyar lp.wSpec = View.MeasureSpec.makeMeasureSpec(50, View.MeasureSpec.AT_MOST); 92f3844451301cb14ca885e125cb27f108a834c386Yigit Boyar } 93f3844451301cb14ca885e125cb27f108a834c386Yigit Boyar rv.setLayoutParams(lp); 94f3844451301cb14ca885e125cb27f108a834c386Yigit Boyar setRecyclerView(rv); 95f3844451301cb14ca885e125cb27f108a834c386Yigit Boyar rv.waitUntilLayout(); 96f3844451301cb14ca885e125cb27f108a834c386Yigit Boyar 97f3844451301cb14ca885e125cb27f108a834c386Yigit Boyar // we don't assert against the given size hint because LM will still ask for more if it 98f3844451301cb14ca885e125cb27f108a834c386Yigit Boyar // lays out more children. This is the correct behavior because the spec is not AT_MOST, 99f3844451301cb14ca885e125cb27f108a834c386Yigit Boyar // it is UNSPECIFIED. 100f3844451301cb14ca885e125cb27f108a834c386Yigit Boyar if (horizontal) { 101f3844451301cb14ca885e125cb27f108a834c386Yigit Boyar int expectedWidth = rv.getPaddingLeft() + rv.getPaddingRight() + itemWidth; 102f3844451301cb14ca885e125cb27f108a834c386Yigit Boyar while (expectedWidth < 25) { 103f3844451301cb14ca885e125cb27f108a834c386Yigit Boyar expectedWidth += itemWidth; 104f3844451301cb14ca885e125cb27f108a834c386Yigit Boyar } 105f3844451301cb14ca885e125cb27f108a834c386Yigit Boyar assertThat(rv.getWidth(), CoreMatchers.is(expectedWidth)); 106f3844451301cb14ca885e125cb27f108a834c386Yigit Boyar } else { 107f3844451301cb14ca885e125cb27f108a834c386Yigit Boyar int expectedHeight = rv.getPaddingTop() + rv.getPaddingBottom() + itemHeight; 108f3844451301cb14ca885e125cb27f108a834c386Yigit Boyar while (expectedHeight < 25) { 109f3844451301cb14ca885e125cb27f108a834c386Yigit Boyar expectedHeight += itemHeight; 110f3844451301cb14ca885e125cb27f108a834c386Yigit Boyar } 111f3844451301cb14ca885e125cb27f108a834c386Yigit Boyar assertThat(rv.getHeight(), CoreMatchers.is(expectedHeight)); 112f3844451301cb14ca885e125cb27f108a834c386Yigit Boyar } 113f3844451301cb14ca885e125cb27f108a834c386Yigit Boyar } 114f3844451301cb14ca885e125cb27f108a834c386Yigit Boyar 1154143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar protected void testScenerio(Scenario scenario) throws Throwable { 116ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikas TestedFrameLayout.FullControlLayoutParams 117ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikas matchParent = new TestedFrameLayout.FullControlLayoutParams( 1184143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar ViewGroup.LayoutParams.MATCH_PARENT, 1194143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar ViewGroup.LayoutParams.MATCH_PARENT); 120ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikas TestedFrameLayout.FullControlLayoutParams 121ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikas wrapContent = new TestedFrameLayout.FullControlLayoutParams( 1224143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar ViewGroup.LayoutParams.WRAP_CONTENT, 1234143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar ViewGroup.LayoutParams.WRAP_CONTENT); 1244143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar if (mWrapContentConfig.isUnlimitedHeight()) { 1254143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar wrapContent.hSpec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED); 1264143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 1274143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar if (mWrapContentConfig.isUnlimitedWidth()) { 1284143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar wrapContent.wSpec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED); 1294143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 1304143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 1314143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar mIsWrapContent = false; 1324143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar List<Snapshot> s1 = runScenario(scenario, matchParent, null); 1334143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar mIsWrapContent = true; 1344143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 1354143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar List<Snapshot> s2 = runScenario(scenario, wrapContent, s1); 1364143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar assertEquals("test sanity", s1.size(), s2.size()); 1374143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 1384143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar for (int i = 0; i < s1.size(); i++) { 1394143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar Snapshot step1 = s1.get(i); 1404143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar Snapshot step2 = s2.get(i); 1414143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar step1.assertSame(step2, i); 1424143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 1434143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 1444143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 1454143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar public List<Snapshot> runScenario(Scenario scenario, ViewGroup.LayoutParams lp, 1464143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar @Nullable List<Snapshot> compareWith) 1474143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar throws Throwable { 1484143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar removeRecyclerView(); 1494143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar Item.idCounter.set(0); 1504143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar List<Snapshot> result = new ArrayList<>(); 1514143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar RecyclerView.LayoutManager layoutManager = scenario.createLayoutManager(); 1524143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar WrappedRecyclerView recyclerView = new WrappedRecyclerView(getActivity()); 1534143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar recyclerView.setBackgroundColor(Color.rgb(0, 0, 255)); 1544143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar recyclerView.setLayoutManager(layoutManager); 1554143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar recyclerView.setLayoutParams(lp); 1564143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar mLayoutManager = layoutManager; 1574143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar mTestAdapter = new TestAdapter(scenario.getSeedAdapterSize()); 1584143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar recyclerView.setAdapter(mTestAdapter); 1594143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar mLoggingItemAnimator = new LoggingItemAnimator(); 1604143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar recyclerView.setItemAnimator(mLoggingItemAnimator); 1614143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar setRecyclerView(recyclerView); 1624143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar recyclerView.waitUntilLayout(); 1634143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar int stepIndex = 0; 1644143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar for (Step step : scenario.mStepList) { 1654143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar mLoggingItemAnimator.reset(); 1664143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar step.onRun(); 1674143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar recyclerView.waitUntilLayout(); 1684143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar recyclerView.waitUntilAnimations(); 1694143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar Snapshot snapshot = takeSnapshot(); 1704143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar if (mIsWrapContent) { 1714143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar snapshot.assertRvSize(); 1724143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 1734143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar result.add(snapshot); 1744143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar if (compareWith != null) { 1754143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar compareWith.get(stepIndex).assertSame(snapshot, stepIndex); 1764143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 1774143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar stepIndex++; 1784143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 1794143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar recyclerView.waitUntilLayout(); 1804143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar recyclerView.waitUntilAnimations(); 1814143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar Snapshot snapshot = takeSnapshot(); 1824143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar if (mIsWrapContent) { 1834143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar snapshot.assertRvSize(); 1844143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 1854143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar result.add(snapshot); 1864143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar if (compareWith != null) { 1874143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar compareWith.get(stepIndex).assertSame(snapshot, stepIndex); 1884143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 1894143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar return result; 1904143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 1914143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 19229f43aa1bb825a46fd7cf161a0cd1d5353aaf821Yigit Boyar protected WrappedRecyclerView createRecyclerView(Activity activity) { 19329f43aa1bb825a46fd7cf161a0cd1d5353aaf821Yigit Boyar return new WrappedRecyclerView(getActivity()); 19429f43aa1bb825a46fd7cf161a0cd1d5353aaf821Yigit Boyar } 19529f43aa1bb825a46fd7cf161a0cd1d5353aaf821Yigit Boyar 1964143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar void layoutAndCheck(TestedFrameLayout.FullControlLayoutParams lp, 1974143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar BaseWrapContentWithAspectRatioTest.WrapContentAdapter adapter, Rect[] expected, 1984143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar int width, int height) throws Throwable { 19929f43aa1bb825a46fd7cf161a0cd1d5353aaf821Yigit Boyar WrappedRecyclerView recyclerView = createRecyclerView(getActivity()); 2004143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar recyclerView.setBackgroundColor(Color.rgb(0, 0, 255)); 2014143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar recyclerView.setLayoutManager(createLayoutManager()); 2024143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar recyclerView.setAdapter(adapter); 2034143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar recyclerView.setLayoutParams(lp); 2046b6a29eea7f6a212447b3cc7b45a081b609ca4b1Yigit Boyar Rect padding = mWrapContentConfig.padding; 205de8a5de43b647f9b61f4859a22a0ce59155f442aYigit Boyar recyclerView.setPadding(padding.left, padding.top, padding.right, padding.bottom); 2064143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar setRecyclerView(recyclerView); 2074143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar recyclerView.waitUntilLayout(); 2084143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar Snapshot snapshot = takeSnapshot(); 2094143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar int index = 0; 2106b6a29eea7f6a212447b3cc7b45a081b609ca4b1Yigit Boyar Rect tmp = new Rect(); 2114143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar for (BaseWrapContentWithAspectRatioTest.MeasureBehavior behavior : adapter.behaviors) { 2126b6a29eea7f6a212447b3cc7b45a081b609ca4b1Yigit Boyar tmp.set(expected[index]); 2136b6a29eea7f6a212447b3cc7b45a081b609ca4b1Yigit Boyar tmp.offset(padding.left, padding.top); 2144143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar assertThat("behavior " + index, snapshot.mChildCoordinates.get(behavior.getId()), 2156b6a29eea7f6a212447b3cc7b45a081b609ca4b1Yigit Boyar is(tmp)); 2164143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar index ++; 2174143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 2184143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar Rect boundingBox = new Rect(0, 0, 0, 0); 2194143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar for (Rect rect : expected) { 2204143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar boundingBox.union(rect); 2214143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 2226b6a29eea7f6a212447b3cc7b45a081b609ca4b1Yigit Boyar assertThat(recyclerView.getWidth(), is(width + padding.left + padding.right)); 2236b6a29eea7f6a212447b3cc7b45a081b609ca4b1Yigit Boyar assertThat(recyclerView.getHeight(), is(height + padding.top + padding.bottom)); 2244143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 2254143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 2264143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 2274143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar abstract protected int getVerticalGravity(RecyclerView.LayoutManager layoutManager); 2284143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 2294143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar abstract protected int getHorizontalGravity(RecyclerView.LayoutManager layoutManager); 2304143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 2314143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar protected Snapshot takeSnapshot() throws Throwable { 2324143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar Snapshot snapshot = new Snapshot(mRecyclerView, mLoggingItemAnimator, 2334143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar getHorizontalGravity(mLayoutManager), getVerticalGravity(mLayoutManager)); 2344143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar return snapshot; 2354143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 2364143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 2374143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar abstract class Scenario { 2384143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 2394143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar ArrayList<Step> mStepList = new ArrayList<>(); 2404143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 2414143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar public Scenario(Step... steps) { 2424143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar Collections.addAll(mStepList, steps); 2434143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 2444143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 2454143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar public int getSeedAdapterSize() { 2464143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar return 10; 2474143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 2484143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 2494143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar public RecyclerView.LayoutManager createLayoutManager() { 2504143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar return BaseWrapContentTest.this.createLayoutManager(); 2514143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 2524143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 2534143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 2544143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar abstract static class Step { 2554143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 2564143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar abstract void onRun() throws Throwable; 2574143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 2584143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 2594143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar class Snapshot { 2604143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 2614143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar Rect mRawChildrenBox = new Rect(); 2624143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 2634143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar Rect mRvSize = new Rect(); 2644143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 2654143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar Rect mRvPadding = new Rect(); 2664143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 2674143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar Rect mRvParentSize = new Rect(); 2684143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 2694143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar LongSparseArray<Rect> mChildCoordinates = new LongSparseArray<>(); 2704143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 2714143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar LongSparseArray<String> mAppear = new LongSparseArray<>(); 2724143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 2734143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar LongSparseArray<String> mDisappear = new LongSparseArray<>(); 2744143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 2754143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar LongSparseArray<String> mPersistent = new LongSparseArray<>(); 2764143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 2774143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar LongSparseArray<String> mChanged = new LongSparseArray<>(); 2784143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 2794143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar int mVerticalGravity; 2804143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 2814143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar int mHorizontalGravity; 2824143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 2834143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar int mOffsetX, mOffsetY;// how much we should offset children 2844143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 2854143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar public Snapshot(RecyclerView recyclerView, LoggingItemAnimator loggingItemAnimator, 2864143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar int horizontalGravity, int verticalGravity) 2874143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar throws Throwable { 2884143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar mRvSize = getViewBounds(recyclerView); 2894143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar mRvParentSize = getViewBounds((View) recyclerView.getParent()); 2904143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar mRvPadding = new Rect(recyclerView.getPaddingLeft(), recyclerView.getPaddingTop(), 2914143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar recyclerView.getPaddingRight(), recyclerView.getPaddingBottom()); 2924143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar mVerticalGravity = verticalGravity; 2934143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar mHorizontalGravity = horizontalGravity; 2944143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar if (mVerticalGravity == Gravity.TOP) { 2954143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar mOffsetY = 0; 2964143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } else { 2974143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar mOffsetY = mRvParentSize.bottom - mRvSize.bottom; 2984143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 2994143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 3004143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar if (mHorizontalGravity == Gravity.LEFT) { 3014143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar mOffsetX = 0; 3024143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } else { 3034143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar mOffsetX = mRvParentSize.right - mRvSize.right; 3044143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 3054143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar collectChildCoordinates(recyclerView); 3064143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar if (loggingItemAnimator != null) { 3074143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar collectInto(mAppear, loggingItemAnimator.mAnimateAppearanceList); 3084143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar collectInto(mDisappear, loggingItemAnimator.mAnimateDisappearanceList); 3094143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar collectInto(mPersistent, loggingItemAnimator.mAnimatePersistenceList); 3104143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar collectInto(mChanged, loggingItemAnimator.mAnimateChangeList); 3114143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 3124143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 3134143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 3144143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar public boolean doesChildrenFitVertically() { 3154143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar return mRawChildrenBox.top >= mRvPadding.top 3164143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar && mRawChildrenBox.bottom <= mRvSize.bottom - mRvPadding.bottom; 3174143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 3184143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 3194143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar public boolean doesChildrenFitHorizontally() { 3204143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar return mRawChildrenBox.left >= mRvPadding.left 3214143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar && mRawChildrenBox.right <= mRvSize.right - mRvPadding.right; 3224143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 3234143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 3244143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar public void assertSame(Snapshot other, int step) { 3254143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar if (mWrapContentConfig.isUnlimitedHeight() && 3264143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar (!doesChildrenFitVertically() || !other.doesChildrenFitVertically())) { 3274143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar if (DEBUG) { 3284143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar Log.d(TAG, "cannot assert coordinates because it does not fit vertically"); 3294143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 3304143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar return; 3314143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 3324143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar if (mWrapContentConfig.isUnlimitedWidth() && 3334143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar (!doesChildrenFitHorizontally() || !other.doesChildrenFitHorizontally())) { 3344143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar if (DEBUG) { 3354143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar Log.d(TAG, "cannot assert coordinates because it does not fit horizontally"); 3364143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 3374143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar return; 3384143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 3394143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar assertMap("child coordinates. step:" + step, mChildCoordinates, 3404143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar other.mChildCoordinates); 3414143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar if (mWrapContentConfig.isUnlimitedHeight() || mWrapContentConfig.isUnlimitedWidth()) { 3424143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar return;//cannot assert animatinos in unlimited size 3434143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 3444143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar assertMap("appearing step:" + step, mAppear, other.mAppear); 3454143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar assertMap("disappearing step:" + step, mDisappear, other.mDisappear); 3464143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar assertMap("persistent step:" + step, mPersistent, other.mPersistent); 3474143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar assertMap("changed step:" + step, mChanged, other.mChanged); 3484143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 3494143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 3504143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar private void assertMap(String prefix, LongSparseArray<?> map1, LongSparseArray<?> map2) { 3514143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar StringBuilder logBuilder = new StringBuilder(); 3524143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar logBuilder.append(prefix).append("\n"); 3534143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar logBuilder.append("map1").append("\n"); 3544143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar logInto(map1, logBuilder); 3554143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar logBuilder.append("map2").append("\n"); 3564143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar logInto(map2, logBuilder); 3574143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar final String log = logBuilder.toString(); 3584143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar assertEquals(log + " same size", map1.size(), map2.size()); 3594143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar for (int i = 0; i < map1.size(); i++) { 3604143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar assertAtIndex(log, map1, map2, i); 3614143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 3624143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 3634143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 3644143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar private void assertAtIndex(String prefix, LongSparseArray<?> map1, LongSparseArray<?> map2, 3654143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar int index) { 3664143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar long key1 = map1.keyAt(index); 3674143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar long key2 = map2.keyAt(index); 3684143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar assertEquals(prefix + "key mismatch at index " + index, key1, key2); 3694143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar Object value1 = map1.valueAt(index); 3704143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar Object value2 = map2.valueAt(index); 3714143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar assertEquals(prefix + " value mismatch at index " + index, value1, value2); 3724143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 3734143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 3744143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar private void logInto(LongSparseArray<?> map, StringBuilder sb) { 3754143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar for (int i = 0; i < map.size(); i++) { 3764143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar long key = map.keyAt(i); 3774143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar Object value = map.valueAt(i); 3784143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar sb.append(key).append(" : ").append(value).append("\n"); 3794143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 3804143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 3814143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 3824143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar @Override 3834143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar public String toString() { 3844143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar StringBuilder sb = new StringBuilder("Snapshot{\n"); 3854143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar sb.append("child coordinates:\n"); 3864143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar logInto(mChildCoordinates, sb); 3874143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar sb.append("appear animations:\n"); 3884143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar logInto(mAppear, sb); 3894143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar sb.append("disappear animations:\n"); 3904143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar logInto(mDisappear, sb); 3914143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar sb.append("change animations:\n"); 3924143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar logInto(mChanged, sb); 3934143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar sb.append("persistent animations:\n"); 3944143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar logInto(mPersistent, sb); 3954143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar sb.append("}"); 3964143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar return sb.toString(); 3974143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 3984143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 3994143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar @Override 4004143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar public int hashCode() { 4014143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar int result = mChildCoordinates.hashCode(); 4024143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar result = 31 * result + mAppear.hashCode(); 4034143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar result = 31 * result + mDisappear.hashCode(); 4044143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar result = 31 * result + mPersistent.hashCode(); 4054143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar result = 31 * result + mChanged.hashCode(); 4064143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar return result; 4074143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 4084143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 4094143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar private void collectInto( 4104143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar LongSparseArray<String> target, 4114143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar List<? extends BaseRecyclerViewAnimationsTest.AnimateLogBase> list) { 4124143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar for (BaseRecyclerViewAnimationsTest.AnimateLogBase base : list) { 4134143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar long id = getItemId(base.viewHolder); 4144143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar assertNull(target.get(id)); 4154143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar target.put(id, log(base)); 4164143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 4174143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 4184143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 4194143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar private String log(BaseRecyclerViewAnimationsTest.AnimateLogBase base) { 4204143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar return base.getClass().getSimpleName() + 4214143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar ((TextView) base.viewHolder.itemView).getText() + ": " + 4224143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar "[pre:" + log(base.postInfo) + 4234143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar ", post:" + log(base.postInfo) + "]"; 4244143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 4254143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 4264143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar private String log(BaseRecyclerViewAnimationsTest.LoggingInfo postInfo) { 4274143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar if (postInfo == null) { 4284143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar return "?"; 4294143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 4304143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar return "PI[flags: " + postInfo.changeFlags 4314143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar + ",l:" + (postInfo.left + mOffsetX) 4324143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar + ",t:" + (postInfo.top + mOffsetY) 4334143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar + ",r:" + (postInfo.right + mOffsetX) 4344143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar + ",b:" + (postInfo.bottom + mOffsetY) + "]"; 4354143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 4364143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 4374143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar void collectChildCoordinates(RecyclerView recyclerView) throws Throwable { 4384143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar mRawChildrenBox = new Rect(0, 0, 0, 0); 4394143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar final int childCount = recyclerView.getChildCount(); 4404143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar for (int i = 0; i < childCount; i++) { 4414143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar View child = recyclerView.getChildAt(i); 4424143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar Rect childBounds = getChildBounds(recyclerView, child, true); 4434143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar mRawChildrenBox.union(getChildBounds(recyclerView, child, false)); 4444143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar RecyclerView.ViewHolder childViewHolder = recyclerView.getChildViewHolder(child); 4454143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar mChildCoordinates.put(getItemId(childViewHolder), childBounds); 4464143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 4474143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 4484143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 4494143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar private Rect getViewBounds(View view) { 4504143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar return new Rect(view.getLeft(), view.getTop(), view.getRight(), view.getBottom()); 4514143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 4524143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 4534143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar private Rect getChildBounds(RecyclerView recyclerView, View child, boolean offset) { 4544143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar RecyclerView.LayoutManager layoutManager = recyclerView.getLayoutManager(); 4554143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar RecyclerView.LayoutParams lp = (RecyclerView.LayoutParams) child.getLayoutParams(); 4564143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar Rect rect = new Rect(layoutManager.getDecoratedLeft(child) - lp.leftMargin, 4574143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar layoutManager.getDecoratedTop(child) - lp.topMargin, 4584143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar layoutManager.getDecoratedRight(child) + lp.rightMargin, 4594143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar layoutManager.getDecoratedBottom(child) + lp.bottomMargin); 4604143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar if (offset) { 4614143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar rect.offset(mOffsetX, mOffsetY); 4624143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 4634143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar return rect; 4644143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 4654143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 4664143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar private long getItemId(RecyclerView.ViewHolder vh) { 4674143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar if (vh instanceof TestViewHolder) { 4684143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar return ((TestViewHolder) vh).mBoundItem.mId; 4694143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } else if (vh instanceof BaseWrapContentWithAspectRatioTest.WrapContentViewHolder) { 4704143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar BaseWrapContentWithAspectRatioTest.WrapContentViewHolder casted = 4714143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar (BaseWrapContentWithAspectRatioTest.WrapContentViewHolder) vh; 4724143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar return casted.mView.mBehavior.getId(); 4734143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } else { 4744143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar throw new IllegalArgumentException("i don't support any VH"); 4754143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 4764143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 4774143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 4784143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar public void assertRvSize() { 4794143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar if (shouldWrapContentHorizontally()) { 4804143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar int expectedW = mRawChildrenBox.width() + mRvPadding.left + mRvPadding.right; 4814143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar assertTrue(mRvSize.width() + " <= " + expectedW, mRvSize.width() <= expectedW); 4824143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 4834143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar if (shouldWrapContentVertically()) { 4844143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar int expectedH = mRawChildrenBox.height() + mRvPadding.top + mRvPadding.bottom; 4854143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar assertTrue(mRvSize.height() + "<=" + expectedH, mRvSize.height() <= expectedH); 4864143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 4874143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 4884143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 4894143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 4904143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar protected boolean shouldWrapContentHorizontally() { 4914143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar return true; 4924143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 4934143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 4944143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar protected boolean shouldWrapContentVertically() { 4954143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar return true; 4964143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 4974143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 4984143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar static class WrapContentConfig { 4994143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 5006b6a29eea7f6a212447b3cc7b45a081b609ca4b1Yigit Boyar public boolean unlimitedWidth; 5016b6a29eea7f6a212447b3cc7b45a081b609ca4b1Yigit Boyar public boolean unlimitedHeight; 5026b6a29eea7f6a212447b3cc7b45a081b609ca4b1Yigit Boyar public Rect padding = new Rect(0, 0, 0, 0); 5034143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 5044143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar public WrapContentConfig(boolean unlimitedWidth, boolean unlimitedHeight) { 5054143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar this.unlimitedWidth = unlimitedWidth; 5064143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar this.unlimitedHeight = unlimitedHeight; 5074143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 5084143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 5096b6a29eea7f6a212447b3cc7b45a081b609ca4b1Yigit Boyar public WrapContentConfig(boolean unlimitedWidth, boolean unlimitedHeight, Rect padding) { 5106b6a29eea7f6a212447b3cc7b45a081b609ca4b1Yigit Boyar this.unlimitedWidth = unlimitedWidth; 5116b6a29eea7f6a212447b3cc7b45a081b609ca4b1Yigit Boyar this.unlimitedHeight = unlimitedHeight; 5126b6a29eea7f6a212447b3cc7b45a081b609ca4b1Yigit Boyar this.padding.set(padding); 5136b6a29eea7f6a212447b3cc7b45a081b609ca4b1Yigit Boyar } 5146b6a29eea7f6a212447b3cc7b45a081b609ca4b1Yigit Boyar 5154143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar public boolean isUnlimitedWidth() { 5164143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar return unlimitedWidth; 5174143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 5184143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 5194143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar public WrapContentConfig setUnlimitedWidth(boolean unlimitedWidth) { 5204143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar this.unlimitedWidth = unlimitedWidth; 5214143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar return this; 5224143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 5234143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 5244143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar public boolean isUnlimitedHeight() { 5254143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar return unlimitedHeight; 5264143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 5274143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 5284143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar public WrapContentConfig setUnlimitedHeight(boolean unlimitedHeight) { 5294143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar this.unlimitedHeight = unlimitedHeight; 5304143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar return this; 5314143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 5324143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 5334143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar @Override 5344143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar public String toString() { 535142ca4048bd0de39ddbc0e8981914bdff103ead3Aurimas Liutikas StringBuilder sb = new StringBuilder(32); 536142ca4048bd0de39ddbc0e8981914bdff103ead3Aurimas Liutikas sb.append("Rect("); sb.append(padding.left); sb.append(","); 537142ca4048bd0de39ddbc0e8981914bdff103ead3Aurimas Liutikas sb.append(padding.top); sb.append("-"); sb.append(padding.right); 538142ca4048bd0de39ddbc0e8981914bdff103ead3Aurimas Liutikas sb.append(","); sb.append(padding.bottom); sb.append(")"); 5396b6a29eea7f6a212447b3cc7b45a081b609ca4b1Yigit Boyar return "WrapContentConfig{" 5406b6a29eea7f6a212447b3cc7b45a081b609ca4b1Yigit Boyar + "unlimitedWidth=" + unlimitedWidth 541e9f9cd8d0e9008340985d17a2541ab24b3adb391Aurimas Liutikas + ",unlimitedHeight=" + unlimitedHeight 542142ca4048bd0de39ddbc0e8981914bdff103ead3Aurimas Liutikas + ",padding=" + sb.toString() 5436b6a29eea7f6a212447b3cc7b45a081b609ca4b1Yigit Boyar + '}'; 5444143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 5454143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 5464143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar public TestedFrameLayout.FullControlLayoutParams toLayoutParams(int wDim, int hDim) { 5474143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar TestedFrameLayout.FullControlLayoutParams 5484143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar lp = new TestedFrameLayout.FullControlLayoutParams( 5494143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar wDim, hDim); 5504143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar if (unlimitedWidth) { 5514143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar lp.wSpec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED); 5524143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 5534143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar if (unlimitedHeight) { 5544143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar lp.hSpec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED); 5554143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 5564143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar return lp; 5574143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 5584143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 5594143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar} 560