BaseWrapContentTest.java revision e9f9cd8d0e9008340985d17a2541ab24b3adb391
14143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar/* 24143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar * Copyright (C) 2015 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 */ 164143554adb9b31b700b6876a251a64419e6111e2Yigit Boyarpackage android.support.v7.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.support.annotation.Nullable; 284143554adb9b31b700b6876a251a64419e6111e2Yigit Boyarimport android.support.v4.util.LongSparseArray; 294143554adb9b31b700b6876a251a64419e6111e2Yigit Boyarimport android.support.v7.widget.TestedFrameLayout.FullControlLayoutParams; 304143554adb9b31b700b6876a251a64419e6111e2Yigit Boyarimport android.util.Log; 314143554adb9b31b700b6876a251a64419e6111e2Yigit Boyarimport android.view.Gravity; 324143554adb9b31b700b6876a251a64419e6111e2Yigit Boyarimport android.view.View; 334143554adb9b31b700b6876a251a64419e6111e2Yigit Boyarimport android.view.ViewGroup; 344143554adb9b31b700b6876a251a64419e6111e2Yigit Boyarimport android.widget.TextView; 354143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 36f3844451301cb14ca885e125cb27f108a834c386Yigit Boyarimport org.hamcrest.CoreMatchers; 37959f4c0fac89425a8a9842e82fc180ec736fffacYigit Boyar 384143554adb9b31b700b6876a251a64419e6111e2Yigit Boyarimport java.util.ArrayList; 394143554adb9b31b700b6876a251a64419e6111e2Yigit Boyarimport java.util.Collections; 404143554adb9b31b700b6876a251a64419e6111e2Yigit Boyarimport java.util.List; 414143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 424143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar/** 434143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar * Class to test any generic wrap content behavior. 444143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar * It does so by running the same view scenario twice. Once with match parent setup to record all 454143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar * dimensions and once with wrap_content setup. Then compares all child locations & ids + 464143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar * RecyclerView size. 474143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar */ 484143554adb9b31b700b6876a251a64419e6111e2Yigit Boyarabstract public class BaseWrapContentTest extends BaseRecyclerViewInstrumentationTest { 494143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 504143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar static final boolean DEBUG = false; 514143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar static final String TAG = "WrapContentTest"; 524143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar RecyclerView.LayoutManager mLayoutManager; 534143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 544143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar TestAdapter mTestAdapter; 554143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 564143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar LoggingItemAnimator mLoggingItemAnimator; 574143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 584143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar boolean mIsWrapContent; 594143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 604143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar protected final WrapContentConfig mWrapContentConfig; 614143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 624143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar public BaseWrapContentTest(WrapContentConfig config) { 634143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar mWrapContentConfig = config; 644143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 654143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 664143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar abstract RecyclerView.LayoutManager createLayoutManager(); 674143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 68f3844451301cb14ca885e125cb27f108a834c386Yigit Boyar void unspecifiedWithHintTest(boolean horizontal) throws Throwable { 69f3844451301cb14ca885e125cb27f108a834c386Yigit Boyar final int itemHeight = 20; 70f3844451301cb14ca885e125cb27f108a834c386Yigit Boyar final int itemWidth = 15; 71f3844451301cb14ca885e125cb27f108a834c386Yigit Boyar RecyclerView.LayoutManager layoutManager = createLayoutManager(); 72f3844451301cb14ca885e125cb27f108a834c386Yigit Boyar WrappedRecyclerView rv = createRecyclerView(getActivity()); 73f3844451301cb14ca885e125cb27f108a834c386Yigit Boyar TestAdapter testAdapter = new TestAdapter(20) { 74f3844451301cb14ca885e125cb27f108a834c386Yigit Boyar @Override 75f3844451301cb14ca885e125cb27f108a834c386Yigit Boyar public void onBindViewHolder(TestViewHolder holder, 76f3844451301cb14ca885e125cb27f108a834c386Yigit Boyar int position) { 77f3844451301cb14ca885e125cb27f108a834c386Yigit Boyar super.onBindViewHolder(holder, position); 78f3844451301cb14ca885e125cb27f108a834c386Yigit Boyar holder.itemView.setLayoutParams(new ViewGroup.LayoutParams(itemWidth, itemHeight)); 79f3844451301cb14ca885e125cb27f108a834c386Yigit Boyar } 80f3844451301cb14ca885e125cb27f108a834c386Yigit Boyar }; 81f3844451301cb14ca885e125cb27f108a834c386Yigit Boyar rv.setLayoutManager(layoutManager); 82f3844451301cb14ca885e125cb27f108a834c386Yigit Boyar rv.setAdapter(testAdapter); 83f3844451301cb14ca885e125cb27f108a834c386Yigit Boyar TestedFrameLayout.FullControlLayoutParams lp = 84f3844451301cb14ca885e125cb27f108a834c386Yigit Boyar new TestedFrameLayout.FullControlLayoutParams(0, 0); 85f3844451301cb14ca885e125cb27f108a834c386Yigit Boyar if (horizontal) { 86f3844451301cb14ca885e125cb27f108a834c386Yigit Boyar lp.wSpec = View.MeasureSpec.makeMeasureSpec(25, View.MeasureSpec.UNSPECIFIED); 87f3844451301cb14ca885e125cb27f108a834c386Yigit Boyar lp.hSpec = View.MeasureSpec.makeMeasureSpec(50, View.MeasureSpec.AT_MOST); 88f3844451301cb14ca885e125cb27f108a834c386Yigit Boyar } else { 89f3844451301cb14ca885e125cb27f108a834c386Yigit Boyar lp.hSpec = View.MeasureSpec.makeMeasureSpec(25, View.MeasureSpec.UNSPECIFIED); 90f3844451301cb14ca885e125cb27f108a834c386Yigit Boyar lp.wSpec = View.MeasureSpec.makeMeasureSpec(50, View.MeasureSpec.AT_MOST); 91f3844451301cb14ca885e125cb27f108a834c386Yigit Boyar } 92f3844451301cb14ca885e125cb27f108a834c386Yigit Boyar rv.setLayoutParams(lp); 93f3844451301cb14ca885e125cb27f108a834c386Yigit Boyar setRecyclerView(rv); 94f3844451301cb14ca885e125cb27f108a834c386Yigit Boyar rv.waitUntilLayout(); 95f3844451301cb14ca885e125cb27f108a834c386Yigit Boyar 96f3844451301cb14ca885e125cb27f108a834c386Yigit Boyar // we don't assert against the given size hint because LM will still ask for more if it 97f3844451301cb14ca885e125cb27f108a834c386Yigit Boyar // lays out more children. This is the correct behavior because the spec is not AT_MOST, 98f3844451301cb14ca885e125cb27f108a834c386Yigit Boyar // it is UNSPECIFIED. 99f3844451301cb14ca885e125cb27f108a834c386Yigit Boyar if (horizontal) { 100f3844451301cb14ca885e125cb27f108a834c386Yigit Boyar int expectedWidth = rv.getPaddingLeft() + rv.getPaddingRight() + itemWidth; 101f3844451301cb14ca885e125cb27f108a834c386Yigit Boyar while (expectedWidth < 25) { 102f3844451301cb14ca885e125cb27f108a834c386Yigit Boyar expectedWidth += itemWidth; 103f3844451301cb14ca885e125cb27f108a834c386Yigit Boyar } 104f3844451301cb14ca885e125cb27f108a834c386Yigit Boyar assertThat(rv.getWidth(), CoreMatchers.is(expectedWidth)); 105f3844451301cb14ca885e125cb27f108a834c386Yigit Boyar } else { 106f3844451301cb14ca885e125cb27f108a834c386Yigit Boyar int expectedHeight = rv.getPaddingTop() + rv.getPaddingBottom() + itemHeight; 107f3844451301cb14ca885e125cb27f108a834c386Yigit Boyar while (expectedHeight < 25) { 108f3844451301cb14ca885e125cb27f108a834c386Yigit Boyar expectedHeight += itemHeight; 109f3844451301cb14ca885e125cb27f108a834c386Yigit Boyar } 110f3844451301cb14ca885e125cb27f108a834c386Yigit Boyar assertThat(rv.getHeight(), CoreMatchers.is(expectedHeight)); 111f3844451301cb14ca885e125cb27f108a834c386Yigit Boyar } 112f3844451301cb14ca885e125cb27f108a834c386Yigit Boyar } 113f3844451301cb14ca885e125cb27f108a834c386Yigit Boyar 1144143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar protected void testScenerio(Scenario scenario) throws Throwable { 1154143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar FullControlLayoutParams matchParent = new FullControlLayoutParams( 1164143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar ViewGroup.LayoutParams.MATCH_PARENT, 1174143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar ViewGroup.LayoutParams.MATCH_PARENT); 1184143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar FullControlLayoutParams wrapContent = new FullControlLayoutParams( 1194143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar ViewGroup.LayoutParams.WRAP_CONTENT, 1204143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar ViewGroup.LayoutParams.WRAP_CONTENT); 1214143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar if (mWrapContentConfig.isUnlimitedHeight()) { 1224143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar wrapContent.hSpec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED); 1234143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 1244143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar if (mWrapContentConfig.isUnlimitedWidth()) { 1254143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar wrapContent.wSpec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED); 1264143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 1274143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 1284143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar mIsWrapContent = false; 1294143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar List<Snapshot> s1 = runScenario(scenario, matchParent, null); 1304143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar mIsWrapContent = true; 1314143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 1324143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar List<Snapshot> s2 = runScenario(scenario, wrapContent, s1); 1334143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar assertEquals("test sanity", s1.size(), s2.size()); 1344143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 1354143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar for (int i = 0; i < s1.size(); i++) { 1364143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar Snapshot step1 = s1.get(i); 1374143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar Snapshot step2 = s2.get(i); 1384143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar step1.assertSame(step2, i); 1394143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 1404143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 1414143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 1424143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar public List<Snapshot> runScenario(Scenario scenario, ViewGroup.LayoutParams lp, 1434143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar @Nullable List<Snapshot> compareWith) 1444143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar throws Throwable { 1454143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar removeRecyclerView(); 1464143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar Item.idCounter.set(0); 1474143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar List<Snapshot> result = new ArrayList<>(); 1484143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar RecyclerView.LayoutManager layoutManager = scenario.createLayoutManager(); 1494143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar WrappedRecyclerView recyclerView = new WrappedRecyclerView(getActivity()); 1504143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar recyclerView.setBackgroundColor(Color.rgb(0, 0, 255)); 1514143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar recyclerView.setLayoutManager(layoutManager); 1524143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar recyclerView.setLayoutParams(lp); 1534143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar mLayoutManager = layoutManager; 1544143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar mTestAdapter = new TestAdapter(scenario.getSeedAdapterSize()); 1554143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar recyclerView.setAdapter(mTestAdapter); 1564143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar mLoggingItemAnimator = new LoggingItemAnimator(); 1574143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar recyclerView.setItemAnimator(mLoggingItemAnimator); 1584143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar setRecyclerView(recyclerView); 1594143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar recyclerView.waitUntilLayout(); 1604143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar int stepIndex = 0; 1614143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar for (Step step : scenario.mStepList) { 1624143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar mLoggingItemAnimator.reset(); 1634143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar step.onRun(); 1644143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar recyclerView.waitUntilLayout(); 1654143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar recyclerView.waitUntilAnimations(); 1664143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar Snapshot snapshot = takeSnapshot(); 1674143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar if (mIsWrapContent) { 1684143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar snapshot.assertRvSize(); 1694143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 1704143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar result.add(snapshot); 1714143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar if (compareWith != null) { 1724143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar compareWith.get(stepIndex).assertSame(snapshot, stepIndex); 1734143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 1744143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar stepIndex++; 1754143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 1764143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar recyclerView.waitUntilLayout(); 1774143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar recyclerView.waitUntilAnimations(); 1784143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar Snapshot snapshot = takeSnapshot(); 1794143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar if (mIsWrapContent) { 1804143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar snapshot.assertRvSize(); 1814143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 1824143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar result.add(snapshot); 1834143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar if (compareWith != null) { 1844143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar compareWith.get(stepIndex).assertSame(snapshot, stepIndex); 1854143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 1864143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar return result; 1874143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 1884143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 18929f43aa1bb825a46fd7cf161a0cd1d5353aaf821Yigit Boyar protected WrappedRecyclerView createRecyclerView(Activity activity) { 19029f43aa1bb825a46fd7cf161a0cd1d5353aaf821Yigit Boyar return new WrappedRecyclerView(getActivity()); 19129f43aa1bb825a46fd7cf161a0cd1d5353aaf821Yigit Boyar } 19229f43aa1bb825a46fd7cf161a0cd1d5353aaf821Yigit Boyar 1934143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar void layoutAndCheck(TestedFrameLayout.FullControlLayoutParams lp, 1944143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar BaseWrapContentWithAspectRatioTest.WrapContentAdapter adapter, Rect[] expected, 1954143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar int width, int height) throws Throwable { 19629f43aa1bb825a46fd7cf161a0cd1d5353aaf821Yigit Boyar WrappedRecyclerView recyclerView = createRecyclerView(getActivity()); 1974143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar recyclerView.setBackgroundColor(Color.rgb(0, 0, 255)); 1984143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar recyclerView.setLayoutManager(createLayoutManager()); 1994143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar recyclerView.setAdapter(adapter); 2004143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar recyclerView.setLayoutParams(lp); 2016b6a29eea7f6a212447b3cc7b45a081b609ca4b1Yigit Boyar Rect padding = mWrapContentConfig.padding; 202de8a5de43b647f9b61f4859a22a0ce59155f442aYigit Boyar recyclerView.setPadding(padding.left, padding.top, padding.right, padding.bottom); 2034143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar setRecyclerView(recyclerView); 2044143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar recyclerView.waitUntilLayout(); 2054143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar Snapshot snapshot = takeSnapshot(); 2064143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar int index = 0; 2076b6a29eea7f6a212447b3cc7b45a081b609ca4b1Yigit Boyar Rect tmp = new Rect(); 2084143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar for (BaseWrapContentWithAspectRatioTest.MeasureBehavior behavior : adapter.behaviors) { 2096b6a29eea7f6a212447b3cc7b45a081b609ca4b1Yigit Boyar tmp.set(expected[index]); 2106b6a29eea7f6a212447b3cc7b45a081b609ca4b1Yigit Boyar tmp.offset(padding.left, padding.top); 2114143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar assertThat("behavior " + index, snapshot.mChildCoordinates.get(behavior.getId()), 2126b6a29eea7f6a212447b3cc7b45a081b609ca4b1Yigit Boyar is(tmp)); 2134143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar index ++; 2144143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 2154143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar Rect boundingBox = new Rect(0, 0, 0, 0); 2164143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar for (Rect rect : expected) { 2174143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar boundingBox.union(rect); 2184143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 2196b6a29eea7f6a212447b3cc7b45a081b609ca4b1Yigit Boyar assertThat(recyclerView.getWidth(), is(width + padding.left + padding.right)); 2206b6a29eea7f6a212447b3cc7b45a081b609ca4b1Yigit Boyar assertThat(recyclerView.getHeight(), is(height + padding.top + padding.bottom)); 2214143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 2224143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 2234143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 2244143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar abstract protected int getVerticalGravity(RecyclerView.LayoutManager layoutManager); 2254143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 2264143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar abstract protected int getHorizontalGravity(RecyclerView.LayoutManager layoutManager); 2274143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 2284143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar protected Snapshot takeSnapshot() throws Throwable { 2294143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar Snapshot snapshot = new Snapshot(mRecyclerView, mLoggingItemAnimator, 2304143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar getHorizontalGravity(mLayoutManager), getVerticalGravity(mLayoutManager)); 2314143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar return snapshot; 2324143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 2334143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 2344143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar abstract class Scenario { 2354143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 2364143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar ArrayList<Step> mStepList = new ArrayList<>(); 2374143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 2384143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar public Scenario(Step... steps) { 2394143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar Collections.addAll(mStepList, steps); 2404143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 2414143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 2424143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar public int getSeedAdapterSize() { 2434143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar return 10; 2444143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 2454143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 2464143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar public RecyclerView.LayoutManager createLayoutManager() { 2474143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar return BaseWrapContentTest.this.createLayoutManager(); 2484143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 2494143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 2504143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 2514143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar abstract static class Step { 2524143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 2534143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar abstract void onRun() throws Throwable; 2544143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 2554143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 2564143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar class Snapshot { 2574143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 2584143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar Rect mRawChildrenBox = new Rect(); 2594143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 2604143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar Rect mRvSize = new Rect(); 2614143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 2624143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar Rect mRvPadding = new Rect(); 2634143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 2644143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar Rect mRvParentSize = new Rect(); 2654143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 2664143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar LongSparseArray<Rect> mChildCoordinates = new LongSparseArray<>(); 2674143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 2684143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar LongSparseArray<String> mAppear = new LongSparseArray<>(); 2694143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 2704143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar LongSparseArray<String> mDisappear = new LongSparseArray<>(); 2714143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 2724143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar LongSparseArray<String> mPersistent = new LongSparseArray<>(); 2734143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 2744143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar LongSparseArray<String> mChanged = new LongSparseArray<>(); 2754143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 2764143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar int mVerticalGravity; 2774143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 2784143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar int mHorizontalGravity; 2794143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 2804143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar int mOffsetX, mOffsetY;// how much we should offset children 2814143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 2824143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar public Snapshot(RecyclerView recyclerView, LoggingItemAnimator loggingItemAnimator, 2834143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar int horizontalGravity, int verticalGravity) 2844143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar throws Throwable { 2854143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar mRvSize = getViewBounds(recyclerView); 2864143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar mRvParentSize = getViewBounds((View) recyclerView.getParent()); 2874143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar mRvPadding = new Rect(recyclerView.getPaddingLeft(), recyclerView.getPaddingTop(), 2884143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar recyclerView.getPaddingRight(), recyclerView.getPaddingBottom()); 2894143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar mVerticalGravity = verticalGravity; 2904143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar mHorizontalGravity = horizontalGravity; 2914143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar if (mVerticalGravity == Gravity.TOP) { 2924143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar mOffsetY = 0; 2934143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } else { 2944143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar mOffsetY = mRvParentSize.bottom - mRvSize.bottom; 2954143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 2964143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 2974143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar if (mHorizontalGravity == Gravity.LEFT) { 2984143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar mOffsetX = 0; 2994143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } else { 3004143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar mOffsetX = mRvParentSize.right - mRvSize.right; 3014143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 3024143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar collectChildCoordinates(recyclerView); 3034143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar if (loggingItemAnimator != null) { 3044143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar collectInto(mAppear, loggingItemAnimator.mAnimateAppearanceList); 3054143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar collectInto(mDisappear, loggingItemAnimator.mAnimateDisappearanceList); 3064143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar collectInto(mPersistent, loggingItemAnimator.mAnimatePersistenceList); 3074143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar collectInto(mChanged, loggingItemAnimator.mAnimateChangeList); 3084143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 3094143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 3104143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 3114143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar public boolean doesChildrenFitVertically() { 3124143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar return mRawChildrenBox.top >= mRvPadding.top 3134143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar && mRawChildrenBox.bottom <= mRvSize.bottom - mRvPadding.bottom; 3144143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 3154143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 3164143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar public boolean doesChildrenFitHorizontally() { 3174143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar return mRawChildrenBox.left >= mRvPadding.left 3184143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar && mRawChildrenBox.right <= mRvSize.right - mRvPadding.right; 3194143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 3204143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 3214143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar public void assertSame(Snapshot other, int step) { 3224143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar if (mWrapContentConfig.isUnlimitedHeight() && 3234143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar (!doesChildrenFitVertically() || !other.doesChildrenFitVertically())) { 3244143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar if (DEBUG) { 3254143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar Log.d(TAG, "cannot assert coordinates because it does not fit vertically"); 3264143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 3274143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar return; 3284143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 3294143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar if (mWrapContentConfig.isUnlimitedWidth() && 3304143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar (!doesChildrenFitHorizontally() || !other.doesChildrenFitHorizontally())) { 3314143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar if (DEBUG) { 3324143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar Log.d(TAG, "cannot assert coordinates because it does not fit horizontally"); 3334143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 3344143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar return; 3354143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 3364143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar assertMap("child coordinates. step:" + step, mChildCoordinates, 3374143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar other.mChildCoordinates); 3384143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar if (mWrapContentConfig.isUnlimitedHeight() || mWrapContentConfig.isUnlimitedWidth()) { 3394143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar return;//cannot assert animatinos in unlimited size 3404143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 3414143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar assertMap("appearing step:" + step, mAppear, other.mAppear); 3424143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar assertMap("disappearing step:" + step, mDisappear, other.mDisappear); 3434143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar assertMap("persistent step:" + step, mPersistent, other.mPersistent); 3444143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar assertMap("changed step:" + step, mChanged, other.mChanged); 3454143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 3464143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 3474143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar private void assertMap(String prefix, LongSparseArray<?> map1, LongSparseArray<?> map2) { 3484143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar StringBuilder logBuilder = new StringBuilder(); 3494143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar logBuilder.append(prefix).append("\n"); 3504143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar logBuilder.append("map1").append("\n"); 3514143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar logInto(map1, logBuilder); 3524143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar logBuilder.append("map2").append("\n"); 3534143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar logInto(map2, logBuilder); 3544143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar final String log = logBuilder.toString(); 3554143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar assertEquals(log + " same size", map1.size(), map2.size()); 3564143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar for (int i = 0; i < map1.size(); i++) { 3574143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar assertAtIndex(log, map1, map2, i); 3584143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 3594143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 3604143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 3614143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar private void assertAtIndex(String prefix, LongSparseArray<?> map1, LongSparseArray<?> map2, 3624143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar int index) { 3634143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar long key1 = map1.keyAt(index); 3644143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar long key2 = map2.keyAt(index); 3654143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar assertEquals(prefix + "key mismatch at index " + index, key1, key2); 3664143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar Object value1 = map1.valueAt(index); 3674143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar Object value2 = map2.valueAt(index); 3684143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar assertEquals(prefix + " value mismatch at index " + index, value1, value2); 3694143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 3704143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 3714143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar private void logInto(LongSparseArray<?> map, StringBuilder sb) { 3724143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar for (int i = 0; i < map.size(); i++) { 3734143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar long key = map.keyAt(i); 3744143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar Object value = map.valueAt(i); 3754143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar sb.append(key).append(" : ").append(value).append("\n"); 3764143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 3774143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 3784143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 3794143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar @Override 3804143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar public String toString() { 3814143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar StringBuilder sb = new StringBuilder("Snapshot{\n"); 3824143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar sb.append("child coordinates:\n"); 3834143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar logInto(mChildCoordinates, sb); 3844143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar sb.append("appear animations:\n"); 3854143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar logInto(mAppear, sb); 3864143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar sb.append("disappear animations:\n"); 3874143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar logInto(mDisappear, sb); 3884143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar sb.append("change animations:\n"); 3894143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar logInto(mChanged, sb); 3904143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar sb.append("persistent animations:\n"); 3914143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar logInto(mPersistent, sb); 3924143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar sb.append("}"); 3934143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar return sb.toString(); 3944143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 3954143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 3964143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar @Override 3974143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar public int hashCode() { 3984143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar int result = mChildCoordinates.hashCode(); 3994143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar result = 31 * result + mAppear.hashCode(); 4004143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar result = 31 * result + mDisappear.hashCode(); 4014143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar result = 31 * result + mPersistent.hashCode(); 4024143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar result = 31 * result + mChanged.hashCode(); 4034143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar return result; 4044143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 4054143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 4064143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar private void collectInto( 4074143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar LongSparseArray<String> target, 4084143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar List<? extends BaseRecyclerViewAnimationsTest.AnimateLogBase> list) { 4094143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar for (BaseRecyclerViewAnimationsTest.AnimateLogBase base : list) { 4104143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar long id = getItemId(base.viewHolder); 4114143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar assertNull(target.get(id)); 4124143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar target.put(id, log(base)); 4134143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 4144143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 4154143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 4164143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar private String log(BaseRecyclerViewAnimationsTest.AnimateLogBase base) { 4174143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar return base.getClass().getSimpleName() + 4184143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar ((TextView) base.viewHolder.itemView).getText() + ": " + 4194143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar "[pre:" + log(base.postInfo) + 4204143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar ", post:" + log(base.postInfo) + "]"; 4214143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 4224143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 4234143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar private String log(BaseRecyclerViewAnimationsTest.LoggingInfo postInfo) { 4244143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar if (postInfo == null) { 4254143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar return "?"; 4264143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 4274143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar return "PI[flags: " + postInfo.changeFlags 4284143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar + ",l:" + (postInfo.left + mOffsetX) 4294143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar + ",t:" + (postInfo.top + mOffsetY) 4304143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar + ",r:" + (postInfo.right + mOffsetX) 4314143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar + ",b:" + (postInfo.bottom + mOffsetY) + "]"; 4324143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 4334143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 4344143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar void collectChildCoordinates(RecyclerView recyclerView) throws Throwable { 4354143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar mRawChildrenBox = new Rect(0, 0, 0, 0); 4364143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar final int childCount = recyclerView.getChildCount(); 4374143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar for (int i = 0; i < childCount; i++) { 4384143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar View child = recyclerView.getChildAt(i); 4394143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar Rect childBounds = getChildBounds(recyclerView, child, true); 4404143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar mRawChildrenBox.union(getChildBounds(recyclerView, child, false)); 4414143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar RecyclerView.ViewHolder childViewHolder = recyclerView.getChildViewHolder(child); 4424143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar mChildCoordinates.put(getItemId(childViewHolder), childBounds); 4434143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 4444143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 4454143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 4464143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar private Rect getViewBounds(View view) { 4474143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar return new Rect(view.getLeft(), view.getTop(), view.getRight(), view.getBottom()); 4484143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 4494143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 4504143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar private Rect getChildBounds(RecyclerView recyclerView, View child, boolean offset) { 4514143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar RecyclerView.LayoutManager layoutManager = recyclerView.getLayoutManager(); 4524143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar RecyclerView.LayoutParams lp = (RecyclerView.LayoutParams) child.getLayoutParams(); 4534143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar Rect rect = new Rect(layoutManager.getDecoratedLeft(child) - lp.leftMargin, 4544143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar layoutManager.getDecoratedTop(child) - lp.topMargin, 4554143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar layoutManager.getDecoratedRight(child) + lp.rightMargin, 4564143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar layoutManager.getDecoratedBottom(child) + lp.bottomMargin); 4574143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar if (offset) { 4584143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar rect.offset(mOffsetX, mOffsetY); 4594143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 4604143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar return rect; 4614143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 4624143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 4634143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar private long getItemId(RecyclerView.ViewHolder vh) { 4644143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar if (vh instanceof TestViewHolder) { 4654143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar return ((TestViewHolder) vh).mBoundItem.mId; 4664143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } else if (vh instanceof BaseWrapContentWithAspectRatioTest.WrapContentViewHolder) { 4674143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar BaseWrapContentWithAspectRatioTest.WrapContentViewHolder casted = 4684143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar (BaseWrapContentWithAspectRatioTest.WrapContentViewHolder) vh; 4694143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar return casted.mView.mBehavior.getId(); 4704143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } else { 4714143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar throw new IllegalArgumentException("i don't support any VH"); 4724143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 4734143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 4744143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 4754143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar public void assertRvSize() { 4764143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar if (shouldWrapContentHorizontally()) { 4774143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar int expectedW = mRawChildrenBox.width() + mRvPadding.left + mRvPadding.right; 4784143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar assertTrue(mRvSize.width() + " <= " + expectedW, mRvSize.width() <= expectedW); 4794143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 4804143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar if (shouldWrapContentVertically()) { 4814143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar int expectedH = mRawChildrenBox.height() + mRvPadding.top + mRvPadding.bottom; 4824143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar assertTrue(mRvSize.height() + "<=" + expectedH, mRvSize.height() <= expectedH); 4834143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 4844143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 4854143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 4864143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 4874143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar protected boolean shouldWrapContentHorizontally() { 4884143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar return true; 4894143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 4904143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 4914143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar protected boolean shouldWrapContentVertically() { 4924143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar return true; 4934143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 4944143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 4954143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar static class WrapContentConfig { 4964143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 4976b6a29eea7f6a212447b3cc7b45a081b609ca4b1Yigit Boyar public boolean unlimitedWidth; 4986b6a29eea7f6a212447b3cc7b45a081b609ca4b1Yigit Boyar public boolean unlimitedHeight; 4996b6a29eea7f6a212447b3cc7b45a081b609ca4b1Yigit Boyar public Rect padding = new Rect(0, 0, 0, 0); 5004143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 5014143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar public WrapContentConfig(boolean unlimitedWidth, boolean unlimitedHeight) { 5024143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar this.unlimitedWidth = unlimitedWidth; 5034143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar this.unlimitedHeight = unlimitedHeight; 5044143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 5054143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 5066b6a29eea7f6a212447b3cc7b45a081b609ca4b1Yigit Boyar public WrapContentConfig(boolean unlimitedWidth, boolean unlimitedHeight, Rect padding) { 5076b6a29eea7f6a212447b3cc7b45a081b609ca4b1Yigit Boyar this.unlimitedWidth = unlimitedWidth; 5086b6a29eea7f6a212447b3cc7b45a081b609ca4b1Yigit Boyar this.unlimitedHeight = unlimitedHeight; 5096b6a29eea7f6a212447b3cc7b45a081b609ca4b1Yigit Boyar this.padding.set(padding); 5106b6a29eea7f6a212447b3cc7b45a081b609ca4b1Yigit Boyar } 5116b6a29eea7f6a212447b3cc7b45a081b609ca4b1Yigit Boyar 5124143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar public boolean isUnlimitedWidth() { 5134143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar return unlimitedWidth; 5144143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 5154143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 5164143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar public WrapContentConfig setUnlimitedWidth(boolean unlimitedWidth) { 5174143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar this.unlimitedWidth = unlimitedWidth; 5184143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar return this; 5194143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 5204143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 5214143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar public boolean isUnlimitedHeight() { 5224143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar return unlimitedHeight; 5234143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 5244143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 5254143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar public WrapContentConfig setUnlimitedHeight(boolean unlimitedHeight) { 5264143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar this.unlimitedHeight = unlimitedHeight; 5274143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar return this; 5284143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 5294143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 5304143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar @Override 5314143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar public String toString() { 5326b6a29eea7f6a212447b3cc7b45a081b609ca4b1Yigit Boyar return "WrapContentConfig{" 5336b6a29eea7f6a212447b3cc7b45a081b609ca4b1Yigit Boyar + "unlimitedWidth=" + unlimitedWidth 534e9f9cd8d0e9008340985d17a2541ab24b3adb391Aurimas Liutikas + ",unlimitedHeight=" + unlimitedHeight 535e9f9cd8d0e9008340985d17a2541ab24b3adb391Aurimas Liutikas + ",padding=" + padding 5366b6a29eea7f6a212447b3cc7b45a081b609ca4b1Yigit Boyar + '}'; 5374143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 5384143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar 5394143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar public TestedFrameLayout.FullControlLayoutParams toLayoutParams(int wDim, int hDim) { 5404143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar TestedFrameLayout.FullControlLayoutParams 5414143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar lp = new TestedFrameLayout.FullControlLayoutParams( 5424143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar wDim, hDim); 5434143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar if (unlimitedWidth) { 5444143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar lp.wSpec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED); 5454143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 5464143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar if (unlimitedHeight) { 5474143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar lp.hSpec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED); 5484143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 5494143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar return lp; 5504143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 5514143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar } 5524143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar} 553