diff options
| author | 2021-05-06 00:31:02 -0700 | |
|---|---|---|
| committer | 2021-05-06 02:17:43 -0700 | |
| commit | b30ccb3dffb61089eedbbb3525cb672b6d6c62ce (patch) | |
| tree | 633e301d273eef99ceac41a4a94a79efda59ea86 | |
| parent | 208f294d4ea228e1bdf0dab500d3712803f7246c (diff) | |
Wallet view UI tweaks.
1. Increase the card view bottom margin to avoid weird card shadow.
before: https://hsv.googleplex.com/6352365370212352
after: https://hsv.googleplex.com/5745851513176064
2. Center the card image in card view.
3. Add fade-in animation for the card carousel UI elements when card
carousel is shown; clean up the unnecessary animation for empty state
view -> non-empty state view.
see demo video:
https://drive.google.com/file/d/1Eih4p1uzw_To_SUQsWGYpkd4M85WX2C9/view?usp=sharing&resourcekey=0-oD7hpOg7uKW6xeCmVNvS0Q
Test: manual
Fix: 184905963
Change-Id: Ied2fffef1f2d9bd6bfcfed0985d39cbed3f52cb0
4 files changed, 51 insertions, 81 deletions
diff --git a/packages/SystemUI/res/layout/wallet_card_view.xml b/packages/SystemUI/res/layout/wallet_card_view.xml index 5fd556d1fe25..b5a6601062a8 100644 --- a/packages/SystemUI/res/layout/wallet_card_view.xml +++ b/packages/SystemUI/res/layout/wallet_card_view.xml @@ -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> diff --git a/packages/SystemUI/src/com/android/systemui/wallet/ui/WalletCardCarousel.java b/packages/SystemUI/src/com/android/systemui/wallet/ui/WalletCardCarousel.java index 4200241603ea..1e1b459382d7 100644 --- a/packages/SystemUI/src/com/android/systemui/wallet/ui/WalletCardCarousel.java +++ b/packages/SystemUI/src/com/android/systemui/wallet/ui/WalletCardCarousel.java @@ -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 @@ -222,19 +207,6 @@ public class WalletCardCarousel extends RecyclerView { } /** - * 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; - notifyDataSetChanged(); + 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; } } diff --git a/packages/SystemUI/src/com/android/systemui/wallet/ui/WalletCardViewInfo.java b/packages/SystemUI/src/com/android/systemui/wallet/ui/WalletCardViewInfo.java index 3d37320f3d32..08fbe4aa3ce5 100644 --- a/packages/SystemUI/src/com/android/systemui/wallet/ui/WalletCardViewInfo.java +++ b/packages/SystemUI/src/com/android/systemui/wallet/ui/WalletCardViewInfo.java @@ -54,4 +54,11 @@ interface WalletCardViewInfo { */ @NonNull PendingIntent getPendingIntent(); + + default boolean isUiEquivalent(WalletCardViewInfo other) { + if (other == null) { + return false; + } + return getCardId().equals(other.getCardId()); + } } diff --git a/packages/SystemUI/src/com/android/systemui/wallet/ui/WalletView.java b/packages/SystemUI/src/com/android/systemui/wallet/ui/WalletView.java index 44074f706183..c547bb346617 100644 --- a/packages/SystemUI/src/com/android/systemui/wallet/ui/WalletView.java +++ b/packages/SystemUI/src/com/android/systemui/wallet/ui/WalletView.java @@ -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(); |