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