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

Commit d245565a authored by Silin Huang's avatar Silin Huang Committed by Android (Google) Code Review
Browse files

Merge "Wallet view UI tweaks." into sc-dev

parents ee8da6bd b30ccb3d
Loading
Loading
Loading
Loading
+2 −9
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_marginHorizontal="@dimen/card_margin"
        android:layout_marginBottom="@dimen/card_margin"
        android:foreground="?android:attr/selectableItemBackground"
        app:cardBackgroundColor="@android:color/transparent"
        app:cardElevation="12dp">
@@ -32,16 +33,8 @@
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:adjustViewBounds="true"
            android:contentDescription="@null"
            android:scaleType="fitXY"/>
        <ImageView
            android:id="@+id/add_card_logo"
            android:layout_width="28dp"
            android:layout_height="28dp"
            android:layout_gravity="center"
            android:drawable="@drawable/ic_qs_plus"
            android:contentDescription="@null"
            android:scaleType="fitCenter"
            android:visibility="gone"/>
            android:scaleType="fitXY"/>
    </com.android.systemui.wallet.ui.WalletCardView>
</FrameLayout>
+27 −35
Original line number Diff line number Diff line
@@ -61,7 +61,7 @@ public class WalletCardCarousel extends RecyclerView {
    static final int CARD_ANIM_ALPHA_DELAY = 50;

    private final Rect mSystemGestureExclusionZone = new Rect();
    private WalletCardCarouselAdapter mWalletCardCarouselAdapter;
    private final WalletCardCarouselAdapter mWalletCardCarouselAdapter;
    private int mExpectedViewWidth;
    private int mCardMarginPx;
    private int mCardWidthPx;
@@ -79,12 +79,6 @@ public class WalletCardCarousel extends RecyclerView {
    // also be used in DotIndicatorDecoration.
    float mEdgeToCenterDistance = Float.MAX_VALUE;
    private float mCardCenterToScreenCenterDistancePx = Float.MAX_VALUE;
    // When card data is loaded, this many cards should be animated as data is bound to them.
    private int mNumCardsToAnimate;
    // When card data is loaded, this is the position of the leftmost card to be animated.
    private int mCardAnimationStartPosition;
    // When card data is loaded, the animations may be delayed so that other animations can complete
    private int mExtraAnimationDelay;

    interface OnSelectionListener {
        /**
@@ -179,10 +173,6 @@ public class WalletCardCarousel extends RecyclerView {
        }
    }

    void setExtraAnimationDelay(int extraAnimationDelay) {
        mExtraAnimationDelay = extraAnimationDelay;
    }

    void setSelectionListener(OnSelectionListener selectionListener) {
        mSelectionListener = selectionListener;
    }
@@ -200,19 +190,14 @@ public class WalletCardCarousel extends RecyclerView {
    }

    /**
     * Set card data. Returns true if carousel was empty, indicating that views will be animated
     * Returns true if the data set is changed.
     */
    boolean setData(List<WalletCardViewInfo> data, int selectedIndex) {
        boolean wasEmpty = mWalletCardCarouselAdapter.getItemCount() == 0;
        mWalletCardCarouselAdapter.setData(data);
    boolean setData(List<WalletCardViewInfo> data, int selectedIndex, boolean hasLockStateChanged) {
        boolean hasDataChanged = mWalletCardCarouselAdapter.setData(data, hasLockStateChanged);
        scrollToPosition(selectedIndex);
        if (wasEmpty) {
            mNumCardsToAnimate = numCardsOnScreen(data.size(), selectedIndex);
            mCardAnimationStartPosition = Math.max(selectedIndex - 1, 0);
        }
        WalletCardViewInfo selectedCard = data.get(selectedIndex);
        mCardScrollListener.onCardScroll(selectedCard, selectedCard, 0);
        return wasEmpty;
        return hasDataChanged;
    }

    @Override
@@ -221,19 +206,6 @@ public class WalletCardCarousel extends RecyclerView {
        mSelectionListener.onCardSelected(mWalletCardCarouselAdapter.mData.get(position));
    }

    /**
     * The number of cards shown on screen when one of the cards is position in the center. This is
     * also the num
     */
    private static int numCardsOnScreen(int numCards, int selectedIndex) {
        if (numCards <= 2) {
            return numCards;
        }
        // When there are 3 or more cards, 3 cards will be shown unless the first or last card is
        // centered on screen.
        return selectedIndex > 0 && selectedIndex < (numCards - 1) ? 3 : 2;
    }

    /**
     * The padding pushes the first and last cards in the list to the center when they are
     * selected.
@@ -439,9 +411,29 @@ public class WalletCardCarousel extends RecyclerView {
            return mData.get(position).getCardId().hashCode();
        }

        void setData(List<WalletCardViewInfo> data) {
        private boolean setData(List<WalletCardViewInfo> data, boolean hasLockedStateChanged) {
            List<WalletCardViewInfo> oldData = mData;
            mData = data;
            if (hasLockedStateChanged || !isUiEquivalent(oldData, data)) {
                notifyDataSetChanged();
                return true;
            }
            return false;
        }

        private boolean isUiEquivalent(
                List<WalletCardViewInfo> oldData, List<WalletCardViewInfo> newData) {
            if (oldData.size() != newData.size()) {
                return false;
            }
            for (int i = 0; i < newData.size(); i++) {
                WalletCardViewInfo oldItem = oldData.get(i);
                WalletCardViewInfo newItem = newData.get(i);
                if (!oldItem.isUiEquivalent(newItem)) {
                    return false;
                }
            }
            return true;
        }
    }

+7 −0
Original line number Diff line number Diff line
@@ -54,4 +54,11 @@ interface WalletCardViewInfo {
     */
    @NonNull
    PendingIntent getPendingIntent();

    default boolean isUiEquivalent(WalletCardViewInfo other) {
        if (other == null) {
            return false;
        }
        return getCardId().equals(other.getCardId());
    }
}
+15 −37
Original line number Diff line number Diff line
@@ -19,8 +19,6 @@ package com.android.systemui.wallet.ui;
import static com.android.systemui.wallet.ui.WalletCardCarousel.CARD_ANIM_ALPHA_DELAY;
import static com.android.systemui.wallet.ui.WalletCardCarousel.CARD_ANIM_ALPHA_DURATION;

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.annotation.Nullable;
import android.app.PendingIntent;
import android.content.Context;
@@ -29,6 +27,7 @@ import android.text.TextUtils;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.AnimationUtils;
import android.view.animation.Interpolator;
@@ -46,9 +45,8 @@ import java.util.List;
public class WalletView extends FrameLayout implements WalletCardCarousel.OnCardScrollListener {

    private static final String TAG = "WalletView";
    private static final int CAROUSEL_IN_ANIMATION_DURATION = 300;
    private static final int CAROUSEL_IN_ANIMATION_DURATION = 100;
    private static final int CAROUSEL_OUT_ANIMATION_DURATION = 200;
    private static final int CARD_LABEL_ANIM_DELAY = 133;

    private final WalletCardCarousel mCardCarousel;
    private final ImageView mIcon;
@@ -57,14 +55,12 @@ public class WalletView extends FrameLayout implements WalletCardCarousel.OnCard
    private final Button mAppButton;
    // Displays underneath the carousel, allow user to unlock device, verify card, etc.
    private final Button mActionButton;
    private final Interpolator mInInterpolator;
    private final Interpolator mOutInterpolator;
    private final float mAnimationTranslationX;
    private final ViewGroup mCardCarouselContainer;
    private final TextView mErrorView;
    private final ViewGroup mEmptyStateView;
    private CharSequence mCenterCardText;
    private Drawable mCenterCardIcon;
    private boolean mIsDeviceLocked = false;

    public WalletView(Context context) {
@@ -83,8 +79,6 @@ public class WalletView extends FrameLayout implements WalletCardCarousel.OnCard
        mActionButton = requireViewById(R.id.wallet_action_button);
        mErrorView = requireViewById(R.id.error_view);
        mEmptyStateView = requireViewById(R.id.wallet_empty_state);
        mInInterpolator =
                AnimationUtils.loadInterpolator(context, android.R.interpolator.fast_out_slow_in);
        mOutInterpolator =
                AnimationUtils.loadInterpolator(context, android.R.interpolator.accelerate_cubic);
        mAnimationTranslationX = mCardCarousel.getCardWidthPx() / 4f;
@@ -109,7 +103,6 @@ public class WalletView extends FrameLayout implements WalletCardCarousel.OnCard
        Drawable centerCardIcon = centerCard.getIcon();
        if (!TextUtils.equals(mCenterCardText, centerCardText)) {
            mCenterCardText = centerCardText;
            mCenterCardIcon = centerCardIcon;
            mCardLabel.setText(centerCardText);
            mIcon.setImageDrawable(centerCardIcon);
        }
@@ -134,39 +127,15 @@ public class WalletView extends FrameLayout implements WalletCardCarousel.OnCard
     */
    void showCardCarousel(
            List<WalletCardViewInfo> data, int selectedIndex, boolean isDeviceLocked) {
        boolean shouldAnimate =
                mCardCarousel.setData(data, selectedIndex, mIsDeviceLocked != isDeviceLocked);
        mIsDeviceLocked = isDeviceLocked;
        boolean shouldAnimate = mCardCarousel.setData(data, selectedIndex);
        mCardCarouselContainer.setVisibility(VISIBLE);
        mErrorView.setVisibility(GONE);
        mEmptyStateView.setVisibility(GONE);
        renderHeaderIconAndActionButton(data.get(selectedIndex), isDeviceLocked);
        if (shouldAnimate) {
            // If the empty state is visible, animate it away and delay the card carousel animation
            int emptyStateAnimDelay = 0;
            if (mEmptyStateView.getVisibility() == VISIBLE) {
                emptyStateAnimDelay = CARD_ANIM_ALPHA_DURATION;
                mEmptyStateView.animate()
                        .alpha(0)
                        .setDuration(emptyStateAnimDelay)
                        .setListener(new AnimatorListenerAdapter() {
                            @Override
                            public void onAnimationEnd(Animator animation) {
                                mEmptyStateView.setVisibility(GONE);
                            }
                        })
                        .start();
            }
            mCardLabel.setAlpha(0f);
            mCardLabel.animate().alpha(1f)
                    .setStartDelay(CARD_LABEL_ANIM_DELAY + emptyStateAnimDelay)
                    .setDuration(CARD_ANIM_ALPHA_DURATION)
                    .start();
            mCardCarousel.setExtraAnimationDelay(emptyStateAnimDelay);
            mCardCarousel.setTranslationX(mAnimationTranslationX);
            mCardCarousel.animate().translationX(0)
                    .setInterpolator(mInInterpolator)
                    .setDuration(CAROUSEL_IN_ANIMATION_DURATION)
                    .setStartDelay(emptyStateAnimDelay)
                    .start();
            animateViewsShown(mIcon, mCardLabel, mActionButton);
        }
    }

@@ -277,6 +246,15 @@ public class WalletView extends FrameLayout implements WalletCardCarousel.OnCard
        }
    }

    private static void animateViewsShown(View... uiElements) {
        for (View view : uiElements) {
            if (view.getVisibility() == VISIBLE) {
                view.setAlpha(0f);
                view.animate().alpha(1f).setDuration(CAROUSEL_IN_ANIMATION_DURATION).start();
            }
        }
    }

    private static CharSequence getLabelText(WalletCardViewInfo card) {
        String[] rawLabel = card.getLabel().toString().split("\\n");
        return rawLabel.length == 2 ? rawLabel[0] : card.getLabel();