diff options
author | timhypeng <timhypeng@google.com> | 2020-12-08 06:30:18 +0000 |
---|---|---|
committer | Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com> | 2020-12-08 06:30:18 +0000 |
commit | 66fed6fcc9b5f15267ff78c834d94eee005bd836 (patch) | |
tree | b8ed81e357722d5da542ce1b044e72e88c8dfc70 /packages/SystemUI/src | |
parent | 2921cfe397295a1030935be11ab39daee6d4184d (diff) | |
parent | 411e7a5b7c0efe331002ff6c3d05c9cbd3cb2c39 (diff) |
Add animation when switching output device am: 411e7a5b7c
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/13109610
MUST ONLY BE SUBMITTED BY AUTOMERGER
Change-Id: I700cb5a98db53b4028c3c5a930dfdc1f1298a399
Diffstat (limited to 'packages/SystemUI/src')
3 files changed, 97 insertions, 24 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputAdapter.java b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputAdapter.java index 9b6a9ea80ebe..d1630ebe8dc8 100644 --- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputAdapter.java +++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputAdapter.java @@ -44,6 +44,8 @@ public class MediaOutputAdapter extends MediaOutputBaseAdapter { private static final String TAG = "MediaOutputAdapter"; private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); + private ViewGroup mConnectedItem; + public MediaOutputAdapter(MediaOutputController controller) { super(controller); } @@ -79,18 +81,6 @@ public class MediaOutputAdapter extends MediaOutputBaseAdapter { return mController.getMediaDevices().size(); } - void onItemClick(MediaDevice device) { - mController.connectDevice(device); - device.setState(MediaDeviceState.STATE_CONNECTING); - notifyDataSetChanged(); - } - - void onItemClick(int customizedItem) { - if (customizedItem == CUSTOMIZED_ITEM_PAIR_NEW) { - mController.launchBluetoothPairing(); - } - } - @Override CharSequence getItemTitle(MediaDevice device) { if (device.getDeviceType() == MediaDevice.MediaDeviceType.TYPE_BLUETOOTH_DEVICE @@ -117,6 +107,10 @@ public class MediaOutputAdapter extends MediaOutputBaseAdapter { @Override void onBind(MediaDevice device, boolean topMargin, boolean bottomMargin) { super.onBind(device, topMargin, bottomMargin); + final boolean currentlyConnected = isCurrentlyConnected(device); + if (currentlyConnected) { + mConnectedItem = mFrameLayout; + } if (mController.isTransferring()) { if (device.getState() == MediaDeviceState.STATE_CONNECTING && !mController.hasAdjustVolumeUserRestriction()) { @@ -133,16 +127,16 @@ public class MediaOutputAdapter extends MediaOutputBaseAdapter { false /* showSeekBar*/, false /* showProgressBar */, true /* showSubtitle */); mSubTitleText.setText(R.string.media_output_dialog_connect_failed); - mFrameLayout.setOnClickListener(v -> onItemClick(device)); + mFrameLayout.setOnClickListener(v -> onItemClick(v, device)); } else if (!mController.hasAdjustVolumeUserRestriction() - && isCurrentConnected(device)) { + && currentlyConnected) { setTwoLineLayout(device, null /* title */, true /* bFocused */, true /* showSeekBar*/, false /* showProgressBar */, false /* showSubtitle */); initSeekbar(device); } else { setSingleLineLayout(getItemTitle(device), false /* bFocused */); - mFrameLayout.setOnClickListener(v -> onItemClick(device)); + mFrameLayout.setOnClickListener(v -> onItemClick(v, device)); } } } @@ -160,5 +154,24 @@ public class MediaOutputAdapter extends MediaOutputBaseAdapter { mFrameLayout.setOnClickListener(v -> onItemClick(CUSTOMIZED_ITEM_PAIR_NEW)); } } + + private void onItemClick(View view, MediaDevice device) { + if (mController.isTransferring()) { + return; + } + + playSwitchingAnim(mConnectedItem, view); + mController.connectDevice(device); + device.setState(MediaDeviceState.STATE_CONNECTING); + if (!isAnimating()) { + notifyDataSetChanged(); + } + } + + private void onItemClick(int customizedItem) { + if (customizedItem == CUSTOMIZED_ITEM_PAIR_NEW) { + mController.launchBluetoothPairing(); + } + } } } diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseAdapter.java b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseAdapter.java index 01dc6c4b71da..2d3e77db1ea3 100644 --- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseAdapter.java +++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseAdapter.java @@ -16,6 +16,8 @@ package com.android.systemui.media.dialog; +import android.animation.Animator; +import android.animation.AnimatorListenerAdapter; import android.content.Context; import android.graphics.Typeface; import android.text.TextUtils; @@ -33,6 +35,7 @@ import androidx.annotation.NonNull; import androidx.recyclerview.widget.RecyclerView; import com.android.settingslib.media.MediaDevice; +import com.android.systemui.Interpolators; import com.android.systemui.R; /** @@ -50,6 +53,7 @@ public abstract class MediaOutputBaseAdapter extends private boolean mIsDragging; private int mMargin; + private boolean mIsAnimating; Context mContext; View mHolderView; @@ -75,7 +79,7 @@ public abstract class MediaOutputBaseAdapter extends return device.getName(); } - boolean isCurrentConnected(MediaDevice device) { + boolean isCurrentlyConnected(MediaDevice device) { return TextUtils.equals(device.getId(), mController.getCurrentConnectedMediaDevice().getId()); } @@ -84,10 +88,17 @@ public abstract class MediaOutputBaseAdapter extends return mIsDragging; } + boolean isAnimating() { + return mIsAnimating; + } + /** * ViewHolder for binding device view. */ abstract class MediaDeviceBaseViewHolder extends RecyclerView.ViewHolder { + + private static final int ANIM_DURATION = 200; + final FrameLayout mFrameLayout; final TextView mTitleText; final TextView mTwoLineTitleText; @@ -123,17 +134,16 @@ public abstract class MediaOutputBaseAdapter extends private void setMargin(boolean topMargin, boolean bottomMargin) { ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) mFrameLayout .getLayoutParams(); - if (topMargin) { - params.topMargin = mMargin; - } - if (bottomMargin) { - params.bottomMargin = mMargin; - } + params.topMargin = topMargin ? mMargin : 0; + params.bottomMargin = bottomMargin ? mMargin : 0; mFrameLayout.setLayoutParams(params); } + void setSingleLineLayout(CharSequence title, boolean bFocused) { - mTitleText.setVisibility(View.VISIBLE); mTwoLineLayout.setVisibility(View.GONE); + mProgressBar.setVisibility(View.GONE); + mTitleText.setVisibility(View.VISIBLE); + mTitleText.setTranslationY(0); mTitleText.setText(title); if (bFocused) { mTitleText.setTypeface(Typeface.create(FONT_SELECTED_TITLE, Typeface.NORMAL)); @@ -146,9 +156,11 @@ public abstract class MediaOutputBaseAdapter extends boolean showSeekBar, boolean showProgressBar, boolean showSubtitle) { mTitleText.setVisibility(View.GONE); mTwoLineLayout.setVisibility(View.VISIBLE); + mSeekBar.setAlpha(1); mSeekBar.setVisibility(showSeekBar ? View.VISIBLE : View.GONE); mProgressBar.setVisibility(showProgressBar ? View.VISIBLE : View.GONE); mSubTitleText.setVisibility(showSubtitle ? View.VISIBLE : View.GONE); + mTwoLineTitleText.setTranslationY(0); if (device == null) { mTwoLineTitleText.setText(title); } else { @@ -189,5 +201,53 @@ public abstract class MediaOutputBaseAdapter extends } }); } + + void playSwitchingAnim(@NonNull View from, @NonNull View to) { + final float delta = (float) (mContext.getResources().getDimensionPixelSize( + R.dimen.media_output_dialog_title_anim_y_delta)); + final SeekBar fromSeekBar = from.requireViewById(R.id.volume_seekbar); + final TextView toTitleText = to.requireViewById(R.id.title); + if (fromSeekBar.getVisibility() != View.VISIBLE || toTitleText.getVisibility() + != View.VISIBLE) { + return; + } + mIsAnimating = true; + // Animation for title text + toTitleText.setTypeface(Typeface.create(FONT_SELECTED_TITLE, Typeface.NORMAL)); + toTitleText.animate() + .setDuration(ANIM_DURATION) + .translationY(-delta) + .setInterpolator(Interpolators.FAST_OUT_SLOW_IN) + .setListener(new AnimatorListenerAdapter() { + @Override + public void onAnimationEnd(Animator animation) { + to.requireViewById(R.id.volume_indeterminate_progress).setVisibility( + View.VISIBLE); + } + }); + // Animation for seek bar + fromSeekBar.animate() + .alpha(0) + .setDuration(ANIM_DURATION) + .setListener(new AnimatorListenerAdapter() { + @Override + public void onAnimationEnd(Animator animation) { + final TextView fromTitleText = from.requireViewById( + R.id.two_line_title); + fromTitleText.setTypeface(Typeface.create(FONT_TITLE, Typeface.NORMAL)); + fromTitleText.animate() + .setDuration(ANIM_DURATION) + .translationY(delta) + .setInterpolator(Interpolators.FAST_OUT_SLOW_IN) + .setListener(new AnimatorListenerAdapter() { + @Override + public void onAnimationEnd(Animator animation) { + mIsAnimating = false; + notifyDataSetChanged(); + } + }); + } + }); + } } } diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseDialog.java b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseDialog.java index a589b07b61fc..e3e399b2aee2 100644 --- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseDialog.java +++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseDialog.java @@ -170,7 +170,7 @@ public abstract class MediaOutputBaseDialog extends SystemUIDialog implements mHeaderSubtitle.setText(subTitle); mHeaderTitle.setGravity(Gravity.NO_GRAVITY); } - if (!mAdapter.isDragging()) { + if (!mAdapter.isDragging() && !mAdapter.isAnimating()) { mAdapter.notifyDataSetChanged(); } // Show when remote media session is available |