Trigger haptic feedback at touch down on the EmojiPalettesView

EmojiPalettesView triggers the haptic feedback at the timing of touch-up rather than touch-down.
This patch set changes the timing to touch-up so that the UX on the EmojiPalettesView can be consistent with normal keyboard layouts.

This patch set also fixes the missing haptic feedback from facemarks such as ":-)".

Bug: 11439600
Change-Id: I22245946712bd1c36226786d6ff81e3b563f7ef7
main
Yohei Yukawa 2014-01-08 16:39:55 +09:00
parent 6d5f9fd3d1
commit df10aeb1da
2 changed files with 54 additions and 32 deletions

View File

@ -71,8 +71,8 @@ import java.util.concurrent.ConcurrentHashMap;
* Because of the above reasons, this class doesn't extend {@link KeyboardView}. * Because of the above reasons, this class doesn't extend {@link KeyboardView}.
*/ */
public final class EmojiPalettesView extends LinearLayout implements OnTabChangeListener, public final class EmojiPalettesView extends LinearLayout implements OnTabChangeListener,
ViewPager.OnPageChangeListener, View.OnClickListener, ViewPager.OnPageChangeListener, View.OnTouchListener,
EmojiPageKeyboardView.OnKeyClickListener { EmojiPageKeyboardView.OnKeyEventListener {
static final String TAG = EmojiPalettesView.class.getSimpleName(); static final String TAG = EmojiPalettesView.class.getSimpleName();
private static final boolean DEBUG_PAGER = false; private static final boolean DEBUG_PAGER = false;
private final int mKeyBackgroundId; private final int mKeyBackgroundId;
@ -486,16 +486,16 @@ public final class EmojiPalettesView extends LinearLayout implements OnTabChange
final ImageView alphabetKey = (ImageView)findViewById(R.id.emoji_keyboard_alphabet); final ImageView alphabetKey = (ImageView)findViewById(R.id.emoji_keyboard_alphabet);
alphabetKey.setBackgroundResource(mEmojiFunctionalKeyBackgroundId); alphabetKey.setBackgroundResource(mEmojiFunctionalKeyBackgroundId);
alphabetKey.setTag(Constants.CODE_SWITCH_ALPHA_SYMBOL); alphabetKey.setTag(Constants.CODE_SWITCH_ALPHA_SYMBOL);
alphabetKey.setOnClickListener(this); alphabetKey.setOnTouchListener(this);
final ImageView spaceKey = (ImageView)findViewById(R.id.emoji_keyboard_space); final ImageView spaceKey = (ImageView)findViewById(R.id.emoji_keyboard_space);
spaceKey.setBackgroundResource(mKeyBackgroundId); spaceKey.setBackgroundResource(mKeyBackgroundId);
spaceKey.setTag(Constants.CODE_SPACE); spaceKey.setTag(Constants.CODE_SPACE);
spaceKey.setOnClickListener(this); spaceKey.setOnTouchListener(this);
mEmojiLayoutParams.setKeyProperties(spaceKey); mEmojiLayoutParams.setKeyProperties(spaceKey);
final ImageView alphabetKey2 = (ImageView)findViewById(R.id.emoji_keyboard_alphabet2); final ImageView alphabetKey2 = (ImageView)findViewById(R.id.emoji_keyboard_alphabet2);
alphabetKey2.setBackgroundResource(mEmojiFunctionalKeyBackgroundId); alphabetKey2.setBackgroundResource(mEmojiFunctionalKeyBackgroundId);
alphabetKey2.setTag(Constants.CODE_SWITCH_ALPHA_SYMBOL); alphabetKey2.setTag(Constants.CODE_SWITCH_ALPHA_SYMBOL);
alphabetKey2.setOnClickListener(this); alphabetKey2.setOnTouchListener(this);
} }
@Override @Override
@ -543,31 +543,51 @@ public final class EmojiPalettesView extends LinearLayout implements OnTabChange
} }
} }
// Called from {@link EmojiPageKeyboardView} through {@link View.OnTouchListener} interface to
// handle touch events from View-based elements such as the space bar.
@Override @Override
public void onClick(final View v) { public boolean onTouch(final View v, final MotionEvent event) {
if (v.getTag() instanceof Integer) { final Object tag = v.getTag();
final int code = (Integer)v.getTag(); if (!(tag instanceof Integer)) {
registerCode(code); return false;
return;
} }
final int code = (Integer) tag;
switch(event.getAction()) {
case MotionEvent.ACTION_DOWN:
mKeyboardActionListener.onPressKey(
code, 0 /* repeatCount */, true /* isSinglePointer */);
break;
case MotionEvent.ACTION_UP:
mKeyboardActionListener.onCodeInput(code, NOT_A_COORDINATE, NOT_A_COORDINATE);
mKeyboardActionListener.onReleaseKey(code, false /* withSliding */);
break;
}
return false;
} }
private void registerCode(final int code) { // Called from {@link EmojiPageKeyboardView} through
mKeyboardActionListener.onPressKey(code, 0 /* repeatCount */, true /* isSinglePointer */); // {@link EmojiPageKeyboardView.OnKeyEventListener} interface to handle touch events from
mKeyboardActionListener.onCodeInput(code, NOT_A_COORDINATE, NOT_A_COORDINATE); // non-View-based elements like typical Emoji characters.
mKeyboardActionListener.onReleaseKey(code, false /* withSliding */);
}
@Override @Override
public void onKeyClick(final Key key) { public void onPressKey(final Key key) {
final int code = key.getCode();
mKeyboardActionListener.onPressKey(code, 0 /* repeatCount */, true /* isSinglePointer */);
}
// Called from {@link EmojiPageKeyboardView} through
// {@link EmojiPageKeyboardView.OnKeyEventListener} interface to handle touch events from
// non-View-based elements like typical Emoji characters.
@Override
public void onReleaseKey(final Key key) {
mEmojiPalettesAdapter.addRecentKey(key); mEmojiPalettesAdapter.addRecentKey(key);
mEmojiCategory.saveLastTypedCategoryPage(); mEmojiCategory.saveLastTypedCategoryPage();
final int code = key.getCode(); final int code = key.getCode();
if (code == Constants.CODE_OUTPUT_TEXT) { if (code == Constants.CODE_OUTPUT_TEXT) {
mKeyboardActionListener.onTextInput(key.getOutputText()); mKeyboardActionListener.onTextInput(key.getOutputText());
return; } else {
mKeyboardActionListener.onCodeInput(code, NOT_A_COORDINATE, NOT_A_COORDINATE);
} }
registerCode(code); mKeyboardActionListener.onReleaseKey(code, false /* withSliding */);
} }
public void setHardwareAcceleratedDrawingEnabled(final boolean enabled) { public void setHardwareAcceleratedDrawingEnabled(final boolean enabled) {
@ -630,7 +650,7 @@ public final class EmojiPalettesView extends LinearLayout implements OnTabChange
} }
private static class EmojiPalettesAdapter extends PagerAdapter { private static class EmojiPalettesAdapter extends PagerAdapter {
private final EmojiPageKeyboardView.OnKeyClickListener mListener; private final EmojiPageKeyboardView.OnKeyEventListener mListener;
private final DynamicGridKeyboard mRecentsKeyboard; private final DynamicGridKeyboard mRecentsKeyboard;
private final SparseArray<EmojiPageKeyboardView> mActiveKeyboardViews = private final SparseArray<EmojiPageKeyboardView> mActiveKeyboardViews =
CollectionUtils.newSparseArray(); CollectionUtils.newSparseArray();
@ -638,7 +658,7 @@ public final class EmojiPalettesView extends LinearLayout implements OnTabChange
private int mActivePosition = 0; private int mActivePosition = 0;
public EmojiPalettesAdapter(final EmojiCategory emojiCategory, public EmojiPalettesAdapter(final EmojiCategory emojiCategory,
final EmojiPageKeyboardView.OnKeyClickListener listener) { final EmojiPageKeyboardView.OnKeyEventListener listener) {
mEmojiCategory = emojiCategory; mEmojiCategory = emojiCategory;
mListener = listener; mListener = listener;
mRecentsKeyboard = mEmojiCategory.getKeyboard(CATEGORY_ID_RECENTS, 0); mRecentsKeyboard = mEmojiCategory.getKeyboard(CATEGORY_ID_RECENTS, 0);
@ -702,7 +722,7 @@ public final class EmojiPalettesView extends LinearLayout implements OnTabChange
final EmojiPageKeyboardView keyboardView = (EmojiPageKeyboardView)inflater.inflate( final EmojiPageKeyboardView keyboardView = (EmojiPageKeyboardView)inflater.inflate(
R.layout.emoji_keyboard_page, container, false /* attachToRoot */); R.layout.emoji_keyboard_page, container, false /* attachToRoot */);
keyboardView.setKeyboard(keyboard); keyboardView.setKeyboard(keyboard);
keyboardView.setOnKeyClickListener(mListener); keyboardView.setOnKeyEventListener(mListener);
container.addView(keyboardView); container.addView(keyboardView);
mActiveKeyboardViews.put(position, keyboardView); mActiveKeyboardViews.put(position, keyboardView);
return keyboardView; return keyboardView;

View File

@ -35,16 +35,19 @@ import com.android.inputmethod.latin.R;
// TODO: Implement key popup preview. // TODO: Implement key popup preview.
public final class EmojiPageKeyboardView extends KeyboardView implements public final class EmojiPageKeyboardView extends KeyboardView implements
GestureDetector.OnGestureListener { GestureDetector.OnGestureListener {
public interface OnKeyClickListener { public interface OnKeyEventListener {
public void onKeyClick(Key key); public void onPressKey(Key key);
public void onReleaseKey(Key key);
} }
private static final OnKeyClickListener EMPTY_LISTENER = new OnKeyClickListener() { private static final OnKeyEventListener EMPTY_LISTENER = new OnKeyEventListener() {
@Override @Override
public void onKeyClick(final Key key) {} public void onPressKey(final Key key) {}
@Override
public void onReleaseKey(final Key key) {}
}; };
private OnKeyClickListener mListener = EMPTY_LISTENER; private OnKeyEventListener mListener = EMPTY_LISTENER;
private final KeyDetector mKeyDetector = new KeyDetector(0.0f /*keyHysteresisDistance */); private final KeyDetector mKeyDetector = new KeyDetector(0.0f /*keyHysteresisDistance */);
private final GestureDetector mGestureDetector; private final GestureDetector mGestureDetector;
@ -59,7 +62,7 @@ public final class EmojiPageKeyboardView extends KeyboardView implements
mGestureDetector.setIsLongpressEnabled(false /* isLongpressEnabled */); mGestureDetector.setIsLongpressEnabled(false /* isLongpressEnabled */);
} }
public void setOnKeyClickListener(final OnKeyClickListener listener) { public void setOnKeyEventListener(final OnKeyEventListener listener) {
mListener = listener; mListener = listener;
} }
@ -115,9 +118,9 @@ public final class EmojiPageKeyboardView extends KeyboardView implements
if (key == null) { if (key == null) {
return false; return false;
} }
// TODO: May call {@link KeyboardActionListener#onPressKey(int,int,boolean)}.
key.onPressed(); key.onPressed();
invalidateKey(key); invalidateKey(key);
mListener.onPressKey(key);
return false; return false;
} }
@ -133,10 +136,9 @@ public final class EmojiPageKeyboardView extends KeyboardView implements
if (key == null) { if (key == null) {
return false; return false;
} }
// TODO: May call {@link KeyboardActionListener#onReleaseKey(int,boolean)}.
key.onReleased(); key.onReleased();
invalidateKey(key); invalidateKey(key);
mListener.onKeyClick(key); mListener.onReleaseKey(key);
return true; return true;
} }