显示键盘时如何调整布局?

Posted

技术标签:

【中文标题】显示键盘时如何调整布局?【英文标题】:how to adapt a layout when the keyboard is shown? 【发布时间】:2019-03-05 15:08:14 【问题描述】:

我想“指导”android 在用户执行某些弹出键盘的操作时如何正确调整屏幕布局。

实际上,当显示键盘时,android 简单地将其绘制在屏幕最底部的项目上。虽然这是一种简单且有时是正确的方法

在某些情况下,它会变得非常糟糕。例如,如果正在输入的输入文本是屏幕最底部的项目...键盘将简单地覆盖它,用户将丢失有关他正在输入的内容的信息。

另一种情况是当键盘仅部分覆盖某些项目时,android会进入屏幕不稳定的疯狂状态

图像没有显示,但是当键盘弹出时,这两个部分覆盖的按钮正在疯狂地闪烁

所以问题又是......我如何告诉 android 它可以缩小哪些布局项目,或者从屏幕上简单地删除,以便为显示键盘创造空间?

=================更新===============

我认为整个键盘布局情况有两种可能的“最佳方案”: 1- 我想向用户显示的信息在屏幕顶部,所以我希望键盘盖在底部 2- 我想显示的信息在底部,所以我希望键盘“向上推”屏幕,这样用户就可以看到底部的内容,就像下一张照片一样

理想的解决方案不是“应用程序范围”的配置,因为行为应该由布局选择布局

【问题讨论】:

与问题分享您的layout.xml 文件 @NileshRathod,我想要一个通用的标准 android 方式...从我的布局中“挑选”视图并手动将其设置为 GONE 真的不是我想要的 【参考方案1】:

使用

android:windowSoftInputMode="adjustPan"

在您的屏幕上,您将根设置为带有 android:fitSystemView="true" 的 ScrollView

还将下面的按钮从 edittext 设置为可聚焦,将 focusableInTouchMode 设置为 true。

【讨论】:

这应该是公认的答案,因为它是唯一可行的方法。【参考方案2】:

您可以将此行添加到您的manifest(在您的activitytag

android:windowSoftInputMode="adjustPan|adjustResize"

这将滚动视图,这样soft keyboard 不会覆盖视图,

但我不知道你是否可以具体告诉 android 哪些项目要覆盖......

【讨论】:

【参考方案3】:

当键盘显示时,我使用了一种“特殊”(??) 方法来隐藏/更改某些界面:一个隐藏的全屏视图,当键盘变得可见时,它的高度会发生变化,区别在于从键盘。使用以下方法很容易拦截该事件:

View.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() 
    @Override
    public void onGlobalLayout() 
        //the resize event will be triggered here
        ...
    
);

【讨论】:

【参考方案4】:

我通常用 Rx 做这样的(当视图被破坏时它可以很容易地取消订阅) 在我的 BaseFragment 中:

protected fun setSoftwareKeyboardListener(root: View) 
    addDisposable(Flowable.create<Boolean>( emitter ->
        root.viewTreeObserver.addOnGlobalLayoutListener 
            val parentHeight = root.rootView.height
            val heightDiff = parentHeight - root.height
            emitter.onNext(heightDiff > parentHeight / 4)
        
    , BUFFER)
        .subscribe  if (it) onKeyboardOpened() else onKeyboardClosed() )


protected open fun onKeyboardOpened() 

protected open fun onKeyboardClosed() 

以及扩展BaseFragment的内部片段:

override fun onViewCreated(view: View?, savedInstanceState: Bundle?) 
    super.onViewCreated(view, savedInstanceState)
    view?.let  setSoftwareKeyboardListener(it) 

【讨论】:

【参考方案5】:

您可以使用以下方法来解决您的问题。

ma​​in_activity.xml

<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_
    android:layout_
    android:fillViewport="true">

    <android.support.constraint.ConstraintLayout
        android:layout_
        android:layout_
        android:clickable="true"
        android:focusable="true"
        android:focusableInTouchMode="true"
        android:orientation="vertical"
        android:padding="16dp">

        <ImageView
            android:id="@+id/image_logo"
            android:layout_
            android:layout_
            android:layout_marginTop="24dp"
            android:adjustViewBounds="true"
            android:src="@drawable/demo"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

        <EditText
            android:id="@+id/edit_login"
            android:layout_
            android:layout_
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/image_logo" />

        <EditText
            android:id="@+id/edit_password"
            android:layout_
            android:layout_
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/edit_login" />

        <Button
            android:id="@+id/btn_login"
            android:layout_
            android:layout_
            android:text="@string/login"
            android:textAllCaps="false"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/edit_password" />

        <Button
            android:id="@+id/btn_password"
            android:layout_
            android:layout_
            android:layout_alignParentEnd="true"
            android:text="@string/login_with"
            android:textAllCaps="false"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/edit_password" />

        <TextView
            android:layout_
            android:layout_
            android:layout_marginBottom="24dp"
            android:text="@string/forgot_password_q"
            android:textSize="16sp"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/btn_login"
            app:layout_constraintVertical_bias="0.0" />

    </android.support.constraint.ConstraintLayout>

</ScrollView>

在这种情况下,您可以使用默认的 windowSoftInputMode。

<activity android:name=".MainActivity">
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
</activity>

因此,当软件键盘出现时,用户可以滚动 UI。

before scrolling

after scrolling

software keyboard is gone

【讨论】:

以上是关于显示键盘时如何调整布局?的主要内容,如果未能解决你的问题,请参考以下文章

避免 android 软键盘调整布局大小。或回调隐藏视图

我的布局键盘上的空格按钮大小不会调整大小

显示软键盘时向上移动布局?

键盘出现时 UIScrollView “滞后”

键盘显示时离子含量未正确调整

android 横屏状态,如何监听键盘的弹起与隐藏