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

Commit 67519b22 authored by Hugo Hudson's avatar Hugo Hudson
Browse files

Fade transitions between messages for voicemails.

- Change playback layout to have two superimposed text views, both
  visible, one transparent and the other opaque.
- When swapping between permanent and temporary text, fade out one view
  and fade in the other.
- Also uses the constrain() method from MathUtils and get rid of my
  clamp() method.

Bug: 5113788
Change-Id: Ia72a3f2a85fd9ac32303e7cf18744a12ba46f75f
parent c24f1714
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -77,6 +77,16 @@
                android:layout_centerHorizontal="true"
                android:layout_marginTop="10dip"
            />
            <TextView
                android:id="@+id/playback_speed_text"
                android:layout_height="wrap_content"
                android:layout_width="wrap_content"
                android:textSize="14sp"
                android:layout_alignParentTop="true"
                android:layout_centerHorizontal="true"
                android:layout_marginTop="10dip"
                android:alpha="0"
            />
            <ImageButton
                android:id="@+id/rate_decrease_button"
                android:src="@drawable/ic_minus_holo_dark"
+24 −21
Original line number Diff line number Diff line
@@ -66,7 +66,6 @@ public class VoicemailPlaybackFragment extends Fragment {
    private SeekBar mPlaybackSeek;
    private ImageButton mStartStopButton;
    private ImageButton mPlaybackSpeakerphone;
    private TextView mPlaybackPositionText;
    private ImageButton mRateDecreaseButton;
    private ImageButton mRateIncreaseButton;
    private TextViewWithMessagesController mTextController;
@@ -79,10 +78,11 @@ public class VoicemailPlaybackFragment extends Fragment {
        mPlaybackSeek = (SeekBar) view.findViewById(R.id.playback_seek);
        mStartStopButton = (ImageButton) view.findViewById(R.id.playback_start_stop);
        mPlaybackSpeakerphone = (ImageButton) view.findViewById(R.id.playback_speakerphone);
        mPlaybackPositionText = (TextView) view.findViewById(R.id.playback_position_text);
        mRateDecreaseButton = (ImageButton) view.findViewById(R.id.rate_decrease_button);
        mRateIncreaseButton = (ImageButton) view.findViewById(R.id.rate_increase_button);
        mTextController = new TextViewWithMessagesController(mPlaybackPositionText);
        mTextController = new TextViewWithMessagesController(
                (TextView) view.findViewById(R.id.playback_position_text),
                (TextView) view.findViewById(R.id.playback_speed_text));
        return view;
    }

@@ -259,30 +259,30 @@ public class VoicemailPlaybackFragment extends Fragment {
     * All the methods on this class must be called from the ui thread.
     */
    private static final class TextViewWithMessagesController {
        private static final float VISIBLE = 1;
        private static final float INVISIBLE = 0;
        private static final long SHORT_ANIMATION_MS = 200;
        private static final long LONG_ANIMATION_MS = 400;
        private final Object mLock = new Object();
        private final TextView mTextView;
        @GuardedBy("mLock") String mCurrentText = "";
        @GuardedBy("mLock") Runnable mRunnable;
        private final TextView mPermanentTextView;
        private final TextView mTemporaryTextView;
        @GuardedBy("mLock") private Runnable mRunnable;

        public TextViewWithMessagesController(TextView textView) {
            mTextView = textView;
        public TextViewWithMessagesController(TextView permanentTextView,
                TextView temporaryTextView) {
            mPermanentTextView = permanentTextView;
            mTemporaryTextView = temporaryTextView;
        }

        public void setPermanentText(String text) {
            synchronized (mLock) {
                mCurrentText = text;
                // If there's currently a Runnable pending, then we don't alter the display
                // text. The Runnable will use the most recent version of mCurrentText
                // when it completes.
                if (mRunnable == null) {
                    mTextView.setText(text);
                }
            }
            mPermanentTextView.setText(text);
        }

        public void setTemporaryText(String text, long duration, TimeUnit units) {
            synchronized (mLock) {
                mTextView.setText(text);
                mTemporaryTextView.setText(text);
                mTemporaryTextView.animate().alpha(VISIBLE).setDuration(SHORT_ANIMATION_MS);
                mPermanentTextView.animate().alpha(INVISIBLE).setDuration(SHORT_ANIMATION_MS);
                mRunnable = new Runnable() {
                    @Override
                    public void run() {
@@ -292,12 +292,15 @@ public class VoicemailPlaybackFragment extends Fragment {
                            // one is now defunct and needs to take no action.
                            if (mRunnable == this) {
                                mRunnable = null;
                                mTextView.setText(mCurrentText);
                                mTemporaryTextView.animate()
                                        .alpha(INVISIBLE).setDuration(LONG_ANIMATION_MS);
                                mPermanentTextView.animate()
                                        .alpha(VISIBLE).setDuration(LONG_ANIMATION_MS);
                            }
                        }
                    }
                };
                mTextView.postDelayed(mRunnable, units.toMillis(duration));
                mTemporaryTextView.postDelayed(mRunnable, units.toMillis(duration));
            }
        }
    }
+4 −7
Original line number Diff line number Diff line
@@ -16,6 +16,8 @@

package com.android.contacts.voicemail;

import static android.util.MathUtils.constrain;

import com.android.contacts.R;
import com.android.ex.variablespeed.MediaPlayerProxy;
import com.android.ex.variablespeed.SingleThreadedMediaPlayerProxy;
@@ -211,7 +213,7 @@ import javax.annotation.concurrent.ThreadSafe;
        @Override
        public void onClick(View v) {
            // Adjust the current rate, then clamp it to the allowed values.
            mRateIndex = clamp(mRateIndex + (mIncrease ? 1 : -1), 0, PRESET_RATES.length - 1);
            mRateIndex = constrain(mRateIndex + (mIncrease ? 1 : -1), 0, PRESET_RATES.length - 1);
            // Whether or not we have actually changed the index, call changeRate().
            // This will ensure that we show the "fastest" or "slowest" text on the ui to indicate
            // to the user that it doesn't get any faster or slower.
@@ -219,18 +221,13 @@ import javax.annotation.concurrent.ThreadSafe;
        }
    }

    /** Clamp the input value to between min and max inclusive. */
    private static int clamp(int input, int min, int max) {
        return Math.max(Math.min(input, max), min);
    }

    private void resetPrepareStartPlaying(int clipPositionInMillis) {
        try {
            mPlayer.reset();
            mPlayer.setDataSource(mView.getDataSourceContext(), mVoicemailUri);
            mPlayer.prepare();
            mDuration.set(mPlayer.getDuration());
            int startPosition = clamp(clipPositionInMillis, 0, mDuration.get());
            int startPosition = constrain(clipPositionInMillis, 0, mDuration.get());
            mView.setClipPosition(startPosition, mDuration.get());
            mPlayer.seekTo(startPosition);
            mPlayer.start();