Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a7776955 authored by timhypeng's avatar timhypeng
Browse files

Add animation when switching output device

Bug: 155822415
Test: manual test
Change-Id: Ia3370222427b77099d987d59d5d5fd08c11557d7
parent b0424a35
Loading
Loading
Loading
Loading
+11 −12
Original line number Diff line number Diff line
@@ -75,18 +75,6 @@
            android:textSize="12sp"
            android:fontFamily="roboto-regular"
            android:visibility="gone"/>
        <ProgressBar
            android:id="@+id/volume_indeterminate_progress"
            style="@*android:style/Widget.Material.ProgressBar.Horizontal"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginStart="16dp"
            android:layout_marginEnd="15dp"
            android:layout_marginBottom="1dp"
            android:layout_alignParentBottom="true"
            android:indeterminate="true"
            android:indeterminateOnly="true"
            android:visibility="gone"/>
        <SeekBar
            android:id="@+id/volume_seekbar"
            android:layout_width="match_parent"
@@ -94,6 +82,17 @@
            android:layout_alignParentBottom="true"/>
    </RelativeLayout>

    <ProgressBar
        android:id="@+id/volume_indeterminate_progress"
        style="@*android:style/Widget.Material.ProgressBar.Horizontal"
        android:layout_width="258dp"
        android:layout_height="18dp"
        android:layout_marginStart="68dp"
        android:layout_marginTop="40dp"
        android:indeterminate="true"
        android:indeterminateOnly="true"
        android:visibility="gone"/>

    <View
        android:layout_width="1dp"
        android:layout_height="36dp"
+1 −0
Original line number Diff line number Diff line
@@ -1380,4 +1380,5 @@
    <dimen name="media_output_dialog_header_back_icon_size">36dp</dimen>
    <dimen name="media_output_dialog_header_icon_padding">16dp</dimen>
    <dimen name="media_output_dialog_icon_corner_radius">16dp</dimen>
    <dimen name="media_output_dialog_title_anim_y_delta">12.5dp</dimen>
</resources>
+28 −15
Original line number Diff line number Diff line
@@ -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();
            }
        }
    }
}
+68 −8
Original line number Diff line number Diff line
@@ -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();
                                        }
                                    });
                        }
                    });
        }
    }
}
+1 −1
Original line number Diff line number Diff line
@@ -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
Loading