[go: nahoru, domu]

1/*
2 * Copyright (C) 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package android.support.v7.widget;
18
19import org.junit.Before;
20import org.junit.Test;
21import org.junit.runner.RunWith;
22import org.junit.runners.Parameterized;
23
24import android.graphics.Color;
25import android.test.suitebuilder.annotation.MediumTest;
26import android.view.View;
27
28import java.util.ArrayList;
29import java.util.List;
30
31import static android.support.v7.widget.LinearLayoutManager.HORIZONTAL;
32import static android.support.v7.widget.LinearLayoutManager.VERTICAL;
33import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
34import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
35import static org.hamcrest.MatcherAssert.assertThat;
36import static android.support.v7.widget.BaseWrapContentTest.WrapContentConfig;
37import static android.support.v7.widget.GridLayoutManagerTest.Config;
38import static org.hamcrest.CoreMatchers.*;
39import static android.view.View.MeasureSpec.UNSPECIFIED;
40import static android.view.View.MeasureSpec.AT_MOST;
41import static android.view.View.MeasureSpec.EXACTLY;
42
43@RunWith(Parameterized.class)
44@MediumTest
45public class GridLayoutManagerWrapContentWithAspectRatioTest
46        extends BaseWrapContentWithAspectRatioTest {
47
48    @Parameterized.Parameters(name = "{0} {1} {2}")
49    public static List<Object[]> params() {
50        List<Object[]> params = new ArrayList<>();
51        for (int orientation : new int[]{VERTICAL, HORIZONTAL}) {
52            for (boolean reverseLayout : new boolean[]{false, true}) {
53                for (boolean unlimitedW : new boolean[]{true, false}) {
54                    for (boolean unlimitedH : new boolean[]{true, false}) {
55                        for (int behavior1Size : new int[]{8, 10, 12}) {
56                            params.add(new Object[]{
57                                    new WrapContentConfig(unlimitedW, unlimitedH),
58                                    new Config(3, orientation, reverseLayout),
59                                    behavior1Size
60                            });
61                        }
62
63                    }
64                }
65
66            }
67        }
68        return params;
69    }
70
71    private GridLayoutManagerTest.Config mConfig;
72
73    private int mBehavior1Size;
74
75    int mTestOrientation;
76
77    boolean mUnlimited;
78
79    RecyclerView.LayoutManager mLayoutManager;
80
81    BaseWrapContentTest.WrappedRecyclerView mRecyclerView;
82
83    OrientationHelper mHelper;
84
85    public GridLayoutManagerWrapContentWithAspectRatioTest(WrapContentConfig wrapContentConfig,
86            GridLayoutManagerTest.Config config, int behavior1Size) {
87        super(wrapContentConfig);
88        mConfig = config;
89        mBehavior1Size = behavior1Size;
90    }
91
92    @Before
93    public final void init() {
94        TestedFrameLayout.FullControlLayoutParams lp =
95                mWrapContentConfig.toLayoutParams(WRAP_CONTENT, WRAP_CONTENT);
96        if (mConfig.mOrientation == VERTICAL) {
97            mTestOrientation = HORIZONTAL;
98            mUnlimited = lp.wSpec != null;
99        } else {
100            mTestOrientation = VERTICAL;
101            mUnlimited = lp.hSpec != null;
102        }
103        mLayoutManager = createFromConfig();
104
105        mRecyclerView = new BaseWrapContentTest.WrappedRecyclerView(getActivity());
106        mHelper = OrientationHelper.createOrientationHelper(
107                mLayoutManager, 1 - mConfig.mOrientation);
108
109        mRecyclerView.setBackgroundColor(Color.rgb(0, 0, 255));
110        mRecyclerView.setLayoutManager(mLayoutManager);
111        mRecyclerView.setLayoutParams(lp);
112    }
113
114    @Test
115    public void testChildWithMultipleSpans() throws Throwable {
116        MeasureBehavior behavior1;
117        behavior1 = new MeasureBehavior(mBehavior1Size, mBehavior1Size,
118                mTestOrientation == HORIZONTAL ? MATCH_PARENT : WRAP_CONTENT,
119                mTestOrientation == VERTICAL ? MATCH_PARENT : WRAP_CONTENT);
120
121        MeasureBehavior behavior2 = new MeasureBehavior(
122                mTestOrientation == HORIZONTAL ? 30 : 10,
123                mTestOrientation == VERTICAL ? 30 : 10, WRAP_CONTENT, WRAP_CONTENT);
124        WrapContentAdapter adapter = new WrapContentAdapter(behavior1, behavior2);
125        ((GridLayoutManager) mLayoutManager).setSpanSizeLookup(
126                new GridLayoutManager.SpanSizeLookup() {
127                    @Override
128                    public int getSpanSize(int position) {
129                        return position == 1 ? 2 : 1;
130                    }
131                });
132        mRecyclerView.setAdapter(adapter);
133        setRecyclerView(mRecyclerView);
134        mRecyclerView.waitUntilLayout();
135
136        final int parentSize = getSize((View) mRecyclerView.getParent(), mTestOrientation);
137
138        if (mUnlimited) {
139            assertThat(behavior1.getSpec(0, mTestOrientation),
140                    MeasureSpecMatcher.mode(UNSPECIFIED));
141            assertThat(behavior2.getSpec(0, mTestOrientation),
142                    MeasureSpecMatcher.mode(UNSPECIFIED));
143        } else {
144            int[] borders = GridLayoutManager.calculateItemBorders(null,
145                    mConfig.mSpanCount, parentSize);
146            assertThat(behavior1.getSpec(0, mTestOrientation),
147                    MeasureSpecMatcher.is(borders[1] - borders[0], AT_MOST));
148            assertThat(behavior2.getSpec(0, mTestOrientation),
149                    MeasureSpecMatcher.is(borders[3] - borders[1], AT_MOST));
150        }
151        // child0 should be measured again because it measured its size as 10
152        assertThat(behavior1.getSpec(1, mTestOrientation),
153                MeasureSpecMatcher.is(15, EXACTLY));
154        assertThat(behavior1.getSpec(1, mConfig.mOrientation),
155                MeasureSpecMatcher.mode(UNSPECIFIED));
156        switch (mBehavior1Size) {
157            case 10:
158                assertThat(behavior1.measureSpecs.size(), is(2));
159                assertThat(behavior2.measureSpecs.size(), is(1));
160                break;
161            case 8:
162                assertThat(behavior2.measureSpecs.size(), is(1));
163                assertThat(behavior1.measureSpecs.size(), is(3));
164                assertThat(behavior1.getSpec(2, mTestOrientation),
165                        MeasureSpecMatcher.is(15, EXACTLY));
166                assertThat(behavior1.getSpec(2, mConfig.mOrientation),
167                        MeasureSpecMatcher.is(10, EXACTLY));
168                break;
169            case 12:
170                assertThat(behavior1.measureSpecs.size(), is(2));
171                assertThat(behavior2.measureSpecs.size(), is(2));
172                assertThat(behavior2.getSpec(1, mTestOrientation),
173                        MeasureSpecMatcher.is(30, AT_MOST));
174                assertThat(behavior2.getSpec(1, mConfig.mOrientation),
175                        MeasureSpecMatcher.is(12, EXACTLY));
176                break;
177        }
178
179        View child0 = mRecyclerView.getChildAt(0);
180        assertThat(getSize(child0, mTestOrientation), is(15));
181
182        View child1 = mRecyclerView.getChildAt(1);
183        assertThat(getSize(child1, mTestOrientation), is(30));
184
185        assertThat(mHelper.getDecoratedStart(child0), is(0));
186        assertThat(mHelper.getDecoratedStart(child1), is(15));
187
188        assertThat(mHelper.getDecoratedEnd(child0), is(15));
189        assertThat(mHelper.getDecoratedEnd(child1), is(45));
190
191        assertThat(mHelper.getDecoratedMeasurementInOther(child0),
192                is(Math.max(10, mBehavior1Size)));
193        assertThat(mHelper.getDecoratedMeasurementInOther(child1),
194                is(Math.max(10, mBehavior1Size)));
195
196        assertThat(getSize(mRecyclerView, mTestOrientation), is(45));
197        assertThat(getSize(mRecyclerView, 1 - mTestOrientation), is(Math.max(10, mBehavior1Size)));
198    }
199
200    @Test
201    public void testChildWithMatchParentInOtherDirection() throws Throwable {
202        MeasureBehavior behavior1;
203        behavior1 = new MeasureBehavior(mBehavior1Size, mBehavior1Size,
204                mTestOrientation == HORIZONTAL ? MATCH_PARENT : WRAP_CONTENT,
205                mTestOrientation == VERTICAL ? MATCH_PARENT : WRAP_CONTENT);
206
207        MeasureBehavior behavior2 = new MeasureBehavior(
208                mTestOrientation == HORIZONTAL ? 15 : 10,
209                mTestOrientation == VERTICAL ? 15 : 10, WRAP_CONTENT, WRAP_CONTENT);
210        WrapContentAdapter adapter = new WrapContentAdapter(behavior1, behavior2);
211
212        mRecyclerView.setAdapter(adapter);
213        setRecyclerView(mRecyclerView);
214        mRecyclerView.waitUntilLayout();
215        final int parentSize = getSize((View) mRecyclerView.getParent(), mTestOrientation);
216        if (mUnlimited) {
217            assertThat(behavior1.getSpec(0, mTestOrientation),
218                    MeasureSpecMatcher.mode(UNSPECIFIED));
219            assertThat(behavior2.getSpec(0, mTestOrientation),
220                    MeasureSpecMatcher.mode(UNSPECIFIED));
221        } else {
222            int[] borders = GridLayoutManager.calculateItemBorders(null, mConfig.mSpanCount,
223                    parentSize);
224            assertThat(behavior1.getSpec(0, mTestOrientation),
225                    MeasureSpecMatcher.is(borders[1] - borders[0], AT_MOST));
226            assertThat(behavior2.getSpec(0, mTestOrientation),
227                    MeasureSpecMatcher.is(borders[2] - borders[1], AT_MOST));
228        }
229        // child0 should be measured again because it measured its size as 10
230        assertThat(behavior1.getSpec(1, mTestOrientation),
231                MeasureSpecMatcher.is(15, EXACTLY));
232        assertThat(behavior1.getSpec(1, mConfig.mOrientation),
233                MeasureSpecMatcher.mode(UNSPECIFIED));
234        switch (mBehavior1Size) {
235            case 10:
236                assertThat(behavior1.measureSpecs.size(), is(2));
237                assertThat(behavior2.measureSpecs.size(), is(1));
238                break;
239            case 8:
240                assertThat(behavior2.measureSpecs.size(), is(1));
241                assertThat(behavior1.measureSpecs.size(), is(3));
242                assertThat(behavior1.getSpec(2, mTestOrientation),
243                        MeasureSpecMatcher.is(15, EXACTLY));
244                assertThat(behavior1.getSpec(2, mConfig.mOrientation),
245                        MeasureSpecMatcher.is(10, EXACTLY));
246                break;
247            case 12:
248                assertThat(behavior1.measureSpecs.size(), is(2));
249                assertThat(behavior2.measureSpecs.size(), is(2));
250                assertThat(behavior2.getSpec(1, mTestOrientation),
251                        MeasureSpecMatcher.is(15, AT_MOST));
252                assertThat(behavior2.getSpec(1, mConfig.mOrientation),
253                        MeasureSpecMatcher.is(12, EXACTLY));
254                break;
255        }
256
257        View child0 = mRecyclerView.getChildAt(0);
258        assertThat(getSize(child0, mTestOrientation), is(15));
259
260        View child1 = mRecyclerView.getChildAt(1);
261        assertThat(getSize(child1, mTestOrientation), is(15));
262
263        assertThat(mHelper.getDecoratedStart(child0), is(0));
264        assertThat(mHelper.getDecoratedStart(child1), is(15));
265
266        assertThat(mHelper.getDecoratedEnd(child0), is(15));
267        assertThat(mHelper.getDecoratedEnd(child1), is(30));
268
269        assertThat(mHelper.getDecoratedMeasurementInOther(child0),
270                is(Math.max(10, mBehavior1Size)));
271        assertThat(mHelper.getDecoratedMeasurementInOther(child1),
272                is(Math.max(10, mBehavior1Size)));
273
274        assertThat(getSize(mRecyclerView, mTestOrientation), is(45));
275        assertThat(getSize(mRecyclerView, 1 - mTestOrientation), is(Math.max(10, mBehavior1Size)));
276    }
277
278    @Test
279    public void testAllChildrenWrapContentInOtherDirection() throws Throwable {
280        MeasureBehavior behavior1;
281        behavior1 = new MeasureBehavior(mBehavior1Size, mBehavior1Size, WRAP_CONTENT, WRAP_CONTENT);
282
283        MeasureBehavior behavior2 = new MeasureBehavior(
284                mTestOrientation == HORIZONTAL ? 15 : 10,
285                mTestOrientation == VERTICAL ? 15 : 10, WRAP_CONTENT, WRAP_CONTENT);
286        WrapContentAdapter adapter = new WrapContentAdapter(behavior1, behavior2);
287
288        mRecyclerView.setAdapter(adapter);
289        setRecyclerView(mRecyclerView);
290        mRecyclerView.waitUntilLayout();
291        final int parentSize = getSize((View) mRecyclerView.getParent(), mTestOrientation);
292        if (mUnlimited) {
293            assertThat(behavior1.getSpec(0, mTestOrientation),
294                    MeasureSpecMatcher.mode(UNSPECIFIED));
295            assertThat(behavior2.getSpec(0, mTestOrientation),
296                    MeasureSpecMatcher.mode(UNSPECIFIED));
297        } else {
298            int[] borders = GridLayoutManager.calculateItemBorders(null,
299                    mConfig.mSpanCount, parentSize);
300            assertThat(behavior1.getSpec(0, mTestOrientation),
301                    MeasureSpecMatcher.is(borders[1] - borders[0], AT_MOST));
302            assertThat(behavior2.getSpec(0, mTestOrientation),
303                    MeasureSpecMatcher.is(borders[2] - borders[1], AT_MOST));
304        }
305
306        switch (mBehavior1Size) {
307            case 10:
308                assertThat(behavior1.measureSpecs.size(), is(1));
309                assertThat(behavior2.measureSpecs.size(), is(1));
310                break;
311            case 8:
312                assertThat(behavior2.measureSpecs.size(), is(1));
313                assertThat(behavior1.measureSpecs.size(), is(2));
314                assertThat(behavior1.getSpec(1, mTestOrientation),
315                        MeasureSpecMatcher.is(15, AT_MOST));
316                assertThat(behavior1.getSpec(1, mConfig.mOrientation),
317                        MeasureSpecMatcher.is(10, EXACTLY));
318                break;
319            case 12:
320                assertThat(behavior1.measureSpecs.size(), is(1));
321                assertThat(behavior2.measureSpecs.size(), is(2));
322                assertThat(behavior2.getSpec(1, mTestOrientation),
323                        MeasureSpecMatcher.is(15, AT_MOST));
324                assertThat(behavior2.getSpec(1, mConfig.mOrientation),
325                        MeasureSpecMatcher.is(12, EXACTLY));
326                break;
327        }
328
329        View child0 = mRecyclerView.getChildAt(0);
330        assertThat(getSize(child0, mTestOrientation), is(mBehavior1Size));
331
332        View child1 = mRecyclerView.getChildAt(1);
333        assertThat(getSize(child1, mTestOrientation), is(15));
334
335        assertThat(mHelper.getDecoratedStart(child0), is(0));
336        assertThat(mHelper.getDecoratedStart(child1), is(15));
337
338        assertThat(mHelper.getDecoratedEnd(child0), is(mBehavior1Size));
339        assertThat(mHelper.getDecoratedEnd(child1), is(30));
340
341        assertThat(mHelper.getDecoratedMeasurementInOther(child0),
342                is(Math.max(10, mBehavior1Size)));
343        assertThat(mHelper.getDecoratedMeasurementInOther(child1),
344                is(Math.max(10, mBehavior1Size)));
345
346        assertThat(getSize(mRecyclerView, mTestOrientation), is(45));
347        assertThat(getSize(mRecyclerView, 1 - mTestOrientation), is(Math.max(10, mBehavior1Size)));
348    }
349
350    private RecyclerView.LayoutManager createFromConfig() {
351        return new GridLayoutManager(getActivity(), mConfig.mSpanCount,
352                mConfig.mOrientation, mConfig.mReverseLayout);
353    }
354}
355