【问题标题】:Adjust layout when soft keyboard is on开启软键盘时调整布局
【发布时间】:2011-09-04 16:12:37
【问题描述】:

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

【问题讨论】:

  • 您的问题是显示键盘时布局向上移动吗?
  • 问题是怎么做。
  • 意味着你不希望你的 Layout 拉起来,对吧?
  • 如果您为您的活动设置adjustPan 选项,并且当您的软键盘显示时,UI 将向上移动以显示您当前正在输入文本的 editText。这很好。我的问题是如何使整个布局不可见,而不仅仅是活动的editText(s)。
  • 完全没有让你明白,你只希望 EditText 可见而不是整个布局。如果能附上一些截图就更好了。

标签: android


【解决方案1】:

这是一个类似于 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。

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

【讨论】:

  • 我们在项目中使用相同的方法。讨厌它,但似乎这是在 Android 2.x 上挂钩 IME 显示/隐藏事件的唯一方法。
  • 这有时会有一些错误。这里的这个版本更好:stackoverflow.com/questions/2150078/…
  • 在 Galaxy S4 上无法正常工作。为了更正需要更改 if (oldSpec > newSpec) .. else ... 用 if (oldSpec
  • @JonathanWareham 正如其他链接答案中提到的那样,您还应该采取大约一百像素的任意边距以避免误报。
【解决方案2】:

在 AndroidManifest.xml 中使用 "adjustResize" 而不是 "adjustPan"

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

来自documentation:

“调整大小”
Activity 的主窗口总是会调整大小,以便为屏幕上的软键盘腾出空间。

“调整盘”
Activity 的主窗口没有调整大小来为软键盘腾出空间。相反,窗口的内容会自动平移,因此当前焦点永远不会被键盘遮挡,用户始终可以看到他们正在输入的内容。这通常不如调整大小可取,因为用户可能需要关闭软键盘才能到达窗口的模糊部分并与之交互。

【讨论】:

    【解决方案3】:
    【解决方案4】:

    这对我有用..这是你的 oncreate

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

    【讨论】:

      【解决方案5】:

      所选答案不适用于全屏模式。 以下一条线解决方案对我有用:

       AndroidBug5497Workaround.assistActivity(this);
      

      从以下位置复制 AndroidBug5497Workaround 类:

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

      【讨论】:

      • 谢谢,它正在工作。在我的情况下,布局过于复杂,当键盘出现时,在 Activity 中进行一些定位后,它可能会崩溃(内存不足)。
      • 这些变通方法很危险,因为如果更新库,会在不知不觉中出现冲突,实际上它对我不起作用。有时最好的解决方案不是变通方法,而是从另一个角度看待问题。
      【解决方案6】:

      在父级内的布局中使用滚动视图,并从清单文件中删除 adjustpan 或 adjustresize 设置。 您的布局中的 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>
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-10-09
        • 2017-09-09
        • 1970-01-01
        • 2016-06-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多