diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardView.java b/java/src/com/android/inputmethod/keyboard/KeyboardView.java index 670564c39..4dab50fd8 100644 --- a/java/src/com/android/inputmethod/keyboard/KeyboardView.java +++ b/java/src/com/android/inputmethod/keyboard/KeyboardView.java @@ -169,11 +169,11 @@ public class KeyboardView extends View { public void setKeyboard(final Keyboard keyboard) { mKeyboard = keyboard; LatinImeLogger.onSetKeyboard(keyboard); - requestLayout(); - invalidateAllKeys(); final int keyHeight = keyboard.mMostCommonKeyHeight - keyboard.mVerticalGap; mKeyDrawParams.updateParams(keyHeight, mKeyVisualAttributes); mKeyDrawParams.updateParams(keyHeight, keyboard.mKeyVisualAttributes); + invalidateAllKeys(); + requestLayout(); } /** @@ -638,7 +638,6 @@ public class KeyboardView extends View { public void closing() { mInvalidateAllKeys = true; mKeyboard = null; - requestLayout(); } @Override diff --git a/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java b/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java index d8ff5c265..28a22f35c 100644 --- a/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java +++ b/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java @@ -174,9 +174,9 @@ public final class MainKeyboardView extends KeyboardView implements PointerTrack // More keys keyboard private final Paint mBackgroundDimAlphaPaint = new Paint(); private boolean mNeedsToDimEntireKeyboard; - private final WeakHashMap mMoreKeysPanelCache = - new WeakHashMap(); - private final int mMoreKeysLayout; + private final View mMoreKeysKeyboardContainer; + private final WeakHashMap mMoreKeysKeyboardCache = + CollectionUtils.newWeakHashMap(); private final boolean mConfigShowMoreKeysKeyboardAtTouchedPoint; // More keys panel (used by both more keys keyboard and more suggestions view) // TODO: Consider extending to support multiple more keys panels @@ -245,7 +245,7 @@ public final class MainKeyboardView extends KeyboardView implements PointerTrack break; case MSG_LONGPRESS_KEY: if (tracker != null) { - keyboardView.openMoreKeysKeyboardIfRequired(tracker.getKey(), tracker); + keyboardView.onLongPress(tracker); } else { KeyboardSwitcher.getInstance().onLongPressTimeout(msg.arg1); } @@ -544,7 +544,7 @@ public final class MainKeyboardView extends KeyboardView implements PointerTrack if (mKeyPreviewLayoutId == 0) { mShowKeyPreviewPopup = false; } - mMoreKeysLayout = mainKeyboardViewAttr.getResourceId( + final int moreKeysKeyboardLayoutId = mainKeyboardViewAttr.getResourceId( R.styleable.MainKeyboardView_moreKeysKeyboardLayout, 0); mConfigShowMoreKeysKeyboardAtTouchedPoint = mainKeyboardViewAttr.getBoolean( R.styleable.MainKeyboardView_showMoreKeysKeyboardAtTouchedPoint, false); @@ -566,6 +566,8 @@ public final class MainKeyboardView extends KeyboardView implements PointerTrack mPreviewPlacerView.addPreview(mSlidingKeyInputPreview); mainKeyboardViewAttr.recycle(); + mMoreKeysKeyboardContainer = LayoutInflater.from(getContext()) + .inflate(moreKeysKeyboardLayoutId, null); mLanguageOnSpacebarFadeoutAnimator = loadObjectAnimator( languageOnSpacebarFadeoutAnimatorResId, this); mAltCodeKeyWhileTypingFadeoutAnimator = loadObjectAnimator( @@ -653,7 +655,7 @@ public final class MainKeyboardView extends KeyboardView implements PointerTrack keyboard, -getPaddingLeft(), -getPaddingTop() + mVerticalCorrection); PointerTracker.setKeyDetector(mKeyDetector); mTouchScreenRegulator.setKeyboardGeometry(keyboard.mOccupiedWidth); - mMoreKeysPanelCache.clear(); + mMoreKeysKeyboardCache.clear(); mSpaceKey = keyboard.getKey(Constants.CODE_SPACE); mSpaceIcon = (mSpaceKey != null) @@ -942,123 +944,105 @@ public final class MainKeyboardView extends KeyboardView implements PointerTrack } } - private boolean openMoreKeysKeyboardIfRequired(final Key parentKey, - final PointerTracker tracker) { - // Check if we have a popup layout specified first. - if (mMoreKeysLayout == 0) { - return false; - } - - // Check if we are already displaying popup panel. - if (mMoreKeysPanel != null) { - return false; - } - if (parentKey == null) { - return false; - } - return onLongPress(parentKey, tracker); - } - - private MoreKeysPanel onCreateMoreKeysPanel(final Key parentKey) { - if (parentKey.mMoreKeys == null) { + private MoreKeysPanel onCreateMoreKeysPanel(final Key key, final Context context) { + if (key.mMoreKeys == null) { return null; } - - final View container = LayoutInflater.from(getContext()).inflate(mMoreKeysLayout, null); - if (container == null) { - throw new NullPointerException(); + Keyboard moreKeysKeyboard = mMoreKeysKeyboardCache.get(key); + if (moreKeysKeyboard == null) { + moreKeysKeyboard = new MoreKeysKeyboard.Builder( + context, key, this, mKeyPreviewDrawParams).build(); + mMoreKeysKeyboardCache.put(key, moreKeysKeyboard); } + final View container = mMoreKeysKeyboardContainer; final MoreKeysKeyboardView moreKeysKeyboardView = (MoreKeysKeyboardView)container.findViewById(R.id.more_keys_keyboard_view); - final Keyboard moreKeysKeyboard = new MoreKeysKeyboard.Builder( - container, parentKey, this, mKeyPreviewDrawParams) - .build(); moreKeysKeyboardView.setKeyboard(moreKeysKeyboard); container.measure(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT); - return moreKeysKeyboardView; } /** * Called when a key is long pressed. - * @param parentKey the key that was long pressed * @param tracker the pointer tracker which pressed the parent key * @return true if the long press is handled, false otherwise. Subclasses should call the * method on the base class if the subclass doesn't wish to handle the call. */ - private boolean onLongPress(final Key parentKey, final PointerTracker tracker) { + private boolean onLongPress(final PointerTracker tracker) { + if (isShowingMoreKeysPanel()) { + return false; + } + final Key key = tracker.getKey(); + if (key == null) { + return false; + } if (ProductionFlag.IS_EXPERIMENTAL) { ResearchLogger.mainKeyboardView_onLongPress(); } - final int primaryCode = parentKey.mCode; - if (parentKey.hasEmbeddedMoreKey()) { - final int embeddedCode = parentKey.mMoreKeys[0].mCode; + final int code = key.mCode; + if (key.hasEmbeddedMoreKey()) { + final int embeddedCode = key.mMoreKeys[0].mCode; tracker.onLongPressed(); invokeCodeInput(embeddedCode); - invokeReleaseKey(primaryCode); - KeyboardSwitcher.getInstance().hapticAndAudioFeedback(primaryCode); + invokeReleaseKey(code); + KeyboardSwitcher.getInstance().hapticAndAudioFeedback(code); return true; } - if (primaryCode == Constants.CODE_SPACE || primaryCode == Constants.CODE_LANGUAGE_SWITCH) { + if (code == Constants.CODE_SPACE || code == Constants.CODE_LANGUAGE_SWITCH) { // Long pressing the space key invokes IME switcher dialog. if (invokeCustomRequest(LatinIME.CODE_SHOW_INPUT_METHOD_PICKER)) { tracker.onLongPressed(); - invokeReleaseKey(primaryCode); + invokeReleaseKey(code); return true; } } - return openMoreKeysPanel(parentKey, tracker); + return openMoreKeysPanel(key, tracker); } - private boolean invokeCustomRequest(final int code) { - return mKeyboardActionListener.onCustomRequest(code); + private boolean invokeCustomRequest(final int requestCode) { + return mKeyboardActionListener.onCustomRequest(requestCode); } - private void invokeCodeInput(final int primaryCode) { + private void invokeCodeInput(final int code) { mKeyboardActionListener.onCodeInput( - primaryCode, Constants.NOT_A_COORDINATE, Constants.NOT_A_COORDINATE); + code, Constants.NOT_A_COORDINATE, Constants.NOT_A_COORDINATE); } - private void invokeReleaseKey(final int primaryCode) { - mKeyboardActionListener.onReleaseKey(primaryCode, false); + private void invokeReleaseKey(final int code) { + mKeyboardActionListener.onReleaseKey(code, false); } - private boolean openMoreKeysPanel(final Key parentKey, final PointerTracker tracker) { - MoreKeysPanel moreKeysPanel = mMoreKeysPanelCache.get(parentKey); + private boolean openMoreKeysPanel(final Key key, final PointerTracker tracker) { + final MoreKeysPanel moreKeysPanel = onCreateMoreKeysPanel(key, getContext()); if (moreKeysPanel == null) { - moreKeysPanel = onCreateMoreKeysPanel(parentKey); - if (moreKeysPanel == null) { - return false; - } - mMoreKeysPanelCache.put(parentKey, moreKeysPanel); + return false; } final int[] lastCoords = CoordinateUtils.newInstance(); tracker.getLastCoordinates(lastCoords); - final boolean keyPreviewEnabled = isKeyPreviewPopupEnabled() && !parentKey.noKeyPreview(); + final boolean keyPreviewEnabled = isKeyPreviewPopupEnabled() && !key.noKeyPreview(); // The more keys keyboard is usually horizontally aligned with the center of the parent key. // If showMoreKeysKeyboardAtTouchedPoint is true and the key preview is disabled, the more // keys keyboard is placed at the touch point of the parent key. final int pointX = (mConfigShowMoreKeysKeyboardAtTouchedPoint && !keyPreviewEnabled) ? CoordinateUtils.x(lastCoords) - : parentKey.mX + parentKey.mWidth / 2; + : key.mX + key.mWidth / 2; // The more keys keyboard is usually vertically aligned with the top edge of the parent key // (plus vertical gap). If the key preview is enabled, the more keys keyboard is vertically // aligned with the bottom edge of the visible part of the key preview. // {@code mPreviewVisibleOffset} has been set appropriately in // {@link KeyboardView#showKeyPreview(PointerTracker)}. - final int pointY = parentKey.mY + mKeyPreviewDrawParams.mPreviewVisibleOffset; + final int pointY = key.mY + mKeyPreviewDrawParams.mPreviewVisibleOffset; moreKeysPanel.showMoreKeysPanel(this, this, pointX, pointY, mKeyboardActionListener); final int translatedX = moreKeysPanel.translateX(CoordinateUtils.x(lastCoords)); final int translatedY = moreKeysPanel.translateY(CoordinateUtils.y(lastCoords)); tracker.onShowMoreKeysPanel(translatedX, translatedY, moreKeysPanel); - dimEntireKeyboard(true /* dimmed */); return true; } public boolean isInSlidingKeyInput() { - if (mMoreKeysPanel != null) { + if (isShowingMoreKeysPanel()) { return true; } return PointerTracker.isAnyInSlidingKeyInput(); @@ -1069,19 +1053,17 @@ public final class MainKeyboardView extends KeyboardView implements PointerTrack if (isShowingMoreKeysPanel()) { onDismissMoreKeysPanel(); } + mPreviewPlacerView.addView(panel.getContainerView()); mMoreKeysPanel = panel; - mPreviewPlacerView.addView(mMoreKeysPanel.getContainerView()); + dimEntireKeyboard(true /* dimmed */); } public boolean isShowingMoreKeysPanel() { - return (mMoreKeysPanel != null); + return mMoreKeysPanel != null && mMoreKeysPanel.isShowingInParent(); } @Override public void onCancelMoreKeysPanel() { - if (isShowingMoreKeysPanel()) { - mMoreKeysPanel.dismissMoreKeysPanel(); - } PointerTracker.dismissAllMoreKeysPanels(); } @@ -1254,9 +1236,9 @@ public final class MainKeyboardView extends KeyboardView implements PointerTrack public void closing() { dismissAllKeyPreviews(); cancelAllMessages(); + onDismissMoreKeysPanel(); + mMoreKeysKeyboardCache.clear(); super.closing(); - onCancelMoreKeysPanel(); - mMoreKeysPanelCache.clear(); } /** @@ -1331,7 +1313,7 @@ public final class MainKeyboardView extends KeyboardView implements PointerTrack invalidateKey(mSpaceKey); } - public void dimEntireKeyboard(final boolean dimmed) { + private void dimEntireKeyboard(final boolean dimmed) { final boolean needsRedrawing = mNeedsToDimEntireKeyboard != dimmed; mNeedsToDimEntireKeyboard = dimmed; if (needsRedrawing) { diff --git a/java/src/com/android/inputmethod/keyboard/MoreKeysKeyboard.java b/java/src/com/android/inputmethod/keyboard/MoreKeysKeyboard.java index 6df883e41..66c30149c 100644 --- a/java/src/com/android/inputmethod/keyboard/MoreKeysKeyboard.java +++ b/java/src/com/android/inputmethod/keyboard/MoreKeysKeyboard.java @@ -16,9 +16,9 @@ package com.android.inputmethod.keyboard; +import android.content.Context; import android.graphics.Paint; import android.graphics.drawable.Drawable; -import android.view.View; import com.android.inputmethod.annotations.UsedForTesting; import com.android.inputmethod.keyboard.internal.KeyPreviewDrawParams; @@ -260,15 +260,15 @@ public final class MoreKeysKeyboard extends Keyboard { /** * The builder of MoreKeysKeyboard. - * @param containerView the container of {@link MoreKeysKeyboardView}. + * @param context the context of {@link MoreKeysKeyboardView}. * @param parentKey the {@link Key} that invokes more keys keyboard. * @param parentKeyboardView the {@link KeyboardView} that contains the parentKey. * @param keyPreviewDrawParams the parameter to place key preview. */ - public Builder(final View containerView, final Key parentKey, + public Builder(final Context context, final Key parentKey, final MainKeyboardView parentKeyboardView, final KeyPreviewDrawParams keyPreviewDrawParams) { - super(containerView.getContext(), new MoreKeysKeyboardParams()); + super(context, new MoreKeysKeyboardParams()); final Keyboard parentKeyboard = parentKeyboardView.getKeyboard(); load(parentKeyboard.mMoreKeysTemplate, parentKeyboard.mId); diff --git a/java/src/com/android/inputmethod/keyboard/MoreKeysKeyboardView.java b/java/src/com/android/inputmethod/keyboard/MoreKeysKeyboardView.java index 0d42ab2fe..9e75f8b8a 100644 --- a/java/src/com/android/inputmethod/keyboard/MoreKeysKeyboardView.java +++ b/java/src/com/android/inputmethod/keyboard/MoreKeysKeyboardView.java @@ -174,6 +174,7 @@ public class MoreKeysKeyboardView extends KeyboardView implements MoreKeysPanel @Override public boolean dismissMoreKeysPanel() { + super.closing(); if (mController == null) return false; return mController.onDismissMoreKeysPanel(); } diff --git a/java/src/com/android/inputmethod/latin/CollectionUtils.java b/java/src/com/android/inputmethod/latin/CollectionUtils.java index c75f2df5c..a8623cc63 100644 --- a/java/src/com/android/inputmethod/latin/CollectionUtils.java +++ b/java/src/com/android/inputmethod/latin/CollectionUtils.java @@ -27,6 +27,7 @@ import java.util.LinkedList; import java.util.Map; import java.util.TreeMap; import java.util.TreeSet; +import java.util.WeakHashMap; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.CopyOnWriteArrayList; @@ -39,6 +40,10 @@ public final class CollectionUtils { return new HashMap(); } + public static WeakHashMap newWeakHashMap() { + return new WeakHashMap(); + } + public static TreeMap newTreeMap() { return new TreeMap(); } diff --git a/java/src/com/android/inputmethod/latin/suggestions/MoreSuggestionsView.java b/java/src/com/android/inputmethod/latin/suggestions/MoreSuggestionsView.java index 26a304ef8..438820d17 100644 --- a/java/src/com/android/inputmethod/latin/suggestions/MoreSuggestionsView.java +++ b/java/src/com/android/inputmethod/latin/suggestions/MoreSuggestionsView.java @@ -19,7 +19,6 @@ package com.android.inputmethod.latin.suggestions; import android.content.Context; import android.util.AttributeSet; -import com.android.inputmethod.keyboard.Keyboard; import com.android.inputmethod.keyboard.MoreKeysKeyboardView; import com.android.inputmethod.latin.R; @@ -28,7 +27,6 @@ import com.android.inputmethod.latin.R; * key presses and touch movements. */ public final class MoreSuggestionsView extends MoreKeysKeyboardView { - public MoreSuggestionsView(final Context context, final AttributeSet attrs) { this(context, attrs, R.attr.moreSuggestionsViewStyle); } @@ -44,32 +42,15 @@ public final class MoreSuggestionsView extends MoreKeysKeyboardView { return pane.mOccupiedWidth / 2; } - @Override - protected void onMeasure(final int widthMeasureSpec, final int heightMeasureSpec) { - final Keyboard keyboard = getKeyboard(); - if (keyboard != null) { - final int width = keyboard.mOccupiedWidth + getPaddingLeft() + getPaddingRight(); - final int height = keyboard.mOccupiedHeight + getPaddingTop() + getPaddingBottom(); - setMeasuredDimension(width, height); - } else { - super.onMeasure(widthMeasureSpec, heightMeasureSpec); - } - } - public void updateKeyboardGeometry(final int keyHeight) { mKeyDrawParams.updateParams(keyHeight, mKeyVisualAttributes); } @Override - public void onCodeInput(final int primaryCode, final int x, final int y) { - final int index = primaryCode - MoreSuggestions.SUGGESTION_CODE_BASE; + public void onCodeInput(final int code, final int x, final int y) { + final int index = code - MoreSuggestions.SUGGESTION_CODE_BASE; if (index >= 0 && index < SuggestionStripView.MAX_SUGGESTIONS) { mListener.onCustomRequest(index); } } - - @Override - public boolean isShowingInParent() { - return (getContainerView().getParent() != null); - } } diff --git a/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripView.java b/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripView.java index 92b96e754..bc51d5d62 100644 --- a/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripView.java +++ b/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripView.java @@ -676,12 +676,11 @@ public final class SuggestionStripView extends RelativeLayout implements OnClick new MoreKeysPanel.Controller() { @Override public boolean onDismissMoreKeysPanel() { - mMainKeyboardView.dimEntireKeyboard(false /* dimmed */); return mMainKeyboardView.onDismissMoreKeysPanel(); } @Override - public void onShowMoreKeysPanel(MoreKeysPanel panel) { + public void onShowMoreKeysPanel(final MoreKeysPanel panel) { mMainKeyboardView.onShowMoreKeysPanel(panel); } @@ -728,7 +727,6 @@ public final class SuggestionStripView extends RelativeLayout implements OnClick mMoreSuggestionsMode = MORE_SUGGESTIONS_CHECKING_MODAL_OR_SLIDING; mOriginX = mLastX; mOriginY = mLastY; - mMainKeyboardView.dimEntireKeyboard(true /* dimmed */); for (int i = 0; i < params.mSuggestionsCountInStrip; i++) { mWords.get(i).setPressed(false); }