Merge "Fixes issues with multiple ringer rows (which also addresses a few RTL/landscape issues)." into sc-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
b3ca17a237
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>
|
||||
<size android:width="@dimen/volume_dialog_panel_width" />
|
||||
<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>
|
||||
</item>
|
||||
</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">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/main"
|
||||
android:id="@+id/volume_dialog_rows_container"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="right"
|
||||
|
||||
@@ -39,13 +39,12 @@
|
||||
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/volume_dialog_ringer_and_rows_container"
|
||||
android:id="@+id/volume_dialog_top_container"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:padding="7dp"
|
||||
android:clipChildren="false"
|
||||
android:background="@drawable/volume_background">
|
||||
android:gravity="right">
|
||||
|
||||
<include layout="@layout/volume_ringer_drawer" />
|
||||
|
||||
@@ -80,7 +79,7 @@
|
||||
</FrameLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/main"
|
||||
android:id="@+id/volume_dialog_rows_container"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="right"
|
||||
@@ -93,14 +92,17 @@
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
android:orientation="horizontal"
|
||||
android:layout_marginTop="@dimen/volume_row_slider_padding_start">
|
||||
android:orientation="horizontal">
|
||||
<!-- volume rows added and removed here! :-) -->
|
||||
</LinearLayout>
|
||||
<FrameLayout
|
||||
android:id="@+id/settings_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
android:layout_width="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
|
||||
android:id="@+id/settings"
|
||||
android:src="@drawable/horizontal_ellipsis"
|
||||
@@ -124,7 +126,7 @@
|
||||
android:gravity="right"
|
||||
android:layout_gravity="right"
|
||||
android:clipToPadding="false"
|
||||
android:background="@drawable/volume_background">
|
||||
android:background="@drawable/volume_row_rounded_background">
|
||||
<com.android.systemui.volume.CaptionsToggleImageButton
|
||||
android:id="@+id/odi_captions_icon"
|
||||
android:src="@drawable/ic_volume_odi_captions_disabled"
|
||||
|
||||
@@ -37,15 +37,13 @@
|
||||
android:clipToPadding="false"
|
||||
android:clipChildren="false">
|
||||
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/volume_dialog_ringer_and_rows_container"
|
||||
android:id="@+id/volume_dialog_top_container"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:padding="7dp"
|
||||
android:clipChildren="false"
|
||||
android:background="@drawable/volume_background">
|
||||
android:orientation="vertical"
|
||||
android:gravity="right">
|
||||
|
||||
<include layout="@layout/volume_ringer_drawer" />
|
||||
|
||||
@@ -80,7 +78,7 @@
|
||||
</FrameLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/main"
|
||||
android:id="@+id/volume_dialog_rows_container"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="right"
|
||||
@@ -93,14 +91,17 @@
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
android:orientation="horizontal"
|
||||
android:layout_marginTop="@dimen/volume_row_slider_padding_start">
|
||||
android:orientation="horizontal">
|
||||
<!-- volume rows added and removed here! :-) -->
|
||||
</LinearLayout>
|
||||
<FrameLayout
|
||||
android:id="@+id/settings_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
android:layout_width="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
|
||||
android:id="@+id/settings"
|
||||
android:src="@drawable/horizontal_ellipsis"
|
||||
@@ -122,9 +123,9 @@
|
||||
android:layout_height="@dimen/volume_dialog_caption_size"
|
||||
android:layout_marginTop="@dimen/volume_dialog_row_margin_bottom"
|
||||
android:gravity="right"
|
||||
android:layout_gravity="center"
|
||||
android:layout_gravity="right"
|
||||
android:clipToPadding="false"
|
||||
android:background="@drawable/volume_background">
|
||||
android:background="@drawable/volume_row_rounded_background">
|
||||
<com.android.systemui.volume.CaptionsToggleImageButton
|
||||
android:id="@+id/odi_captions_icon"
|
||||
android:src="@drawable/ic_volume_odi_captions_disabled"
|
||||
|
||||
@@ -17,15 +17,18 @@
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:tag="row"
|
||||
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: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">
|
||||
|
||||
<LinearLayout
|
||||
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:layout_gravity="center"
|
||||
android:orientation="vertical" >
|
||||
|
||||
@@ -18,9 +18,16 @@
|
||||
<!-- Contains the active ringer icon and a hidden drawer containing all three ringer options. -->
|
||||
<FrameLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/volume_ringer_and_drawer_container"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
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:clipChildren="false">
|
||||
|
||||
|
||||
@@ -472,6 +472,8 @@
|
||||
|
||||
<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_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.GONE;
|
||||
import static android.view.View.INVISIBLE;
|
||||
import static android.view.View.LAYOUT_DIRECTION_RTL;
|
||||
import static android.view.View.VISIBLE;
|
||||
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.TypedArray;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.Outline;
|
||||
import android.graphics.PixelFormat;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.Region;
|
||||
@@ -74,11 +76,13 @@ import android.util.Log;
|
||||
import android.util.Slog;
|
||||
import android.util.SparseBooleanArray;
|
||||
import android.view.ContextThemeWrapper;
|
||||
import android.view.Gravity;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.view.View.AccessibilityDelegate;
|
||||
import android.view.View.OnAttachStateChangeListener;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.ViewOutlineProvider;
|
||||
import android.view.ViewPropertyAnimator;
|
||||
import android.view.ViewStub;
|
||||
import android.view.ViewTreeObserver;
|
||||
@@ -147,7 +151,10 @@ public class VolumeDialogImpl implements VolumeDialog,
|
||||
|
||||
private final int mDialogShowAnimationDurationMs;
|
||||
private final int mDialogHideAnimationDurationMs;
|
||||
private final int mDialogWidth;
|
||||
private final int mDialogCornerRadius;
|
||||
private final int mRingerDrawerItemSize;
|
||||
private final int mRingerRowsPadding;
|
||||
private final boolean mShowVibrate;
|
||||
private final int mRingerCount;
|
||||
private final boolean mShowLowMediaVolumeIcon;
|
||||
@@ -162,11 +169,25 @@ public class VolumeDialogImpl implements VolumeDialog,
|
||||
private Window mWindow;
|
||||
private CustomDialog mDialog;
|
||||
private ViewGroup mDialogView;
|
||||
private ViewGroup mDialogRowsViewContainer;
|
||||
private ViewGroup mDialogRowsView;
|
||||
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 ImageView mSelectedRingerIcon;
|
||||
@@ -196,6 +217,7 @@ public class VolumeDialogImpl implements VolumeDialog,
|
||||
private final ValueAnimator mAnimateUpBackgroundToMatchDrawer = ValueAnimator.ofFloat(1f, 0f);
|
||||
|
||||
private boolean mIsRingerDrawerOpen = false;
|
||||
private float mRingerDrawerClosedAmount = 1f;
|
||||
|
||||
private ImageButton mRingerIcon;
|
||||
private ViewGroup mODICaptionsView;
|
||||
@@ -266,8 +288,14 @@ public class VolumeDialogImpl implements VolumeDialog,
|
||||
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(
|
||||
R.dimen.volume_ringer_drawer_item_size);
|
||||
mRingerRowsPadding = mContext.getResources().getDimensionPixelSize(
|
||||
R.dimen.volume_dialog_ringer_rows_padding);
|
||||
mShowVibrate = mController.hasVibrator();
|
||||
|
||||
// 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
|
||||
// drawer. This area should not be touchable unless the ringer drawer is open.
|
||||
if (view == mRingerAndRowsContainer && !mIsRingerDrawerOpen) {
|
||||
if (view == mTopContainer && !mIsRingerDrawerOpen) {
|
||||
if (!isLandscape()) {
|
||||
y += getRingerDrawerOpenExtraSize();
|
||||
} 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);
|
||||
if (mRinger != null) {
|
||||
mRingerIcon = mRinger.findViewById(R.id.ringer_icon);
|
||||
@@ -510,6 +578,11 @@ public class VolumeDialogImpl implements VolumeDialog,
|
||||
Configuration.ORIENTATION_LANDSCAPE;
|
||||
}
|
||||
|
||||
private boolean isRtl() {
|
||||
return mContext.getResources().getConfiguration().getLayoutDirection()
|
||||
== LAYOUT_DIRECTION_RTL;
|
||||
}
|
||||
|
||||
public void setStreamImportant(int stream, boolean important) {
|
||||
mHandler.obtainMessage(H.SET_STREAM_IMPORTANT, stream, important ? 1 : 0).sendToTarget();
|
||||
}
|
||||
@@ -612,23 +685,6 @@ public class VolumeDialogImpl implements VolumeDialog,
|
||||
|
||||
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 =
|
||||
(LayerDrawable) mContext.getDrawable(R.drawable.volume_row_seekbar);
|
||||
|
||||
@@ -764,8 +820,10 @@ public class VolumeDialogImpl implements VolumeDialog,
|
||||
});
|
||||
mRingerDrawerIconColorAnimator.setDuration(DRAWER_ANIMATION_DURATION_SHORT);
|
||||
|
||||
mAnimateUpBackgroundToMatchDrawer.addUpdateListener(valueAnimator ->
|
||||
setRingerAndRowsBackgroundTop((float) valueAnimator.getAnimatedValue()));
|
||||
mAnimateUpBackgroundToMatchDrawer.addUpdateListener(valueAnimator -> {
|
||||
mRingerDrawerClosedAmount = (float) valueAnimator.getAnimatedValue();
|
||||
updateBackgroundForDrawerClosedAmount();
|
||||
});
|
||||
}
|
||||
|
||||
private ImageView getDrawerIconViewForMode(int mode) {
|
||||
@@ -792,6 +850,10 @@ public class VolumeDialogImpl implements VolumeDialog,
|
||||
|
||||
/** Animates in the ringer drawer. */
|
||||
private void showRingerDrawer() {
|
||||
if (mIsRingerDrawerOpen) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Show all ringer icons except the currently selected one, since we're going to animate the
|
||||
// ringer button to that position.
|
||||
mRingerDrawerVibrateIcon.setVisibility(
|
||||
@@ -874,6 +936,10 @@ public class VolumeDialogImpl implements VolumeDialog,
|
||||
return;
|
||||
}
|
||||
|
||||
if (!mIsRingerDrawerOpen) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 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.
|
||||
getDrawerIconViewForMode(mState.ringerModeInternal).setVisibility(INVISIBLE);
|
||||
@@ -1143,6 +1209,7 @@ public class VolumeDialogImpl implements VolumeDialog,
|
||||
mController.notifyVisible(true);
|
||||
mController.getCaptionsComponentState(false);
|
||||
checkODICaptionsTooltip(false);
|
||||
updateBackgroundForDrawerClosedAmount();
|
||||
}
|
||||
|
||||
protected void rescheduleTimeoutH() {
|
||||
@@ -1258,15 +1325,65 @@ public class VolumeDialogImpl implements VolumeDialog,
|
||||
if (!mShowing) {
|
||||
trimObsoleteH();
|
||||
}
|
||||
|
||||
// Index of the last row that is actually visible.
|
||||
int rightmostVisibleRowIndex = !isRtl() ? -1 : Short.MAX_VALUE;
|
||||
|
||||
// apply changes to all rows
|
||||
for (final VolumeRow row : mRows) {
|
||||
final boolean isActive = row == activeRow;
|
||||
final boolean shouldBeVisible = shouldBeVisibleH(row, activeRow);
|
||||
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()) {
|
||||
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() {
|
||||
@@ -1742,32 +1859,74 @@ public class VolumeDialogImpl implements VolumeDialog,
|
||||
return (mRingerCount - 1) * mRingerDrawerItemSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the top of the background drawable behind the container view for the ringer icon and the
|
||||
* volume rows, depending on whether the ringer drawer is open or closed.
|
||||
*/
|
||||
private void setRingerAndRowsBackgroundTop(float drawerClosedAmount) {
|
||||
if (mRingerAndRowsContainerBackground == null) {
|
||||
private void updateBackgroundForDrawerClosedAmount() {
|
||||
if (mRingerAndDrawerContainerBackground == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
final Rect bounds = mRingerAndRowsContainerBackground.copyBounds();
|
||||
|
||||
final Rect bounds = mRingerAndDrawerContainerBackground.copyBounds();
|
||||
if (!isLandscape()) {
|
||||
// In portrait, the background should fill the full width, but only go up to the ringer
|
||||
// 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());
|
||||
bounds.top = (int) (mRingerDrawerClosedAmount * getRingerDrawerOpenExtraSize());
|
||||
} else {
|
||||
// In landscape, the background should be inset by the size of the open drawer, since it
|
||||
// opens sideways. It should extend to the top of the container since we haven't left
|
||||
// space for the drawer to open upward.
|
||||
bounds.left = getRingerDrawerOpenExtraSize();
|
||||
bounds.top = 0;
|
||||
bounds.left = (int) (mRingerDrawerClosedAmount * getRingerDrawerOpenExtraSize());
|
||||
}
|
||||
mRingerAndDrawerContainerBackground.setBounds(bounds);
|
||||
}
|
||||
|
||||
/*
|
||||
* 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
|
||||
|
||||
Reference in New Issue
Block a user