[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.hamcrest.CoreMatchers;
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;
27import android.view.ViewGroup;
28
29import java.util.ArrayList;
30import java.util.List;
31
32import static android.support.v7.widget.LinearLayoutManager.HORIZONTAL;
33import static android.support.v7.widget.LinearLayoutManager.VERTICAL;
34import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
35import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
36import static org.hamcrest.MatcherAssert.assertThat;
37
38@RunWith(Parameterized.class)
39@MediumTest
40public class LinearLayoutManagerWrapContentWithAspectRatioTest
41        extends BaseWrapContentWithAspectRatioTest {
42
43    final LinearLayoutManagerTest.Config mConfig;
44    final float mRatio;
45
46    public LinearLayoutManagerWrapContentWithAspectRatioTest(
47            BaseLinearLayoutManagerTest.Config config,
48            BaseWrapContentTest.WrapContentConfig wrapContentConfig,
49            float ratio) {
50        super(wrapContentConfig);
51        mConfig = config;
52        mRatio = ratio;
53    }
54
55    @Parameterized.Parameters(name = "{0} {1} ratio:{2}")
56    public static Iterable<Object[]> data() {
57        List<Object[]> params = new ArrayList<>();
58        for (float ratio : new float[]{.5f, 1f, 2f}) {
59            for (int orientation : new int[]{VERTICAL, HORIZONTAL}) {
60                for (boolean reverseLayout : new boolean[]{false, true}) {
61                    for (boolean stackFromBottom : new boolean[]{false, true}) {
62                        params.add(
63                                new Object[]{
64                                        new BaseLinearLayoutManagerTest.Config(orientation,
65                                                reverseLayout, stackFromBottom),
66                                        new BaseWrapContentTest.WrapContentConfig(
67                                                false, false),
68                                        ratio
69                                }
70                        );
71                        params.add(
72                                new Object[]{
73                                        new BaseLinearLayoutManagerTest.Config(orientation,
74                                                reverseLayout, stackFromBottom),
75                                        new BaseWrapContentTest.WrapContentConfig(
76                                                HORIZONTAL == orientation,
77                                                VERTICAL == orientation),
78                                        ratio
79                                }
80                        );
81                        params.add(
82                                new Object[]{
83                                        new BaseLinearLayoutManagerTest.Config(orientation,
84                                                reverseLayout, stackFromBottom),
85                                        new BaseWrapContentTest.WrapContentConfig(
86                                                VERTICAL == orientation,
87                                                HORIZONTAL == orientation),
88                                        ratio
89                                }
90                        );
91                        params.add(
92                                new Object[]{
93                                        new BaseLinearLayoutManagerTest.Config(orientation,
94                                                reverseLayout, stackFromBottom),
95                                        new BaseWrapContentTest.WrapContentConfig(
96                                                true, true),
97                                        ratio
98                                }
99                        );
100                    }
101                }
102            }
103        }
104        return params;
105    }
106
107    @Test
108    public void wrapContentAffectsOtherOrientation() throws Throwable {
109        TestedFrameLayout.FullControlLayoutParams
110                wrapContent = new TestedFrameLayout.FullControlLayoutParams(
111                ViewGroup.LayoutParams.WRAP_CONTENT,
112                ViewGroup.LayoutParams.WRAP_CONTENT);
113        int testOrientation = mConfig.mOrientation == VERTICAL ? HORIZONTAL : VERTICAL;
114        boolean unlimitedSize = false;
115        if (mWrapContentConfig.isUnlimitedHeight()) {
116            wrapContent.hSpec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
117            unlimitedSize = testOrientation == VERTICAL;
118        }
119        if (mWrapContentConfig.isUnlimitedWidth()) {
120            wrapContent.wSpec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
121            unlimitedSize |= testOrientation == HORIZONTAL;
122        }
123
124        RecyclerView.LayoutManager layoutManager = createFromConfig();
125        BaseWrapContentTest.WrappedRecyclerView
126                recyclerView = new BaseWrapContentTest.WrappedRecyclerView(getActivity());
127        recyclerView.setBackgroundColor(Color.rgb(0, 0, 255));
128        recyclerView.setLayoutManager(layoutManager);
129        recyclerView.setLayoutParams(wrapContent);
130
131        AspectRatioMeasureBehavior behavior1 = new AspectRatioMeasureBehavior(10, 10,
132                WRAP_CONTENT, WRAP_CONTENT).aspectRatio(testOrientation, mRatio);
133        AspectRatioMeasureBehavior behavior2 = new AspectRatioMeasureBehavior(15, 15,
134                testOrientation == HORIZONTAL ? MATCH_PARENT : WRAP_CONTENT,
135                testOrientation == VERTICAL ? MATCH_PARENT : WRAP_CONTENT)
136                .aspectRatio(testOrientation, mRatio);
137        AspectRatioMeasureBehavior behavior3 = new AspectRatioMeasureBehavior(8, 8,
138                testOrientation == HORIZONTAL ? MATCH_PARENT : WRAP_CONTENT,
139                testOrientation == VERTICAL ? MATCH_PARENT : WRAP_CONTENT)
140                .aspectRatio(testOrientation, mRatio);
141
142        WrapContentAdapter adapter = new WrapContentAdapter(
143                behavior1, behavior2, behavior3
144        );
145
146        recyclerView.setAdapter(adapter);
147        setRecyclerView(recyclerView);
148        recyclerView.waitUntilLayout();
149
150        int parentDim = getSize((View) recyclerView.getParent(), testOrientation);
151
152        View itemView1 = recyclerView.findViewHolderForAdapterPosition(0).itemView;
153        assertThat("first child test size", getSize(itemView1, testOrientation),
154                CoreMatchers.is(10));
155        assertThat("first child dependant size", getSize(itemView1, mConfig.mOrientation),
156                CoreMatchers.is(behavior1.getSecondary(10)));
157
158        View itemView2 = recyclerView.findViewHolderForAdapterPosition(1).itemView;
159        assertThat("second child test size", getSize(itemView2, testOrientation),
160                CoreMatchers.is(15));
161        assertThat("second child dependant size", getSize(itemView2, mConfig.mOrientation),
162                CoreMatchers.is(behavior2.getSecondary(15)));
163
164        View itemView3 = recyclerView.findViewHolderForAdapterPosition(2).itemView;
165        assertThat("third child test size", getSize(itemView3, testOrientation),
166                CoreMatchers.is(15));
167        assertThat("third child dependant size", getSize(itemView3, mConfig.mOrientation),
168                CoreMatchers.is(behavior3.getSecondary(15)));
169
170        assertThat("it should be measured only once", behavior1.measureSpecs.size(),
171                CoreMatchers.is(1));
172        if (unlimitedSize) {
173            assertThat(behavior1.getSpec(0, testOrientation),
174                    MeasureSpecMatcher.is(0, View.MeasureSpec.UNSPECIFIED));
175        } else {
176            assertThat(behavior1.getSpec(0, testOrientation),
177                    MeasureSpecMatcher.is(parentDim, View.MeasureSpec.AT_MOST));
178        }
179
180        assertThat("it should be measured once", behavior2.measureSpecs.size(), CoreMatchers.is(1));
181        if (unlimitedSize) {
182            assertThat(behavior2.getSpec(0, testOrientation),
183                    MeasureSpecMatcher.is(0, View.MeasureSpec.UNSPECIFIED));
184        } else {
185            assertThat(behavior2.getSpec(0, testOrientation),
186                    MeasureSpecMatcher.is(parentDim, View.MeasureSpec.AT_MOST));
187        }
188
189        assertThat("it should be measured twice", behavior3.measureSpecs.size(),
190                CoreMatchers.is(2));
191        if (unlimitedSize) {
192            assertThat(behavior3.getSpec(0, testOrientation),
193                    MeasureSpecMatcher.is(0, View.MeasureSpec.UNSPECIFIED));
194        } else {
195            assertThat(behavior3.getSpec(0, testOrientation),
196                    MeasureSpecMatcher.is(parentDim, View.MeasureSpec.AT_MOST));
197        }
198
199        assertThat(behavior3.getSpec(1, testOrientation),
200                MeasureSpecMatcher.is(15, View.MeasureSpec.EXACTLY));
201        final int totalScrollSize = getSize(itemView1, mConfig.mOrientation)
202                + getSize(itemView2, mConfig.mOrientation)
203                + getSize(itemView3, mConfig.mOrientation);
204        assertThat("RecyclerView should wrap its content in the scroll direction",
205                getSize(mRecyclerView, mConfig.mOrientation), CoreMatchers.is(totalScrollSize));
206        assertThat("RecyclerView should wrap its content in the scroll direction",
207                getSize(mRecyclerView, testOrientation), CoreMatchers.is(15));
208    }
209
210    private LinearLayoutManager createFromConfig() {
211        LinearLayoutManager llm = new LinearLayoutManager(getActivity(), mConfig.mOrientation,
212                mConfig.mReverseLayout);
213        llm.setStackFromEnd(mConfig.mStackFromEnd);
214        return llm;
215    }
216}
217