Simplify onComputeInsets of LatinIME

This CL expands SoftInputWindow to the entire screen. Thus a key
review backing view is eliminated and onComputeInsets() gets
simplified too.

Bug: 17212702
Bug: 10841052
Bug: 10541453
Change-Id: I2d859f4e4698c64cabe399000821f13bab729996
This commit is contained in:
Tadashi G. Takaoka 2014-08-25 18:26:11 +09:00
parent 97681ebdf1
commit 37beaf1529
7 changed files with 130 additions and 102 deletions

View file

@ -20,10 +20,10 @@
<com.android.inputmethod.keyboard.emoji.EmojiPalettesView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/emoji_keyboard_view"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:orientation="vertical"
style="?attr/emojiPalettesViewStyle"
>
<LinearLayout

View file

@ -21,38 +21,11 @@
<com.android.inputmethod.latin.InputView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="bottom|center_horizontal"
android:orientation="vertical" >
<!-- The height of key_preview_backing view will automatically be determined by code. -->
<FrameLayout
android:id="@+id/key_preview_backing"
android:layout_width="match_parent"
android:layout_height="0dp" />
<LinearLayout
android:id="@+id/main_keyboard_frame"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical" >
<!-- To ensure that key preview popup is correctly placed when the current system locale is
one of RTL locales, layoutDirection="ltr" is needed in the SDK version 17+. -->
<com.android.inputmethod.latin.suggestions.SuggestionStripView
android:id="@+id/suggestion_strip_view"
android:layoutDirection="ltr"
android:layout_width="match_parent"
android:layout_height="@dimen/config_suggestions_strip_height"
android:gravity="center_vertical"
style="?attr/suggestionStripViewStyle" />
<!-- To ensure that key preview popup is correctly placed when the current system locale is
one of RTL locales, layoutDirection="ltr" is needed in the SDK version 17+. -->
<com.android.inputmethod.keyboard.MainKeyboardView
android:id="@+id/keyboard_view"
android:layoutDirection="ltr"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
android:layout_height="wrap_content">
<include
android:id="@+id/main_keyboard_frame"
layout="@layout/main_keyboard_frame" />
<include
android:id="@+id/emoji_palettes_view"
layout="@layout/emoji_palettes_view" />
</com.android.inputmethod.latin.InputView>

View file

@ -0,0 +1,45 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
/*
**
** Copyright 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.
*/
-->
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:orientation="vertical" >
<!-- To ensure that key preview popup is correctly placed when the current system locale is
one of RTL locales, layoutDirection="ltr" is needed in the SDK version 17+. -->
<com.android.inputmethod.latin.suggestions.SuggestionStripView
android:id="@+id/suggestion_strip_view"
android:layoutDirection="ltr"
android:layout_width="match_parent"
android:layout_height="@dimen/config_suggestions_strip_height"
android:gravity="center_vertical"
style="?attr/suggestionStripViewStyle" />
<!-- To ensure that key preview popup is correctly placed when the current system locale is
one of RTL locales, layoutDirection="ltr" is needed in the SDK version 17+. -->
<com.android.inputmethod.keyboard.MainKeyboardView
android:id="@+id/keyboard_view"
android:layoutDirection="ltr"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>

View file

@ -359,7 +359,7 @@ public final class KeyboardSwitcher implements KeyboardState.SwitchActions {
R.layout.input_view, null);
mMainKeyboardFrame = mCurrentInputView.findViewById(R.id.main_keyboard_frame);
mEmojiPalettesView = (EmojiPalettesView)mCurrentInputView.findViewById(
R.id.emoji_keyboard_view);
R.id.emoji_palettes_view);
mKeyboardView = (MainKeyboardView) mCurrentInputView.findViewById(R.id.keyboard_view);
mKeyboardView.setHardwareAcceleratedDrawingEnabled(isHardwareAcceleratedDrawingEnabled);

View file

