/*
 * Copyright (C) 2007-2008 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 android.inputmethodservice;

import android.app.Dialog;
import android.content.Context;
import android.graphics.Rect;
import android.os.IBinder;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.WindowManager;

A SoftInputWindow is a Dialog that is intended to be used for a top-level input method window. It will be displayed along the edge of the screen, moving the application user interface away from it so that the focused item is always visible.
@hide
/** * A SoftInputWindow is a Dialog that is intended to be used for a top-level input * method window. It will be displayed along the edge of the screen, moving * the application user interface away from it so that the focused item is * always visible. * @hide */
public class SoftInputWindow extends Dialog { final String mName; final Callback mCallback; final KeyEvent.Callback mKeyEventCallback; final KeyEvent.DispatcherState mDispatcherState; final int mWindowType; final int mGravity; final boolean mTakesFocus; private final Rect mBounds = new Rect(); public interface Callback { public void onBackPressed(); } public void setToken(IBinder token) { WindowManager.LayoutParams lp = getWindow().getAttributes(); lp.token = token; getWindow().setAttributes(lp); }
Create a SoftInputWindow that uses a custom style.
Params:
  • context – The Context in which the DockWindow should run. In particular, it uses the window manager and theme from this context to present its UI.
  • theme – A style resource describing the theme to use for the window. See Style and Theme Resources for more information about defining and using styles. This theme is applied on top of the current theme in context. If 0, the default dialog theme will be used.
/** * Create a SoftInputWindow that uses a custom style. * * @param context The Context in which the DockWindow should run. In * particular, it uses the window manager and theme from this context * to present its UI. * @param theme A style resource describing the theme to use for the window. * See <a href="{@docRoot}reference/available-resources.html#stylesandthemes">Style * and Theme Resources</a> for more information about defining and * using styles. This theme is applied on top of the current theme in * <var>context</var>. If 0, the default dialog theme will be used. */
public SoftInputWindow(Context context, String name, int theme, Callback callback, KeyEvent.Callback keyEventCallback, KeyEvent.DispatcherState dispatcherState, int windowType, int gravity, boolean takesFocus) { super(context, theme); mName = name; mCallback = callback; mKeyEventCallback = keyEventCallback; mDispatcherState = dispatcherState; mWindowType = windowType; mGravity = gravity; mTakesFocus = takesFocus; initDockWindow(); } @Override public void onWindowFocusChanged(boolean hasFocus) { super.onWindowFocusChanged(hasFocus); mDispatcherState.reset(); } @Override public boolean dispatchTouchEvent(MotionEvent ev) { getWindow().getDecorView().getHitRect(mBounds); if (ev.isWithinBoundsNoHistory(mBounds.left, mBounds.top, mBounds.right - 1, mBounds.bottom - 1)) { return super.dispatchTouchEvent(ev); } else { MotionEvent temp = ev.clampNoHistory(mBounds.left, mBounds.top, mBounds.right - 1, mBounds.bottom - 1); boolean handled = super.dispatchTouchEvent(temp); temp.recycle(); return handled; } }
Set which boundary of the screen the DockWindow sticks to.
Params:
  • gravity – The boundary of the screen to stick. See LEFT, TOP, BOTTOM, RIGHT.
/** * Set which boundary of the screen the DockWindow sticks to. * * @param gravity The boundary of the screen to stick. See {@link * android.view.Gravity.LEFT}, {@link android.view.Gravity.TOP}, * {@link android.view.Gravity.BOTTOM}, {@link * android.view.Gravity.RIGHT}. */
public void setGravity(int gravity) { WindowManager.LayoutParams lp = getWindow().getAttributes(); lp.gravity = gravity; updateWidthHeight(lp); getWindow().setAttributes(lp); } public int getGravity() { return getWindow().getAttributes().gravity; } private void updateWidthHeight(WindowManager.LayoutParams lp) { if (lp.gravity == Gravity.TOP || lp.gravity == Gravity.BOTTOM) { lp.width = WindowManager.LayoutParams.MATCH_PARENT; lp.height = WindowManager.LayoutParams.WRAP_CONTENT; } else { lp.width = WindowManager.LayoutParams.WRAP_CONTENT; lp.height = WindowManager.LayoutParams.MATCH_PARENT; } } public boolean onKeyDown(int keyCode, KeyEvent event) { if (mKeyEventCallback != null && mKeyEventCallback.onKeyDown(keyCode, event)) { return true; } return super.onKeyDown(keyCode, event); } public boolean onKeyLongPress(int keyCode, KeyEvent event) { if (mKeyEventCallback != null && mKeyEventCallback.onKeyLongPress(keyCode, event)) { return true; } return super.onKeyLongPress(keyCode, event); } public boolean onKeyUp(int keyCode, KeyEvent event) { if (mKeyEventCallback != null && mKeyEventCallback.onKeyUp(keyCode, event)) { return true; } return super.onKeyUp(keyCode, event); } public boolean onKeyMultiple(int keyCode, int count, KeyEvent event) { if (mKeyEventCallback != null && mKeyEventCallback.onKeyMultiple(keyCode, count, event)) { return true; } return super.onKeyMultiple(keyCode, count, event); } public void onBackPressed() { if (mCallback != null) { mCallback.onBackPressed(); } else { super.onBackPressed(); } } private void initDockWindow() { WindowManager.LayoutParams lp = getWindow().getAttributes(); lp.type = mWindowType; lp.setTitle(mName); lp.gravity = mGravity; updateWidthHeight(lp); getWindow().setAttributes(lp); int windowSetFlags = WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN; int windowModFlags = WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_DIM_BEHIND; if (!mTakesFocus) { windowSetFlags |= WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE; } else { windowSetFlags |= WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL; windowModFlags |= WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL; } getWindow().setFlags(windowSetFlags, windowModFlags); } }