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

Commit 8b4929db authored by Steve Elliott's avatar Steve Elliott
Browse files

Add importance ring animation on convo priority change

Bug: 157480039
Test: manual
Change-Id: I0c3b2a857c871fc344705f98aa8463e7de0c4b6b
parent 06174db5
Loading
Loading
Loading
Loading
+74 −5
Original line number Diff line number Diff line
@@ -21,6 +21,10 @@ import static com.android.internal.widget.MessagingGroup.IMAGE_DISPLAY_LOCATION_
import static com.android.internal.widget.MessagingPropertyAnimator.ALPHA_IN;
import static com.android.internal.widget.MessagingPropertyAnimator.ALPHA_OUT;

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ValueAnimator;
import android.annotation.AttrRes;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -36,6 +40,7 @@ import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.Typeface;
import android.graphics.drawable.GradientDrawable;
import android.graphics.drawable.Icon;
import android.os.Bundle;
import android.os.Parcelable;
@@ -93,8 +98,12 @@ public class ConversationLayout extends FrameLayout
    public static final Interpolator LINEAR_OUT_SLOW_IN = new PathInterpolator(0f, 0f, 0.2f, 1f);
    public static final Interpolator FAST_OUT_LINEAR_IN = new PathInterpolator(0.4f, 0f, 1f, 1f);
    public static final Interpolator FAST_OUT_SLOW_IN = new PathInterpolator(0.4f, 0f, 0.2f, 1f);
    public static final Interpolator OVERSHOOT = new PathInterpolator(0.4f, 0f, 0.2f, 1.4f);
    public static final OnLayoutChangeListener MESSAGING_PROPERTY_ANIMATOR
            = new MessagingPropertyAnimator();
    public static final int IMPORTANCE_ANIM_GROW_DURATION = 250;
    public static final int IMPORTANCE_ANIM_SHRINK_DURATION = 200;
    public static final int IMPORTANCE_ANIM_SHRINK_DELAY = 25;
    private List<MessagingMessage> mMessages = new ArrayList<>();
    private List<MessagingMessage> mHistoricMessages = new ArrayList<>();
    private MessagingLinearLayout mMessagingLinearLayout;
@@ -331,14 +340,74 @@ public class ConversationLayout extends FrameLayout
        mNameReplacement = nameReplacement;
    }

    /**
     * Sets this conversation as "important", adding some additional UI treatment.
     */
    /** Sets this conversation as "important", adding some additional UI treatment. */
    @RemotableViewMethod
    public void setIsImportantConversation(boolean isImportantConversation) {
        setIsImportantConversation(isImportantConversation, false);
    }

    /** @hide **/
    public void setIsImportantConversation(boolean isImportantConversation, boolean animate) {
        mImportantConversation = isImportantConversation;
        mImportanceRingView.setVisibility(isImportantConversation
                && mIcon.getVisibility() != GONE ? VISIBLE : GONE);
        mImportanceRingView.setVisibility(isImportantConversation && mIcon.getVisibility() != GONE
                ? VISIBLE : GONE);

        if (animate && isImportantConversation) {
            GradientDrawable ring = (GradientDrawable) mImportanceRingView.getDrawable();
            ring.mutate();
            GradientDrawable bg = (GradientDrawable) mConversationIconBadgeBg.getDrawable();
            bg.mutate();
            int ringColor = getResources()
                    .getColor(R.color.conversation_important_highlight);
            int standardThickness = getResources()
                    .getDimensionPixelSize(R.dimen.importance_ring_stroke_width);
            int largeThickness = getResources()
                    .getDimensionPixelSize(R.dimen.importance_ring_anim_max_stroke_width);
            int standardSize = getResources().getDimensionPixelSize(
                    R.dimen.importance_ring_size);
            int baseSize = standardSize - standardThickness * 2;
            int bgSize = getResources()
                    .getDimensionPixelSize(R.dimen.conversation_icon_size_badged);

            ValueAnimator.AnimatorUpdateListener animatorUpdateListener = animation -> {
                int strokeWidth = Math.round((float) animation.getAnimatedValue());
                ring.setStroke(strokeWidth, ringColor);
                int newSize = baseSize + strokeWidth * 2;
                ring.setSize(newSize, newSize);
                mImportanceRingView.invalidate();
            };

            ValueAnimator growAnimation = ValueAnimator.ofFloat(0, largeThickness);
            growAnimation.setInterpolator(LINEAR_OUT_SLOW_IN);
            growAnimation.setDuration(IMPORTANCE_ANIM_GROW_DURATION);
            growAnimation.addUpdateListener(animatorUpdateListener);

            ValueAnimator shrinkAnimation =
                    ValueAnimator.ofFloat(largeThickness, standardThickness);
            shrinkAnimation.setDuration(IMPORTANCE_ANIM_SHRINK_DURATION);
            shrinkAnimation.setStartDelay(IMPORTANCE_ANIM_SHRINK_DELAY);
            shrinkAnimation.setInterpolator(OVERSHOOT);
            shrinkAnimation.addUpdateListener(animatorUpdateListener);
            shrinkAnimation.addListener(new AnimatorListenerAdapter() {
                @Override
                public void onAnimationStart(Animator animation) {
                    // Shrink the badge bg so that it doesn't peek behind the animation
                    bg.setSize(baseSize, baseSize);
                    mConversationIconBadgeBg.invalidate();
                }

                @Override
                public void onAnimationEnd(Animator animation) {
                    // Reset bg back to normal size
                    bg.setSize(bgSize, bgSize);
                    mConversationIconBadgeBg.invalidate();
                }
            });

            AnimatorSet anims = new AnimatorSet();
            anims.playSequentially(growAnimation, shrinkAnimation);
            anims.start();
        }
    }

    public boolean isImportantConversation() {
+2 −2
Original line number Diff line number Diff line
@@ -22,7 +22,7 @@
        android:color="#ffffff"/>

    <size
        android:width="26dp"
        android:height="26dp"/>
        android:width="20dp"
        android:height="20dp"/>
</shape>
+8 −7
Original line number Diff line number Diff line
@@ -16,17 +16,18 @@
  -->

<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="oval">

    <solid
        android:color="@color/transparent"/>
    android:shape="oval"
>
    <solid android:color="@color/transparent" />

    <stroke
        android:color="@color/conversation_important_highlight"
        android:width="2dp"/>
        android:width="@dimen/importance_ring_stroke_width"
    />

    <size
        android:width="26dp"
        android:height="26dp"/>
        android:width="@dimen/importance_ring_size"
        android:height="@dimen/importance_ring_size"
    />
</shape>
+11 −2
Original line number Diff line number Diff line
@@ -38,6 +38,8 @@
        <FrameLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:clipChildren="false"
            android:clipToPadding="false"
            android:layout_gravity="top|center_horizontal"
        >

@@ -63,13 +65,17 @@
                android:layout_height="@dimen/conversation_icon_size_badged"
                android:layout_marginLeft="@dimen/conversation_badge_side_margin"
                android:layout_marginTop="@dimen/conversation_badge_side_margin"
                android:clipChildren="false"
                android:clipToPadding="false"
            >
                <com.android.internal.widget.CachingIconView
                    android:id="@+id/conversation_icon_badge_bg"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:layout_gravity="center"
                    android:src="@drawable/conversation_badge_background"
                    android:forceHasOverlappingRendering="false"
                    android:scaleType="center"
                />
                <com.android.internal.widget.CachingIconView
                    android:id="@+id/icon"
@@ -81,11 +87,14 @@
                />
                <com.android.internal.widget.CachingIconView
                    android:id="@+id/conversation_icon_badge_ring"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_gravity="center"
                    android:src="@drawable/conversation_badge_ring"
                    android:visibility="gone"
                    android:forceHasOverlappingRendering="false"
                    android:clipToPadding="false"
                    android:scaleType="center"
                />
            </FrameLayout>
        </FrameLayout>
+6 −0
Original line number Diff line number Diff line
@@ -720,6 +720,12 @@
    <dimen name="conversation_face_pile_protection_width_expanded">1dp</dimen>
    <!-- The padding of the expanded message container-->
    <dimen name="expanded_group_conversation_message_padding">14dp</dimen>
    <!-- The stroke width of the ring used to visually mark a conversation as important -->
    <dimen name="importance_ring_stroke_width">2dp</dimen>
    <!-- The maximum stroke width used for the animation shown when a conversation is marked as important -->
    <dimen name="importance_ring_anim_max_stroke_width">10dp</dimen>
    <!-- The size of the importance ring -->
    <dimen name="importance_ring_size">20dp</dimen>

    <!-- The top padding of the conversation icon container in the regular state-->
    <dimen name="conversation_icon_container_top_padding">9dp</dimen>
Loading