Add test for toggling view visibility affecting layout
Toggling the visibility between GONE and VISIBILITY may affect
other children in that parent layout.
Issue #25980198 requestLayout() sometimes doesn't result in measure/layout for view
Change-Id: I826dbfe8018c19d50a033380c6748345bfdcd21d
diff --git a/tests/tests/view/src/android/view/cts/ViewTest.java b/tests/tests/view/src/android/view/cts/ViewTest.java
index 355850f..314bd2a 100644
--- a/tests/tests/view/src/android/view/cts/ViewTest.java
+++ b/tests/tests/view/src/android/view/cts/ViewTest.java
@@ -2266,13 +2266,16 @@
assertTrue(listener.hasOnClick());
}
- private void checkValues(final ViewGroup viewGroup, final ViewGroup parent,
- final CountDownLatch countDownLatch, final int width, final int height) {
+ private void checkBounds(final ViewGroup viewGroup, final View view,
+ final CountDownLatch countDownLatch, final int left, final int top,
+ final int width, final int height) {
viewGroup.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
@Override
public boolean onPreDraw() {
- assertEquals(width, parent.getWidth());
- assertEquals(height, parent.getHeight());
+ assertEquals(left, view.getLeft());
+ assertEquals(top, view.getTop());
+ assertEquals(width, view.getWidth());
+ assertEquals(height, view.getHeight());
countDownLatch.countDown();
viewGroup.getViewTreeObserver().removeOnPreDrawListener(this);
return true;
@@ -2304,7 +2307,7 @@
public void run() {
viewGroup.removeAllViews();
viewGroup.addView(parent);
- checkValues(viewGroup, parent, countDownLatch1, 0, parentHeight);
+ checkBounds(viewGroup, parent, countDownLatch1, 0, 0, 0, parentHeight);
}
});
countDownLatch1.await(500, TimeUnit.MILLISECONDS);
@@ -2313,7 +2316,7 @@
runTestOnUiThread(new Runnable() {
public void run() {
parent.addView(child);
- checkValues(viewGroup, parent, countDownLatch2, childWidth, parentHeight);
+ checkBounds(viewGroup, parent, countDownLatch2, 0, 0, childWidth, parentHeight);
}
});
countDownLatch2.await(500, TimeUnit.MILLISECONDS);
@@ -2322,7 +2325,7 @@
runTestOnUiThread(new Runnable() {
public void run() {
parent.removeView(child);
- checkValues(viewGroup, parent, countDownLatch3, 0, parentHeight);
+ checkBounds(viewGroup, parent, countDownLatch3, 0, 0, 0, parentHeight);
}
});
countDownLatch3.await(500, TimeUnit.MILLISECONDS);
diff --git a/tests/tests/widget/res/layout/linearlayout_layout.xml b/tests/tests/widget/res/layout/linearlayout_layout.xml
index c70937d..8881552 100644
--- a/tests/tests/widget/res/layout/linearlayout_layout.xml
+++ b/tests/tests/widget/res/layout/linearlayout_layout.xml
@@ -15,6 +15,7 @@
* limitations under the License.
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/linearlayout_root"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
diff --git a/tests/tests/widget/src/android/widget/cts/LinearLayoutTest.java b/tests/tests/widget/src/android/widget/cts/LinearLayoutTest.java
index 78a8eee..76fa782 100644
--- a/tests/tests/widget/src/android/widget/cts/LinearLayoutTest.java
+++ b/tests/tests/widget/src/android/widget/cts/LinearLayoutTest.java
@@ -16,6 +16,9 @@
package android.widget.cts;
+import android.graphics.Color;
+import android.view.View;
+import android.view.ViewTreeObserver;
import org.xmlpull.v1.XmlPullParser;
import android.app.Activity;
@@ -33,6 +36,9 @@
import android.widget.cts.R;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
/**
* Test {@link LinearLayout}.
*/
@@ -327,6 +333,78 @@
assertEquals(parent.getWidth(), rightView.getRight());
}
+ private void checkBounds(final ViewGroup viewGroup, final View view,
+ final CountDownLatch countDownLatch, final int left, final int top,
+ final int width, final int height) {
+ viewGroup.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
+ @Override
+ public boolean onPreDraw() {
+ assertEquals(left, view.getLeft());
+ assertEquals(top, view.getTop());
+ assertEquals(width, view.getWidth());
+ assertEquals(height, view.getHeight());
+ countDownLatch.countDown();
+ viewGroup.getViewTreeObserver().removeOnPreDrawListener(this);
+ return true;
+ }
+ });
+ }
+
+ public void testVisibilityAffectsLayout() throws Throwable {
+ // Toggling view visibility between GONE/VISIBLE can affect the position of
+ // other children in that container. This test verifies that these changes
+ // on the first child of a LinearLayout affects the position of a second child
+ final int childWidth = 100;
+ final int childHeight = 200;
+ final LinearLayout parent = new LinearLayout(mActivity);
+ ViewGroup.LayoutParams parentParams = new ViewGroup.LayoutParams(
+ ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
+ parent.setLayoutParams(parentParams);
+ final View child1 = new View(mActivity);
+ child1.setBackgroundColor(Color.GREEN);
+ ViewGroup.LayoutParams childParams = new ViewGroup.LayoutParams(childWidth, childHeight);
+ child1.setLayoutParams(childParams);
+ final View child2 = new View(mActivity);
+ child2.setBackgroundColor(Color.RED);
+ childParams = new ViewGroup.LayoutParams(childWidth, childHeight);
+ child2.setLayoutParams(childParams);
+ final ViewGroup viewGroup = (ViewGroup) mActivity.findViewById(R.id.linearlayout_root);
+
+ final CountDownLatch countDownLatch1 = new CountDownLatch(1);
+ runTestOnUiThread(new Runnable() {
+ public void run() {
+ viewGroup.removeAllViews();
+ viewGroup.addView(parent);
+ parent.addView(child1);
+ parent.addView(child2);
+ checkBounds(viewGroup, child1, countDownLatch1, 0, 0, childWidth, childHeight);
+ checkBounds(viewGroup, child2, countDownLatch1,
+ childWidth, 0, childWidth, childHeight);
+ }
+ });
+ countDownLatch1.await(500, TimeUnit.MILLISECONDS);
+
+ final CountDownLatch countDownLatch2 = new CountDownLatch(1);
+ runTestOnUiThread(new Runnable() {
+ public void run() {
+ child1.setVisibility(View.GONE);
+ checkBounds(viewGroup, child2, countDownLatch2, 0, 0, childWidth, childHeight);
+ }
+ });
+ countDownLatch2.await(500, TimeUnit.MILLISECONDS);
+
+ final CountDownLatch countDownLatch3 = new CountDownLatch(2);
+ runTestOnUiThread(new Runnable() {
+ public void run() {
+ child1.setVisibility(View.VISIBLE);
+ checkBounds(viewGroup, child1, countDownLatch3, 0, 0, childWidth, childHeight);
+ checkBounds(viewGroup, child2, countDownLatch3,
+ childWidth, 0, childWidth, childHeight);
+ }
+ });
+ countDownLatch3.await(500, TimeUnit.MILLISECONDS);
+ }
+
private class MockListView extends ListView {
private final static int DEFAULT_CHILD_BASE_LINE = 1;