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); |
+ } |
} |
}); |
} |