diff options
author | 2024-03-15 14:36:49 +0800 | |
---|---|---|
committer | 2024-04-15 18:13:14 +0000 | |
commit | ee151ae49c0f0afc1fd9a2043ca7b5e1b78dcd8e (patch) | |
tree | 24f60007be48b71af026b7d09e26a49e38dd2eba | |
parent | 869e636a5c6cc17d6faaf0b95b4568286caa06fc (diff) |
Let WindowInsetsTests support edge-to-edge
This CL lets the activities handle insets properly because apps
targeting V are forced to go edge-to-edge.
This CL also lets the app support dark theme.
Fix: 329647020
Bug: 309578419
Test: Open each activity with or without dark theme, and see if the
layout and the color are correct.
Change-Id: I159a042e546a60c33bd0e2fb3b66736501386979
8 files changed, 245 insertions, 141 deletions
diff --git a/tests/WindowInsetsTests/AndroidManifest.xml b/tests/WindowInsetsTests/AndroidManifest.xml index 61dd9d4cd021..dbe9d363e285 100644 --- a/tests/WindowInsetsTests/AndroidManifest.xml +++ b/tests/WindowInsetsTests/AndroidManifest.xml @@ -18,7 +18,8 @@ <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.google.android.test.windowinsetstests"> - <application android:label="@string/application_title"> + <application android:label="@string/application_title" + android:theme="@style/base"> <activity android:name=".WindowInsetsTestsMainActivity" android:exported="true"> <intent-filter> @@ -29,11 +30,9 @@ <activity android:name=".ChatActivity" android:label="@string/chat_activity_title" - android:theme="@style/chat" android:windowSoftInputMode="adjustResize" /> <activity android:name=".ControllerActivity" - android:label="@string/controller_activity_title" - android:theme="@style/controller" /> + android:label="@string/controller_activity_title" /> </application> </manifest> diff --git a/tests/WindowInsetsTests/res/layout/controller_activity.xml b/tests/WindowInsetsTests/res/layout/controller_activity.xml index 5550eab61a33..7013059e1334 100644 --- a/tests/WindowInsetsTests/res/layout/controller_activity.xml +++ b/tests/WindowInsetsTests/res/layout/controller_activity.xml @@ -15,92 +15,110 @@ --> -<ScrollView xmlns:android="http://schemas.android.com/apk/res/android" - android:layout_width="match_parent" - android:layout_height="match_parent"> +<LinearLayout + xmlns:android="http://schemas.android.com/apk/res/android" + android:id="@+id/root" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:orientation="vertical"> + + <androidx.appcompat.widget.Toolbar + android:id="@+id/toolbar" + android:layout_width="match_parent" + android:layout_height="?attr/actionBarSize" + /> - <LinearLayout - android:id="@+id/content" + <ScrollView android:layout_width="match_parent" android:layout_height="match_parent" - android:orientation="vertical"> - - <Spinner - android:id="@+id/spinnerBehavior" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:layout_marginTop="10dp" - android:layout_marginBottom="20dp" /> - - <ToggleButton - android:id="@+id/toggleButtonStatus" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:checked="true" - android:text="Status Bars Toggle Button" - android:textOff="Status Bars Invisible" - android:textOn="Status Bars Visible" /> - - <SeekBar - android:id="@+id/seekBarStatus" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:layout_marginTop="10dp" - android:layout_marginBottom="20dp" - android:max="10000" - android:progress="10000" /> - - <ToggleButton - android:id="@+id/toggleButtonNavigation" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:checked="true" - android:text="Navigation Bars Toggle Button" - android:textOff="Navigation Bars Invisible" - android:textOn="Navigation Bars Visible" /> + android:paddingStart="8dp" + android:paddingEnd="8dp"> - <SeekBar - android:id="@+id/seekBarNavigation" + <LinearLayout + android:id="@+id/content" android:layout_width="match_parent" android:layout_height="wrap_content" - android:layout_marginTop="10dp" - android:layout_marginBottom="20dp" - android:max="10000" - android:progress="10000" /> - - <ToggleButton - android:id="@+id/toggleButtonIme" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:checked="true" - android:text="IME Toggle Button" - android:textOff="IME Invisible" - android:textOn="IME Visible" /> - - <SeekBar - android:id="@+id/seekBarIme" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:layout_marginTop="10dp" - android:layout_marginBottom="20dp" - android:max="10000" - android:progress="0" /> - - <TextView - android:id="@+id/textViewControllableInsets" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:layout_margin="5dp" /> - - <EditText - android:id="@+id/editText" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:ems="10" - android:hint="For testing IME..." - android:inputType="text" - android:text="" /> - - </LinearLayout> - -</ScrollView>
\ No newline at end of file + android:orientation="vertical"> + + <Spinner + android:id="@+id/spinnerBehavior" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_marginTop="10dp" + android:layout_marginBottom="20dp" /> + + <ToggleButton + android:id="@+id/toggleButtonStatus" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:checked="true" + android:text="@string/status_bars_toggle_button" + android:textOff="@string/status_bars_invisible" + android:textOn="@string/status_bars_visible" /> + + <SeekBar + android:id="@+id/seekBarStatus" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_marginTop="10dp" + android:layout_marginBottom="20dp" + android:max="10000" + android:progress="10000" /> + + <ToggleButton + android:id="@+id/toggleButtonNavigation" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:checked="true" + android:text="@string/navigation_bars_toggle_button" + android:textOff="@string/navigation_bars_invisible" + android:textOn="@string/navigation_bars_visible" /> + + <SeekBar + android:id="@+id/seekBarNavigation" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_marginTop="10dp" + android:layout_marginBottom="20dp" + android:max="10000" + android:progress="10000" /> + + <ToggleButton + android:id="@+id/toggleButtonIme" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:checked="true" + android:text="@string/ime_toggle_button" + android:textOff="@string/ime_invisible" + android:textOn="@string/ime_visible" /> + + <SeekBar + android:id="@+id/seekBarIme" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_marginTop="10dp" + android:layout_marginBottom="20dp" + android:max="10000" + android:progress="0" /> + + <TextView + android:id="@+id/textViewControllableInsets" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_margin="5dp" /> + + <EditText + android:id="@+id/editText" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:ems="10" + android:autofillHints="@string/for_testing_ime" + android:hint="@string/for_testing_ime" + android:inputType="text" + android:text="" /> + + </LinearLayout> + + </ScrollView> + +</LinearLayout> diff --git a/tests/WindowInsetsTests/res/layout/main_activity.xml b/tests/WindowInsetsTests/res/layout/main_activity.xml index 621ed89204d1..d6d4ff9ca0a9 100644 --- a/tests/WindowInsetsTests/res/layout/main_activity.xml +++ b/tests/WindowInsetsTests/res/layout/main_activity.xml @@ -16,22 +16,38 @@ <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:id="@+id/root" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> - <Button - android:id="@+id/chat_button" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:text="@string/chat_activity_title" - android:textAllCaps="false"/> + <androidx.appcompat.widget.Toolbar + android:id="@+id/toolbar" + android:layout_width="match_parent" + android:layout_height="?attr/actionBarSize" + /> - <Button - android:id="@+id/controller_button" - android:layout_width="wrap_content" + <LinearLayout + android:orientation="vertical" + android:layout_width="match_parent" android:layout_height="wrap_content" - android:text="@string/controller_activity_title" - android:textAllCaps="false"/> + android:paddingStart="8dp" + android:paddingEnd="8dp"> + + <Button + android:id="@+id/chat_button" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="@string/chat_activity_title" + android:textAllCaps="false"/> + + <Button + android:id="@+id/controller_button" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="@string/controller_activity_title" + android:textAllCaps="false"/> + + </LinearLayout> </LinearLayout> diff --git a/tests/WindowInsetsTests/res/values-night/styles.xml b/tests/WindowInsetsTests/res/values-night/styles.xml new file mode 100644 index 000000000000..323c5fd9698e --- /dev/null +++ b/tests/WindowInsetsTests/res/values-night/styles.xml @@ -0,0 +1,43 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + ~ Copyright (C) 2024 The Android Open Source Project + ~ + ~ Licensed under the Apache License, Version 2.0 (the "License"); + ~ you may not use this file except in compliance with the License. + ~ You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License. + --> + +<resources> + + <style name="base" parent="@style/Theme.MaterialComponents"> + <item name="windowActionBar">false</item> + <item name="windowNoTitle">true</item> + + <item name="colorPrimary">@color/primaryColor</item> + <item name="colorPrimaryDark">@color/primaryDarkColor</item> + <item name="colorSecondary">?attr/colorPrimary</item> + <item name="colorOnSecondary">@color/primaryTextColor</item> + + <!-- Window decor --> + <item name="android:windowLightStatusBar">false</item> + <item name="android:windowLightNavigationBar">false</item> + + </style> + + <color name="primaryColor">#639ff9</color> + <color name="primaryLightColor">#6f6bff</color> + <color name="primaryDarkColor">#0016bb</color> + <color name="primaryTextColor">#ffffff</color> + + <color name="bubble">#333333</color> + <color name="bubble_self">#185abc</color> + +</resources> diff --git a/tests/WindowInsetsTests/res/values/strings.xml b/tests/WindowInsetsTests/res/values/strings.xml index 516d4584426e..7b70852e6082 100644 --- a/tests/WindowInsetsTests/res/values/strings.xml +++ b/tests/WindowInsetsTests/res/values/strings.xml @@ -19,6 +19,16 @@ <string name="application_title">Window Insets Tests</string> <string name="chat_activity_title">New Insets Chat</string> <string name="controller_activity_title">Window Insets Controller</string> + <string name="status_bars_toggle_button">Status Bars Toggle Button</string> + <string name="status_bars_invisible">Status Bars Invisible</string> + <string name="status_bars_visible">Status Bars Visible</string> + <string name="navigation_bars_toggle_button">Navigation Bars Toggle Button</string> + <string name="navigation_bars_invisible">Navigation Bars Invisible</string> + <string name="navigation_bars_visible">Navigation Bars Visible</string> + <string name="ime_toggle_button">IME Bars Toggle Button</string> + <string name="ime_invisible">IME Bars Invisible</string> + <string name="ime_visible">IME Bars Visible</string> + <string name="for_testing_ime">For testing IME…</string> <!-- The item positions should match the flag values respectively. --> <string-array name="behaviors"> diff --git a/tests/WindowInsetsTests/res/values/styles.xml b/tests/WindowInsetsTests/res/values/styles.xml index a84ffbed600d..4ce6323d8189 100644 --- a/tests/WindowInsetsTests/res/values/styles.xml +++ b/tests/WindowInsetsTests/res/values/styles.xml @@ -17,7 +17,7 @@ <resources> - <style name="chat" parent="@style/Theme.MaterialComponents.Light"> + <style name="base" parent="@style/Theme.MaterialComponents.Light"> <item name="windowActionBar">false</item> <item name="windowNoTitle">true</item> @@ -27,10 +27,8 @@ <item name="colorOnSecondary">@color/primaryTextColor</item> <!-- Window decor --> - <item name="android:statusBarColor">#ffffff</item> <item name="android:windowLightStatusBar">true</item> <item name="android:windowLightNavigationBar">true</item> - <item name="android:navigationBarColor">#ffffff</item> </style> @@ -63,11 +61,4 @@ <dimen name="bubble_padding">8dp</dimen> <dimen name="bubble_padding_side">16dp</dimen> - <style name="controller" parent="android:Theme.Material"> - <item name="android:colorPrimaryDark">#111111</item> - <item name="android:navigationBarColor">#111111</item> - <item name="android:colorPrimary">#222222</item> - <item name="android:colorAccent">#33ccff</item> - </style> - -</resources>
\ No newline at end of file +</resources> diff --git a/tests/WindowInsetsTests/src/com/google/android/test/windowinsetstests/ControllerActivity.java b/tests/WindowInsetsTests/src/com/google/android/test/windowinsetstests/ControllerActivity.java index 167d560633ab..1dd87dfd3977 100644 --- a/tests/WindowInsetsTests/src/com/google/android/test/windowinsetstests/ControllerActivity.java +++ b/tests/WindowInsetsTests/src/com/google/android/test/windowinsetstests/ControllerActivity.java @@ -16,12 +16,18 @@ package com.google.android.test.windowinsetstests; -import android.app.Activity; +import static android.view.WindowInsets.Type.displayCutout; +import static android.view.WindowInsets.Type.ime; +import static android.view.WindowInsets.Type.navigationBars; +import static android.view.WindowInsets.Type.statusBars; +import static android.view.WindowInsets.Type.systemBars; +import static android.view.WindowInsets.Type.systemGestures; + import android.graphics.Insets; import android.os.Bundle; import android.view.View; import android.view.WindowInsets; -import android.view.WindowInsets.Type; +import android.view.WindowInsets.Type.InsetsType; import android.view.WindowInsetsAnimationControlListener; import android.view.WindowInsetsAnimationController; import android.widget.AdapterView; @@ -32,7 +38,9 @@ import android.widget.Spinner; import android.widget.TextView; import android.widget.ToggleButton; -public class ControllerActivity extends Activity implements View.OnApplyWindowInsetsListener { +import androidx.appcompat.app.AppCompatActivity; + +public class ControllerActivity extends AppCompatActivity { private ToggleButton mToggleStatus; private SeekBar mSeekStatus; @@ -48,6 +56,29 @@ public class ControllerActivity extends Activity implements View.OnApplyWindowIn protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.controller_activity); + setSupportActionBar(findViewById(R.id.toolbar)); + getWindow().setDecorFitsSystemWindows(false); + findViewById(R.id.root).setOnApplyWindowInsetsListener( + (v, insets) -> { + final int visibleTypes = systemBars() | displayCutout(); + final Insets i = insets.getInsets(visibleTypes); + v.setPadding(i.left, i.top, i.right, i.bottom); + + // Make the content view not obscured by gesture insets to prevent triggering + // system gestures while controlling seek bars. + final Insets gi = Insets.subtract( + insets.getInsets(systemGestures() | visibleTypes), i); + findViewById(R.id.content).setPadding(gi.left, gi.top, gi.right, gi.bottom); + + mNotFromUser[0] = true; + updateWidgets(insets, statusBars(), mToggleStatus, mSeekStatus); + updateWidgets(insets, navigationBars(), mToggleNavigation, mSeekNavigation); + updateWidgets(insets, ime(), mToggleIme, mSeekIme); + mLastInsets = insets; + mNotFromUser[0] = false; + + return WindowInsets.CONSUMED; + }); final Spinner spinnerBehavior = findViewById(R.id.spinnerBehavior); ArrayAdapter<CharSequence> adapterBehavior = ArrayAdapter.createFromResource(this, R.array.behaviors, android.R.layout.simple_spinner_item); @@ -66,23 +97,21 @@ public class ControllerActivity extends Activity implements View.OnApplyWindowIn }); mToggleStatus = findViewById(R.id.toggleButtonStatus); mToggleStatus.setTag(mNotFromUser); - mToggleStatus.setOnCheckedChangeListener(new ToggleListener(Type.statusBars())); + mToggleStatus.setOnCheckedChangeListener(new ToggleListener(statusBars())); mSeekStatus = findViewById(R.id.seekBarStatus); - mSeekStatus.setOnSeekBarChangeListener(new SeekBarListener(Type.statusBars())); + mSeekStatus.setOnSeekBarChangeListener(new SeekBarListener(statusBars())); mToggleNavigation = findViewById(R.id.toggleButtonNavigation); mToggleNavigation.setTag(mNotFromUser); - mToggleNavigation.setOnCheckedChangeListener(new ToggleListener(Type.navigationBars())); + mToggleNavigation.setOnCheckedChangeListener(new ToggleListener(navigationBars())); mSeekNavigation = findViewById(R.id.seekBarNavigation); - mSeekNavigation.setOnSeekBarChangeListener(new SeekBarListener(Type.navigationBars())); + mSeekNavigation.setOnSeekBarChangeListener(new SeekBarListener(navigationBars())); mToggleIme = findViewById(R.id.toggleButtonIme); mToggleIme.setTag(mNotFromUser); - mToggleIme.setOnCheckedChangeListener(new ToggleListener(Type.ime())); + mToggleIme.setOnCheckedChangeListener(new ToggleListener(ime())); mSeekIme = findViewById(R.id.seekBarIme); - mSeekIme.setOnSeekBarChangeListener(new SeekBarListener(Type.ime())); + mSeekIme.setOnSeekBarChangeListener(new SeekBarListener(ime())); mTextControllableInsets = findViewById(R.id.textViewControllableInsets); - final View contentView = findViewById(R.id.content); - contentView.setOnApplyWindowInsetsListener(this); - contentView.getWindowInsetsController().addOnControllableInsetsChangedListener( + mTextControllableInsets.getWindowInsetsController().addOnControllableInsetsChangedListener( (c, types) -> mTextControllableInsets.setText( "ControllableInsetsTypes:\n" + insetsTypesToString(types))); } @@ -91,22 +120,6 @@ public class ControllerActivity extends Activity implements View.OnApplyWindowIn return types == 0 ? "none" : WindowInsets.Type.toString(types); } - @Override - public WindowInsets onApplyWindowInsets(View v, WindowInsets insets) { - mNotFromUser[0] = true; - updateWidgets(insets, Type.statusBars(), mToggleStatus, mSeekStatus); - updateWidgets(insets, Type.navigationBars(), mToggleNavigation, mSeekNavigation); - updateWidgets(insets, Type.ime(), mToggleIme, mSeekIme); - mLastInsets = insets; - mNotFromUser[0] = false; - - // Prevent triggering system gestures while controlling seek bars. - final Insets gestureInsets = insets.getInsets(Type.systemGestures()); - v.setPadding(gestureInsets.left, 0, gestureInsets.right, 0); - - return v.onApplyWindowInsets(insets); - } - private void updateWidgets(WindowInsets insets, int types, ToggleButton toggle, SeekBar seek) { final boolean isVisible = insets.isVisible(types); final boolean wasVisible = mLastInsets != null ? mLastInsets.isVisible(types) : !isVisible; @@ -121,7 +134,7 @@ public class ControllerActivity extends Activity implements View.OnApplyWindowIn private static class ToggleListener implements CompoundButton.OnCheckedChangeListener { - private final @Type.InsetsType int mTypes; + private final @InsetsType int mTypes; ToggleListener(int types) { mTypes = types; @@ -143,7 +156,7 @@ public class ControllerActivity extends Activity implements View.OnApplyWindowIn private static class SeekBarListener implements SeekBar.OnSeekBarChangeListener { - private final @Type.InsetsType int mTypes; + private final @InsetsType int mTypes; private WindowInsetsAnimationController mController; diff --git a/tests/WindowInsetsTests/src/com/google/android/test/windowinsetstests/WindowInsetsTestsMainActivity.java b/tests/WindowInsetsTests/src/com/google/android/test/windowinsetstests/WindowInsetsTestsMainActivity.java index 8b77a78ff51e..278ad845d2bb 100644 --- a/tests/WindowInsetsTests/src/com/google/android/test/windowinsetstests/WindowInsetsTestsMainActivity.java +++ b/tests/WindowInsetsTests/src/com/google/android/test/windowinsetstests/WindowInsetsTestsMainActivity.java @@ -16,16 +16,30 @@ package com.google.android.test.windowinsetstests; -import android.app.Activity; +import static android.view.WindowInsets.Type.displayCutout; +import static android.view.WindowInsets.Type.systemBars; + import android.content.Intent; +import android.graphics.Insets; import android.os.Bundle; +import android.view.WindowInsets; + +import androidx.appcompat.app.AppCompatActivity; -public class WindowInsetsTestsMainActivity extends Activity { +public class WindowInsetsTestsMainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main_activity); + setSupportActionBar(findViewById(R.id.toolbar)); + + findViewById(R.id.root).setOnApplyWindowInsetsListener( + (v, insets) -> { + final Insets i = insets.getInsets(systemBars() | displayCutout()); + v.setPadding(i.left, i.top, i.right, i.bottom); + return WindowInsets.CONSUMED; + }); findViewById(R.id.chat_button).setOnClickListener( v -> startActivity(new Intent(this, ChatActivity.class))); |