Merge "Volume dialog redesign"
This commit is contained in:
committed by
Android (Google) Code Review
commit
d8b49d3908
@@ -17,130 +17,76 @@
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@android:color/transparent"
|
||||
android:theme="@style/qs_theme"
|
||||
android:clipChildren="false" >
|
||||
<RelativeLayout
|
||||
<LinearLayout
|
||||
android:id="@+id/volume_dialog"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingTop="@dimen/volume_row_padding_bottom"
|
||||
android:background="@drawable/rounded_full_bg_bottom"
|
||||
android:layout_gravity="center_vertical|end"
|
||||
android:minWidth="@dimen/volume_dialog_panel_width"
|
||||
android:background="@android:color/transparent"
|
||||
android:layout_margin="12dp"
|
||||
android:translationZ="8dp"
|
||||
android:orientation="vertical"
|
||||
android:clipChildren="false" >
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/volume_dialog_content"
|
||||
android:layout_width="match_parent"
|
||||
android:id="@+id/volume_dialog_rows"
|
||||
android:layout_width="@dimen/volume_dialog_panel_width"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_toStartOf="@id/expand"
|
||||
android:clipChildren="false"
|
||||
android:clipToPadding="false"
|
||||
android:paddingTop="12dp"
|
||||
android:paddingBottom="12dp"
|
||||
android:background="@drawable/rounded_bg_full"
|
||||
android:orientation="horizontal" >
|
||||
<!-- volume rows added and removed here! :-) -->
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/footer"
|
||||
android:layout_width="@dimen/volume_dialog_panel_width"
|
||||
android:layout_height="@dimen/volume_dialog_panel_width"
|
||||
android:clipChildren="false"
|
||||
android:clipToPadding="false"
|
||||
android:layout_marginTop="6dp"
|
||||
android:layout_marginBottom="6dp"
|
||||
android:layout_below="@id/volume_dialog_rows"
|
||||
android:background="@drawable/rounded_bg_full"
|
||||
android:gravity="center"
|
||||
android:orientation="vertical" >
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/volume_dialog_rows"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical" >
|
||||
<!-- volume rows added and removed here! :-) -->
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
</LinearLayout>
|
||||
<LinearLayout
|
||||
android:id="@+id/expand"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_alignParentTop="true"
|
||||
android:layout_marginEnd="@dimen/volume_expander_margin_end" >
|
||||
<TextView
|
||||
android:id="@+id/ringer_title"
|
||||
android:text="@string/ring_toggle_title"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="1"
|
||||
android:textAppearance="@style/TextAppearance.Volume.Header" />
|
||||
android:layout_centerVertical="true"
|
||||
android:textColor="?android:attr/colorControlNormal"
|
||||
android:textAppearance="?android:attr/textAppearanceSmall" />
|
||||
|
||||
<com.android.keyguard.AlphaOptimizedImageButton
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/volume_expand_button"
|
||||
style="@style/VolumeButtons"
|
||||
android:layout_width="@dimen/volume_button_size"
|
||||
android:layout_height="@dimen/volume_button_size"
|
||||
android:clickable="true"
|
||||
android:soundEffectsEnabled="false"
|
||||
android:src="@drawable/ic_volume_expand_animation"
|
||||
android:background="@drawable/ripple_drawable"
|
||||
tools:ignore="RtlHardcoded" />
|
||||
</LinearLayout>
|
||||
<RelativeLayout
|
||||
android:id="@+id/footer"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:clipChildren="false"
|
||||
android:clipToPadding="false"
|
||||
android:layout_below="@id/volume_dialog_content"
|
||||
android:layout_margin="10dp">
|
||||
<!-- special row for ringer mode -->
|
||||
<RelativeLayout
|
||||
android:id="@+id/ringer_mode"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@drawable/rounded_bg_full"
|
||||
android:clipChildren="false"
|
||||
android:clipToPadding="false"
|
||||
android:layout_toStartOf="@id/output_chooser"
|
||||
android:layout_margin="10dp">
|
||||
|
||||
<com.android.keyguard.AlphaOptimizedImageButton
|
||||
android:id="@+id/ringer_icon"
|
||||
style="@style/VolumeButtons"
|
||||
android:background="?android:selectableItemBackgroundBorderless"
|
||||
android:layout_width="@dimen/volume_button_size"
|
||||
android:layout_height="@dimen/volume_button_size"
|
||||
android:layout_alignParentStart="true"
|
||||
android:layout_centerVertical="true"
|
||||
android:soundEffectsEnabled="false" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/ringer_title"
|
||||
android:text="@string/ring_toggle_title"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="1"
|
||||
android:layout_alignParentStart="true"
|
||||
android:layout_centerVertical="true"
|
||||
android:layout_toEndOf="@+id/ringer_icon"
|
||||
android:layout_marginStart="64dp"
|
||||
android:textColor="?android:attr/colorControlNormal"
|
||||
android:textAppearance="?android:attr/textAppearanceSmall"
|
||||
android:paddingStart="@dimen/volume_row_header_padding_start" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/ringer_status"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:ellipsize="end"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_centerVertical="true"
|
||||
android:layout_marginEnd="14dp"
|
||||
android:maxLines="1"
|
||||
android:textColor="?android:attr/colorControlNormal"
|
||||
android:textAppearance="?android:attr/textAppearanceSmall" />
|
||||
|
||||
</RelativeLayout>
|
||||
<com.android.keyguard.AlphaOptimizedImageButton
|
||||
android:id="@+id/output_chooser"
|
||||
android:id="@+id/ringer_icon"
|
||||
style="@style/VolumeButtons"
|
||||
android:background="?android:selectableItemBackgroundBorderless"
|
||||
android:layout_width="@dimen/volume_button_size"
|
||||
android:layout_height="@dimen/volume_button_size"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_centerVertical="true"
|
||||
android:src="@drawable/ic_settings_bluetooth"
|
||||
android:tint="?android:attr/colorAccent"
|
||||
android:soundEffectsEnabled="false" />
|
||||
</RelativeLayout>
|
||||
</RelativeLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/ringer_status"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="1"
|
||||
android:textColor="?android:attr/colorControlNormal"
|
||||
android:textAppearance="?android:attr/textAppearanceSmall" />
|
||||
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
</com.android.systemui.volume.VolumeUiLayout>
|
||||
@@ -15,48 +15,70 @@
|
||||
-->
|
||||
<LinearLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/volume_row_height"
|
||||
android:clipChildren="false"
|
||||
android:clipToPadding="false"
|
||||
android:tag="row"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_width="@dimen/volume_dialog_panel_width"
|
||||
android:clipChildren="true"
|
||||
android:clipToPadding="true"
|
||||
android:theme="@style/qs_theme"
|
||||
android:gravity="center"
|
||||
android:orientation="vertical" >
|
||||
|
||||
<TextView
|
||||
android:id="@+id/volume_row_header"
|
||||
<LinearLayout
|
||||
android:orientation="vertical"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="1"
|
||||
android:textColor="?android:attr/colorControlNormal"
|
||||
android:textAppearance="?android:attr/textAppearanceSmall"
|
||||
android:paddingStart="@dimen/volume_row_header_padding_start" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/volume_row_slider_height"
|
||||
android:orientation="horizontal"
|
||||
android:paddingStart="@dimen/volume_row_padding_start" >
|
||||
android:gravity="center"
|
||||
android:padding="10dp">
|
||||
<TextView
|
||||
android:id="@+id/volume_row_header"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="1"
|
||||
android:textColor="?android:attr/colorControlNormal"
|
||||
android:textAppearance="?android:attr/textAppearanceSmall" />
|
||||
<TextView
|
||||
android:id="@+id/volume_row_connected_device"
|
||||
android:visibility="gone"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="1"
|
||||
android:textAppearance="@style/TextAppearance.QS.DetailItemSecondary" />
|
||||
<com.android.keyguard.AlphaOptimizedImageButton
|
||||
android:id="@+id/volume_row_icon"
|
||||
style="@style/VolumeButtons"
|
||||
android:layout_width="@dimen/volume_button_size"
|
||||
android:layout_height="@dimen/volume_button_size"
|
||||
android:soundEffectsEnabled="false" />
|
||||
|
||||
<SeekBar
|
||||
android:id="@+id/volume_row_slider"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_alignWithParentIfMissing="true"
|
||||
android:focusable="true"
|
||||
android:focusableInTouchMode="true"
|
||||
android:paddingStart="@dimen/volume_row_slider_padding_start"/>
|
||||
android:id="@+id/output_chooser"
|
||||
style="@style/VolumeButtons"
|
||||
android:background="?android:selectableItemBackgroundBorderless"
|
||||
android:layout_width="@dimen/volume_button_size"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_centerVertical="true"
|
||||
android:src="@drawable/ic_volume_expand_animation"
|
||||
android:soundEffectsEnabled="false" />
|
||||
</LinearLayout>
|
||||
<FrameLayout
|
||||
android:id="@+id/volume_row_slider_frame"
|
||||
android:padding="10dp"
|
||||
android:layout_width="@dimen/volume_dialog_panel_width"
|
||||
android:layout_height="150dp">
|
||||
<SeekBar
|
||||
android:id="@+id/volume_row_slider"
|
||||
android:padding="0dp"
|
||||
android:layout_margin="0dp"
|
||||
android:layout_width="150dp"
|
||||
android:layout_height="@dimen/volume_dialog_panel_width"
|
||||
android:layout_gravity="center"
|
||||
android:focusable="true"
|
||||
android:focusableInTouchMode="true"
|
||||
android:rotation="270" />
|
||||
</FrameLayout>
|
||||
|
||||
<Space
|
||||
android:id="@+id/spacer"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/volume_row_padding_bottom"/>
|
||||
<com.android.keyguard.AlphaOptimizedImageButton
|
||||
android:id="@+id/volume_row_icon"
|
||||
style="@style/VolumeButtons"
|
||||
android:padding="10dp"
|
||||
android:layout_width="@dimen/volume_button_size"
|
||||
android:layout_height="@dimen/volume_button_size"
|
||||
android:soundEffectsEnabled="false" />
|
||||
|
||||
</LinearLayout>
|
||||
@@ -264,7 +264,7 @@
|
||||
<!-- The width of the panel that holds the quick settings. -->
|
||||
<dimen name="qs_panel_width">@dimen/notification_panel_width</dimen>
|
||||
|
||||
<dimen name="volume_dialog_panel_width">315dp</dimen>
|
||||
<dimen name="volume_dialog_panel_width">120dp</dimen>
|
||||
|
||||
<!-- Gravity for the notification panel -->
|
||||
<integer name="notification_panel_layout_gravity">0x31</integer><!-- center_horizontal|top -->
|
||||
|
||||
@@ -52,7 +52,7 @@ public class VolumeDialogComponent implements VolumeComponent, TunerService.Tuna
|
||||
public static final String VOLUME_UP_SILENT = "sysui_volume_up_silent";
|
||||
public static final String VOLUME_SILENT_DO_NOT_DISTURB = "sysui_do_not_disturb";
|
||||
|
||||
public static final boolean DEFAULT_VOLUME_DOWN_TO_ENTER_SILENT = true;
|
||||
public static final boolean DEFAULT_VOLUME_DOWN_TO_ENTER_SILENT = false;
|
||||
public static final boolean DEFAULT_VOLUME_UP_TO_EXIT_SILENT = true;
|
||||
public static final boolean DEFAULT_DO_NOT_DISTURB_WHEN_SILENT = true;
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@ import static android.accessibilityservice.AccessibilityServiceInfo.FEEDBACK_ALL
|
||||
import static android.accessibilityservice.AccessibilityServiceInfo.FEEDBACK_GENERIC;
|
||||
|
||||
import static com.android.systemui.volume.Events.DISMISS_REASON_OUTPUT_CHOOSER;
|
||||
import static com.android.systemui.volume.Events.DISMISS_REASON_SETTINGS_CLICKED;
|
||||
import static com.android.systemui.volume.Events.DISMISS_REASON_TOUCH_OUTSIDE;
|
||||
|
||||
import android.accessibilityservice.AccessibilityServiceInfo;
|
||||
@@ -30,14 +31,13 @@ import android.app.Dialog;
|
||||
import android.app.KeyguardManager;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.res.ColorStateList;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.drawable.AnimatedVectorDrawable;
|
||||
import android.graphics.drawable.ColorDrawable;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.media.AudioManager;
|
||||
import android.media.AudioSystem;
|
||||
import android.os.Debug;
|
||||
@@ -45,9 +45,8 @@ import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.os.Message;
|
||||
import android.os.SystemClock;
|
||||
import android.provider.Settings;
|
||||
import android.provider.Settings.Global;
|
||||
import android.transition.AutoTransition;
|
||||
import android.transition.TransitionManager;
|
||||
import android.util.Log;
|
||||
import android.util.Slog;
|
||||
import android.util.SparseBooleanArray;
|
||||
@@ -72,7 +71,6 @@ import android.widget.TextView;
|
||||
|
||||
import com.android.settingslib.Utils;
|
||||
import com.android.systemui.Dependency;
|
||||
import com.android.systemui.Interpolators;
|
||||
import com.android.systemui.R;
|
||||
import com.android.systemui.plugins.VolumeDialog;
|
||||
import com.android.systemui.plugins.VolumeDialogController;
|
||||
@@ -104,7 +102,6 @@ public class VolumeDialogImpl implements VolumeDialog {
|
||||
private CustomDialog mDialog;
|
||||
private ViewGroup mDialogView;
|
||||
private ViewGroup mDialogRowsView;
|
||||
private ImageButton mExpandButton;
|
||||
private ImageButton mRingerIcon;
|
||||
private ImageButton mOutputChooser;
|
||||
private TextView mRingerStatus;
|
||||
@@ -120,8 +117,6 @@ public class VolumeDialogImpl implements VolumeDialog {
|
||||
private final ColorStateList mInactiveSliderTint;
|
||||
|
||||
private boolean mShowing;
|
||||
private boolean mExpanded;
|
||||
private boolean mExpandButtonAnimationRunning;
|
||||
private boolean mShowA11yStream;
|
||||
|
||||
private int mActiveStream;
|
||||
@@ -182,11 +177,11 @@ public class VolumeDialogImpl implements VolumeDialog {
|
||||
|
||||
mDialog.setContentView(R.layout.volume_dialog);
|
||||
mDialog.setOnShowListener(dialog -> {
|
||||
mDialogView.setTranslationY(-mDialogView.getHeight());
|
||||
mDialogView.setTranslationX(mDialogView.getWidth() / 2);
|
||||
mDialogView.setAlpha(0);
|
||||
mDialogView.animate()
|
||||
.alpha(1)
|
||||
.translationY(0)
|
||||
.translationX(0)
|
||||
.setDuration(300)
|
||||
.setInterpolator(new SystemUIInterpolators.LogDecelerateInterpolator())
|
||||
.withEndAction(() -> {
|
||||
@@ -205,20 +200,10 @@ public class VolumeDialogImpl implements VolumeDialog {
|
||||
VolumeUiLayout hardwareLayout = VolumeUiLayout.get(mDialogView);
|
||||
hardwareLayout.setOutsideTouchListener(view -> dismiss(DISMISS_REASON_TOUCH_OUTSIDE));
|
||||
|
||||
ViewGroup dialogContentView = mDialog.findViewById(R.id.volume_dialog_content);
|
||||
mDialogRowsView = dialogContentView.findViewById(R.id.volume_dialog_rows);
|
||||
mDialogRowsView = mDialog.findViewById(R.id.volume_dialog_rows);
|
||||
mRingerIcon = mDialog.findViewById(R.id.ringer_icon);
|
||||
mRingerStatus = mDialog.findViewById(R.id.ringer_status);
|
||||
|
||||
mExpanded = false;
|
||||
mExpandButton = mDialogView.findViewById(R.id.volume_expand_button);
|
||||
mExpandButton.setOnClickListener(mClickExpand);
|
||||
mExpandButton.setVisibility(
|
||||
AudioSystem.isSingleVolume(mContext) ? View.GONE : View.VISIBLE);
|
||||
|
||||
mOutputChooser = mDialogView.findViewById(R.id.output_chooser);
|
||||
mOutputChooser.setOnClickListener(mClickOutputChooser);
|
||||
|
||||
if (mRows.isEmpty()) {
|
||||
addRow(AudioManager.STREAM_MUSIC,
|
||||
R.drawable.ic_volume_media, R.drawable.ic_volume_media_mute, true, true);
|
||||
@@ -239,6 +224,10 @@ public class VolumeDialogImpl implements VolumeDialog {
|
||||
} else {
|
||||
addExistingRows();
|
||||
}
|
||||
|
||||
mOutputChooser = mDialogView.findViewById(R.id.output_chooser);
|
||||
mOutputChooser.setOnClickListener(mClickOutputChooser);
|
||||
|
||||
updateRowsH(getActiveRow());
|
||||
initRingerH();
|
||||
}
|
||||
@@ -273,11 +262,9 @@ public class VolumeDialogImpl implements VolumeDialog {
|
||||
VolumeRow row = new VolumeRow();
|
||||
initRow(row, stream, iconRes, iconMuteRes, important, defaultStream);
|
||||
int rowSize;
|
||||
int viewSize;
|
||||
if (mShowA11yStream && dynamic && (rowSize = mRows.size()) > 1
|
||||
&& (viewSize = mDialogRowsView.getChildCount()) > 1) {
|
||||
// A11y Stream should be the last in the list
|
||||
mDialogRowsView.addView(row.view, viewSize - 2);
|
||||
if (mShowA11yStream && dynamic && (rowSize = mRows.size()) > 1) {
|
||||
// A11y Stream should be the first in the list, so it's shown to start of other rows
|
||||
mDialogRowsView.addView(row.view, 0);
|
||||
mRows.add(rowSize - 2, row);
|
||||
} else {
|
||||
mDialogRowsView.addView(row.view);
|
||||
@@ -315,7 +302,6 @@ public class VolumeDialogImpl implements VolumeDialog {
|
||||
public void dump(PrintWriter writer) {
|
||||
writer.println(VolumeDialogImpl.class.getSimpleName() + " state:");
|
||||
writer.print(" mShowing: "); writer.println(mShowing);
|
||||
writer.print(" mExpanded: "); writer.println(mExpanded);
|
||||
writer.print(" mActiveStream: "); writer.println(mActiveStream);
|
||||
writer.print(" mDynamic: "); writer.println(mDynamic);
|
||||
writer.print(" mAutomute: "); writer.println(mAutomute);
|
||||
@@ -432,6 +418,13 @@ public class VolumeDialogImpl implements VolumeDialog {
|
||||
}
|
||||
updateRingerH();
|
||||
});
|
||||
mRingerIcon.setOnLongClickListener(v -> {
|
||||
Intent intent = new Intent(Settings.ACTION_SOUND_SETTINGS);
|
||||
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
dismissH(DISMISS_REASON_SETTINGS_CLICKED);
|
||||
mContext.startActivity(intent);
|
||||
return true;
|
||||
});
|
||||
updateRingerH();
|
||||
}
|
||||
|
||||
@@ -468,7 +461,6 @@ public class VolumeDialogImpl implements VolumeDialog {
|
||||
private int computeTimeoutH() {
|
||||
if (mAccessibility.mFeedbackEnabled) return 20000;
|
||||
if (mHovering) return 16000;
|
||||
if (mExpanded) return 5000;
|
||||
if (mSafetyWarning != null) return 5000;
|
||||
return 3000;
|
||||
}
|
||||
@@ -480,13 +472,11 @@ public class VolumeDialogImpl implements VolumeDialog {
|
||||
mDialogView.animate().cancel();
|
||||
mShowing = false;
|
||||
|
||||
updateExpandedH(false /* expanding */, true /* dismissing */);
|
||||
|
||||
mDialogView.setTranslationY(0);
|
||||
mDialogView.setTranslationX(0);
|
||||
mDialogView.setAlpha(1);
|
||||
mDialogView.animate()
|
||||
.alpha(0)
|
||||
.translationY(-mDialogView.getHeight())
|
||||
.translationX(mDialogView.getWidth() / 2)
|
||||
.setDuration(250)
|
||||
.setInterpolator(new SystemUIInterpolators.LogAccelerateInterpolator())
|
||||
.withEndAction(() -> mHandler.postDelayed(() -> {
|
||||
@@ -514,67 +504,6 @@ public class VolumeDialogImpl implements VolumeDialog {
|
||||
}
|
||||
}
|
||||
|
||||
private void updateExpandedH(final boolean expanded, final boolean dismissing) {
|
||||
if (D.BUG) Log.d(TAG, "updateExpandedH " + expanded);
|
||||
|
||||
if (mExpanded == expanded) return;
|
||||
mExpanded = expanded;
|
||||
mExpandButtonAnimationRunning = isAttached();
|
||||
updateExpandButtonH();
|
||||
TransitionManager.endTransitions(mDialogView);
|
||||
final VolumeRow activeRow = getActiveRow();
|
||||
if (!dismissing) {
|
||||
mWindow.setLayout(mWindow.getAttributes().width, ViewGroup.LayoutParams.MATCH_PARENT);
|
||||
TransitionManager.beginDelayedTransition(mDialogView, getTransition());
|
||||
}
|
||||
updateRowsH(activeRow);
|
||||
rescheduleTimeoutH();
|
||||
}
|
||||
|
||||
private AutoTransition getTransition() {
|
||||
AutoTransition transition = new AutoTransition();
|
||||
transition.setDuration(300);
|
||||
transition.setInterpolator(Interpolators.LINEAR_OUT_SLOW_IN);
|
||||
return transition;
|
||||
}
|
||||
|
||||
private void updateExpandButtonH() {
|
||||
if (D.BUG) Log.d(TAG, "updateExpandButtonH");
|
||||
|
||||
mExpandButton.setClickable(!mExpandButtonAnimationRunning);
|
||||
if (!(mExpandButtonAnimationRunning && isAttached())) {
|
||||
final int res = mExpanded ? R.drawable.ic_volume_collapse_animation
|
||||
: R.drawable.ic_volume_expand_animation;
|
||||
if (hasTouchFeature()) {
|
||||
mExpandButton.setImageResource(res);
|
||||
} else {
|
||||
// if there is no touch feature, show the volume ringer instead
|
||||
mExpandButton.setImageResource(R.drawable.ic_volume_ringer);
|
||||
mExpandButton.setBackgroundResource(0); // remove gray background emphasis
|
||||
}
|
||||
mExpandButton.setContentDescription(mContext.getString(mExpanded ?
|
||||
R.string.accessibility_volume_collapse : R.string.accessibility_volume_expand));
|
||||
}
|
||||
if (mExpandButtonAnimationRunning) {
|
||||
final Drawable d = mExpandButton.getDrawable();
|
||||
if (d instanceof AnimatedVectorDrawable) {
|
||||
// workaround to reset drawable
|
||||
final AnimatedVectorDrawable avd = (AnimatedVectorDrawable) d.getConstantState()
|
||||
.newDrawable();
|
||||
mExpandButton.setImageDrawable(avd);
|
||||
avd.start();
|
||||
mHandler.postDelayed(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
mExpandButtonAnimationRunning = false;
|
||||
updateExpandButtonH();
|
||||
rescheduleTimeoutH();
|
||||
}
|
||||
}, 300);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isAttached() {
|
||||
return mDialogView != null && mDialogView.isAttachedToWindow();
|
||||
}
|
||||
@@ -597,7 +526,7 @@ public class VolumeDialogImpl implements VolumeDialog {
|
||||
return true;
|
||||
}
|
||||
|
||||
return row.defaultStream || isActive || (mExpanded && row.important);
|
||||
return row.defaultStream || isActive;
|
||||
}
|
||||
|
||||
private void updateRowsH(final VolumeRow activeRow) {
|
||||
@@ -954,16 +883,6 @@ public class VolumeDialogImpl implements VolumeDialog {
|
||||
}
|
||||
}
|
||||
|
||||
private final OnClickListener mClickExpand = new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
mExpandButton.animate().cancel();
|
||||
final boolean newExpand = !mExpanded;
|
||||
Events.writeEvent(mContext, Events.EVENT_EXPAND, newExpand);
|
||||
updateExpandedH(newExpand, false /* dismissing */);
|
||||
}
|
||||
};
|
||||
|
||||
private final OnClickListener mClickOutputChooser = new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
|
||||
@@ -14,15 +14,37 @@
|
||||
|
||||
package com.android.systemui.volume;
|
||||
|
||||
import static com.android.systemui.util.leak.RotationUtils.ROTATION_LANDSCAPE;
|
||||
import static com.android.systemui.util.leak.RotationUtils.ROTATION_NONE;
|
||||
import static com.android.systemui.util.leak.RotationUtils.ROTATION_SEASCAPE;
|
||||
|
||||
import android.animation.Animator;
|
||||
import android.animation.AnimatorListenerAdapter;
|
||||
import android.animation.AnimatorSet;
|
||||
import android.animation.ObjectAnimator;
|
||||
import android.content.Context;
|
||||
import android.content.res.Configuration;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.Gravity;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.ViewOutlineProvider;
|
||||
import android.view.ViewTreeObserver;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.SeekBar;
|
||||
|
||||
import com.android.systemui.R;
|
||||
import com.android.systemui.util.leak.RotationUtils;
|
||||
|
||||
public class VolumeUiLayout extends FrameLayout {
|
||||
|
||||
private View mChild;
|
||||
private int mOldHeight;
|
||||
private boolean mAnimating;
|
||||
private AnimatorSet mAnimation;
|
||||
private boolean mHasOutsideTouch;
|
||||
private int mRotation = ROTATION_NONE;
|
||||
public VolumeUiLayout(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
}
|
||||
@@ -39,12 +61,246 @@ public class VolumeUiLayout extends FrameLayout {
|
||||
getViewTreeObserver().removeOnComputeInternalInsetsListener(mInsetsListener);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
||||
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
|
||||
if (mChild == null) {
|
||||
if (getChildCount() != 0) {
|
||||
mChild = getChildAt(0);
|
||||
mOldHeight = mChild.getMeasuredHeight();
|
||||
updateRotation();
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
int newHeight = mChild.getMeasuredHeight();
|
||||
if (newHeight != mOldHeight) {
|
||||
animateChild(mOldHeight, newHeight);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onConfigurationChanged(Configuration newConfig) {
|
||||
super.onConfigurationChanged(newConfig);
|
||||
updateRotation();
|
||||
}
|
||||
|
||||
private void updateRotation() {
|
||||
int rotation = RotationUtils.getRotation(getContext());
|
||||
if (rotation != mRotation) {
|
||||
rotate(mRotation, rotation);
|
||||
mRotation = rotation;
|
||||
}
|
||||
}
|
||||
|
||||
private void rotate(View view, int from, int to, boolean swapDimens) {
|
||||
if (from != ROTATION_NONE && to != ROTATION_NONE) {
|
||||
// Rather than handling this confusing case, just do 2 rotations.
|
||||
rotate(view, from, ROTATION_NONE, swapDimens);
|
||||
rotate(view, ROTATION_NONE, to, swapDimens);
|
||||
return;
|
||||
}
|
||||
if (from == ROTATION_LANDSCAPE || to == ROTATION_SEASCAPE) {
|
||||
rotateRight(view);
|
||||
} else {
|
||||
rotateLeft(view);
|
||||
}
|
||||
if (to != ROTATION_NONE) {
|
||||
if (swapDimens && view instanceof LinearLayout) {
|
||||
LinearLayout linearLayout = (LinearLayout) view;
|
||||
linearLayout.setOrientation(LinearLayout.HORIZONTAL);
|
||||
swapDimens(view);
|
||||
}
|
||||
} else {
|
||||
if (swapDimens && view instanceof LinearLayout) {
|
||||
LinearLayout linearLayout = (LinearLayout) view;
|
||||
linearLayout.setOrientation(LinearLayout.VERTICAL);
|
||||
swapDimens(view);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void rotate(int from, int to) {
|
||||
View footer = mChild.findViewById(R.id.footer);
|
||||
rotate(footer, from, to, false);
|
||||
rotate(this, from, to, true);
|
||||
rotate(mChild, from, to, true);
|
||||
ViewGroup rows = mChild.findViewById(R.id.volume_dialog_rows);
|
||||
rotate(rows, from, to, true);
|
||||
int rowCount = rows.getChildCount();
|
||||
for (int i = 0; i < rowCount; i++) {
|
||||
View child = rows.getChildAt(i);
|
||||
if (to == ROTATION_SEASCAPE) {
|
||||
rotateSeekBars(to, 0);
|
||||
} else if (to == ROTATION_LANDSCAPE) {
|
||||
rotateSeekBars(to, 180);
|
||||
} else {
|
||||
rotateSeekBars(to, 270);
|
||||
}
|
||||
rotate(child, from, to, true);
|
||||
}
|
||||
}
|
||||
|
||||
private void swapDimens(View v) {
|
||||
if (v == null) {
|
||||
return;
|
||||
}
|
||||
ViewGroup.LayoutParams params = v.getLayoutParams();
|
||||
int h = params.width;
|
||||
params.width = params.height;
|
||||
params.height = h;
|
||||
v.setLayoutParams(params);
|
||||
}
|
||||
|
||||
private void rotateSeekBars(int to, int rotation) {
|
||||
SeekBar seekbar = mChild.findViewById(R.id.volume_row_slider);
|
||||
if (seekbar != null) {
|
||||
seekbar.setRotation((float) rotation);
|
||||
}
|
||||
|
||||
View parent = mChild.findViewById(R.id.volume_row_slider_frame);
|
||||
swapDimens(parent);
|
||||
ViewGroup.LayoutParams params = seekbar.getLayoutParams();
|
||||
ViewGroup.LayoutParams parentParams = parent.getLayoutParams();
|
||||
if (to != ROTATION_NONE) {
|
||||
params.height = parentParams.height;
|
||||
params.width = parentParams.width;
|
||||
} else {
|
||||
params.height = parentParams.width;
|
||||
params.width = parentParams.height;
|
||||
}
|
||||
seekbar.setLayoutParams(params);
|
||||
}
|
||||
|
||||
private int rotateGravityRight(int gravity) {
|
||||
int retGravity = 0;
|
||||
int layoutDirection = getLayoutDirection();
|
||||
final int absoluteGravity = Gravity.getAbsoluteGravity(gravity, layoutDirection);
|
||||
final int verticalGravity = gravity & Gravity.VERTICAL_GRAVITY_MASK;
|
||||
|
||||
switch (absoluteGravity & Gravity.HORIZONTAL_GRAVITY_MASK) {
|
||||
case Gravity.CENTER_HORIZONTAL:
|
||||
retGravity |= Gravity.CENTER_VERTICAL;
|
||||
break;
|
||||
case Gravity.RIGHT:
|
||||
retGravity |= Gravity.BOTTOM;
|
||||
break;
|
||||
case Gravity.LEFT:
|
||||
default:
|
||||
retGravity |= Gravity.TOP;
|
||||
break;
|
||||
}
|
||||
|
||||
switch (verticalGravity) {
|
||||
case Gravity.CENTER_VERTICAL:
|
||||
retGravity |= Gravity.CENTER_HORIZONTAL;
|
||||
break;
|
||||
case Gravity.BOTTOM:
|
||||
retGravity |= Gravity.LEFT;
|
||||
break;
|
||||
case Gravity.TOP:
|
||||
default:
|
||||
retGravity |= Gravity.RIGHT;
|
||||
break;
|
||||
}
|
||||
return retGravity;
|
||||
}
|
||||
|
||||
private int rotateGravityLeft(int gravity) {
|
||||
if (gravity == -1) {
|
||||
gravity = Gravity.TOP | Gravity.START;
|
||||
}
|
||||
int retGravity = 0;
|
||||
int layoutDirection = getLayoutDirection();
|
||||
final int absoluteGravity = Gravity.getAbsoluteGravity(gravity, layoutDirection);
|
||||
final int verticalGravity = gravity & Gravity.VERTICAL_GRAVITY_MASK;
|
||||
|
||||
switch (absoluteGravity & Gravity.HORIZONTAL_GRAVITY_MASK) {
|
||||
case Gravity.CENTER_HORIZONTAL:
|
||||
retGravity |= Gravity.CENTER_VERTICAL;
|
||||
break;
|
||||
case Gravity.RIGHT:
|
||||
retGravity |= Gravity.TOP;
|
||||
break;
|
||||
case Gravity.LEFT:
|
||||
default:
|
||||
retGravity |= Gravity.BOTTOM;
|
||||
break;
|
||||
}
|
||||
|
||||
switch (verticalGravity) {
|
||||
case Gravity.CENTER_VERTICAL:
|
||||
retGravity |= Gravity.CENTER_HORIZONTAL;
|
||||
break;
|
||||
case Gravity.BOTTOM:
|
||||
retGravity |= Gravity.RIGHT;
|
||||
break;
|
||||
case Gravity.TOP:
|
||||
default:
|
||||
retGravity |= Gravity.LEFT;
|
||||
break;
|
||||
}
|
||||
return retGravity;
|
||||
}
|
||||
|
||||
private void rotateLeft(View v) {
|
||||
if (v.getParent() instanceof FrameLayout) {
|
||||
LayoutParams p = (LayoutParams) v.getLayoutParams();
|
||||
p.gravity = rotateGravityLeft(p.gravity);
|
||||
}
|
||||
|
||||
v.setPadding(v.getPaddingTop(), v.getPaddingRight(), v.getPaddingBottom(),
|
||||
v.getPaddingLeft());
|
||||
MarginLayoutParams params = (MarginLayoutParams) v.getLayoutParams();
|
||||
params.setMargins(params.topMargin, params.rightMargin, params.bottomMargin,
|
||||
params.leftMargin);
|
||||
v.setLayoutParams(params);
|
||||
}
|
||||
|
||||
private void rotateRight(View v) {
|
||||
if (v.getParent() instanceof FrameLayout) {
|
||||
LayoutParams p = (LayoutParams) v.getLayoutParams();
|
||||
p.gravity = rotateGravityRight(p.gravity);
|
||||
}
|
||||
|
||||
v.setPadding(v.getPaddingBottom(), v.getPaddingLeft(), v.getPaddingTop(),
|
||||
v.getPaddingRight());
|
||||
MarginLayoutParams params = (MarginLayoutParams) v.getLayoutParams();
|
||||
params.setMargins(params.bottomMargin, params.leftMargin, params.topMargin,
|
||||
params.rightMargin);
|
||||
v.setLayoutParams(params);
|
||||
}
|
||||
|
||||
private void animateChild(int oldHeight, int newHeight) {
|
||||
if (true) return;
|
||||
if (mAnimating) {
|
||||
mAnimation.cancel();
|
||||
}
|
||||
mAnimating = true;
|
||||
mAnimation = new AnimatorSet();
|
||||
mAnimation.addListener(new AnimatorListenerAdapter() {
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animation) {
|
||||
mAnimating = false;
|
||||
}
|
||||
});
|
||||
int fromTop = mChild.getTop();
|
||||
int fromBottom = mChild.getBottom();
|
||||
int toTop = fromTop - ((newHeight - oldHeight) / 2);
|
||||
int toBottom = fromBottom + ((newHeight - oldHeight) / 2);
|
||||
ObjectAnimator top = ObjectAnimator.ofInt(mChild, "top", fromTop, toTop);
|
||||
mAnimation.playTogether(top,
|
||||
ObjectAnimator.ofInt(mChild, "bottom", fromBottom, toBottom));
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public ViewOutlineProvider getOutlineProvider() {
|
||||
return super.getOutlineProvider();
|
||||
}
|
||||
|
||||
public void setOutsideTouchListener(OnClickListener onClickListener) {
|
||||
mHasOutsideTouch = true;
|
||||
requestLayout();
|
||||
setOnClickListener(onClickListener);
|
||||
setClickable(true);
|
||||
@@ -60,7 +316,14 @@ public class VolumeUiLayout extends FrameLayout {
|
||||
}
|
||||
|
||||
private final ViewTreeObserver.OnComputeInternalInsetsListener mInsetsListener = inoutInfo -> {
|
||||
if (mHasOutsideTouch || (mChild == null)) {
|
||||
inoutInfo.setTouchableInsets(
|
||||
ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_FRAME);
|
||||
return;
|
||||
}
|
||||
inoutInfo.setTouchableInsets(
|
||||
ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_FRAME);
|
||||
ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_CONTENT);
|
||||
inoutInfo.contentInsets.set(mChild.getLeft(), mChild.getTop(),
|
||||
0, getBottom() - mChild.getBottom());
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user