Forward touch events above the keyboard to the suggestions strip
The gutter area between the suggestions strip and the top-row keys looks like a part of the suggestions strip, and the touch events landing on the area should be forwarded to the suggestions strip. Bug: 5246673 Change-Id: I92af763be0feed21aa36ceffb5d575abe554f19e
This commit is contained in:
parent
e4ff4d6b1c
commit
f451ed2012
3 changed files with 118 additions and 4 deletions
|
@ -18,7 +18,7 @@
|
|||
*/
|
||||
-->
|
||||
|
||||
<LinearLayout
|
||||
<com.android.inputmethod.latin.InputView
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
|
||||
android:orientation="vertical"
|
||||
|
@ -61,4 +61,4 @@
|
|||
android:layout_alignParentBottom="true"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content" />
|
||||
</LinearLayout>
|
||||
</com.android.inputmethod.latin.InputView>
|
||||
|
|
|
@ -32,6 +32,7 @@ import android.view.inputmethod.EditorInfo;
|
|||
import com.android.inputmethod.accessibility.AccessibleKeyboardViewProxy;
|
||||
import com.android.inputmethod.keyboard.internal.ModifierKeyState;
|
||||
import com.android.inputmethod.keyboard.internal.ShiftKeyState;
|
||||
import com.android.inputmethod.latin.InputView;
|
||||
import com.android.inputmethod.latin.LatinIME;
|
||||
import com.android.inputmethod.latin.LatinImeLogger;
|
||||
import com.android.inputmethod.latin.LocaleUtils;
|
||||
|
@ -62,7 +63,7 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha
|
|||
private SubtypeSwitcher mSubtypeSwitcher;
|
||||
private SharedPreferences mPrefs;
|
||||
|
||||
private View mCurrentInputView;
|
||||
private InputView mCurrentInputView;
|
||||
private LatinKeyboardView mKeyboardView;
|
||||
private LatinIME mInputMethodService;
|
||||
private String mPackageName;
|
||||
|
@ -230,6 +231,7 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha
|
|||
private void setKeyboard(final Keyboard keyboard) {
|
||||
final Keyboard oldKeyboard = mKeyboardView.getKeyboard();
|
||||
mKeyboardView.setKeyboard(keyboard);
|
||||
mCurrentInputView.setKeyboardGeometry(keyboard.mTopPadding);
|
||||
mCurrentId = keyboard.mId;
|
||||
mSwitchState = getSwitchState(mCurrentId);
|
||||
updateShiftLockState(keyboard);
|
||||
|
@ -762,7 +764,7 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha
|
|||
for (int i = 0; i < Utils.GCUtils.GC_TRY_LOOP_MAX && tryGC; ++i) {
|
||||
try {
|
||||
setContextThemeWrapper(mInputMethodService, newThemeIndex);
|
||||
mCurrentInputView = LayoutInflater.from(mThemeContext).inflate(
|
||||
mCurrentInputView = (InputView)LayoutInflater.from(mThemeContext).inflate(
|
||||
R.layout.input_view, null);
|
||||
tryGC = false;
|
||||
} catch (OutOfMemoryError e) {
|
||||
|
|
112
java/src/com/android/inputmethod/latin/InputView.java
Normal file
112
java/src/com/android/inputmethod/latin/InputView.java
Normal file
|
@ -0,0 +1,112 @@
|
|||
/*
|
||||
* Copyright (C) 2011 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.latin;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Rect;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.widget.LinearLayout;
|
||||
|
||||
public class InputView extends LinearLayout {
|
||||
private View mSuggestionsContainer;
|
||||
private View mKeyboardView;
|
||||
private int mKeyboardTopPadding;
|
||||
|
||||
private boolean mIsForwardingEvent;
|
||||
private final Rect mInputViewRect = new Rect();
|
||||
private final Rect mEventForwardingRect = new Rect();
|
||||
private final Rect mEventReceivingRect = new Rect();
|
||||
|
||||
public InputView(Context context, AttributeSet attrs) {
|
||||
super(context, attrs, 0);
|
||||
}
|
||||
|
||||
public void setKeyboardGeometry(int keyboardTopPadding) {
|
||||
mKeyboardTopPadding = keyboardTopPadding;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onFinishInflate() {
|
||||
mSuggestionsContainer = findViewById(R.id.suggestions_container);
|
||||
mKeyboardView = findViewById(R.id.keyboard_view);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean dispatchTouchEvent(MotionEvent me) {
|
||||
if (mSuggestionsContainer.getVisibility() == VISIBLE
|
||||
&& mKeyboardView.getVisibility() == VISIBLE
|
||||
&& forwardTouchEvent(me)) {
|
||||
return true;
|
||||
}
|
||||
return super.dispatchTouchEvent(me);
|
||||
}
|
||||
|
||||
// The touch events that hit the top padding of keyboard should be forwarded to SuggestionsView.
|
||||
private boolean forwardTouchEvent(MotionEvent me) {
|
||||
final Rect rect = mInputViewRect;
|
||||
this.getGlobalVisibleRect(rect);
|
||||
final int x = (int)me.getX() + rect.left;
|
||||
final int y = (int)me.getY() + rect.top;
|
||||
|
||||
final Rect forwardingRect = mEventForwardingRect;
|
||||
mKeyboardView.getGlobalVisibleRect(forwardingRect);
|
||||
if (!mIsForwardingEvent && !forwardingRect.contains(x, y)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final int forwardingLimitY = forwardingRect.top + mKeyboardTopPadding;
|
||||
boolean sendToTarget = false;
|
||||
|
||||
switch (me.getAction()) {
|
||||
case MotionEvent.ACTION_DOWN:
|
||||
if (y < forwardingLimitY) {
|
||||
// This down event and further move and up events should be forwarded to the target.
|
||||
mIsForwardingEvent = true;
|
||||
sendToTarget = true;
|
||||
}
|
||||
break;
|
||||
case MotionEvent.ACTION_MOVE:
|
||||
sendToTarget = mIsForwardingEvent;
|
||||
break;
|
||||
case MotionEvent.ACTION_UP:
|
||||
case MotionEvent.ACTION_CANCEL:
|
||||
sendToTarget = mIsForwardingEvent;
|
||||
mIsForwardingEvent = false;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!sendToTarget) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final Rect receivingRect = mEventReceivingRect;
|
||||
mSuggestionsContainer.getGlobalVisibleRect(receivingRect);
|
||||
final int translatedX = x - receivingRect.left;
|
||||
final int translatedY;
|
||||
if (y < forwardingLimitY) {
|
||||
// The forwarded event should have coordinates that are inside of the target.
|
||||
translatedY = Math.min(y - receivingRect.top, receivingRect.height() - 1);
|
||||
} else {
|
||||
translatedY = y - receivingRect.top;
|
||||
}
|
||||
me.setLocation(translatedX, translatedY);
|
||||
mSuggestionsContainer.dispatchTouchEvent(me);
|
||||
return true;
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue