Chromium Code Reviews| Index: components/autofill/android/java/src/org/chromium/components/autofill/AutofillKeyboardAccessory.java |
| diff --git a/components/autofill/android/java/src/org/chromium/components/autofill/AutofillKeyboardAccessory.java b/components/autofill/android/java/src/org/chromium/components/autofill/AutofillKeyboardAccessory.java |
| index 56475a385245b4eda771492457202070f1e3d3b9..a49aa799ff5ba02b3381bea30494d80b85738089 100644 |
| --- a/components/autofill/android/java/src/org/chromium/components/autofill/AutofillKeyboardAccessory.java |
| +++ b/components/autofill/android/java/src/org/chromium/components/autofill/AutofillKeyboardAccessory.java |
| @@ -4,6 +4,9 @@ |
| package org.chromium.components.autofill; |
| +import android.animation.Animator; |
| +import android.animation.AnimatorListenerAdapter; |
| +import android.animation.ObjectAnimator; |
| import android.annotation.SuppressLint; |
| import android.graphics.Typeface; |
| import android.os.Build; |
| @@ -29,19 +32,31 @@ import org.chromium.ui.base.WindowAndroid; |
| public class AutofillKeyboardAccessory extends LinearLayout |
| implements WindowAndroid.KeyboardVisibilityListener, View.OnClickListener, |
| View.OnLongClickListener { |
| + // We start animating by scrolling the suggestions from beyond the viewport. |
| + private static final int NUM_DIP_TO_ANIMATE_SCROLL_FROM = 100; |
|
Ted C
2017/05/17 00:04:30
I would call this START_ANIMATION_TRANSLATION_X_DP
csashi
2017/05/17 01:14:15
Done.
|
| + |
| + // Time to pause before reversing animation when the first suggestion is a hint. |
| + private static final long PAUSE_ANIMATION_BEFORE_REVERSE_MILLIS = 1000; |
| + |
| private final WindowAndroid mWindowAndroid; |
| private final AutofillDelegate mAutofillDelegate; |
| + // If |mMaximumLabelWidthPx| is 0, we do not call |setMaxWidth| on the |TextView| for a fillable |
| + // suggestion label. |
| private final int mMaximumLabelWidthPx; |
| private final int mMaximumSublabelWidthPx; |
| + private final int mAnimationDurationMillis; |
| + private ObjectAnimator mAnimator; |
| /** |
| * Creates an AutofillKeyboardAccessory with specified parameters. |
| * @param windowAndroid The owning WindowAndroid. |
| * @param autofillDelegate A object that handles the calls to the native |
| * AutofillKeyboardAccessoryView. |
| + * @param animationDurationMillis If 0, do not animate. |
| + * @param shouldLimitLabelWidth If true, limit suggestion label width to 1/2 device's width. |
| */ |
| - public AutofillKeyboardAccessory( |
| - WindowAndroid windowAndroid, AutofillDelegate autofillDelegate) { |
| + public AutofillKeyboardAccessory(WindowAndroid windowAndroid, AutofillDelegate autofillDelegate, |
| + int animationDurationMillis, boolean shouldLimitLabelWidth) { |
| super(windowAndroid.getActivity().get()); |
| assert autofillDelegate != null; |
| assert windowAndroid.getActivity().get() != null; |
| @@ -49,13 +64,15 @@ public class AutofillKeyboardAccessory extends LinearLayout |
| mAutofillDelegate = autofillDelegate; |
| int deviceWidthPx = windowAndroid.getDisplay().getDisplayWidth(); |
| - mMaximumLabelWidthPx = deviceWidthPx / 2; |
| + mMaximumLabelWidthPx = shouldLimitLabelWidth ? deviceWidthPx / 2 : 0; |
| mMaximumSublabelWidthPx = deviceWidthPx / 4; |
| mWindowAndroid.addKeyboardVisibilityListener(this); |
| int horizontalPaddingPx = getResources().getDimensionPixelSize( |
| R.dimen.keyboard_accessory_half_padding); |
| setPadding(horizontalPaddingPx, 0, horizontalPaddingPx, 0); |
| + |
| + mAnimationDurationMillis = animationDurationMillis; |
| } |
| /** |
| @@ -65,18 +82,28 @@ public class AutofillKeyboardAccessory extends LinearLayout |
| */ |
| @SuppressLint("InlinedApi") |
| public void showWithSuggestions(AutofillSuggestion[] suggestions, final boolean isRtl) { |
|
Ted C
2017/05/17 00:04:30
Is this called only a single time for each showing
csashi
2017/05/17 01:14:15
It may be called again while previous animation in
csashi
2017/05/18 00:04:05
I am now trying a different variation to re-layout
|
| + assert suggestions.length > 0; |
| + |
| removeAllViews(); |
| int separatorPosition = -1; |
| for (int i = 0; i < suggestions.length; i++) { |
| AutofillSuggestion suggestion = suggestions[i]; |
| - assert !TextUtils.isEmpty(suggestion.getLabel()); |
| + // The first suggestion may be a hint to call attention to the keyboard accessory. |
| + // See |IsHintEnabledInKeyboardAccessory|. A 'hint' suggestion does not have a label |
| + // and is not fillable, but has an icon. |
| + boolean isKeyboardAccessoryHint = i == 0 && TextUtils.isEmpty(suggestion.getLabel()); |
| + if (isKeyboardAccessoryHint) { |
| + assert !suggestion.isFillable() && suggestion.getIconId() != 0; |
| + } else { |
| + assert !TextUtils.isEmpty(suggestion.getLabel()); |
| + } |
| View touchTarget; |
| if (!suggestion.isFillable() && suggestion.getIconId() != 0) { |
| touchTarget = LayoutInflater.from(getContext()).inflate( |
| R.layout.autofill_keyboard_accessory_icon, this, false); |
| - if (separatorPosition == -1) separatorPosition = i; |
| + if (separatorPosition == -1 && !isKeyboardAccessoryHint) separatorPosition = i; |
| ImageView icon = (ImageView) touchTarget; |
| icon.setImageDrawable( |
| @@ -89,7 +116,7 @@ public class AutofillKeyboardAccessory extends LinearLayout |
| TextView label = (TextView) touchTarget.findViewById( |
| R.id.autofill_keyboard_accessory_item_label); |
| - if (suggestion.isFillable()) { |
| + if (mMaximumLabelWidthPx > 0 && suggestion.isFillable()) { |
| label.setMaxWidth(mMaximumLabelWidthPx); |
| } |
| @@ -115,12 +142,13 @@ public class AutofillKeyboardAccessory extends LinearLayout |
| } |
| } |
| - touchTarget.setTag(i); |
| - touchTarget.setOnClickListener(this); |
| - if (suggestion.isDeletable()) { |
| - touchTarget.setOnLongClickListener(this); |
| + if (!isKeyboardAccessoryHint) { |
| + touchTarget.setTag(i); |
| + touchTarget.setOnClickListener(this); |
| + if (suggestion.isDeletable()) { |
| + touchTarget.setOnLongClickListener(this); |
| + } |
| } |
| - |
| addView(touchTarget); |
| } |
| @@ -135,16 +163,59 @@ public class AutofillKeyboardAccessory extends LinearLayout |
| final HorizontalScrollView container = |
| (HorizontalScrollView) mWindowAndroid.getKeyboardAccessoryView(); |
| + final boolean isFirstSuggestionAHint = TextUtils.isEmpty(suggestions[0].getLabel()); |
| + if (isFirstSuggestionAHint) { |
|
Ted C
2017/05/17 00:04:30
these asserts seem duplicated with what is in the
csashi
2017/05/17 01:14:15
Done.
|
| + assert suggestions[0].getIconId() != 0 && !suggestions[0].isFillable(); |
| + } |
| + |
| if (getParent() == null) { |
| container.addView(this); |
| - container.setVisibility(View.VISIBLE); |
| + // If we are animating the view, we |setVisibility| in |onAnimationStart|. |
| + if (mAnimationDurationMillis == 0) { |
| + container.setVisibility(View.VISIBLE); |
| + } |
| container.sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED); |
| } |
| + if (mAnimationDurationMillis > 0) { |
| + // TODO(crbug/722897): Fix animation for RTL. |
|
Ted C
2017/05/17 00:04:29
Won't the suggestions just flow from the right to
csashi
2017/05/17 01:14:15
I tried setting developer options to force right-t
|
| + mAnimator = ObjectAnimator.ofFloat( |
| + this, View.TRANSLATION_X, -NUM_DIP_TO_ANIMATE_SCROLL_FROM, 0); |
|
Ted C
2017/05/17 00:04:29
translateX takes pixels, so despite your DIP in th
csashi
2017/05/17 01:14:15
Done.
|
| + mAnimator.setDuration(mAnimationDurationMillis); |
| + mAnimator.addListener(new AnimatorListenerAdapter() { |
| + @Override |
| + public void onAnimationStart(Animator animator) { |
| + container.setVisibility(View.VISIBLE); |
| + } |
| + @Override |
| + public void onAnimationEnd(Animator animator) { |
| + mAnimator.removeListener(this); |
| + if (isFirstSuggestionAHint) { |
|
Ted C
2017/05/17 00:04:29
if would do:
if (!isFirstSuggestionAHint) return;
|
| + // Reverse the animation and scroll the first suggestion (which is a |
| + // non-fillable hint) out of the viewport at the end of the reversed |
| + // animation. |
| + assert getChildCount() > 1; |
| + int hintWidth = getChildAt(0).getWidth(); |
| + // TODO(crbug/722897): Fix animation for RTL. |
| + mAnimator.setFloatValues(0, -hintWidth); |
|
Ted C
2017/05/17 00:04:29
I would just create a new animation. The only thi
csashi
2017/05/17 01:14:15
Done.
|
| + container.postDelayed(new Runnable() { |
| + @Override |
| + public void run() { |
| + mAnimator.start(); |
|
Ted C
2017/05/17 00:04:29
You'll need to make sure you haven't been dismisse
|
| + } |
| + }, PAUSE_ANIMATION_BEFORE_REVERSE_MILLIS); |
| + } |
| + } |
| + }); |
| + } |
| container.post(new Runnable() { |
| @Override |
| public void run() { |
| - container.scrollTo(isRtl ? getRight() : 0, 0); |
| + if (mAnimationDurationMillis > 0) { |
| + mAnimator.start(); |
|
Ted C
2017/05/17 00:04:29
general question about this animation...translatio
csashi
2017/05/17 01:14:15
This is an issue and the view does not take care o
csashi
2017/05/18 00:04:05
I did not have much success with tweaking the widt
csashi
2017/05/18 00:53:04
I resolved this issue by resetting the 'X'. See ht
|
| + } else { |
| + container.scrollTo(isRtl ? getRight() : 0, 0); |
| + } |
| } |
| }); |
| } |