@ -21,14 +21,14 @@ import android.graphics.Rect;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.FrameLayout;
import com.android.inputmethod.accessibility.AccessibilityUtils;
import com.android.inputmethod.keyboard.MainKeyboardView;
import com.android.inputmethod.latin.suggestions.MoreSuggestionsView;
import com.android.inputmethod.latin.suggestions.SuggestionStripView;
public final class InputView extends LinearLayout {
public final class InputView extends FrameLayout {
private final Rect mInputViewRect = new Rect();
private MainKeyboardView mMainKeyboardView;
private KeyboardTopPaddingForwarder mKeyboardTopPaddingForwarder;

View file

@ -29,7 +29,6 @@ import android.content.Intent;
import android.content.IntentFilter;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.graphics.Rect;
import android.inputmethodservice.InputMethodService;
import android.media.AudioManager;
import android.net.ConnectivityManager;
@ -43,6 +42,7 @@ import android.util.Log;
import android.util.PrintWriterPrinter;
import android.util.Printer;
import android.util.SparseArray;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.View;
import android.view.ViewGroup.LayoutParams;
@ -94,6 +94,7 @@ import com.android.inputmethod.latin.utils.JniUtils;
import com.android.inputmethod.latin.utils.LeakGuardHandlerWrapper;
import com.android.inputmethod.latin.utils.StatsUtils;
import com.android.inputmethod.latin.utils.SubtypeLocaleUtils;
import com.android.inputmethod.latin.utils.ViewLayoutUtils;
import java.io.FileDescriptor;
import java.io.PrintWriter;
@ -150,8 +151,6 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
// TODO: Move these {@link View}s to {@link KeyboardSwitcher}.
private View mInputView;
private View mExtractArea;
private View mKeyPreviewBackingView;
private SuggestionStripView mSuggestionStripView;
private RichInputMethodManager mRichImm;
@ -735,9 +734,6 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
public void setInputView(final View view) {
super.setInputView(view);
mInputView = view;
mExtractArea = getWindow().getWindow().getDecorView()
.findViewById(android.R.id.extractArea);
mKeyPreviewBackingView = view.findViewById(R.id.key_preview_backing);
mSuggestionStripView = (SuggestionStripView)view.findViewById(R.id.suggestion_strip_view);
if (hasSuggestionStripView()) {
mSuggestionStripView.setListener(this, view);
@ -1075,36 +1071,6 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
setSuggestedWords(suggestedWords);
}
private int getAdjustedBackingViewHeight() {
final int currentHeight = mKeyPreviewBackingView.getHeight();
if (currentHeight > 0) {
return currentHeight;
}
final View visibleKeyboardView = mKeyboardSwitcher.getVisibleKeyboardView();
if (visibleKeyboardView == null) {
return 0;
}
// TODO: !!!!!!!!!!!!!!!!!!!! Handle different backing view heights between the main !!!
// keyboard and the emoji keyboard. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
final int keyboardHeight = visibleKeyboardView.getHeight();
final int suggestionsHeight = mSuggestionStripView.getHeight();
final int displayHeight = getResources().getDisplayMetrics().heightPixels;
final Rect rect = new Rect();
mKeyPreviewBackingView.getWindowVisibleDisplayFrame(rect);
final int notificationBarHeight = rect.top;
final int remainingHeight = displayHeight - notificationBarHeight - suggestionsHeight
- keyboardHeight;
final LayoutParams params = mKeyPreviewBackingView.getLayoutParams();
mSuggestionStripView.setMoreSuggestionsHeight(remainingHeight);
// Let the backing cover the remaining region entirely.
params.height = remainingHeight;
mKeyPreviewBackingView.setLayoutParams(params);
return params.height;
}
@Override
public void onComputeInsets(final InputMethodService.Insets outInsets) {
super.onComputeInsets(outInsets);
@ -1112,40 +1078,30 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
if (visibleKeyboardView == null || !hasSuggestionStripView()) {
return;
}
final int inputHeight = mInputView.getHeight();
final boolean hasHardwareKeyboard = mKeyboardSwitcher.hasHardwareKeyboard();
if (hasHardwareKeyboard && visibleKeyboardView.getVisibility() == View.GONE) {
// If there is a hardware keyboard and a visible software keyboard view has been hidden,
// no visual element will be shown on the screen.
outInsets.touchableInsets = mInputView.getHeight();
outInsets.visibleTopInsets = mInputView.getHeight();
outInsets.touchableInsets = inputHeight;
outInsets.visibleTopInsets = inputHeight;
return;
}
final int adjustedBackingHeight = getAdjustedBackingViewHeight();
final boolean backingGone = (mKeyPreviewBackingView.getVisibility() == View.GONE);
final int backingHeight = backingGone ? 0 : adjustedBackingHeight;
// In fullscreen mode, the height of the extract area managed by InputMethodService should
// be considered.
// See {@link android.inputmethodservice.InputMethodService#onComputeInsets}.
final int extractHeight = isFullscreenMode() ? mExtractArea.getHeight() : 0;
final int suggestionsHeight = (mSuggestionStripView.getVisibility() == View.GONE) ? 0
: mSuggestionStripView.getHeight();
final int extraHeight = extractHeight + backingHeight + suggestionsHeight;
int visibleTopY = extraHeight;
// Need to set touchable region only if input view is being shown
final int suggestionsHeight = (!mKeyboardSwitcher.isShowingEmojiPalettes()
&& mSuggestionStripView.getVisibility() == View.VISIBLE)
? mSuggestionStripView.getHeight() : 0;
final int visibleTopY = inputHeight - visibleKeyboardView.getHeight() - suggestionsHeight;
mSuggestionStripView.setMoreSuggestionsHeight(visibleTopY);
// Need to set touchable region only if a keyboard view is being shown.
if (visibleKeyboardView.isShown()) {
// Note that the height of Emoji layout is the same as the height of the main keyboard
// and the suggestion strip
if (mKeyboardSwitcher.isShowingEmojiPalettes()
|| mSuggestionStripView.getVisibility() == View.VISIBLE) {
visibleTopY -= suggestionsHeight;
}
final int touchY = mKeyboardSwitcher.isShowingMoreKeysPanel() ? 0 : visibleTopY;
final int touchWidth = visibleKeyboardView.getWidth();
final int touchHeight = visibleKeyboardView.getHeight() + extraHeight
final int touchLeft = 0;
final int touchTop = mKeyboardSwitcher.isShowingMoreKeysPanel() ? 0 : visibleTopY;
final int touchRight = visibleKeyboardView.getWidth();
final int touchBottom = inputHeight
// Extend touchable region below the keyboard.
+ EXTENDED_TOUCHABLE_REGION_HEIGHT;
outInsets.touchableInsets = InputMethodService.Insets.TOUCHABLE_INSETS_REGION;
outInsets.touchableRegion.set(0, touchY, touchWidth, touchHeight);
outInsets.touchableRegion.set(touchLeft, touchTop, touchRight, touchBottom);
}
outInsets.contentTopInsets = visibleTopY;
outInsets.visibleTopInsets = visibleTopY;
@ -1190,12 +1146,27 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
@Override
public void updateFullscreenMode() {
// Override layout parameters to expand {@link SoftInputWindow} to the entire screen.
// See {@link InputMethodService#setinputView(View) and
// {@link SoftInputWindow#updateWidthHeight(WindowManager.LayoutParams)}.
final Window window = getWindow().getWindow();
ViewLayoutUtils.updateLayoutHeightOf(window, LayoutParams.MATCH_PARENT);
// This method may be called before {@link #setInputView(View)}.
if (mInputView != null) {
// In non-fullscreen mode, {@link InputView} and its parent inputArea should expand to
// the entire screen and be placed at the bottom of {@link SoftInputWindow}.
// In fullscreen mode, these shouldn't expand to the entire screen and should be
// coexistent with {@link #mExtractedArea} above.
// See {@link InputMethodService#setInputView(View) and
// com.android.internal.R.layout.input_method.xml.
final int layoutHeight = isFullscreenMode()
? LayoutParams.WRAP_CONTENT : LayoutParams.MATCH_PARENT;
final View inputArea = window.findViewById(android.R.id.inputArea);
ViewLayoutUtils.updateLayoutHeightOf(inputArea, layoutHeight);
ViewLayoutUtils.updateLayoutGravityOf(inputArea, Gravity.BOTTOM);
ViewLayoutUtils.updateLayoutHeightOf(mInputView, layoutHeight);
}
super.updateFullscreenMode();
if (mKeyPreviewBackingView == null) return;
// In fullscreen mode, no need to have extra space to show the key preview.
// If not, we should have extra space above the keyboard to show the key preview.
mKeyPreviewBackingView.setVisibility(isFullscreenMode() ? View.GONE : View.VISIBLE);
mInputLogic.onUpdateFullscreenMode(isFullscreenMode());
}

View file

@ -19,7 +19,10 @@ package com.android.inputmethod.latin.utils;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewGroup.MarginLayoutParams;
import android.view.Window;
import android.view.WindowManager;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
public final class ViewLayoutUtils {
@ -51,4 +54,40 @@ public final class ViewLayoutUtils {
marginLayoutParams.setMargins(x, y, 0, 0);
}
}
public static void updateLayoutHeightOf(final Window window, final int layoutHeight) {
final WindowManager.LayoutParams params = window.getAttributes();
if (params.height != layoutHeight) {
params.height = layoutHeight;
window.setAttributes(params);
}
}
public static void updateLayoutHeightOf(final View view, final int layoutHeight) {
final ViewGroup.LayoutParams params = view.getLayoutParams();
if (params.height != layoutHeight) {
params.height = layoutHeight;
view.setLayoutParams(params);
}
}
public static void updateLayoutGravityOf(final View view, final int layoutGravity) {
final ViewGroup.LayoutParams lp = view.getLayoutParams();
if (lp instanceof LinearLayout.LayoutParams) {
final LinearLayout.LayoutParams params = (LinearLayout.LayoutParams)lp;
if (params.gravity != layoutGravity) {
params.gravity = layoutGravity;
view.setLayoutParams(params);
}
} else if (lp instanceof FrameLayout.LayoutParams) {
final FrameLayout.LayoutParams params = (FrameLayout.LayoutParams)lp;
if (params.gravity != layoutGravity) {
params.gravity = layoutGravity;
view.setLayoutParams(params);
}
} else {
throw new IllegalArgumentException("Layout parameter doesn't have gravity: "
+ lp.getClass().getName());
}
}
}