Implement key preview zoom in/out animations
Bug: 11518021 Change-Id: I139b18708055e0811234886578c5a30b8cc71fecmain
parent
7c542558bf
commit
585fa0491a
|
@ -109,6 +109,10 @@
|
||||||
<attr name="keyPreviewOffset" format="dimension" />
|
<attr name="keyPreviewOffset" format="dimension" />
|
||||||
<!-- Height of the key press feedback popup. -->
|
<!-- Height of the key press feedback popup. -->
|
||||||
<attr name="keyPreviewHeight" format="dimension" />
|
<attr name="keyPreviewHeight" format="dimension" />
|
||||||
|
<!-- Duration of key preview popup zoom in animation in millisecond -->
|
||||||
|
<attr name="keyPreviewZoomInDuration" format="integer" />
|
||||||
|
<!-- Duration of key preview popup zoom out animation in millisecond -->
|
||||||
|
<attr name="keyPreviewZoomOutDuration" format="integer" />
|
||||||
<!-- Delay after key releasing and key press feedback dismissing in millisecond -->
|
<!-- Delay after key releasing and key press feedback dismissing in millisecond -->
|
||||||
<attr name="keyPreviewLingerTimeout" format="integer" />
|
<attr name="keyPreviewLingerTimeout" format="integer" />
|
||||||
<!-- Layout resource for more keys keyboard -->
|
<!-- Layout resource for more keys keyboard -->
|
||||||
|
|
|
@ -52,6 +52,8 @@
|
||||||
<dimen name="config_key_hysteresis_distance_for_sliding_modifier">8.0dp</dimen>
|
<dimen name="config_key_hysteresis_distance_for_sliding_modifier">8.0dp</dimen>
|
||||||
<integer name="config_touch_noise_threshold_time">40</integer>
|
<integer name="config_touch_noise_threshold_time">40</integer>
|
||||||
<dimen name="config_touch_noise_threshold_distance">12.6dp</dimen>
|
<dimen name="config_touch_noise_threshold_distance">12.6dp</dimen>
|
||||||
|
<integer name="config_key_preview_zoom_in_duration">35</integer>
|
||||||
|
<integer name="config_key_preview_zoom_out_duration">40</integer>
|
||||||
<integer name="config_key_preview_linger_timeout">70</integer>
|
<integer name="config_key_preview_linger_timeout">70</integer>
|
||||||
<bool name="config_key_selection_by_dragging_finger">true</bool>
|
<bool name="config_key_selection_by_dragging_finger">true</bool>
|
||||||
<!-- Sliding key input preview parameters -->
|
<!-- Sliding key input preview parameters -->
|
||||||
|
|
|
@ -77,6 +77,8 @@
|
||||||
<item name="ignoreAltCodeKeyTimeout">@integer/config_ignore_alt_code_key_timeout</item>
|
<item name="ignoreAltCodeKeyTimeout">@integer/config_ignore_alt_code_key_timeout</item>
|
||||||
<item name="keyPreviewLayout">@layout/key_preview</item>
|
<item name="keyPreviewLayout">@layout/key_preview</item>
|
||||||
<item name="keyPreviewHeight">@dimen/key_preview_height</item>
|
<item name="keyPreviewHeight">@dimen/key_preview_height</item>
|
||||||
|
<item name="keyPreviewZoomInDuration">@integer/config_key_preview_zoom_in_duration</item>
|
||||||
|
<item name="keyPreviewZoomOutDuration">@integer/config_key_preview_zoom_out_duration</item>
|
||||||
<item name="keyPreviewLingerTimeout">@integer/config_key_preview_linger_timeout</item>
|
<item name="keyPreviewLingerTimeout">@integer/config_key_preview_linger_timeout</item>
|
||||||
<item name="moreKeysKeyboardLayout">@layout/more_keys_keyboard</item>
|
<item name="moreKeysKeyboardLayout">@layout/more_keys_keyboard</item>
|
||||||
<item name="showMoreKeysKeyboardAtTouchedPoint">@bool/config_show_more_keys_keyboard_at_touched_point</item>
|
<item name="showMoreKeysKeyboardAtTouchedPoint">@bool/config_show_more_keys_keyboard_at_touched_point</item>
|
||||||
|
|
|
@ -16,7 +16,10 @@
|
||||||
|
|
||||||
package com.android.inputmethod.keyboard;
|
package com.android.inputmethod.keyboard;
|
||||||
|
|
||||||
|
import android.animation.Animator;
|
||||||
import android.animation.AnimatorInflater;
|
import android.animation.AnimatorInflater;
|
||||||
|
import android.animation.AnimatorListenerAdapter;
|
||||||
|
import android.animation.AnimatorSet;
|
||||||
import android.animation.ObjectAnimator;
|
import android.animation.ObjectAnimator;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.SharedPreferences;
|
import android.content.SharedPreferences;
|
||||||
|
@ -40,6 +43,8 @@ import android.view.MotionEvent;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewConfiguration;
|
import android.view.ViewConfiguration;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
|
import android.view.animation.AccelerateInterpolator;
|
||||||
|
import android.view.animation.DecelerateInterpolator;
|
||||||
import android.view.inputmethod.InputMethodSubtype;
|
import android.view.inputmethod.InputMethodSubtype;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
@ -168,6 +173,15 @@ public final class MainKeyboardView extends KeyboardView implements PointerTrack
|
||||||
private final KeyPreviewDrawParams mKeyPreviewDrawParams = new KeyPreviewDrawParams();
|
private final KeyPreviewDrawParams mKeyPreviewDrawParams = new KeyPreviewDrawParams();
|
||||||
private boolean mShowKeyPreviewPopup = true;
|
private boolean mShowKeyPreviewPopup = true;
|
||||||
private int mKeyPreviewLingerTimeout;
|
private int mKeyPreviewLingerTimeout;
|
||||||
|
private int mKeyPreviewZoomInDuration;
|
||||||
|
private int mKeyPreviewZoomOutDuration;
|
||||||
|
private static final float KEY_PREVIEW_START_ZOOM_IN_SCALE = 0.7f;
|
||||||
|
private static final float KEY_PREVIEW_END_ZOOM_IN_SCALE = 1.0f;
|
||||||
|
private static final float KEY_PREVIEW_END_ZOOM_OUT_SCALE = 0.7f;
|
||||||
|
private static final AccelerateInterpolator ACCELERATE_INTERPOLATOR =
|
||||||
|
new AccelerateInterpolator();
|
||||||
|
private static final DecelerateInterpolator DECELERATE_INTERPOLATOR =
|
||||||
|
new DecelerateInterpolator();
|
||||||
|
|
||||||
// More keys keyboard
|
// More keys keyboard
|
||||||
private final Paint mBackgroundDimAlphaPaint = new Paint();
|
private final Paint mBackgroundDimAlphaPaint = new Paint();
|
||||||
|
@ -389,17 +403,7 @@ public final class MainKeyboardView extends KeyboardView implements PointerTrack
|
||||||
if (mainKeyboardView == null) return;
|
if (mainKeyboardView == null) return;
|
||||||
switch (msg.what) {
|
switch (msg.what) {
|
||||||
case MSG_DISMISS_KEY_PREVIEW:
|
case MSG_DISMISS_KEY_PREVIEW:
|
||||||
final Key key = (Key)msg.obj;
|
mainKeyboardView.dismissKeyPreviewWithoutDelay((Key)msg.obj);
|
||||||
if (key != null) {
|
|
||||||
final TextView previewTextView =
|
|
||||||
mainKeyboardView.mShowingKeyPreviewTextViews.remove(key);
|
|
||||||
if (previewTextView != null) {
|
|
||||||
previewTextView.setVisibility(INVISIBLE);
|
|
||||||
mainKeyboardView.mFreeKeyPreviewTextViews.add(previewTextView);
|
|
||||||
}
|
|
||||||
// To redraw key top letter.
|
|
||||||
mainKeyboardView.invalidateKey(key);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case MSG_DISMISS_GESTURE_FLOATING_PREVIEW_TEXT:
|
case MSG_DISMISS_GESTURE_FLOATING_PREVIEW_TEXT:
|
||||||
mainKeyboardView.showGestureFloatingPreviewText(SuggestedWords.EMPTY);
|
mainKeyboardView.showGestureFloatingPreviewText(SuggestedWords.EMPTY);
|
||||||
|
@ -413,6 +417,9 @@ public final class MainKeyboardView extends KeyboardView implements PointerTrack
|
||||||
|
|
||||||
private void cancelAllDismissKeyPreviews() {
|
private void cancelAllDismissKeyPreviews() {
|
||||||
removeMessages(MSG_DISMISS_KEY_PREVIEW);
|
removeMessages(MSG_DISMISS_KEY_PREVIEW);
|
||||||
|
final MainKeyboardView mainKeyboardView = getOuterInstance();
|
||||||
|
if (mainKeyboardView == null) return;
|
||||||
|
mainKeyboardView.dismissAllKeyPreviews();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void dismissGestureFloatingPreviewText(final long delay) {
|
public void dismissGestureFloatingPreviewText(final long delay) {
|
||||||
|
@ -487,6 +494,10 @@ public final class MainKeyboardView extends KeyboardView implements PointerTrack
|
||||||
if (mKeyPreviewLayoutId == 0) {
|
if (mKeyPreviewLayoutId == 0) {
|
||||||
mShowKeyPreviewPopup = false;
|
mShowKeyPreviewPopup = false;
|
||||||
}
|
}
|
||||||
|
mKeyPreviewZoomInDuration = mainKeyboardViewAttr.getInt(
|
||||||
|
R.styleable.MainKeyboardView_keyPreviewZoomInDuration, 0);
|
||||||
|
mKeyPreviewZoomOutDuration = mainKeyboardViewAttr.getInt(
|
||||||
|
R.styleable.MainKeyboardView_keyPreviewZoomOutDuration, 0);
|
||||||
final int moreKeysKeyboardLayoutId = mainKeyboardViewAttr.getResourceId(
|
final int moreKeysKeyboardLayoutId = mainKeyboardViewAttr.getResourceId(
|
||||||
R.styleable.MainKeyboardView_moreKeysKeyboardLayout, 0);
|
R.styleable.MainKeyboardView_moreKeysKeyboardLayout, 0);
|
||||||
mConfigShowMoreKeysKeyboardAtTouchedPoint = mainKeyboardViewAttr.getBoolean(
|
mConfigShowMoreKeysKeyboardAtTouchedPoint = mainKeyboardViewAttr.getBoolean(
|
||||||
|
@ -712,11 +723,7 @@ public final class MainKeyboardView extends KeyboardView implements PointerTrack
|
||||||
|
|
||||||
private void dismissAllKeyPreviews() {
|
private void dismissAllKeyPreviews() {
|
||||||
for (final Key key : new HashSet<Key>(mShowingKeyPreviewTextViews.keySet())) {
|
for (final Key key : new HashSet<Key>(mShowingKeyPreviewTextViews.keySet())) {
|
||||||
final TextView previewTextView = mShowingKeyPreviewTextViews.remove(key);
|
dismissKeyPreviewWithoutDelay(key);
|
||||||
if (previewTextView != null) {
|
|
||||||
previewTextView.setVisibility(INVISIBLE);
|
|
||||||
mFreeKeyPreviewTextViews.add(previewTextView);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
PointerTracker.setReleasedKeyGraphicsToAllKeys();
|
PointerTracker.setReleasedKeyGraphicsToAllKeys();
|
||||||
}
|
}
|
||||||
|
@ -742,6 +749,7 @@ public final class MainKeyboardView extends KeyboardView implements PointerTrack
|
||||||
private static final int STATE_NORMAL = 0;
|
private static final int STATE_NORMAL = 0;
|
||||||
private static final int STATE_HAS_MOREKEYS = 1;
|
private static final int STATE_HAS_MOREKEYS = 1;
|
||||||
|
|
||||||
|
// TODO: Take this method out of this class.
|
||||||
@Override
|
@Override
|
||||||
public void showKeyPreview(final Key key) {
|
public void showKeyPreview(final Key key) {
|
||||||
// If key is invalid or IME is already closed, we must not show key preview.
|
// If key is invalid or IME is already closed, we must not show key preview.
|
||||||
|
@ -819,13 +827,129 @@ public final class MainKeyboardView extends KeyboardView implements PointerTrack
|
||||||
}
|
}
|
||||||
ViewLayoutUtils.placeViewAt(
|
ViewLayoutUtils.placeViewAt(
|
||||||
previewTextView, previewX, previewY, previewWidth, previewHeight);
|
previewTextView, previewX, previewY, previewWidth, previewHeight);
|
||||||
previewTextView.setVisibility(VISIBLE);
|
|
||||||
mShowingKeyPreviewTextViews.put(key, previewTextView);
|
if (!isHardwareAccelerated()) {
|
||||||
|
previewTextView.setVisibility(VISIBLE);
|
||||||
|
mShowingKeyPreviewTextViews.put(key, previewTextView);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
previewTextView.setPivotX(previewWidth / 2.0f);
|
||||||
|
previewTextView.setPivotY(previewHeight);
|
||||||
|
|
||||||
|
final Animator zoomIn = createZoomInAniation(key, previewTextView);
|
||||||
|
final Animator zoomOut = createZoomOutAnimation(key, previewTextView);
|
||||||
|
final KeyPreviewAnimations animation = new KeyPreviewAnimations(zoomIn, zoomOut);
|
||||||
|
previewTextView.setTag(animation);
|
||||||
|
animation.startZoomIn();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: Move this internal class out to a separate external class.
|
||||||
|
private static class KeyPreviewAnimations extends AnimatorListenerAdapter {
|
||||||
|
private final Animator mZoomIn;
|
||||||
|
private final Animator mZoomOut;
|
||||||
|
|
||||||
|
public KeyPreviewAnimations(final Animator zoomIn, final Animator zoomOut) {
|
||||||
|
mZoomIn = zoomIn;
|
||||||
|
mZoomOut = zoomOut;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void startZoomIn() {
|
||||||
|
mZoomIn.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void startZoomOut() {
|
||||||
|
if (mZoomIn.isRunning()) {
|
||||||
|
mZoomIn.addListener(this);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
mZoomOut.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onAnimationEnd(final Animator animation) {
|
||||||
|
mZoomOut.start();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Take this method out of this class.
|
||||||
|
private Animator createZoomInAniation(final Key key, final TextView previewTextView) {
|
||||||
|
final ObjectAnimator scaleXAnimation = ObjectAnimator.ofFloat(
|
||||||
|
previewTextView, SCALE_X, KEY_PREVIEW_START_ZOOM_IN_SCALE,
|
||||||
|
KEY_PREVIEW_END_ZOOM_IN_SCALE);
|
||||||
|
final ObjectAnimator scaleYAnimation = ObjectAnimator.ofFloat(
|
||||||
|
previewTextView, SCALE_Y, KEY_PREVIEW_START_ZOOM_IN_SCALE,
|
||||||
|
KEY_PREVIEW_END_ZOOM_IN_SCALE);
|
||||||
|
final AnimatorSet zoomInAnimation = new AnimatorSet();
|
||||||
|
zoomInAnimation.play(scaleXAnimation).with(scaleYAnimation);
|
||||||
|
// TODO: Implement preference option to control key preview animation duration.
|
||||||
|
zoomInAnimation.setDuration(mKeyPreviewZoomInDuration);
|
||||||
|
zoomInAnimation.setInterpolator(DECELERATE_INTERPOLATOR);
|
||||||
|
zoomInAnimation.addListener(new AnimatorListenerAdapter() {
|
||||||
|
@Override
|
||||||
|
public void onAnimationStart(final Animator animation) {
|
||||||
|
previewTextView.setVisibility(VISIBLE);
|
||||||
|
mShowingKeyPreviewTextViews.put(key, previewTextView);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return zoomInAnimation;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Take this method out of this class.
|
||||||
|
private Animator createZoomOutAnimation(final Key key, final TextView previewTextView) {
|
||||||
|
final ObjectAnimator scaleXAnimation = ObjectAnimator.ofFloat(
|
||||||
|
previewTextView, SCALE_X, KEY_PREVIEW_END_ZOOM_OUT_SCALE);
|
||||||
|
final ObjectAnimator scaleYAnimation = ObjectAnimator.ofFloat(
|
||||||
|
previewTextView, SCALE_Y, KEY_PREVIEW_END_ZOOM_OUT_SCALE);
|
||||||
|
final AnimatorSet zoomOutAnimation = new AnimatorSet();
|
||||||
|
zoomOutAnimation.play(scaleXAnimation).with(scaleYAnimation);
|
||||||
|
// TODO: Implement preference option to control key preview animation duration.
|
||||||
|
zoomOutAnimation.setDuration(mKeyPreviewZoomOutDuration);
|
||||||
|
zoomOutAnimation.setInterpolator(ACCELERATE_INTERPOLATOR);
|
||||||
|
zoomOutAnimation.addListener(new AnimatorListenerAdapter() {
|
||||||
|
@Override
|
||||||
|
public void onAnimationEnd(final Animator animation) {
|
||||||
|
dismissKeyPreviewWithoutDelay(key);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return zoomOutAnimation;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Take this method out of this class.
|
||||||
|
private void dismissKeyPreviewWithoutDelay(final Key key) {
|
||||||
|
if (key == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
final TextView previewTextView = mShowingKeyPreviewTextViews.remove(key);
|
||||||
|
if (previewTextView != null) {
|
||||||
|
final Object tag = previewTextView.getTag();
|
||||||
|
if (tag instanceof Animator) {
|
||||||
|
((Animator)tag).cancel();
|
||||||
|
}
|
||||||
|
previewTextView.setTag(null);
|
||||||
|
previewTextView.setVisibility(INVISIBLE);
|
||||||
|
mFreeKeyPreviewTextViews.add(previewTextView);
|
||||||
|
}
|
||||||
|
// To redraw key top letter.
|
||||||
|
invalidateKey(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Take this method out of this class.
|
||||||
@Override
|
@Override
|
||||||
public void dismissKeyPreview(final Key key) {
|
public void dismissKeyPreview(final Key key) {
|
||||||
mDrawingHandler.dismissKeyPreview(mKeyPreviewLingerTimeout, key);
|
final TextView previewTextView = mShowingKeyPreviewTextViews.get(key);
|
||||||
|
if (previewTextView == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!isHardwareAccelerated()) {
|
||||||
|
// TODO: Implement preference option to control key preview method and duration.
|
||||||
|
mDrawingHandler.dismissKeyPreview(mKeyPreviewLingerTimeout, key);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
final Object tag = previewTextView.getTag();
|
||||||
|
if (tag instanceof KeyPreviewAnimations) {
|
||||||
|
final KeyPreviewAnimations animation = (KeyPreviewAnimations)tag;
|
||||||
|
animation.startZoomOut();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setSlidingKeyInputPreviewEnabled(final boolean enabled) {
|
public void setSlidingKeyInputPreviewEnabled(final boolean enabled) {
|
||||||
|
@ -984,6 +1108,8 @@ public final class MainKeyboardView extends KeyboardView implements PointerTrack
|
||||||
final int pointY = key.getY() + mKeyPreviewDrawParams.mPreviewVisibleOffset;
|
final int pointY = key.getY() + mKeyPreviewDrawParams.mPreviewVisibleOffset;
|
||||||
moreKeysPanel.showMoreKeysPanel(this, this, pointX, pointY, mKeyboardActionListener);
|
moreKeysPanel.showMoreKeysPanel(this, this, pointX, pointY, mKeyboardActionListener);
|
||||||
tracker.onShowMoreKeysPanel(moreKeysPanel);
|
tracker.onShowMoreKeysPanel(moreKeysPanel);
|
||||||
|
// TODO: Implement zoom in animation of more keys panel.
|
||||||
|
dismissKeyPreviewWithoutDelay(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isInDraggingFinger() {
|
public boolean isInDraggingFinger() {
|
||||||
|
|
Loading…
Reference in New Issue