Merge "Wallet view UI tweaks." into sc-dev
This commit is contained in:
@@ -24,6 +24,7 @@
|
|||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:layout_marginHorizontal="@dimen/card_margin"
|
android:layout_marginHorizontal="@dimen/card_margin"
|
||||||
|
android:layout_marginBottom="@dimen/card_margin"
|
||||||
android:foreground="?android:attr/selectableItemBackground"
|
android:foreground="?android:attr/selectableItemBackground"
|
||||||
app:cardBackgroundColor="@android:color/transparent"
|
app:cardBackgroundColor="@android:color/transparent"
|
||||||
app:cardElevation="12dp">
|
app:cardElevation="12dp">
|
||||||
@@ -32,16 +33,8 @@
|
|||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:adjustViewBounds="true"
|
android:adjustViewBounds="true"
|
||||||
|
android:layout_gravity="center"
|
||||||
android:contentDescription="@null"
|
android:contentDescription="@null"
|
||||||
android:scaleType="fitXY"/>
|
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"/>
|
|
||||||
</com.android.systemui.wallet.ui.WalletCardView>
|
</com.android.systemui.wallet.ui.WalletCardView>
|
||||||
</FrameLayout>
|
</FrameLayout>
|
||||||
|
|||||||
@@ -61,7 +61,7 @@ public class WalletCardCarousel extends RecyclerView {
|
|||||||
static final int CARD_ANIM_ALPHA_DELAY = 50;
|
static final int CARD_ANIM_ALPHA_DELAY = 50;
|
||||||
|
|
||||||
private final Rect mSystemGestureExclusionZone = new Rect();
|
private final Rect mSystemGestureExclusionZone = new Rect();
|
||||||
private WalletCardCarouselAdapter mWalletCardCarouselAdapter;
|
private final WalletCardCarouselAdapter mWalletCardCarouselAdapter;
|
||||||
private int mExpectedViewWidth;
|
private int mExpectedViewWidth;
|
||||||
private int mCardMarginPx;
|
private int mCardMarginPx;
|
||||||
private int mCardWidthPx;
|
private int mCardWidthPx;
|
||||||
@@ -79,12 +79,6 @@ public class WalletCardCarousel extends RecyclerView {
|
|||||||
// also be used in DotIndicatorDecoration.
|
// also be used in DotIndicatorDecoration.
|
||||||
float mEdgeToCenterDistance = Float.MAX_VALUE;
|
float mEdgeToCenterDistance = Float.MAX_VALUE;
|
||||||
private float mCardCenterToScreenCenterDistancePx = 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 {
|
interface OnSelectionListener {
|
||||||
/**
|
/**
|
||||||
@@ -179,10 +173,6 @@ public class WalletCardCarousel extends RecyclerView {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void setExtraAnimationDelay(int extraAnimationDelay) {
|
|
||||||
mExtraAnimationDelay = extraAnimationDelay;
|
|
||||||
}
|
|
||||||
|
|
||||||
void setSelectionListener(OnSelectionListener selectionListener) {
|
void setSelectionListener(OnSelectionListener selectionListener) {
|
||||||
mSelectionListener = 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 setData(List<WalletCardViewInfo> data, int selectedIndex, boolean hasLockStateChanged) {
|
||||||
boolean wasEmpty = mWalletCardCarouselAdapter.getItemCount() == 0;
|
boolean hasDataChanged = mWalletCardCarouselAdapter.setData(data, hasLockStateChanged);
|
||||||
mWalletCardCarouselAdapter.setData(data);
|
|
||||||
scrollToPosition(selectedIndex);
|
scrollToPosition(selectedIndex);
|
||||||
if (wasEmpty) {
|
|
||||||
mNumCardsToAnimate = numCardsOnScreen(data.size(), selectedIndex);
|
|
||||||
mCardAnimationStartPosition = Math.max(selectedIndex - 1, 0);
|
|
||||||
}
|
|
||||||
WalletCardViewInfo selectedCard = data.get(selectedIndex);
|
WalletCardViewInfo selectedCard = data.get(selectedIndex);
|
||||||
mCardScrollListener.onCardScroll(selectedCard, selectedCard, 0);
|
mCardScrollListener.onCardScroll(selectedCard, selectedCard, 0);
|
||||||
return wasEmpty;
|
return hasDataChanged;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -221,19 +206,6 @@ public class WalletCardCarousel extends RecyclerView {
|
|||||||
mSelectionListener.onCardSelected(mWalletCardCarouselAdapter.mData.get(position));
|
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
|
* The padding pushes the first and last cards in the list to the center when they are
|
||||||
* selected.
|
* selected.
|
||||||
@@ -439,9 +411,29 @@ public class WalletCardCarousel extends RecyclerView {
|
|||||||
return mData.get(position).getCardId().hashCode();
|
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;
|
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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -54,4 +54,11 @@ interface WalletCardViewInfo {
|
|||||||
*/
|
*/
|
||||||
@NonNull
|
@NonNull
|
||||||
PendingIntent getPendingIntent();
|
PendingIntent getPendingIntent();
|
||||||
|
|
||||||
|
default boolean isUiEquivalent(WalletCardViewInfo other) {
|
||||||
|
if (other == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return getCardId().equals(other.getCardId());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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_DELAY;
|
||||||
import static com.android.systemui.wallet.ui.WalletCardCarousel.CARD_ANIM_ALPHA_DURATION;
|
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.annotation.Nullable;
|
||||||
import android.app.PendingIntent;
|
import android.app.PendingIntent;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
@@ -29,6 +27,7 @@ import android.text.TextUtils;
|
|||||||
import android.util.AttributeSet;
|
import android.util.AttributeSet;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.view.MotionEvent;
|
import android.view.MotionEvent;
|
||||||
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.view.animation.AnimationUtils;
|
import android.view.animation.AnimationUtils;
|
||||||
import android.view.animation.Interpolator;
|
import android.view.animation.Interpolator;
|
||||||
@@ -46,9 +45,8 @@ import java.util.List;
|
|||||||
public class WalletView extends FrameLayout implements WalletCardCarousel.OnCardScrollListener {
|
public class WalletView extends FrameLayout implements WalletCardCarousel.OnCardScrollListener {
|
||||||
|
|
||||||
private static final String TAG = "WalletView";
|
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 CAROUSEL_OUT_ANIMATION_DURATION = 200;
|
||||||
private static final int CARD_LABEL_ANIM_DELAY = 133;
|
|
||||||
|
|
||||||
private final WalletCardCarousel mCardCarousel;
|
private final WalletCardCarousel mCardCarousel;
|
||||||
private final ImageView mIcon;
|
private final ImageView mIcon;
|
||||||
@@ -57,14 +55,12 @@ public class WalletView extends FrameLayout implements WalletCardCarousel.OnCard
|
|||||||
private final Button mAppButton;
|
private final Button mAppButton;
|
||||||
// Displays underneath the carousel, allow user to unlock device, verify card, etc.
|
// Displays underneath the carousel, allow user to unlock device, verify card, etc.
|
||||||
private final Button mActionButton;
|
private final Button mActionButton;
|
||||||
private final Interpolator mInInterpolator;
|
|
||||||
private final Interpolator mOutInterpolator;
|
private final Interpolator mOutInterpolator;
|
||||||
private final float mAnimationTranslationX;
|
private final float mAnimationTranslationX;
|
||||||
private final ViewGroup mCardCarouselContainer;
|
private final ViewGroup mCardCarouselContainer;
|
||||||
private final TextView mErrorView;
|
private final TextView mErrorView;
|
||||||
private final ViewGroup mEmptyStateView;
|
private final ViewGroup mEmptyStateView;
|
||||||
private CharSequence mCenterCardText;
|
private CharSequence mCenterCardText;
|
||||||
private Drawable mCenterCardIcon;
|
|
||||||
private boolean mIsDeviceLocked = false;
|
private boolean mIsDeviceLocked = false;
|
||||||
|
|
||||||
public WalletView(Context context) {
|
public WalletView(Context context) {
|
||||||
@@ -83,8 +79,6 @@ public class WalletView extends FrameLayout implements WalletCardCarousel.OnCard
|
|||||||
mActionButton = requireViewById(R.id.wallet_action_button);
|
mActionButton = requireViewById(R.id.wallet_action_button);
|
||||||
mErrorView = requireViewById(R.id.error_view);
|
mErrorView = requireViewById(R.id.error_view);
|
||||||
mEmptyStateView = requireViewById(R.id.wallet_empty_state);
|
mEmptyStateView = requireViewById(R.id.wallet_empty_state);
|
||||||
mInInterpolator =
|
|
||||||
AnimationUtils.loadInterpolator(context, android.R.interpolator.fast_out_slow_in);
|
|
||||||
mOutInterpolator =
|
mOutInterpolator =
|
||||||
AnimationUtils.loadInterpolator(context, android.R.interpolator.accelerate_cubic);
|
AnimationUtils.loadInterpolator(context, android.R.interpolator.accelerate_cubic);
|
||||||
mAnimationTranslationX = mCardCarousel.getCardWidthPx() / 4f;
|
mAnimationTranslationX = mCardCarousel.getCardWidthPx() / 4f;
|
||||||
@@ -109,7 +103,6 @@ public class WalletView extends FrameLayout implements WalletCardCarousel.OnCard
|
|||||||
Drawable centerCardIcon = centerCard.getIcon();
|
Drawable centerCardIcon = centerCard.getIcon();
|
||||||
if (!TextUtils.equals(mCenterCardText, centerCardText)) {
|
if (!TextUtils.equals(mCenterCardText, centerCardText)) {
|
||||||
mCenterCardText = centerCardText;
|
mCenterCardText = centerCardText;
|
||||||
mCenterCardIcon = centerCardIcon;
|
|
||||||
mCardLabel.setText(centerCardText);
|
mCardLabel.setText(centerCardText);
|
||||||
mIcon.setImageDrawable(centerCardIcon);
|
mIcon.setImageDrawable(centerCardIcon);
|
||||||
}
|
}
|
||||||
@@ -134,39 +127,15 @@ public class WalletView extends FrameLayout implements WalletCardCarousel.OnCard
|
|||||||
*/
|
*/
|
||||||
void showCardCarousel(
|
void showCardCarousel(
|
||||||
List<WalletCardViewInfo> data, int selectedIndex, boolean isDeviceLocked) {
|
List<WalletCardViewInfo> data, int selectedIndex, boolean isDeviceLocked) {
|
||||||
|
boolean shouldAnimate =
|
||||||
|
mCardCarousel.setData(data, selectedIndex, mIsDeviceLocked != isDeviceLocked);
|
||||||
mIsDeviceLocked = isDeviceLocked;
|
mIsDeviceLocked = isDeviceLocked;
|
||||||
boolean shouldAnimate = mCardCarousel.setData(data, selectedIndex);
|
|
||||||
mCardCarouselContainer.setVisibility(VISIBLE);
|
mCardCarouselContainer.setVisibility(VISIBLE);
|
||||||
mErrorView.setVisibility(GONE);
|
mErrorView.setVisibility(GONE);
|
||||||
|
mEmptyStateView.setVisibility(GONE);
|
||||||
renderHeaderIconAndActionButton(data.get(selectedIndex), isDeviceLocked);
|
renderHeaderIconAndActionButton(data.get(selectedIndex), isDeviceLocked);
|
||||||
if (shouldAnimate) {
|
if (shouldAnimate) {
|
||||||
// If the empty state is visible, animate it away and delay the card carousel animation
|
animateViewsShown(mIcon, mCardLabel, mActionButton);
|
||||||
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();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -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) {
|
private static CharSequence getLabelText(WalletCardViewInfo card) {
|
||||||
String[] rawLabel = card.getLabel().toString().split("\\n");
|
String[] rawLabel = card.getLabel().toString().split("\\n");
|
||||||
return rawLabel.length == 2 ? rawLabel[0] : card.getLabel();
|
return rawLabel.length == 2 ? rawLabel[0] : card.getLabel();
|
||||||
|
|||||||
Reference in New Issue
Block a user