Merge "Custom view for key preview popup"
This commit is contained in:
commit
496fd77850
9 changed files with 153 additions and 161 deletions
|
@ -1,27 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<!--
|
|
||||||
/*
|
|
||||||
**
|
|
||||||
** Copyright 2013, The Android Open Source Project
|
|
||||||
**
|
|
||||||
** Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
** you may not use this file except in compliance with the License.
|
|
||||||
** You may obtain a copy of the License at
|
|
||||||
**
|
|
||||||
** http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
**
|
|
||||||
** Unless required by applicable law or agreed to in writing, software
|
|
||||||
** distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
** See the License for the specific language governing permissions and
|
|
||||||
** limitations under the License.
|
|
||||||
*/
|
|
||||||
-->
|
|
||||||
|
|
||||||
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:minWidth="32dp"
|
|
||||||
android:gravity="center"
|
|
||||||
style="?attr/keyPreviewTextViewStyle"
|
|
||||||
/>
|
|
|
@ -26,8 +26,6 @@
|
||||||
<attr name="keyboardViewStyle" format="reference" />
|
<attr name="keyboardViewStyle" format="reference" />
|
||||||
<!-- MainKeyboardView style -->
|
<!-- MainKeyboardView style -->
|
||||||
<attr name="mainKeyboardViewStyle" format="reference" />
|
<attr name="mainKeyboardViewStyle" format="reference" />
|
||||||
<!-- Key preview text view style -->
|
|
||||||
<attr name="keyPreviewTextViewStyle" format="reference"/>
|
|
||||||
<!-- EmojiPalettesView style -->
|
<!-- EmojiPalettesView style -->
|
||||||
<attr name="emojiPalettesViewStyle" format="reference" />
|
<attr name="emojiPalettesViewStyle" format="reference" />
|
||||||
<!-- MoreKeysKeyboard style -->
|
<!-- MoreKeysKeyboard style -->
|
||||||
|
@ -106,8 +104,8 @@
|
||||||
<attr name="longPressShiftLockTimeout" format="integer" />
|
<attr name="longPressShiftLockTimeout" format="integer" />
|
||||||
<!-- Ignore special key timeout while typing in millisecond. -->
|
<!-- Ignore special key timeout while typing in millisecond. -->
|
||||||
<attr name="ignoreAltCodeKeyTimeout" format="integer" />
|
<attr name="ignoreAltCodeKeyTimeout" format="integer" />
|
||||||
<!-- Layout resource for key press feedback.-->
|
<!-- Background resource for key press feedback.-->
|
||||||
<attr name="keyPreviewLayout" format="reference" />
|
<attr name="keyPreviewBackground" format="reference" />
|
||||||
<!-- Vertical offset of the key press feedback from the key. -->
|
<!-- Vertical offset of the key press feedback from the key. -->
|
||||||
<attr name="keyPreviewOffset" format="dimension" />
|
<attr name="keyPreviewOffset" format="dimension" />
|
||||||
<!-- Height of the key press feedback popup. -->
|
<!-- Height of the key press feedback popup. -->
|
||||||
|
|
|
@ -75,7 +75,6 @@
|
||||||
<item name="keyRepeatInterval">@integer/config_key_repeat_interval</item>
|
<item name="keyRepeatInterval">@integer/config_key_repeat_interval</item>
|
||||||
<item name="longPressShiftLockTimeout">@integer/config_longpress_shift_lock_timeout</item>
|
<item name="longPressShiftLockTimeout">@integer/config_longpress_shift_lock_timeout</item>
|
||||||
<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="keyPreviewHeight">@dimen/config_key_preview_height</item>
|
<item name="keyPreviewHeight">@dimen/config_key_preview_height</item>
|
||||||
<!-- TODO: consolidate key preview linger timeout with the key preview animation parameters. -->
|
<!-- TODO: consolidate key preview linger timeout with the key preview animation parameters. -->
|
||||||
<item name="keyPreviewLingerTimeout">@integer/config_key_preview_linger_timeout</item>
|
<item name="keyPreviewLingerTimeout">@integer/config_key_preview_linger_timeout</item>
|
||||||
|
@ -106,7 +105,6 @@
|
||||||
<style
|
<style
|
||||||
name="MainKeyboardView"
|
name="MainKeyboardView"
|
||||||
parent="KeyboardView" />
|
parent="KeyboardView" />
|
||||||
<style name="KeyPreviewTextView" />
|
|
||||||
<!-- Though {@link EmojiPalettesView} doesn't extend {@link KeyboardView}, some views inside it,
|
<!-- Though {@link EmojiPalettesView} doesn't extend {@link KeyboardView}, some views inside it,
|
||||||
for instance delete button, need themed {@link KeyboardView} attributes. -->
|
for instance delete button, need themed {@link KeyboardView} attributes. -->
|
||||||
<style name="EmojiPalettesView" />
|
<style name="EmojiPalettesView" />
|
||||||
|
|
|
@ -23,7 +23,6 @@
|
||||||
<item name="keyboardStyle">@style/Keyboard.ICS</item>
|
<item name="keyboardStyle">@style/Keyboard.ICS</item>
|
||||||
<item name="keyboardViewStyle">@style/KeyboardView.ICS</item>
|
<item name="keyboardViewStyle">@style/KeyboardView.ICS</item>
|
||||||
<item name="mainKeyboardViewStyle">@style/MainKeyboardView.ICS</item>
|
<item name="mainKeyboardViewStyle">@style/MainKeyboardView.ICS</item>
|
||||||
<item name="keyPreviewTextViewStyle">@style/KeyPreviewTextView.ICS</item>
|
|
||||||
<item name="emojiPalettesViewStyle">@style/EmojiPalettesView.ICS</item>
|
<item name="emojiPalettesViewStyle">@style/EmojiPalettesView.ICS</item>
|
||||||
<item name="moreKeysKeyboardStyle">@style/MoreKeysKeyboard.ICS</item>
|
<item name="moreKeysKeyboardStyle">@style/MoreKeysKeyboard.ICS</item>
|
||||||
<item name="moreKeysKeyboardViewStyle">@style/MoreKeysKeyboardView.ICS</item>
|
<item name="moreKeysKeyboardViewStyle">@style/MoreKeysKeyboardView.ICS</item>
|
||||||
|
@ -66,6 +65,7 @@
|
||||||
name="MainKeyboardView.ICS"
|
name="MainKeyboardView.ICS"
|
||||||
parent="KeyboardView.ICS"
|
parent="KeyboardView.ICS"
|
||||||
>
|
>
|
||||||
|
<item name="keyPreviewBackground">@drawable/keyboard_key_feedback_ics</item>
|
||||||
<item name="keyPreviewOffset">@dimen/config_key_preview_offset_holo</item>
|
<item name="keyPreviewOffset">@dimen/config_key_preview_offset_holo</item>
|
||||||
<item name="gestureFloatingPreviewTextColor">@color/highlight_color_ics</item>
|
<item name="gestureFloatingPreviewTextColor">@color/highlight_color_ics</item>
|
||||||
<item name="gestureFloatingPreviewColor">@color/gesture_floating_preview_color_holo</item>
|
<item name="gestureFloatingPreviewColor">@color/gesture_floating_preview_color_holo</item>
|
||||||
|
@ -75,12 +75,6 @@
|
||||||
<item name="languageOnSpacebarTextShadowRadius">1.0</item>
|
<item name="languageOnSpacebarTextShadowRadius">1.0</item>
|
||||||
<item name="languageOnSpacebarTextShadowColor">@color/spacebar_text_shadow_color_holo</item>
|
<item name="languageOnSpacebarTextShadowColor">@color/spacebar_text_shadow_color_holo</item>
|
||||||
</style>
|
</style>
|
||||||
<style
|
|
||||||
name="KeyPreviewTextView.ICS"
|
|
||||||
parent="KeyPreviewTextView"
|
|
||||||
>
|
|
||||||
<item name="android:background">@drawable/keyboard_key_feedback_ics</item>
|
|
||||||
</style>
|
|
||||||
<!-- Though {@link EmojiPalettesView} doesn't extend {@link KeyboardView}, some views inside it,
|
<!-- Though {@link EmojiPalettesView} doesn't extend {@link KeyboardView}, some views inside it,
|
||||||
for instance delete button, need themed {@link KeyboardView} attributes. -->
|
for instance delete button, need themed {@link KeyboardView} attributes. -->
|
||||||
<style
|
<style
|
||||||
|
|
|
@ -23,7 +23,6 @@
|
||||||
<item name="keyboardStyle">@style/Keyboard.KLP</item>
|
<item name="keyboardStyle">@style/Keyboard.KLP</item>
|
||||||
<item name="keyboardViewStyle">@style/KeyboardView.KLP</item>
|
<item name="keyboardViewStyle">@style/KeyboardView.KLP</item>
|
||||||
<item name="mainKeyboardViewStyle">@style/MainKeyboardView.KLP</item>
|
<item name="mainKeyboardViewStyle">@style/MainKeyboardView.KLP</item>
|
||||||
<item name="keyPreviewTextViewStyle">@style/KeyPreviewTextView.KLP</item>
|
|
||||||
<item name="emojiPalettesViewStyle">@style/EmojiPalettesView.KLP</item>
|
<item name="emojiPalettesViewStyle">@style/EmojiPalettesView.KLP</item>
|
||||||
<item name="moreKeysKeyboardStyle">@style/MoreKeysKeyboard.KLP</item>
|
<item name="moreKeysKeyboardStyle">@style/MoreKeysKeyboard.KLP</item>
|
||||||
<item name="moreKeysKeyboardViewStyle">@style/MoreKeysKeyboardView.KLP</item>
|
<item name="moreKeysKeyboardViewStyle">@style/MoreKeysKeyboardView.KLP</item>
|
||||||
|
@ -66,6 +65,7 @@
|
||||||
name="MainKeyboardView.KLP"
|
name="MainKeyboardView.KLP"
|
||||||
parent="KeyboardView.KLP"
|
parent="KeyboardView.KLP"
|
||||||
>
|
>
|
||||||
|
<item name="keyPreviewBackground">@drawable/keyboard_key_feedback_klp</item>
|
||||||
<item name="keyPreviewOffset">@dimen/config_key_preview_offset_holo</item>
|
<item name="keyPreviewOffset">@dimen/config_key_preview_offset_holo</item>
|
||||||
<item name="gestureFloatingPreviewTextColor">@color/highlight_color_klp</item>
|
<item name="gestureFloatingPreviewTextColor">@color/highlight_color_klp</item>
|
||||||
<item name="gestureFloatingPreviewColor">@color/gesture_floating_preview_color_holo</item>
|
<item name="gestureFloatingPreviewColor">@color/gesture_floating_preview_color_holo</item>
|
||||||
|
@ -75,12 +75,6 @@
|
||||||
<item name="languageOnSpacebarTextShadowRadius">1.0</item>
|
<item name="languageOnSpacebarTextShadowRadius">1.0</item>
|
||||||
<item name="languageOnSpacebarTextShadowColor">@color/spacebar_text_shadow_color_holo</item>
|
<item name="languageOnSpacebarTextShadowColor">@color/spacebar_text_shadow_color_holo</item>
|
||||||
</style>
|
</style>
|
||||||
<style
|
|
||||||
name="KeyPreviewTextView.KLP"
|
|
||||||
parent="KeyPreviewTextView"
|
|
||||||
>
|
|
||||||
<item name="android:background">@drawable/keyboard_key_feedback_klp</item>
|
|
||||||
</style>
|
|
||||||
<!-- Though {@link EmojiPalettesView} doesn't extend {@link KeyboardView}, some views inside it,
|
<!-- Though {@link EmojiPalettesView} doesn't extend {@link KeyboardView}, some views inside it,
|
||||||
for instance delete button, need themed {@link KeyboardView} attributes. -->
|
for instance delete button, need themed {@link KeyboardView} attributes. -->
|
||||||
<style
|
<style
|
||||||
|
|
|
@ -23,7 +23,6 @@
|
||||||
<item name="keyboardStyle">@style/Keyboard.LXX_Dark</item>
|
<item name="keyboardStyle">@style/Keyboard.LXX_Dark</item>
|
||||||
<item name="keyboardViewStyle">@style/KeyboardView.LXX_Dark</item>
|
<item name="keyboardViewStyle">@style/KeyboardView.LXX_Dark</item>
|
||||||
<item name="mainKeyboardViewStyle">@style/MainKeyboardView.LXX_Dark</item>
|
<item name="mainKeyboardViewStyle">@style/MainKeyboardView.LXX_Dark</item>
|
||||||
<item name="keyPreviewTextViewStyle">@style/KeyPreviewTextView.LXX_Dark</item>
|
|
||||||
<item name="emojiPalettesViewStyle">@style/EmojiPalettesView.LXX_Dark</item>
|
<item name="emojiPalettesViewStyle">@style/EmojiPalettesView.LXX_Dark</item>
|
||||||
<item name="moreKeysKeyboardStyle">@style/MoreKeysKeyboard.LXX_Dark</item>
|
<item name="moreKeysKeyboardStyle">@style/MoreKeysKeyboard.LXX_Dark</item>
|
||||||
<item name="moreKeysKeyboardViewStyle">@style/MoreKeysKeyboardView.LXX_Dark</item>
|
<item name="moreKeysKeyboardViewStyle">@style/MoreKeysKeyboardView.LXX_Dark</item>
|
||||||
|
@ -67,6 +66,7 @@
|
||||||
name="MainKeyboardView.LXX_Dark"
|
name="MainKeyboardView.LXX_Dark"
|
||||||
parent="KeyboardView.LXX_Dark"
|
parent="KeyboardView.LXX_Dark"
|
||||||
>
|
>
|
||||||
|
<item name="keyPreviewBackground">@drawable/keyboard_key_feedback_lxx_dark</item>
|
||||||
<item name="keyPreviewOffset">@dimen/config_key_preview_offset_holo</item>
|
<item name="keyPreviewOffset">@dimen/config_key_preview_offset_holo</item>
|
||||||
<item name="gestureFloatingPreviewTextColor">@color/highlight_color_lxx_dark</item>
|
<item name="gestureFloatingPreviewTextColor">@color/highlight_color_lxx_dark</item>
|
||||||
<item name="gestureFloatingPreviewColor">@color/gesture_floating_preview_color_lxx_dark</item>
|
<item name="gestureFloatingPreviewColor">@color/gesture_floating_preview_color_lxx_dark</item>
|
||||||
|
@ -76,12 +76,6 @@
|
||||||
<!-- A negative value to disable text shadow layer. -->
|
<!-- A negative value to disable text shadow layer. -->
|
||||||
<item name="languageOnSpacebarTextShadowRadius">-1.0</item>
|
<item name="languageOnSpacebarTextShadowRadius">-1.0</item>
|
||||||
</style>
|
</style>
|
||||||
<style
|
|
||||||
name="KeyPreviewTextView.LXX_Dark"
|
|
||||||
parent="KeyPreviewTextView"
|
|
||||||
>
|
|
||||||
<item name="android:background">@drawable/keyboard_key_feedback_lxx_dark</item>
|
|
||||||
</style>
|
|
||||||
<!-- Though {@link EmojiPalettesView} doesn't extend {@link KeyboardView}, some views inside it,
|
<!-- Though {@link EmojiPalettesView} doesn't extend {@link KeyboardView}, some views inside it,
|
||||||
for instance delete button, need themed {@link KeyboardView} attributes. -->
|
for instance delete button, need themed {@link KeyboardView} attributes. -->
|
||||||
<style
|
<style
|
||||||
|
|
|
@ -21,17 +21,12 @@ import android.animation.AnimatorListenerAdapter;
|
||||||
import android.animation.AnimatorSet;
|
import android.animation.AnimatorSet;
|
||||||
import android.animation.ObjectAnimator;
|
import android.animation.ObjectAnimator;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.graphics.drawable.Drawable;
|
|
||||||
import android.util.TypedValue;
|
|
||||||
import android.view.LayoutInflater;
|
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.view.animation.AccelerateInterpolator;
|
import android.view.animation.AccelerateInterpolator;
|
||||||
import android.view.animation.DecelerateInterpolator;
|
import android.view.animation.DecelerateInterpolator;
|
||||||
import android.widget.TextView;
|
|
||||||
|
|
||||||
import com.android.inputmethod.keyboard.Key;
|
import com.android.inputmethod.keyboard.Key;
|
||||||
import com.android.inputmethod.latin.R;
|
|
||||||
import com.android.inputmethod.latin.utils.CoordinateUtils;
|
import com.android.inputmethod.latin.utils.CoordinateUtils;
|
||||||
import com.android.inputmethod.latin.utils.ViewLayoutUtils;
|
import com.android.inputmethod.latin.utils.ViewLayoutUtils;
|
||||||
|
|
||||||
|
@ -46,10 +41,11 @@ import java.util.HashSet;
|
||||||
* - how key previews should be shown and dismissed.
|
* - how key previews should be shown and dismissed.
|
||||||
*/
|
*/
|
||||||
public final class KeyPreviewChoreographer {
|
public final class KeyPreviewChoreographer {
|
||||||
// Free {@link TextView} pool that can be used for key preview.
|
// Free {@link KeyPreviewView} pool that can be used for key preview.
|
||||||
private final ArrayDeque<TextView> mFreeKeyPreviewTextViews = new ArrayDeque<>();
|
private final ArrayDeque<KeyPreviewView> mFreeKeyPreviewViews = new ArrayDeque<>();
|
||||||
// Map from {@link Key} to {@link TextView} that is currently being displayed as key preview.
|
// Map from {@link Key} to {@link KeyPreviewView} that is currently being displayed as key
|
||||||
private final HashMap<Key,TextView> mShowingKeyPreviewTextViews = new HashMap<>();
|
// preview.
|
||||||
|
private final HashMap<Key,KeyPreviewView> mShowingKeyPreviewViews = new HashMap<>();
|
||||||
|
|
||||||
private final KeyPreviewDrawParams mParams;
|
private final KeyPreviewDrawParams mParams;
|
||||||
|
|
||||||
|
@ -57,32 +53,28 @@ public final class KeyPreviewChoreographer {
|
||||||
mParams = params;
|
mParams = params;
|
||||||
}
|
}
|
||||||
|
|
||||||
private TextView getKeyPreviewTextView(final Key key, final ViewGroup placerView) {
|
public KeyPreviewView getKeyPreviewView(final Key key, final ViewGroup placerView) {
|
||||||
TextView previewTextView = mShowingKeyPreviewTextViews.remove(key);
|
KeyPreviewView keyPreviewView = mShowingKeyPreviewViews.remove(key);
|
||||||
if (previewTextView != null) {
|
if (keyPreviewView != null) {
|
||||||
return previewTextView;
|
return keyPreviewView;
|
||||||
}
|
}
|
||||||
previewTextView = mFreeKeyPreviewTextViews.poll();
|
keyPreviewView = mFreeKeyPreviewViews.poll();
|
||||||
if (previewTextView != null) {
|
if (keyPreviewView != null) {
|
||||||
return previewTextView;
|
return keyPreviewView;
|
||||||
}
|
}
|
||||||
final Context context = placerView.getContext();
|
final Context context = placerView.getContext();
|
||||||
if (mParams.mLayoutId != 0) {
|
keyPreviewView = new KeyPreviewView(context, null /* attrs */);
|
||||||
previewTextView = (TextView)LayoutInflater.from(context)
|
keyPreviewView.setBackgroundResource(mParams.mPreviewBackgroundResId);
|
||||||
.inflate(mParams.mLayoutId, null);
|
placerView.addView(keyPreviewView, ViewLayoutUtils.newLayoutParam(placerView, 0, 0));
|
||||||
} else {
|
return keyPreviewView;
|
||||||
previewTextView = new TextView(context);
|
|
||||||
}
|
|
||||||
placerView.addView(previewTextView, ViewLayoutUtils.newLayoutParam(placerView, 0, 0));
|
|
||||||
return previewTextView;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isShowingKeyPreview(final Key key) {
|
public boolean isShowingKeyPreview(final Key key) {
|
||||||
return mShowingKeyPreviewTextViews.containsKey(key);
|
return mShowingKeyPreviewViews.containsKey(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void dismissAllKeyPreviews() {
|
public void dismissAllKeyPreviews() {
|
||||||
for (final Key key : new HashSet<>(mShowingKeyPreviewTextViews.keySet())) {
|
for (final Key key : new HashSet<>(mShowingKeyPreviewViews.keySet())) {
|
||||||
dismissKeyPreview(key, false /* withAnimation */);
|
dismissKeyPreview(key, false /* withAnimation */);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -91,11 +83,11 @@ public final class KeyPreviewChoreographer {
|
||||||
if (key == null) {
|
if (key == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
final TextView previewTextView = mShowingKeyPreviewTextViews.get(key);
|
final KeyPreviewView keyPreviewView = mShowingKeyPreviewViews.get(key);
|
||||||
if (previewTextView == null) {
|
if (keyPreviewView == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
final Object tag = previewTextView.getTag();
|
final Object tag = keyPreviewView.getTag();
|
||||||
if (withAnimation) {
|
if (withAnimation) {
|
||||||
if (tag instanceof KeyPreviewAnimations) {
|
if (tag instanceof KeyPreviewAnimations) {
|
||||||
final KeyPreviewAnimations animation = (KeyPreviewAnimations)tag;
|
final KeyPreviewAnimations animation = (KeyPreviewAnimations)tag;
|
||||||
|
@ -104,114 +96,76 @@ public final class KeyPreviewChoreographer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Dismiss preview without animation.
|
// Dismiss preview without animation.
|
||||||
mShowingKeyPreviewTextViews.remove(key);
|
mShowingKeyPreviewViews.remove(key);
|
||||||
if (tag instanceof Animator) {
|
if (tag instanceof Animator) {
|
||||||
((Animator)tag).cancel();
|
((Animator)tag).cancel();
|
||||||
}
|
}
|
||||||
previewTextView.setTag(null);
|
keyPreviewView.setTag(null);
|
||||||
previewTextView.setVisibility(View.INVISIBLE);
|
keyPreviewView.setVisibility(View.INVISIBLE);
|
||||||
mFreeKeyPreviewTextViews.add(previewTextView);
|
mFreeKeyPreviewViews.add(keyPreviewView);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Background state set
|
|
||||||
private static final int[][][] KEY_PREVIEW_BACKGROUND_STATE_TABLE = {
|
|
||||||
{ // STATE_MIDDLE
|
|
||||||
{},
|
|
||||||
{ R.attr.state_has_morekeys }
|
|
||||||
},
|
|
||||||
{ // STATE_LEFT
|
|
||||||
{ R.attr.state_left_edge },
|
|
||||||
{ R.attr.state_left_edge, R.attr.state_has_morekeys }
|
|
||||||
},
|
|
||||||
{ // STATE_RIGHT
|
|
||||||
{ R.attr.state_right_edge },
|
|
||||||
{ R.attr.state_right_edge, R.attr.state_has_morekeys }
|
|
||||||
}
|
|
||||||
};
|
|
||||||
private static final int STATE_MIDDLE = 0;
|
|
||||||
private static final int STATE_LEFT = 1;
|
|
||||||
private static final int STATE_RIGHT = 2;
|
|
||||||
private static final int STATE_NORMAL = 0;
|
|
||||||
private static final int STATE_HAS_MOREKEYS = 1;
|
|
||||||
|
|
||||||
public void placeKeyPreviewAndShow(final Key key, final KeyboardIconsSet iconsSet,
|
public void placeKeyPreviewAndShow(final Key key, final KeyboardIconsSet iconsSet,
|
||||||
final KeyDrawParams drawParams, final int keyboardViewWidth, final int[] keyboardOrigin,
|
final KeyDrawParams drawParams, final int keyboardViewWidth, final int[] keyboardOrigin,
|
||||||
final ViewGroup placerView, final boolean withAnimation) {
|
final ViewGroup placerView, final boolean withAnimation) {
|
||||||
final TextView previewTextView = getKeyPreviewTextView(key, placerView);
|
final KeyPreviewView keyPreviewView = getKeyPreviewView(key, placerView);
|
||||||
placeKeyPreview(
|
placeKeyPreview(
|
||||||
key, previewTextView, iconsSet, drawParams, keyboardViewWidth, keyboardOrigin);
|
key, keyPreviewView, iconsSet, drawParams, keyboardViewWidth, keyboardOrigin);
|
||||||
showKeyPreview(key, previewTextView, withAnimation);
|
showKeyPreview(key, keyPreviewView, withAnimation);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void placeKeyPreview(final Key key, final TextView previewTextView,
|
private void placeKeyPreview(final Key key, final KeyPreviewView keyPreviewView,
|
||||||
final KeyboardIconsSet iconsSet, final KeyDrawParams drawParams,
|
final KeyboardIconsSet iconsSet, final KeyDrawParams drawParams,
|
||||||
final int keyboardViewWidth, final int[] originCoords) {
|
final int keyboardViewWidth, final int[] originCoords) {
|
||||||
previewTextView.setTextColor(drawParams.mPreviewTextColor);
|
keyPreviewView.setPreviewVisual(key, iconsSet, drawParams);
|
||||||
final Drawable background = previewTextView.getBackground();
|
keyPreviewView.measure(
|
||||||
final String label = key.getPreviewLabel();
|
|
||||||
// What we show as preview should match what we show on a key top in onDraw().
|
|
||||||
if (label != null) {
|
|
||||||
// TODO Should take care of temporaryShiftLabel here.
|
|
||||||
previewTextView.setCompoundDrawables(null, null, null, null);
|
|
||||||
previewTextView.setTextSize(TypedValue.COMPLEX_UNIT_PX,
|
|
||||||
key.selectPreviewTextSize(drawParams));
|
|
||||||
previewTextView.setTypeface(key.selectPreviewTypeface(drawParams));
|
|
||||||
previewTextView.setText(label);
|
|
||||||
} else {
|
|
||||||
previewTextView.setCompoundDrawables(null, null, null, key.getPreviewIcon(iconsSet));
|
|
||||||
previewTextView.setText(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
previewTextView.measure(
|
|
||||||
ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
|
ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
|
||||||
mParams.setGeometry(previewTextView);
|
mParams.setGeometry(keyPreviewView);
|
||||||
final int previewWidth = previewTextView.getMeasuredWidth();
|
final int previewWidth = keyPreviewView.getMeasuredWidth();
|
||||||
final int previewHeight = mParams.mPreviewHeight;
|
final int previewHeight = mParams.mPreviewHeight;
|
||||||
final int keyDrawWidth = key.getDrawWidth();
|
final int keyDrawWidth = key.getDrawWidth();
|
||||||
// The key preview is horizontally aligned with the center of the visible part of the
|
// The key preview is horizontally aligned with the center of the visible part of the
|
||||||
// parent key. If it doesn't fit in this {@link KeyboardView}, it is moved inward to fit and
|
// parent key. If it doesn't fit in this {@link KeyboardView}, it is moved inward to fit and
|
||||||
// the left/right background is used if such background is specified.
|
// the left/right background is used if such background is specified.
|
||||||
final int statePosition;
|
final int keyPreviewPosition;
|
||||||
int previewX = key.getDrawX() - (previewWidth - keyDrawWidth) / 2
|
int previewX = key.getDrawX() - (previewWidth - keyDrawWidth) / 2
|
||||||
+ CoordinateUtils.x(originCoords);
|
+ CoordinateUtils.x(originCoords);
|
||||||
if (previewX < 0) {
|
if (previewX < 0) {
|
||||||
previewX = 0;
|
previewX = 0;
|
||||||
statePosition = STATE_LEFT;
|
keyPreviewPosition = KeyPreviewView.POSITION_LEFT;
|
||||||
} else if (previewX > keyboardViewWidth - previewWidth) {
|
} else if (previewX > keyboardViewWidth - previewWidth) {
|
||||||
previewX = keyboardViewWidth - previewWidth;
|
previewX = keyboardViewWidth - previewWidth;
|
||||||
statePosition = STATE_RIGHT;
|
keyPreviewPosition = KeyPreviewView.POSITION_RIGHT;
|
||||||
} else {
|
} else {
|
||||||
statePosition = STATE_MIDDLE;
|
keyPreviewPosition = KeyPreviewView.POSITION_MIDDLE;
|
||||||
}
|
}
|
||||||
|
final boolean hasMoreKeys = (key.getMoreKeys() != null);
|
||||||
|
keyPreviewView.setPreviewBackground(hasMoreKeys, keyPreviewPosition);
|
||||||
// The key preview is placed vertically above the top edge of the parent key with an
|
// The key preview is placed vertically above the top edge of the parent key with an
|
||||||
// arbitrary offset.
|
// arbitrary offset.
|
||||||
final int previewY = key.getY() - previewHeight + mParams.mPreviewOffset
|
final int previewY = key.getY() - previewHeight + mParams.mPreviewOffset
|
||||||
+ CoordinateUtils.y(originCoords);
|
+ CoordinateUtils.y(originCoords);
|
||||||
|
|
||||||
if (background != null) {
|
|
||||||
final int hasMoreKeys = (key.getMoreKeys() != null) ? STATE_HAS_MOREKEYS : STATE_NORMAL;
|
|
||||||
background.setState(KEY_PREVIEW_BACKGROUND_STATE_TABLE[statePosition][hasMoreKeys]);
|
|
||||||
}
|
|
||||||
ViewLayoutUtils.placeViewAt(
|
ViewLayoutUtils.placeViewAt(
|
||||||
previewTextView, previewX, previewY, previewWidth, previewHeight);
|
keyPreviewView, previewX, previewY, previewWidth, previewHeight);
|
||||||
previewTextView.setPivotX(previewWidth / 2.0f);
|
keyPreviewView.setPivotX(previewWidth / 2.0f);
|
||||||
previewTextView.setPivotY(previewHeight);
|
keyPreviewView.setPivotY(previewHeight);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void showKeyPreview(final Key key, final TextView previewTextView,
|
private void showKeyPreview(final Key key, final KeyPreviewView keyPreviewView,
|
||||||
final boolean withAnimation) {
|
final boolean withAnimation) {
|
||||||
if (!withAnimation) {
|
if (!withAnimation) {
|
||||||
previewTextView.setVisibility(View.VISIBLE);
|
keyPreviewView.setVisibility(View.VISIBLE);
|
||||||
mShowingKeyPreviewTextViews.put(key, previewTextView);
|
mShowingKeyPreviewViews.put(key, keyPreviewView);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Show preview with animation.
|
// Show preview with animation.
|
||||||
final Animator showUpAnimation = createShowUpAniation(key, previewTextView);
|
final Animator showUpAnimation = createShowUpAniation(key, keyPreviewView);
|
||||||
final Animator dismissAnimation = createDismissAnimation(key, previewTextView);
|
final Animator dismissAnimation = createDismissAnimation(key, keyPreviewView);
|
||||||
final KeyPreviewAnimations animation = new KeyPreviewAnimations(
|
final KeyPreviewAnimations animation = new KeyPreviewAnimations(
|
||||||
showUpAnimation, dismissAnimation);
|
showUpAnimation, dismissAnimation);
|
||||||
previewTextView.setTag(animation);
|
keyPreviewView.setTag(animation);
|
||||||
animation.startShowUp();
|
animation.startShowUp();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -221,13 +175,13 @@ public final class KeyPreviewChoreographer {
|
||||||
private static final DecelerateInterpolator DECELERATE_INTERPOLATOR =
|
private static final DecelerateInterpolator DECELERATE_INTERPOLATOR =
|
||||||
new DecelerateInterpolator();
|
new DecelerateInterpolator();
|
||||||
|
|
||||||
private Animator createShowUpAniation(final Key key, final TextView previewTextView) {
|
private Animator createShowUpAniation(final Key key, final KeyPreviewView keyPreviewView) {
|
||||||
// TODO: Optimization for no scale animation and no duration.
|
// TODO: Optimization for no scale animation and no duration.
|
||||||
final ObjectAnimator scaleXAnimation = ObjectAnimator.ofFloat(
|
final ObjectAnimator scaleXAnimation = ObjectAnimator.ofFloat(
|
||||||
previewTextView, View.SCALE_X, mParams.getShowUpStartScale(),
|
keyPreviewView, View.SCALE_X, mParams.getShowUpStartScale(),
|
||||||
KEY_PREVIEW_SHOW_UP_END_SCALE);
|
KEY_PREVIEW_SHOW_UP_END_SCALE);
|
||||||
final ObjectAnimator scaleYAnimation = ObjectAnimator.ofFloat(
|
final ObjectAnimator scaleYAnimation = ObjectAnimator.ofFloat(
|
||||||
previewTextView, View.SCALE_Y, mParams.getShowUpStartScale(),
|
keyPreviewView, View.SCALE_Y, mParams.getShowUpStartScale(),
|
||||||
KEY_PREVIEW_SHOW_UP_END_SCALE);
|
KEY_PREVIEW_SHOW_UP_END_SCALE);
|
||||||
final AnimatorSet showUpAnimation = new AnimatorSet();
|
final AnimatorSet showUpAnimation = new AnimatorSet();
|
||||||
showUpAnimation.play(scaleXAnimation).with(scaleYAnimation);
|
showUpAnimation.play(scaleXAnimation).with(scaleYAnimation);
|
||||||
|
@ -236,18 +190,18 @@ public final class KeyPreviewChoreographer {
|
||||||
showUpAnimation.addListener(new AnimatorListenerAdapter() {
|
showUpAnimation.addListener(new AnimatorListenerAdapter() {
|
||||||
@Override
|
@Override
|
||||||
public void onAnimationStart(final Animator animation) {
|
public void onAnimationStart(final Animator animation) {
|
||||||
showKeyPreview(key, previewTextView, false /* withAnimation */);
|
showKeyPreview(key, keyPreviewView, false /* withAnimation */);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return showUpAnimation;
|
return showUpAnimation;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Animator createDismissAnimation(final Key key, final TextView previewTextView) {
|
private Animator createDismissAnimation(final Key key, final KeyPreviewView keyPreviewView) {
|
||||||
// TODO: Optimization for no scale animation and no duration.
|
// TODO: Optimization for no scale animation and no duration.
|
||||||
final ObjectAnimator scaleXAnimation = ObjectAnimator.ofFloat(
|
final ObjectAnimator scaleXAnimation = ObjectAnimator.ofFloat(
|
||||||
previewTextView, View.SCALE_X, mParams.getDismissEndScale());
|
keyPreviewView, View.SCALE_X, mParams.getDismissEndScale());
|
||||||
final ObjectAnimator scaleYAnimation = ObjectAnimator.ofFloat(
|
final ObjectAnimator scaleYAnimation = ObjectAnimator.ofFloat(
|
||||||
previewTextView, View.SCALE_Y, mParams.getDismissEndScale());
|
keyPreviewView, View.SCALE_Y, mParams.getDismissEndScale());
|
||||||
final AnimatorSet dismissAnimation = new AnimatorSet();
|
final AnimatorSet dismissAnimation = new AnimatorSet();
|
||||||
dismissAnimation.play(scaleXAnimation).with(scaleYAnimation);
|
dismissAnimation.play(scaleXAnimation).with(scaleYAnimation);
|
||||||
final int dismissDuration = Math.min(
|
final int dismissDuration = Math.min(
|
||||||
|
|
|
@ -23,9 +23,9 @@ import com.android.inputmethod.latin.R;
|
||||||
|
|
||||||
public final class KeyPreviewDrawParams {
|
public final class KeyPreviewDrawParams {
|
||||||
// XML attributes of {@link MainKeyboardView}.
|
// XML attributes of {@link MainKeyboardView}.
|
||||||
public final int mLayoutId;
|
|
||||||
public final int mPreviewOffset;
|
public final int mPreviewOffset;
|
||||||
public final int mPreviewHeight;
|
public final int mPreviewHeight;
|
||||||
|
public final int mPreviewBackgroundResId;
|
||||||
private int mShowUpDuration;
|
private int mShowUpDuration;
|
||||||
private int mDismissDuration;
|
private int mDismissDuration;
|
||||||
private float mShowUpStartScale;
|
private float mShowUpStartScale;
|
||||||
|
@ -63,13 +63,10 @@ public final class KeyPreviewDrawParams {
|
||||||
R.styleable.MainKeyboardView_keyPreviewOffset, 0);
|
R.styleable.MainKeyboardView_keyPreviewOffset, 0);
|
||||||
mPreviewHeight = mainKeyboardViewAttr.getDimensionPixelSize(
|
mPreviewHeight = mainKeyboardViewAttr.getDimensionPixelSize(
|
||||||
R.styleable.MainKeyboardView_keyPreviewHeight, 0);
|
R.styleable.MainKeyboardView_keyPreviewHeight, 0);
|
||||||
|
mPreviewBackgroundResId = mainKeyboardViewAttr.getResourceId(
|
||||||
|
R.styleable.MainKeyboardView_keyPreviewBackground, 0);
|
||||||
mLingerTimeout = mainKeyboardViewAttr.getInt(
|
mLingerTimeout = mainKeyboardViewAttr.getInt(
|
||||||
R.styleable.MainKeyboardView_keyPreviewLingerTimeout, 0);
|
R.styleable.MainKeyboardView_keyPreviewLingerTimeout, 0);
|
||||||
mLayoutId = mainKeyboardViewAttr.getResourceId(
|
|
||||||
R.styleable.MainKeyboardView_keyPreviewLayout, 0);
|
|
||||||
if (mLayoutId == 0) {
|
|
||||||
mShowPopup = false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setVisibleOffset(final int previewVisibleOffset) {
|
public void setVisibleOffset(final int previewVisibleOffset) {
|
||||||
|
|
|
@ -0,0 +1,90 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2014 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.android.inputmethod.keyboard.internal;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.graphics.drawable.Drawable;
|
||||||
|
import android.util.AttributeSet;
|
||||||
|
import android.util.TypedValue;
|
||||||
|
import android.view.Gravity;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import com.android.inputmethod.keyboard.Key;
|
||||||
|
import com.android.inputmethod.latin.R;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The pop up key preview view.
|
||||||
|
*/
|
||||||
|
public class KeyPreviewView extends TextView {
|
||||||
|
public static final int POSITION_MIDDLE = 0;
|
||||||
|
public static final int POSITION_LEFT = 1;
|
||||||
|
public static final int POSITION_RIGHT = 2;
|
||||||
|
|
||||||
|
public KeyPreviewView(final Context context, final AttributeSet attrs) {
|
||||||
|
this(context, attrs, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public KeyPreviewView(final Context context, final AttributeSet attrs, final int defStyleAttr) {
|
||||||
|
super(context, attrs, defStyleAttr);
|
||||||
|
setGravity(Gravity.CENTER);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPreviewVisual(final Key key, final KeyboardIconsSet iconsSet,
|
||||||
|
final KeyDrawParams drawParams) {
|
||||||
|
// What we show as preview should match what we show on a key top in onDraw().
|
||||||
|
final int iconId = key.getIconId();
|
||||||
|
if (iconId != KeyboardIconsSet.ICON_UNDEFINED) {
|
||||||
|
setCompoundDrawables(null, null, null, key.getPreviewIcon(iconsSet));
|
||||||
|
setText(null);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
setCompoundDrawables(null, null, null, null);
|
||||||
|
setTextColor(drawParams.mPreviewTextColor);
|
||||||
|
setTextSize(TypedValue.COMPLEX_UNIT_PX, key.selectPreviewTextSize(drawParams));
|
||||||
|
setTypeface(key.selectPreviewTypeface(drawParams));
|
||||||
|
// TODO Should take care of temporaryShiftLabel here.
|
||||||
|
setText(key.getPreviewLabel());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Background state set
|
||||||
|
private static final int[][][] KEY_PREVIEW_BACKGROUND_STATE_TABLE = {
|
||||||
|
{ // POSITION_MIDDLE
|
||||||
|
{},
|
||||||
|
{ R.attr.state_has_morekeys }
|
||||||
|
},
|
||||||
|
{ // POSITION_LEFT
|
||||||
|
{ R.attr.state_left_edge },
|
||||||
|
{ R.attr.state_left_edge, R.attr.state_has_morekeys }
|
||||||
|
},
|
||||||
|
{ // POSITION_RIGHT
|
||||||
|
{ R.attr.state_right_edge },
|
||||||
|
{ R.attr.state_right_edge, R.attr.state_has_morekeys }
|
||||||
|
}
|
||||||
|
};
|
||||||
|
private static final int STATE_NORMAL = 0;
|
||||||
|
private static final int STATE_HAS_MOREKEYS = 1;
|
||||||
|
|
||||||
|
public void setPreviewBackground(final boolean hasMoreKeys, final int position) {
|
||||||
|
final Drawable background = getBackground();
|
||||||
|
if (background == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
final int hasMoreKeysState = hasMoreKeys ? STATE_HAS_MOREKEYS : STATE_NORMAL;
|
||||||
|
background.setState(KEY_PREVIEW_BACKGROUND_STATE_TABLE[position][hasMoreKeysState]);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue