Home | History | Annotate | Download | only in cts
      1 /*
      2  * Copyright (C) 2012 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 
     17 package android.widget.cts;
     18 
     19 import static android.widget.GridLayout.spec;
     20 
     21 import static org.junit.Assert.assertEquals;
     22 import static org.junit.Assert.assertNotNull;
     23 import static org.junit.Assert.assertTrue;
     24 
     25 import android.app.Activity;
     26 import android.content.Context;
     27 import android.util.AttributeSet;
     28 import android.util.Xml;
     29 import android.view.Gravity;
     30 import android.view.View;
     31 import android.view.ViewGroup;
     32 import android.widget.AbsoluteLayout;
     33 import android.widget.Button;
     34 import android.widget.GridLayout;
     35 import android.widget.TextView;
     36 
     37 import androidx.test.annotation.UiThreadTest;
     38 import androidx.test.filters.MediumTest;
     39 import androidx.test.rule.ActivityTestRule;
     40 import androidx.test.runner.AndroidJUnit4;
     41 
     42 import org.junit.Before;
     43 import org.junit.Rule;
     44 import org.junit.Test;
     45 import org.junit.runner.RunWith;
     46 import org.xmlpull.v1.XmlPullParser;
     47 
     48 /**
     49  * Test {@link GridLayout}.
     50  */
     51 @MediumTest
     52 @RunWith(AndroidJUnit4.class)
     53 public class GridLayoutTest {
     54 
     55     // The size of the off-screen test container in which we we will testing layout.
     56     public static final int MAX_X = 2000;
     57     public static final int MAX_Y = 2000;
     58 
     59     private static abstract class Alignment {
     60         String name;
     61         int gravity;
     62 
     63         abstract int getValue(View v);
     64 
     65         protected Alignment(String name, int gravity) {
     66             this.name = name;
     67             this.gravity = gravity;
     68         }
     69     }
     70 
     71     private static final Alignment[] HORIZONTAL_ALIGNMENTS = {
     72             new Alignment("LEFT", Gravity.LEFT) {
     73                 @Override
     74                 int getValue(View v) {
     75                     return v.getLeft();
     76                 }
     77             },
     78             new Alignment("CENTER", Gravity.CENTER_HORIZONTAL) {
     79                 @Override
     80                 int getValue(View v) {
     81                     return (v.getLeft() + v.getRight()) / 2;
     82                 }
     83             },
     84             new Alignment("RIGHT", Gravity.RIGHT) {
     85                 @Override
     86                 int getValue(View v) {
     87                     return v.getRight();
     88                 }
     89             },
     90             new Alignment("FILL", Gravity.FILL_HORIZONTAL) {
     91                 @Override
     92                 int getValue(View v) {
     93                     return v.getWidth();
     94                 }
     95             }
     96     };
     97 
     98     private static final Alignment[] VERTICAL_ALIGNMENTS = {
     99             new Alignment("TOP", Gravity.TOP) {
    100                 @Override
    101                 int getValue(View v) {
    102                     return v.getTop();
    103                 }
    104             },
    105             new Alignment("CENTER", Gravity.CENTER_VERTICAL) {
    106                 @Override
    107                 int getValue(View v) {
    108                     return (v.getTop() + v.getBottom()) / 2;
    109                 }
    110             },
    111             new Alignment("BASELINE", Gravity.NO_GRAVITY) {
    112                 @Override
    113                 int getValue(View v) {
    114                     return v.getTop() + v.getBaseline();
    115                 }
    116             },
    117             new Alignment("BOTTOM", Gravity.BOTTOM) {
    118                 @Override
    119                 int getValue(View v) {
    120                     return v.getBottom();
    121                 }
    122             },
    123             new Alignment("FILL", Gravity.FILL_VERTICAL) {
    124                 @Override
    125                 int getValue(View v) {
    126                     return v.getHeight();
    127                 }
    128             }
    129     };
    130 
    131     private Activity mActivity;
    132     private GridLayout mGridLayout;
    133 
    134     @Rule
    135     public ActivityTestRule<GridLayoutCtsActivity> mActivityRule =
    136             new ActivityTestRule<>(GridLayoutCtsActivity.class);
    137 
    138     @Before
    139     public void setup() {
    140         mActivity = mActivityRule.getActivity();
    141         mGridLayout = (GridLayout) mActivity.findViewById(R.id.gridlayout);
    142     }
    143 
    144     @Test
    145     public void testConstructor() {
    146         new GridLayout(mActivity);
    147 
    148         new GridLayout(mActivity, null);
    149 
    150         XmlPullParser parser = mActivity.getResources().getXml(R.layout.gridlayout_layout);
    151         AttributeSet attrs = Xml.asAttributeSet(parser);
    152         new GridLayout(mActivity, attrs);
    153     }
    154 
    155     @Test(expected=NullPointerException.class)
    156     public void testConstructorNullContext() {
    157         new GridLayout(null, null);
    158     }
    159 
    160     @UiThreadTest
    161     @Test
    162     public void testCheckLayoutParams() {
    163         mGridLayout.addView(new TextView(mActivity),
    164                 new AbsoluteLayout.LayoutParams(0, 0, 0, 0));
    165 
    166         mGridLayout.addView(new TextView(mActivity),
    167                 new GridLayout.LayoutParams(GridLayout.spec(0), GridLayout.spec(0)));
    168     }
    169 
    170     @UiThreadTest
    171     @Test
    172     public void testGenerateDefaultLayoutParams() {
    173         ViewGroup.LayoutParams lp = mGridLayout.generateLayoutParams(null);
    174         assertNotNull(lp);
    175         assertTrue(lp instanceof GridLayout.LayoutParams);
    176         assertEquals(ViewGroup.LayoutParams.WRAP_CONTENT, lp.width);
    177         assertEquals(ViewGroup.LayoutParams.WRAP_CONTENT, lp.height);
    178     }
    179 
    180     @Test
    181     public void testGenerateLayoutParamsFromMarginParams() {
    182         MyGridLayout gridLayout = new MyGridLayout(mActivity);
    183         ViewGroup.MarginLayoutParams lp = new ViewGroup.MarginLayoutParams(3, 5);
    184         lp.leftMargin = 1;
    185         lp.topMargin = 2;
    186         lp.rightMargin = 3;
    187         lp.bottomMargin = 4;
    188         GridLayout.LayoutParams generated = gridLayout.generateLayoutParams(lp);
    189         assertNotNull(generated);
    190         assertEquals(3, generated.width);
    191         assertEquals(5, generated.height);
    192 
    193         assertEquals(1, generated.leftMargin);
    194         assertEquals(2, generated.topMargin);
    195         assertEquals(3, generated.rightMargin);
    196         assertEquals(4, generated.bottomMargin);
    197     }
    198 
    199     private View[][] populate(GridLayout container) {
    200         Context context = container.getContext();
    201         int N = VERTICAL_ALIGNMENTS.length;
    202         int M = HORIZONTAL_ALIGNMENTS.length;
    203 
    204         View[][] table = new View[N + 1][M + 1];
    205 
    206         {
    207             TextView v = new TextView(context);
    208             GridLayout.LayoutParams lp = new GridLayout.LayoutParams(spec(0), spec(0));
    209             lp.setGravity(Gravity.CENTER);
    210             v.setText("*");
    211             container.addView(v, lp);
    212         }
    213         for (int i = 0; i < N; i++) {
    214             Alignment va = VERTICAL_ALIGNMENTS[i];
    215             int row = i + 1;
    216             GridLayout.LayoutParams lp = new GridLayout.LayoutParams(spec(row), spec(0));
    217             lp.setGravity(va.gravity | Gravity.CENTER_HORIZONTAL);
    218             TextView v = new TextView(context);
    219             v.setGravity(Gravity.CENTER);
    220             v.setText(va.name);
    221             container.addView(v, lp);
    222             table[row][0] = v;
    223         }
    224         for (int j = 0; j < M; j++) {
    225             Alignment ha = HORIZONTAL_ALIGNMENTS[j];
    226             int col = j + 1;
    227             GridLayout.LayoutParams lp = new GridLayout.LayoutParams(spec(0), spec(col));
    228             lp.setGravity(Gravity.CENTER_VERTICAL | ha.gravity);
    229             TextView v = new TextView(context);
    230             v.setGravity(Gravity.CENTER);
    231             v.setText(ha.name);
    232             container.addView(v, lp);
    233             table[0][col] = v;
    234         }
    235         for (int i = 0; i < N; i++) {
    236             for (int j = 0; j < M; j++) {
    237                 Alignment ha = HORIZONTAL_ALIGNMENTS[j];
    238                 Alignment va = VERTICAL_ALIGNMENTS[i];
    239                 int row = i + 1;
    240                 int col = j + 1;
    241                 GridLayout.LayoutParams lp = new GridLayout.LayoutParams(spec(row), spec(col));
    242                 lp.setGravity(va.gravity | ha.gravity);
    243                 TextView v = new Button(context);
    244                 v.setText("X");
    245                 v.setTextSize(10 + 5 * row * col);
    246                 container.addView(v, lp);
    247                 table[row][col] = v;
    248             }
    249         }
    250         return table;
    251     }
    252 
    253     private void verifyCellAlignment(int row, int col, Alignment a, View v0, View v1,
    254             String group) {
    255         int a0 = a.getValue(v0);
    256         int a1 = a.getValue(v1);
    257         assertEquals("View at row " + row + ", column " + col + " was not " + a.name +
    258                 " aligned with its title " + group + ";",
    259                 a0, a1);
    260     }
    261 
    262     private void verifyGridAlignment(GridLayout p, View[][] table) {
    263         p.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);
    264         p.layout(0, 0, MAX_X, MAX_Y);
    265 
    266         int N = VERTICAL_ALIGNMENTS.length;
    267         int M = HORIZONTAL_ALIGNMENTS.length;
    268 
    269         // test all horizontal alignments in each column
    270         for (int j = 0; j < M; j++) {
    271             int col = j + 1;
    272             View v0 = table[0][col];
    273             Alignment alignment = HORIZONTAL_ALIGNMENTS[j];
    274             for (int i = 0; i < N; i++) {
    275                 int row = i + 1;
    276                 verifyCellAlignment(row, col, alignment, v0, table[row][col], "column");
    277             }
    278         }
    279 
    280         // test all vertical alignments in each row
    281         for (int i = 0; i < N; i++) {
    282             int row = i + 1;
    283             View v0 = table[row][0];
    284             Alignment alignment = VERTICAL_ALIGNMENTS[i];
    285             for (int j = 0; j < M; j++) {
    286                 int col = j + 1;
    287                 verifyCellAlignment(row, col, alignment, v0, table[row][col], "row");
    288             }
    289         }
    290     }
    291 
    292     @UiThreadTest
    293     @Test
    294     public void testAlignment() {
    295         View[][] table = populate(mGridLayout);
    296         verifyGridAlignment(mGridLayout, table);
    297     }
    298 
    299     private static class MyGridLayout extends GridLayout {
    300 
    301         public MyGridLayout(Context context) {
    302             super(context);
    303         }
    304 
    305         public MyGridLayout(Context context, AttributeSet attrs) {
    306             super(context, attrs);
    307         }
    308 
    309         public MyGridLayout(Context context, AttributeSet attrs, int defStyleAttr) {
    310             super(context, attrs, defStyleAttr);
    311         }
    312 
    313         public MyGridLayout(Context context, AttributeSet attrs, int defStyleAttr,
    314                 int defStyleRes) {
    315             super(context, attrs, defStyleAttr, defStyleRes);
    316         }
    317 
    318         @Override
    319         protected LayoutParams generateLayoutParams(ViewGroup.LayoutParams p) {
    320             return super.generateLayoutParams(p);
    321         }
    322     }
    323 }
    324