Merge "Fixes issues with multiple ringer rows (which also addresses a few RTL/landscape issues)." into sc-dev am: b3ca17a237
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/14722110 Change-Id: I1b2edcf7a43f253ddb6404553530e33ee197b428
This commit is contained in:
23
packages/SystemUI/res/drawable/volume_background_bottom.xml
Normal file
23
packages/SystemUI/res/drawable/volume_background_bottom.xml
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!--
|
||||||
|
~ Copyright (C) 2021 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
|
||||||
|
-->
|
||||||
|
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:androidprv="http://schemas.android.com/apk/prv/res/android">
|
||||||
|
<size android:width="@dimen/volume_dialog_panel_width" />
|
||||||
|
<solid android:color="?androidprv:attr/colorSurface" />
|
||||||
|
<corners android:bottomLeftRadius="@dimen/volume_dialog_panel_width_half"
|
||||||
|
android:bottomRightRadius="@dimen/volume_dialog_panel_width_half"/>
|
||||||
|
</shape>
|
||||||
@@ -20,7 +20,8 @@
|
|||||||
<shape>
|
<shape>
|
||||||
<size android:width="@dimen/volume_dialog_panel_width" />
|
<size android:width="@dimen/volume_dialog_panel_width" />
|
||||||
<solid android:color="?androidprv:attr/colorSurface" />
|
<solid android:color="?androidprv:attr/colorSurface" />
|
||||||
<corners android:radius="@dimen/volume_dialog_panel_width_half"/>
|
<corners android:topLeftRadius="@dimen/volume_dialog_panel_width_half"
|
||||||
|
android:topRightRadius="@dimen/volume_dialog_panel_width_half"/>
|
||||||
</shape>
|
</shape>
|
||||||
</item>
|
</item>
|
||||||
</layer-list>
|
</layer-list>
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!--
|
||||||
|
~ Copyright (C) 2021 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
|
||||||
|
-->
|
||||||
|
<layer-list xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:androidprv="http://schemas.android.com/apk/prv/res/android">
|
||||||
|
<item>
|
||||||
|
<shape>
|
||||||
|
<size android:width="@dimen/volume_dialog_panel_width" />
|
||||||
|
<solid android:color="?androidprv:attr/colorSurface" />
|
||||||
|
<corners android:topLeftRadius="@dimen/volume_dialog_panel_width_half"
|
||||||
|
android:topRightRadius="@dimen/volume_dialog_panel_width_half"
|
||||||
|
android:bottomLeftRadius="@dimen/volume_dialog_panel_width_half"
|
||||||
|
android:bottomRightRadius="@dimen/volume_dialog_panel_width_half"/>
|
||||||
|
</shape>
|
||||||
|
</item>
|
||||||
|
</layer-list>
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!--
|
||||||
|
~ Copyright (C) 2021 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
|
||||||
|
-->
|
||||||
|
|
||||||
|
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:androidprv="http://schemas.android.com/apk/prv/res/android">
|
||||||
|
<size android:width="@dimen/volume_dialog_panel_width" />
|
||||||
|
<solid android:color="?androidprv:attr/colorSurface" />
|
||||||
|
<corners android:radius="@dimen/volume_dialog_panel_width_half"/>
|
||||||
|
</shape>
|
||||||
@@ -32,7 +32,7 @@
|
|||||||
android:clipToPadding="false">
|
android:clipToPadding="false">
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:id="@+id/main"
|
android:id="@+id/volume_dialog_rows_container"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_gravity="right"
|
android:layout_gravity="right"
|
||||||
|
|||||||
@@ -39,13 +39,12 @@
|
|||||||
|
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:id="@+id/volume_dialog_ringer_and_rows_container"
|
android:id="@+id/volume_dialog_top_container"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="vertical"
|
android:orientation="vertical"
|
||||||
android:padding="7dp"
|
|
||||||
android:clipChildren="false"
|
android:clipChildren="false"
|
||||||
android:background="@drawable/volume_background">
|
android:gravity="right">
|
||||||
|
|
||||||
<include layout="@layout/volume_ringer_drawer" />
|
<include layout="@layout/volume_ringer_drawer" />
|
||||||
|
|
||||||
@@ -80,7 +79,7 @@
|
|||||||
</FrameLayout>
|
</FrameLayout>
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:id="@+id/main"
|
android:id="@+id/volume_dialog_rows_container"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:gravity="right"
|
android:gravity="right"
|
||||||
@@ -93,14 +92,17 @@
|
|||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
android:orientation="horizontal"
|
android:orientation="horizontal">
|
||||||
android:layout_marginTop="@dimen/volume_row_slider_padding_start">
|
|
||||||
<!-- volume rows added and removed here! :-) -->
|
<!-- volume rows added and removed here! :-) -->
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
<FrameLayout
|
<FrameLayout
|
||||||
android:id="@+id/settings_container"
|
android:id="@+id/settings_container"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content">
|
android:layout_height="wrap_content"
|
||||||
|
android:background="@drawable/volume_background_bottom"
|
||||||
|
android:paddingLeft="@dimen/volume_dialog_ringer_rows_padding"
|
||||||
|
android:paddingBottom="@dimen/volume_dialog_ringer_rows_padding"
|
||||||
|
android:paddingRight="@dimen/volume_dialog_ringer_rows_padding">
|
||||||
<com.android.keyguard.AlphaOptimizedImageButton
|
<com.android.keyguard.AlphaOptimizedImageButton
|
||||||
android:id="@+id/settings"
|
android:id="@+id/settings"
|
||||||
android:src="@drawable/horizontal_ellipsis"
|
android:src="@drawable/horizontal_ellipsis"
|
||||||
@@ -124,7 +126,7 @@
|
|||||||
android:gravity="right"
|
android:gravity="right"
|
||||||
android:layout_gravity="right"
|
android:layout_gravity="right"
|
||||||
android:clipToPadding="false"
|
android:clipToPadding="false"
|
||||||
android:background="@drawable/volume_background">
|
android:background="@drawable/volume_row_rounded_background">
|
||||||
<com.android.systemui.volume.CaptionsToggleImageButton
|
<com.android.systemui.volume.CaptionsToggleImageButton
|
||||||
android:id="@+id/odi_captions_icon"
|
android:id="@+id/odi_captions_icon"
|
||||||
android:src="@drawable/ic_volume_odi_captions_disabled"
|
android:src="@drawable/ic_volume_odi_captions_disabled"
|
||||||
|
|||||||
@@ -37,15 +37,13 @@
|
|||||||
android:clipToPadding="false"
|
android:clipToPadding="false"
|
||||||
android:clipChildren="false">
|
android:clipChildren="false">
|
||||||
|
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:id="@+id/volume_dialog_ringer_and_rows_container"
|
android:id="@+id/volume_dialog_top_container"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="vertical"
|
|
||||||
android:padding="7dp"
|
|
||||||
android:clipChildren="false"
|
android:clipChildren="false"
|
||||||
android:background="@drawable/volume_background">
|
android:orientation="vertical"
|
||||||
|
android:gravity="right">
|
||||||
|
|
||||||
<include layout="@layout/volume_ringer_drawer" />
|
<include layout="@layout/volume_ringer_drawer" />
|
||||||
|
|
||||||
@@ -80,7 +78,7 @@
|
|||||||
</FrameLayout>
|
</FrameLayout>
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:id="@+id/main"
|
android:id="@+id/volume_dialog_rows_container"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:gravity="right"
|
android:gravity="right"
|
||||||
@@ -93,14 +91,17 @@
|
|||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
android:orientation="horizontal"
|
android:orientation="horizontal">
|
||||||
android:layout_marginTop="@dimen/volume_row_slider_padding_start">
|
|
||||||
<!-- volume rows added and removed here! :-) -->
|
<!-- volume rows added and removed here! :-) -->
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
<FrameLayout
|
<FrameLayout
|
||||||
android:id="@+id/settings_container"
|
android:id="@+id/settings_container"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content">
|
android:layout_height="wrap_content"
|
||||||
|
android:background="@drawable/volume_background_bottom"
|
||||||
|
android:paddingLeft="@dimen/volume_dialog_ringer_rows_padding"
|
||||||
|
android:paddingBottom="@dimen/volume_dialog_ringer_rows_padding"
|
||||||
|
android:paddingRight="@dimen/volume_dialog_ringer_rows_padding">
|
||||||
<com.android.keyguard.AlphaOptimizedImageButton
|
<com.android.keyguard.AlphaOptimizedImageButton
|
||||||
android:id="@+id/settings"
|
android:id="@+id/settings"
|
||||||
android:src="@drawable/horizontal_ellipsis"
|
android:src="@drawable/horizontal_ellipsis"
|
||||||
@@ -122,9 +123,9 @@
|
|||||||
android:layout_height="@dimen/volume_dialog_caption_size"
|
android:layout_height="@dimen/volume_dialog_caption_size"
|
||||||
android:layout_marginTop="@dimen/volume_dialog_row_margin_bottom"
|
android:layout_marginTop="@dimen/volume_dialog_row_margin_bottom"
|
||||||
android:gravity="right"
|
android:gravity="right"
|
||||||
android:layout_gravity="center"
|
android:layout_gravity="right"
|
||||||
android:clipToPadding="false"
|
android:clipToPadding="false"
|
||||||
android:background="@drawable/volume_background">
|
android:background="@drawable/volume_row_rounded_background">
|
||||||
<com.android.systemui.volume.CaptionsToggleImageButton
|
<com.android.systemui.volume.CaptionsToggleImageButton
|
||||||
android:id="@+id/odi_captions_icon"
|
android:id="@+id/odi_captions_icon"
|
||||||
android:src="@drawable/ic_volume_odi_captions_disabled"
|
android:src="@drawable/ic_volume_odi_captions_disabled"
|
||||||
|
|||||||
@@ -17,15 +17,18 @@
|
|||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:tag="row"
|
android:tag="row"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_width="@dimen/volume_dialog_slider_width"
|
android:layout_width="@dimen/volume_dialog_panel_width"
|
||||||
android:clipChildren="false"
|
android:clipChildren="false"
|
||||||
android:clipToPadding="false"
|
android:clipToPadding="false"
|
||||||
android:translationZ="@dimen/volume_dialog_elevation"
|
android:gravity="center"
|
||||||
|
android:paddingTop="@dimen/volume_dialog_ringer_rows_padding"
|
||||||
|
android:paddingBottom="@dimen/volume_dialog_ringer_rows_padding"
|
||||||
|
android:background="@drawable/volume_row_rounded_background"
|
||||||
android:theme="@style/volume_dialog_theme">
|
android:theme="@style/volume_dialog_theme">
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_width="@dimen/volume_dialog_slider_width"
|
android:layout_width="@dimen/volume_dialog_panel_width"
|
||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
android:layout_gravity="center"
|
android:layout_gravity="center"
|
||||||
android:orientation="vertical" >
|
android:orientation="vertical" >
|
||||||
|
|||||||
@@ -18,9 +18,16 @@
|
|||||||
<!-- Contains the active ringer icon and a hidden drawer containing all three ringer options. -->
|
<!-- Contains the active ringer icon and a hidden drawer containing all three ringer options. -->
|
||||||
<FrameLayout
|
<FrameLayout
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:id="@+id/volume_ringer_and_drawer_container"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
|
android:paddingLeft="@dimen/volume_dialog_ringer_rows_padding"
|
||||||
|
android:paddingTop="@dimen/volume_dialog_ringer_rows_padding"
|
||||||
|
android:paddingRight="@dimen/volume_dialog_ringer_rows_padding"
|
||||||
|
android:paddingBottom="@dimen/volume_dialog_ringer_rows_padding"
|
||||||
|
android:background="@drawable/volume_background_top"
|
||||||
|
android:layoutDirection="ltr"
|
||||||
android:clipToPadding="false"
|
android:clipToPadding="false"
|
||||||
android:clipChildren="false">
|
android:clipChildren="false">
|
||||||
|
|
||||||
|
|||||||
@@ -472,6 +472,8 @@
|
|||||||
|
|
||||||
<dimen name="volume_dialog_panel_transparent_padding">20dp</dimen>
|
<dimen name="volume_dialog_panel_transparent_padding">20dp</dimen>
|
||||||
|
|
||||||
|
<dimen name="volume_dialog_ringer_rows_padding">7dp</dimen>
|
||||||
|
|
||||||
<dimen name="volume_dialog_stream_padding">12dp</dimen>
|
<dimen name="volume_dialog_stream_padding">12dp</dimen>
|
||||||
|
|
||||||
<dimen name="volume_dialog_panel_width">56dp</dimen>
|
<dimen name="volume_dialog_panel_width">56dp</dimen>
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ import static android.media.AudioManager.STREAM_VOICE_CALL;
|
|||||||
import static android.view.View.ACCESSIBILITY_LIVE_REGION_POLITE;
|
import static android.view.View.ACCESSIBILITY_LIVE_REGION_POLITE;
|
||||||
import static android.view.View.GONE;
|
import static android.view.View.GONE;
|
||||||
import static android.view.View.INVISIBLE;
|
import static android.view.View.INVISIBLE;
|
||||||
|
import static android.view.View.LAYOUT_DIRECTION_RTL;
|
||||||
import static android.view.View.VISIBLE;
|
import static android.view.View.VISIBLE;
|
||||||
import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
|
import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
|
||||||
|
|
||||||
@@ -52,6 +53,7 @@ import android.content.res.Configuration;
|
|||||||
import android.content.res.Resources;
|
import android.content.res.Resources;
|
||||||
import android.content.res.TypedArray;
|
import android.content.res.TypedArray;
|
||||||
import android.graphics.Color;
|
import android.graphics.Color;
|
||||||
|
import android.graphics.Outline;
|
||||||
import android.graphics.PixelFormat;
|
import android.graphics.PixelFormat;
|
||||||
import android.graphics.Rect;
|
import android.graphics.Rect;
|
||||||
import android.graphics.Region;
|
import android.graphics.Region;
|
||||||
@@ -74,11 +76,13 @@ import android.util.Log;
|
|||||||
import android.util.Slog;
|
import android.util.Slog;
|
||||||
import android.util.SparseBooleanArray;
|
import android.util.SparseBooleanArray;
|
||||||
import android.view.ContextThemeWrapper;
|
import android.view.ContextThemeWrapper;
|
||||||
|
import android.view.Gravity;
|
||||||
import android.view.MotionEvent;
|
import android.view.MotionEvent;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.View.AccessibilityDelegate;
|
import android.view.View.AccessibilityDelegate;
|
||||||
import android.view.View.OnAttachStateChangeListener;
|
import android.view.View.OnAttachStateChangeListener;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
|
import android.view.ViewOutlineProvider;
|
||||||
import android.view.ViewPropertyAnimator;
|
import android.view.ViewPropertyAnimator;
|
||||||
import android.view.ViewStub;
|
import android.view.ViewStub;
|
||||||
import android.view.ViewTreeObserver;
|
import android.view.ViewTreeObserver;
|
||||||
@@ -147,7 +151,10 @@ public class VolumeDialogImpl implements VolumeDialog,
|
|||||||
|
|
||||||
private final int mDialogShowAnimationDurationMs;
|
private final int mDialogShowAnimationDurationMs;
|
||||||
private final int mDialogHideAnimationDurationMs;
|
private final int mDialogHideAnimationDurationMs;
|
||||||
|
private final int mDialogWidth;
|
||||||
|
private final int mDialogCornerRadius;
|
||||||
private final int mRingerDrawerItemSize;
|
private final int mRingerDrawerItemSize;
|
||||||
|
private final int mRingerRowsPadding;
|
||||||
private final boolean mShowVibrate;
|
private final boolean mShowVibrate;
|
||||||
private final int mRingerCount;
|
private final int mRingerCount;
|
||||||
private final boolean mShowLowMediaVolumeIcon;
|
private final boolean mShowLowMediaVolumeIcon;
|
||||||
@@ -162,11 +169,25 @@ public class VolumeDialogImpl implements VolumeDialog,
|
|||||||
private Window mWindow;
|
private Window mWindow;
|
||||||
private CustomDialog mDialog;
|
private CustomDialog mDialog;
|
||||||
private ViewGroup mDialogView;
|
private ViewGroup mDialogView;
|
||||||
|
private ViewGroup mDialogRowsViewContainer;
|
||||||
private ViewGroup mDialogRowsView;
|
private ViewGroup mDialogRowsView;
|
||||||
private ViewGroup mRinger;
|
private ViewGroup mRinger;
|
||||||
|
|
||||||
@Nullable private View mRingerAndRowsContainer;
|
/**
|
||||||
@Nullable private Drawable mRingerAndRowsContainerBackground;
|
* Container for the top part of the dialog, which contains the ringer, the ringer drawer, the
|
||||||
|
* volume rows, and the ellipsis button. This does not include the live caption button.
|
||||||
|
*/
|
||||||
|
@Nullable private View mTopContainer;
|
||||||
|
|
||||||
|
/** Container for the ringer icon, and for the (initially hidden) ringer drawer view. */
|
||||||
|
@Nullable private View mRingerAndDrawerContainer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Background drawable for the ringer and drawer container. The background's top bound is
|
||||||
|
* initially inset by the height of the (hidden) ringer drawer. When the drawer is animated in,
|
||||||
|
* this top bound is animated to accommodate it.
|
||||||
|
*/
|
||||||
|
@Nullable private Drawable mRingerAndDrawerContainerBackground;
|
||||||
|
|
||||||
private ViewGroup mSelectedRingerContainer;
|
private ViewGroup mSelectedRingerContainer;
|
||||||
private ImageView mSelectedRingerIcon;
|
private ImageView mSelectedRingerIcon;
|
||||||
@@ -196,6 +217,7 @@ public class VolumeDialogImpl implements VolumeDialog,
|
|||||||
private final ValueAnimator mAnimateUpBackgroundToMatchDrawer = ValueAnimator.ofFloat(1f, 0f);
|
private final ValueAnimator mAnimateUpBackgroundToMatchDrawer = ValueAnimator.ofFloat(1f, 0f);
|
||||||
|
|
||||||
private boolean mIsRingerDrawerOpen = false;
|
private boolean mIsRingerDrawerOpen = false;
|
||||||
|
private float mRingerDrawerClosedAmount = 1f;
|
||||||
|
|
||||||
private ImageButton mRingerIcon;
|
private ImageButton mRingerIcon;
|
||||||
private ViewGroup mODICaptionsView;
|
private ViewGroup mODICaptionsView;
|
||||||
@@ -266,8 +288,14 @@ public class VolumeDialogImpl implements VolumeDialog,
|
|||||||
mDialogRowsView.invalidate();
|
mDialogRowsView.invalidate();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
mDialogWidth = mContext.getResources().getDimensionPixelSize(
|
||||||
|
R.dimen.volume_dialog_panel_width);
|
||||||
|
mDialogCornerRadius = mContext.getResources().getDimensionPixelSize(
|
||||||
|
R.dimen.volume_dialog_panel_width_half);
|
||||||
mRingerDrawerItemSize = mContext.getResources().getDimensionPixelSize(
|
mRingerDrawerItemSize = mContext.getResources().getDimensionPixelSize(
|
||||||
R.dimen.volume_ringer_drawer_item_size);
|
R.dimen.volume_ringer_drawer_item_size);
|
||||||
|
mRingerRowsPadding = mContext.getResources().getDimensionPixelSize(
|
||||||
|
R.dimen.volume_dialog_ringer_rows_padding);
|
||||||
mShowVibrate = mController.hasVibrator();
|
mShowVibrate = mController.hasVibrator();
|
||||||
|
|
||||||
// Normal, mute, and possibly vibrate.
|
// Normal, mute, and possibly vibrate.
|
||||||
@@ -321,7 +349,7 @@ public class VolumeDialogImpl implements VolumeDialog,
|
|||||||
|
|
||||||
// The ringer and rows container has extra height at the top to fit the expanded ringer
|
// The ringer and rows container has extra height at the top to fit the expanded ringer
|
||||||
// drawer. This area should not be touchable unless the ringer drawer is open.
|
// drawer. This area should not be touchable unless the ringer drawer is open.
|
||||||
if (view == mRingerAndRowsContainer && !mIsRingerDrawerOpen) {
|
if (view == mTopContainer && !mIsRingerDrawerOpen) {
|
||||||
if (!isLandscape()) {
|
if (!isLandscape()) {
|
||||||
y += getRingerDrawerOpenExtraSize();
|
y += getRingerDrawerOpenExtraSize();
|
||||||
} else {
|
} else {
|
||||||
@@ -431,6 +459,46 @@ public class VolumeDialogImpl implements VolumeDialog,
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mDialogRowsViewContainer = mDialogView.findViewById(R.id.volume_dialog_rows_container);
|
||||||
|
mTopContainer = mDialogView.findViewById(R.id.volume_dialog_top_container);
|
||||||
|
mRingerAndDrawerContainer = mDialogView.findViewById(
|
||||||
|
R.id.volume_ringer_and_drawer_container);
|
||||||
|
|
||||||
|
if (mRingerAndDrawerContainer != null) {
|
||||||
|
if (isLandscape()) {
|
||||||
|
// In landscape, we need to add padding to the bottom of the ringer drawer so that
|
||||||
|
// when it expands to the left, it doesn't overlap any additional volume rows.
|
||||||
|
mRingerAndDrawerContainer.setPadding(
|
||||||
|
mRingerAndDrawerContainer.getPaddingLeft(),
|
||||||
|
mRingerAndDrawerContainer.getPaddingTop(),
|
||||||
|
mRingerAndDrawerContainer.getPaddingRight(),
|
||||||
|
mRingerRowsPadding);
|
||||||
|
|
||||||
|
// Since the ringer drawer is expanding to the left, outside of the background of
|
||||||
|
// the dialog, it needs its own rounded background drawable. We also need that
|
||||||
|
// background to be rounded on all sides. We'll use a background rounded on all four
|
||||||
|
// corners, and then extend the container's background later to fill in the bottom
|
||||||
|
// corners when the drawer is closed.
|
||||||
|
mRingerAndDrawerContainer.setBackgroundDrawable(
|
||||||
|
mContext.getDrawable(R.drawable.volume_background_top_rounded));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Post to wait for layout so that the background bounds are set.
|
||||||
|
mRingerAndDrawerContainer.post(() -> {
|
||||||
|
final LayerDrawable ringerAndDrawerBg =
|
||||||
|
(LayerDrawable) mRingerAndDrawerContainer.getBackground();
|
||||||
|
|
||||||
|
// Retrieve the ShapeDrawable from within the background - this is what we will
|
||||||
|
// animate up and down when the drawer is opened/closed.
|
||||||
|
if (ringerAndDrawerBg != null && ringerAndDrawerBg.getNumberOfLayers() > 0) {
|
||||||
|
mRingerAndDrawerContainerBackground = ringerAndDrawerBg.getDrawable(0);
|
||||||
|
|
||||||
|
updateBackgroundForDrawerClosedAmount();
|
||||||
|
setTopContainerBackgroundDrawable();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
mRinger = mDialog.findViewById(R.id.ringer);
|
mRinger = mDialog.findViewById(R.id.ringer);
|
||||||
if (mRinger != null) {
|
if (mRinger != null) {
|
||||||
mRingerIcon = mRinger.findViewById(R.id.ringer_icon);
|
mRingerIcon = mRinger.findViewById(R.id.ringer_icon);
|
||||||
@@ -510,6 +578,11 @@ public class VolumeDialogImpl implements VolumeDialog,
|
|||||||
Configuration.ORIENTATION_LANDSCAPE;
|
Configuration.ORIENTATION_LANDSCAPE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean isRtl() {
|
||||||
|
return mContext.getResources().getConfiguration().getLayoutDirection()
|
||||||
|
== LAYOUT_DIRECTION_RTL;
|
||||||
|
}
|
||||||
|
|
||||||
public void setStreamImportant(int stream, boolean important) {
|
public void setStreamImportant(int stream, boolean important) {
|
||||||
mHandler.obtainMessage(H.SET_STREAM_IMPORTANT, stream, important ? 1 : 0).sendToTarget();
|
mHandler.obtainMessage(H.SET_STREAM_IMPORTANT, stream, important ? 1 : 0).sendToTarget();
|
||||||
}
|
}
|
||||||
@@ -612,23 +685,6 @@ public class VolumeDialogImpl implements VolumeDialog,
|
|||||||
|
|
||||||
row.anim = null;
|
row.anim = null;
|
||||||
|
|
||||||
mRingerAndRowsContainer = mDialogView.findViewById(
|
|
||||||
R.id.volume_dialog_ringer_and_rows_container);
|
|
||||||
|
|
||||||
if (mRingerAndRowsContainer != null) {
|
|
||||||
// Wait for layout so the background bounds are set, then set the background top to the
|
|
||||||
// ringer drawer closed position.
|
|
||||||
mRingerAndRowsContainer.post(() -> {
|
|
||||||
final LayerDrawable bgWrapper =
|
|
||||||
((LayerDrawable) mRingerAndRowsContainer.getBackground());
|
|
||||||
|
|
||||||
if (bgWrapper != null) {
|
|
||||||
mRingerAndRowsContainerBackground = bgWrapper.getDrawable(0);
|
|
||||||
setRingerAndRowsBackgroundTop(1f /* closedAmount */);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
final LayerDrawable seekbarDrawable =
|
final LayerDrawable seekbarDrawable =
|
||||||
(LayerDrawable) mContext.getDrawable(R.drawable.volume_row_seekbar);
|
(LayerDrawable) mContext.getDrawable(R.drawable.volume_row_seekbar);
|
||||||
|
|
||||||
@@ -764,8 +820,10 @@ public class VolumeDialogImpl implements VolumeDialog,
|
|||||||
});
|
});
|
||||||
mRingerDrawerIconColorAnimator.setDuration(DRAWER_ANIMATION_DURATION_SHORT);
|
mRingerDrawerIconColorAnimator.setDuration(DRAWER_ANIMATION_DURATION_SHORT);
|
||||||
|
|
||||||
mAnimateUpBackgroundToMatchDrawer.addUpdateListener(valueAnimator ->
|
mAnimateUpBackgroundToMatchDrawer.addUpdateListener(valueAnimator -> {
|
||||||
setRingerAndRowsBackgroundTop((float) valueAnimator.getAnimatedValue()));
|
mRingerDrawerClosedAmount = (float) valueAnimator.getAnimatedValue();
|
||||||
|
updateBackgroundForDrawerClosedAmount();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private ImageView getDrawerIconViewForMode(int mode) {
|
private ImageView getDrawerIconViewForMode(int mode) {
|
||||||
@@ -792,6 +850,10 @@ public class VolumeDialogImpl implements VolumeDialog,
|
|||||||
|
|
||||||
/** Animates in the ringer drawer. */
|
/** Animates in the ringer drawer. */
|
||||||
private void showRingerDrawer() {
|
private void showRingerDrawer() {
|
||||||
|
if (mIsRingerDrawerOpen) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Show all ringer icons except the currently selected one, since we're going to animate the
|
// Show all ringer icons except the currently selected one, since we're going to animate the
|
||||||
// ringer button to that position.
|
// ringer button to that position.
|
||||||
mRingerDrawerVibrateIcon.setVisibility(
|
mRingerDrawerVibrateIcon.setVisibility(
|
||||||
@@ -874,6 +936,10 @@ public class VolumeDialogImpl implements VolumeDialog,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!mIsRingerDrawerOpen) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Hide the drawer icon for the selected ringer - it's visible in the ringer button and we
|
// Hide the drawer icon for the selected ringer - it's visible in the ringer button and we
|
||||||
// don't want to be able to see it while it animates away.
|
// don't want to be able to see it while it animates away.
|
||||||
getDrawerIconViewForMode(mState.ringerModeInternal).setVisibility(INVISIBLE);
|
getDrawerIconViewForMode(mState.ringerModeInternal).setVisibility(INVISIBLE);
|
||||||
@@ -1143,6 +1209,7 @@ public class VolumeDialogImpl implements VolumeDialog,
|
|||||||
mController.notifyVisible(true);
|
mController.notifyVisible(true);
|
||||||
mController.getCaptionsComponentState(false);
|
mController.getCaptionsComponentState(false);
|
||||||
checkODICaptionsTooltip(false);
|
checkODICaptionsTooltip(false);
|
||||||
|
updateBackgroundForDrawerClosedAmount();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void rescheduleTimeoutH() {
|
protected void rescheduleTimeoutH() {
|
||||||
@@ -1258,15 +1325,65 @@ public class VolumeDialogImpl implements VolumeDialog,
|
|||||||
if (!mShowing) {
|
if (!mShowing) {
|
||||||
trimObsoleteH();
|
trimObsoleteH();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Index of the last row that is actually visible.
|
||||||
|
int rightmostVisibleRowIndex = !isRtl() ? -1 : Short.MAX_VALUE;
|
||||||
|
|
||||||
// apply changes to all rows
|
// apply changes to all rows
|
||||||
for (final VolumeRow row : mRows) {
|
for (final VolumeRow row : mRows) {
|
||||||
final boolean isActive = row == activeRow;
|
final boolean isActive = row == activeRow;
|
||||||
final boolean shouldBeVisible = shouldBeVisibleH(row, activeRow);
|
final boolean shouldBeVisible = shouldBeVisibleH(row, activeRow);
|
||||||
Util.setVisOrGone(row.view, shouldBeVisible);
|
Util.setVisOrGone(row.view, shouldBeVisible);
|
||||||
|
|
||||||
|
if (shouldBeVisible && mRingerAndDrawerContainerBackground != null) {
|
||||||
|
// For RTL, the rightmost row has the lowest index since child views are laid out
|
||||||
|
// from right to left.
|
||||||
|
rightmostVisibleRowIndex =
|
||||||
|
!isRtl()
|
||||||
|
? Math.max(rightmostVisibleRowIndex,
|
||||||
|
mDialogRowsView.indexOfChild(row.view))
|
||||||
|
: Math.min(rightmostVisibleRowIndex,
|
||||||
|
mDialogRowsView.indexOfChild(row.view));
|
||||||
|
|
||||||
|
// Add spacing between each of the visible rows - we'll remove the spacing from the
|
||||||
|
// last row after the loop.
|
||||||
|
final ViewGroup.LayoutParams layoutParams = row.view.getLayoutParams();
|
||||||
|
if (layoutParams instanceof LinearLayout.LayoutParams) {
|
||||||
|
final LinearLayout.LayoutParams linearLayoutParams =
|
||||||
|
((LinearLayout.LayoutParams) layoutParams);
|
||||||
|
if (!isRtl()) {
|
||||||
|
linearLayoutParams.setMarginEnd(mRingerRowsPadding);
|
||||||
|
} else {
|
||||||
|
linearLayoutParams.setMarginStart(mRingerRowsPadding);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the background on each of the rows. We'll remove this from the last row after
|
||||||
|
// the loop, since the last row's background is drawn by the main volume container.
|
||||||
|
row.view.setBackgroundDrawable(
|
||||||
|
mContext.getDrawable(R.drawable.volume_row_rounded_background));
|
||||||
|
}
|
||||||
|
|
||||||
if (row.view.isShown()) {
|
if (row.view.isShown()) {
|
||||||
updateVolumeRowTintH(row, isActive);
|
updateVolumeRowTintH(row, isActive);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (rightmostVisibleRowIndex > -1 && rightmostVisibleRowIndex < Short.MAX_VALUE) {
|
||||||
|
final View lastVisibleChild = mDialogRowsView.getChildAt(rightmostVisibleRowIndex);
|
||||||
|
final ViewGroup.LayoutParams layoutParams = lastVisibleChild.getLayoutParams();
|
||||||
|
// Remove the spacing on the last row, and remove its background since the container is
|
||||||
|
// drawing a background for this row.
|
||||||
|
if (layoutParams instanceof LinearLayout.LayoutParams) {
|
||||||
|
final LinearLayout.LayoutParams linearLayoutParams =
|
||||||
|
((LinearLayout.LayoutParams) layoutParams);
|
||||||
|
linearLayoutParams.setMarginStart(0);
|
||||||
|
linearLayoutParams.setMarginEnd(0);
|
||||||
|
lastVisibleChild.setBackgroundColor(Color.TRANSPARENT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
updateBackgroundForDrawerClosedAmount();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void updateRingerH() {
|
protected void updateRingerH() {
|
||||||
@@ -1742,32 +1859,74 @@ public class VolumeDialogImpl implements VolumeDialog,
|
|||||||
return (mRingerCount - 1) * mRingerDrawerItemSize;
|
return (mRingerCount - 1) * mRingerDrawerItemSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
private void updateBackgroundForDrawerClosedAmount() {
|
||||||
* Sets the top of the background drawable behind the container view for the ringer icon and the
|
if (mRingerAndDrawerContainerBackground == null) {
|
||||||
* volume rows, depending on whether the ringer drawer is open or closed.
|
|
||||||
*/
|
|
||||||
private void setRingerAndRowsBackgroundTop(float drawerClosedAmount) {
|
|
||||||
if (mRingerAndRowsContainerBackground == null) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
final Rect bounds = mRingerAndRowsContainerBackground.copyBounds();
|
final Rect bounds = mRingerAndDrawerContainerBackground.copyBounds();
|
||||||
|
|
||||||
if (!isLandscape()) {
|
if (!isLandscape()) {
|
||||||
// In portrait, the background should fill the full width, but only go up to the ringer
|
bounds.top = (int) (mRingerDrawerClosedAmount * getRingerDrawerOpenExtraSize());
|
||||||
// icon's top. We'll extend it all the way to the top of the container when the ringer
|
|
||||||
// drawer opens.
|
|
||||||
bounds.left = 0;
|
|
||||||
bounds.top = (int) (drawerClosedAmount * getRingerDrawerOpenExtraSize());
|
|
||||||
} else {
|
} else {
|
||||||
// In landscape, the background should be inset by the size of the open drawer, since it
|
bounds.left = (int) (mRingerDrawerClosedAmount * getRingerDrawerOpenExtraSize());
|
||||||
// opens sideways. It should extend to the top of the container since we haven't left
|
}
|
||||||
// space for the drawer to open upward.
|
mRingerAndDrawerContainerBackground.setBounds(bounds);
|
||||||
bounds.left = getRingerDrawerOpenExtraSize();
|
}
|
||||||
bounds.top = 0;
|
|
||||||
|
/*
|
||||||
|
* The top container is responsible for drawing the solid color background behind the rightmost
|
||||||
|
* (primary) volume row. This is because the volume drawer animates in from below, initially
|
||||||
|
* overlapping the primary row. We need the drawer to draw below the row's SeekBar, since it
|
||||||
|
* looks strange to overlap it, but above the row's background color, since otherwise it will be
|
||||||
|
* clipped.
|
||||||
|
*
|
||||||
|
* Since we can't be both above and below the volume row view, we'll be below it, and render the
|
||||||
|
* background color in the container since they're both above that.
|
||||||
|
*/
|
||||||
|
private void setTopContainerBackgroundDrawable() {
|
||||||
|
if (mTopContainer == null) {
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
mRingerAndRowsContainerBackground.setBounds(bounds);
|
final ColorDrawable solidDrawable = new ColorDrawable(
|
||||||
|
Utils.getColorAttrDefaultColor(mContext, com.android.internal.R.attr.colorSurface));
|
||||||
|
|
||||||
|
final LayerDrawable background = new LayerDrawable(new Drawable[] { solidDrawable });
|
||||||
|
|
||||||
|
// Size the solid color to match the primary volume row. In landscape, extend it upwards
|
||||||
|
// slightly so that it fills in the bottom corners of the ringer icon, whose background is
|
||||||
|
// rounded on all sides so that it can expand to the left, outside the dialog's background.
|
||||||
|
background.setLayerSize(0, mDialogWidth,
|
||||||
|
!isLandscape()
|
||||||
|
? mDialogRowsView.getHeight()
|
||||||
|
: mDialogRowsView.getHeight() + mDialogCornerRadius);
|
||||||
|
// Inset the top so that the color only renders below the ringer drawer, which has its own
|
||||||
|
// background. In landscape, reduce the inset slightly since we are using the background to
|
||||||
|
// fill in the corners of the closed ringer drawer.
|
||||||
|
background.setLayerInsetTop(0,
|
||||||
|
!isLandscape()
|
||||||
|
? mDialogRowsViewContainer.getTop()
|
||||||
|
: mDialogRowsViewContainer.getTop() - mDialogCornerRadius);
|
||||||
|
|
||||||
|
// Set gravity to top-right, since additional rows will be added on the left.
|
||||||
|
background.setLayerGravity(0, Gravity.TOP | Gravity.RIGHT);
|
||||||
|
|
||||||
|
// In landscape, the ringer drawer animates out to the left (instead of down). Since the
|
||||||
|
// drawer comes from the right (beyond the bounds of the dialog), we should clip it so it
|
||||||
|
// doesn't draw outside the dialog background. This isn't an issue in portrait, since the
|
||||||
|
// drawer animates downward, below the volume row.
|
||||||
|
if (isLandscape()) {
|
||||||
|
mRingerAndDrawerContainer.setOutlineProvider(new ViewOutlineProvider() {
|
||||||
|
@Override
|
||||||
|
public void getOutline(View view, Outline outline) {
|
||||||
|
outline.setRoundRect(
|
||||||
|
0, 0, view.getWidth(), view.getHeight(), mDialogCornerRadius);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
mRingerAndDrawerContainer.setClipToOutline(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
mTopContainer.setBackground(background);
|
||||||
}
|
}
|
||||||
|
|
||||||
private final VolumeDialogController.Callbacks mControllerCallbackH
|
private final VolumeDialogController.Callbacks mControllerCallbackH
|
||||||
|
|||||||
Reference in New Issue
Block a user