软键盘打开时调整布局

时间:2011-09-04 16:12:38

标签: android

我在某些应用程序中看到,当显示软键盘时,布局会发生变化。这当然不是adjustPan,因为整个布局(可能是内部布局)不仅会改变当前的EditText。例如,这是在Evernote登录屏幕中。你能告诉我这是怎么做的吗?

6 个答案:

答案 0 :(得分:66)

这是一个像Evernote登录界面一样的解决方案:

首先,定义一个类似于你的特殊LinearLayout的类:

public class MyLayout extends LinearLayout {

public MyLayout(Context context, AttributeSet attrs) {
    super(context, attrs);
}

public MyLayout(Context context) {
    super(context);
}

private OnSoftKeyboardListener onSoftKeyboardListener;

@Override
protected void onMeasure(final int widthMeasureSpec, final int heightMeasureSpec) {
    if (onSoftKeyboardListener != null) {
        final int newSpec = MeasureSpec.getSize(heightMeasureSpec); 
        final int oldSpec = getMeasuredHeight();
        if (oldSpec > newSpec){
            onSoftKeyboardListener.onShown();
        } else {
            onSoftKeyboardListener.onHidden();
        }
    }
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}

public final void setOnSoftKeyboardListener(final OnSoftKeyboardListener listener) {
    this.onSoftKeyboardListener = listener;
}

public interface OnSoftKeyboardListener {
    public void onShown();
    public void onHidden();
}

}

此布局侦听测量更改,并且如果新测量结果为<比旧的,这意味着屏幕的一部分被软键盘吃掉。

但是,为了使其正常工作,您需要设置android:windowSoftInputMode="adjustResize",以便调整内容的大小,而不仅仅是移动。

整个系统的工作原理如下: 你有你的布局:

<MyLayout id="layout">
  <SomeImage id="image"/>
  <SomeText>
  <SomeInput>
</MyLayout>

就像evernotes登录屏幕一样。 然后,在你的活动中:

((MyLayout)findViewById(R.id.layout)).setOnSoftKeyboardListener(new OnSoftKeyboardListener() {
        @Override
        public void onShown() {
            findViewById(R.id.image).setVisibility(View.GONE);
        }
        @Override
        public void onHidden() {
            findViewById(R.id.image).setVisibility(View.VISIBLE);
        }
    });

然后转到manifest.xml并设置

android:windowSoftInputMode="adjustResize"

会发生什么,当显示软键盘时,它会隐藏图像并调整其余内容的大小。 (您实际上可以看到如何在Evernote中调整文本大小)

图像隐藏当然是您可以做的许多事情之一。但是你必须要小心,因为不同的布局变化也会调用onMeasure。

当然这是一个肮脏的变种。您需要检查方向变化,以及实际进行测量时的正确时间,以及在将新规格与旧规格进行比较时可能需要更多逻辑。但我认为这是唯一的方法。

答案 1 :(得分:9)

在AndroidManifest.xml中使用“adjustResize”代替“adjustPan”

<activity
    ...
    android:windowSoftInputMode="adjustResize" />

来自documentation

  

“adjustResize”
  活动的主窗口始终调整大小,以便为屏幕上的软键盘腾出空间。

     

“adjustPan”
  活动的主窗口未调整大小以便为软键盘腾出空间。相反,窗口的内容会自动平移,以便键盘不会遮挡当前焦点,用户可以随时看到他们正在键入的内容。这通常不如调整大小,因为用户可能需要关闭软键盘才能进入并与窗口的模糊部分进行交互。

答案 2 :(得分:6)

答案 3 :(得分:2)

这对我有用..这是你的创造

getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE|WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);

答案 4 :(得分:1)

所选答案不适用于全屏模式。 以下一行解决方案为我工作:

 AndroidBug5497Workaround.assistActivity(this);

从以下位置复制AndroidBug5497解决方法:

Android How to adjust layout in Full Screen Mode when softkeyboard is visible

答案 5 :(得分:0)

在父级布局中使用滚动视图,并从清单文件中删除adjustpan或adjustresize设置。 布局中的ScrollView将为您提供免费功能,可以使用给定布局滚动平移或布局,还可以保护布局以覆盖工具栏或操作栏,也不会隐藏布局中的按钮或文本字段。请记住,您必须在基本布局中使用ScrollView,因此此scrollview将作为整个屏幕的基本布局。 示例

<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >

<ScrollView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:fillViewport="true"
    android:scrollbarStyle="insideInset"
    android:scrollbars="vertical" >

    <LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:orientation="vertical" >

        <!-- Add here which you want -->
    </LinearLayout>
</ScrollView>