软键盘出现时如何调整布局

Roy*_*Lee 147 android android-layout android-softkeyboard

我想在软键盘激活时调整/重新调整布局大小,如下所示:

之前和之后:

在此输入图像描述在此输入图像描述


在SO中找到了几个资源:

  1. 如何在显示软键盘时保持所有字段和文本可见
  2. android软键盘出现时会破坏布局
  3. 软键盘打开时调整布局

但问题和答案相当模糊,这里的问题是我想要的更清晰的画面.

要求:

  • 它应该适用于任何屏幕尺寸的手机.
  • 注意到"FACEBOOK"和"注册Facebook"的保证金/填充空间在之前和之后都发生了变化.
  • 不涉及滚动视图.

Ven*_*h S 183

只需添加

android:windowSoftInputMode="adjustResize"
Run Code Online (Sandbox Code Playgroud)

在AndroidManifest.xml中,您声明此特定活动,这将调整布局调整大小选项.

在此输入图像描述

下面的一些源代码用于布局设计

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <TextView
        android:id="@+id/textView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="20dp"
        android:text="FaceBook"
        android:textAppearance="?android:attr/textAppearanceLarge" />

    <EditText
        android:id="@+id/editText1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@+id/textView1"
        android:layout_marginTop="30dp"
        android:ems="10"
        android:hint="username" >

        <requestFocus />
    </EditText>

    <EditText
        android:id="@+id/editText2"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@+id/editText1"
        android:layout_marginTop="20dp"
        android:ems="10"
        android:hint="password" />

    <Button
        android:id="@+id/button1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@+id/editText2"
        android:layout_centerHorizontal="true"
        android:layout_marginLeft="18dp"
        android:layout_marginTop="20dp"
        android:text="Log In" />

    <TextView
        android:id="@+id/textView2"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_marginTop="17dp"
        android:gravity="center"
        android:text="Sign up for facebook"
        android:textAppearance="?android:attr/textAppearanceLarge" />

</RelativeLayout>
Run Code Online (Sandbox Code Playgroud)

  • 朋友似乎只有带有"注册Facebook"的TextView在软键盘激活时自行调整,其他人保持不变.我希望其他人也能进行调整.任何解决方法?在激活键盘之前,整个布局应位于中心位置, (7认同)
  • +1这简单吗?任何额外的条件?你发布的图片是什么? (2认同)
  • 朋友只是为了显示alignparentbottom ="true"如果屏幕没有正确调整..因此我放置了那个图像朋友 (2认同)
  • k朋友,谢谢大家,希望我们能再见面 (2认同)

Yan*_*000 34

几年前问了这个问题,"秘密Andro Geni"有一个很好的基础解释,"tir38"也对完整的解决方案做了很好的尝试,但是这里没有完整的解决方案.我花了几个小时搞清楚事情,这是我的完整解决方案,底部有详细解释:

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

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:padding="10dp">

        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_above="@+id/mainLayout"
            android:layout_alignParentTop="true"
            android:id="@+id/headerLayout">

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_centerVertical="true"
                android:gravity="center_horizontal">

                <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:id="@+id/textView1"
                    android:text="facebook"
                    android:textStyle="bold"
                    android:ellipsize="marquee"
                    android:singleLine="true"
                    android:textAppearance="?android:attr/textAppearanceLarge" />

            </LinearLayout>

        </RelativeLayout>

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_centerVertical="true"
            android:id="@+id/mainLayout"
            android:orientation="vertical">

            <EditText
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:id="@+id/editText1"
                android:ems="10"
                android:hint="Email or Phone"
                android:inputType="textVisiblePassword">

                <requestFocus />
            </EditText>

            <EditText
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginTop="10dp"
                android:id="@+id/editText2"
                android:ems="10"
                android:hint="Password"
                android:inputType="textPassword" />

            <Button
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginTop="10dp"
                android:id="@+id/button1"
                android:text="Log In"
                android:onClick="login" />

        </LinearLayout>

        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_alignParentBottom="true"
            android:layout_below="@+id/mainLayout"
            android:id="@+id/footerLayout">

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_alignParentBottom="true">

                <RelativeLayout
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content">

                    <TextView
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:id="@+id/textView2"
                        android:text="Sign Up for Facebook"
                        android:layout_centerHorizontal="true"
                        android:layout_alignBottom="@+id/helpButton"
                        android:ellipsize="marquee"
                        android:singleLine="true"
                        android:textAppearance="?android:attr/textAppearanceSmall" />

                    <Button
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:layout_alignParentRight="true"
                        android:id="@+id/helpButton"
                        android:text="\?"
                        android:onClick="help" />

                </RelativeLayout>

            </LinearLayout>

        </RelativeLayout>

    </RelativeLayout>

</ScrollView>
Run Code Online (Sandbox Code Playgroud)

AndroidManifest.xml中,不要忘记设置:

android:windowSoftInputMode="adjustResize"
Run Code Online (Sandbox Code Playgroud)

<activity>标签上你想要这样的布局.

思考:

我已经意识到这RelativeLayout是通过所有可用空间的布局,然后在键盘弹出时调整大小.

并且LinearLayout在调整大小过程中不会调整大小的布局.

这就是为什么你需要RelativeLayoutScrollView通过所有可用屏幕空间后立即获得1 .并且你需要有一个LinearLayout内部的RelativeLayout其他内容,你的内部将在调整大小时被压碎.好的例子是"headerLayout".如果没有LinearLayout内部RelativeLayout"facebook"文本会被粉碎而且不会显示.

在问题中发布的"facebook"登录图片中我也注意到整个登录部分(mainLayout)相对于整个屏幕是垂直居中的,因此属性:

android:layout_centerVertical="true"
Run Code Online (Sandbox Code Playgroud)

LinearLayout布局上.并且因为mainLayout在内部,LinearLayout这意味着该部分不会被调整大小(再次看到相关图片).


Ash*_*wal 23

在您的Manifest中添加此行,您的Activity将被调用

android:windowSoftInputMode="adjustPan|adjustResize"
Run Code Online (Sandbox Code Playgroud)

要么

你可以添加这一行 onCreate

getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE|WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
Run Code Online (Sandbox Code Playgroud)

  • 绝对不要同时使用`adjustPan`和`adjustResize`。这些是不同的模式。在这里阅读有关它们的更多信息:/sf/answers/1218736991/在这里:https://developer.android.com/guide/topics/manifest/activity-element (4认同)

tir*_*r38 13

Android Developer有正确的答案,但提供的源代码非常冗长,并没有实际实现图中描述的模式.

这是一个更好的模板:

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

    <RelativeLayout android:layout_width="match_parent"
                    android:layout_height="match_parent">

        <LinearLayout android:layout_width="match_parent"
                      android:layout_height="wrap_content"
                      android:orientation="vertical">

                <!-- stuff to scroll -->

        </LinearLayout>

        <FrameLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_alignParentBottom="true">

            <!-- footer -->

        </FrameLayout>

    </RelativeLayout>

</ScrollView>
Run Code Online (Sandbox Code Playgroud)

由您自己决定用于"滚动"和"页脚"部分的视图.也知道你可能要设置ScrollViews fillViewPort.


小智 10

它可以适用于所有类型的布局.

  1. 将其添加到AndroidManifest.xml中的activity标记中

机器人:windowSoftInputMode = "adjustResize"

例如:

<activity android:name=".ActivityLogin"
    android:screenOrientation="portrait"
    android:theme="@style/AppThemeTransparent"
    android:windowSoftInputMode="adjustResize"/>
Run Code Online (Sandbox Code Playgroud)
  1. 将它添加到activitypage.xml中的布局标记上,该标记将更改其位置.

机器人:fitsSystemWindows = "真"

机器人:layout_alignParentBottom = "真"

例如:

<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:fitsSystemWindows="true">
Run Code Online (Sandbox Code Playgroud)


Noc*_*urn 9

对于那些使用ConstraintLayout 的人android:windowSoftInputMode="adjustPan|adjustResize"将不起作用。

您可以做的是使用软键盘侦听器,从上视图的底部到底部设置视图的约束,然后将每个视图的垂直偏差(作为约束之间的位置百分比)设置为水平指南(也按百分比定位) ,但对父母)。

对于每个视图,我们只需要在显示键盘时更改app:layout_constraintBottom_toBottomOf为,当然是以编程方式。@+id/guideline

        <ImageView
        android:id="@+id/loginLogo"
        ...
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.15" />


        <RelativeLayout
        android:id="@+id/loginFields"
        ...
        app:layout_constraintVertical_bias=".15"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/loginLogo">

        <Button
        android:id="@+id/login_btn"
        ...
        app:layout_constraintVertical_bias=".25"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/loginFields"/>
Run Code Online (Sandbox Code Playgroud)

一般软键盘占屏幕高度不超过50%。因此,您可以将准则设置为 0.5。

        <android.support.constraint.Guideline
        android:id="@+id/guideline"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        app:layout_constraintGuide_percent="0.5"/>
Run Code Online (Sandbox Code Playgroud)

现在以编程方式,当键盘未显示时,我们可以将所有app:layout_constraintBottom_toBottomOf返回到父级,反之亦然。

            unregistrar = KeyboardVisibilityEvent.registerEventListener(this, isOpen -> {
            loginLayout.startAnimation(AnimationManager.getFade(200));
            if (isOpen) {
                setSoftKeyViewParams(loginLogo, R.id.guideline, ConstraintLayout.LayoutParams.PARENT_ID, -1, "235:64", 0.15f,
                        63, 0, 63, 0);
                setSoftKeyViewParams(loginFields, R.id.guideline, -1, R.id.loginLogo, null, 0.15f,
                        32, 0, 32, 0);
                setSoftKeyViewParams(loginBtn, R.id.guideline, -1, R.id.useFingerPrintIdText, null, 0.5f,
                        32, 0, 32, 0);
            } else {
                setSoftKeyViewParams(loginLogo, ConstraintLayout.LayoutParams.PARENT_ID, ConstraintLayout.LayoutParams.PARENT_ID, -1, "235:64", 0.15f,
                        63, 0, 63, 0);
                setSoftKeyViewParams(loginFields, ConstraintLayout.LayoutParams.PARENT_ID, -1, R.id.loginLogo,null, 0.15f,
                        32, 0, 32, 0);
                setSoftKeyViewParams(loginBtn, ConstraintLayout.LayoutParams.PARENT_ID, -1, R.id.useFingerPrintIdText,null, 0.25f,
                        32, 0, 32, 0);
            }
        });
Run Code Online (Sandbox Code Playgroud)

调用这个方法:

    private void setSoftKeyViewParams(View view, int bottomToBottom, int topToTop, int topToBottom, String ratio, float verticalBias,
                                  int left, int top, int right, int bottom) {
    ConstraintLayout.LayoutParams viewParams = new ConstraintLayout.LayoutParams(view.getLayoutParams().width, view.getLayoutParams().height);
    viewParams.dimensionRatio = ratio;
    viewParams.bottomToBottom = bottomToBottom;
    viewParams.topToTop = topToTop;
    viewParams.topToBottom = topToBottom;
    viewParams.endToEnd = ConstraintLayout.LayoutParams.PARENT_ID;
    viewParams.startToStart = ConstraintLayout.LayoutParams.PARENT_ID;
    viewParams.verticalBias = verticalBias;
    viewParams.setMargins(Dimensions.dpToPx(left), Dimensions.dpToPx(top), Dimensions.dpToPx(right), Dimensions.dpToPx(bottom));
    view.setLayoutParams(viewParams);
}
Run Code Online (Sandbox Code Playgroud)

重要的是要确保设置垂直偏置,以便在显示和未显示键盘时正确缩放。

  • 更简单的方法是将 ConstraintLayout 包装在 ScrollView 或 NestedScrollView 中。计算最终变得过于繁琐。但如果 ScrollView 最终会导致其他问题,你的答案很好 (3认同)

Mor*_*ard 6

这样就可以显示键盘先前隐藏的任何所需布局。

将此添加到AndroidManifest.xml中的活动标签中

android:windowSoftInputMode =“ adjustResize”


用ScrollView包围您的根视图,最好用scrollbars = none包围。ScrollView不会正确更改布局,除非用于解决此问题。

然后在要使其完全显示在键盘上方的视图上设置fitsSystemWindows =“ true”。这将使您的EditText在键盘上方可见,并使向下滚动到EditText下方但在带有fitsSystemWindows =“ true”的视图中的部分成为可能。

android:fitsSystemWindows =“ true”

例如:

<ScrollView
    android:id="@+id/scrollView"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:scrollbars="none">

    <android.support.constraint.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:fitsSystemWindows="true">

        ...

    </android.support.constraint.ConstraintLayout>
</ScrollView>   
Run Code Online (Sandbox Code Playgroud)

如果要在出现键盘时在键盘上方显示fitsSystemWindows =“ true”视图的整个部分,则需要一些代码才能将视图滚动到底部:

// Code is in Kotlin

setupKeyboardListener(scrollView) // call in OnCreate or similar


private fun setupKeyboardListener(view: View) {
    view.viewTreeObserver.addOnGlobalLayoutListener {
        val r = Rect()
        view.getWindowVisibleDisplayFrame(r)
        if (Math.abs(view.rootView.height - (r.bottom - r.top)) > 100) { // if more than 100 pixels, its probably a keyboard...
            onKeyboardShow()
        }
    }
}

private fun onKeyboardShow() {
    scrollView.scrollToBottomWithoutFocusChange()
}

fun ScrollView.scrollToBottomWithoutFocusChange() { // Kotlin extension to scrollView
    val lastChild = getChildAt(childCount - 1)
    val bottom = lastChild.bottom + paddingBottom
    val delta = bottom - (scrollY + height)
    smoothScrollBy(0, delta)
}
Run Code Online (Sandbox Code Playgroud)

完整版式示例:

<android.support.constraint.ConstraintLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:fitsSystemWindows="true">

    <RelativeLayout
        android:id="@+id/statisticsLayout"
        android:layout_width="match_parent"
        android:layout_height="340dp"
        android:background="@drawable/some"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent">

        <ImageView
            android:id="@+id/logoImageView"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="64dp"
            android:src="@drawable/some"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

    </RelativeLayout>

    <RelativeLayout
        android:id="@+id/authenticationLayout"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_marginEnd="32dp"
        android:layout_marginStart="32dp"
        android:layout_marginTop="20dp"
        android:focusableInTouchMode="true"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@id/statisticsLayout">

        <android.support.design.widget.TextInputLayout
            android:id="@+id/usernameEditTextInputLayout"
            android:layout_width="match_parent"
            android:layout_height="68dp">

            <EditText
                android:id="@+id/usernameEditText"
                android:layout_width="match_parent"
                android:layout_height="wrap_content" />

        </android.support.design.widget.TextInputLayout>

        <android.support.design.widget.TextInputLayout
            android:id="@+id/passwordEditTextInputLayout"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_below="@id/usernameEditTextInputLayout">

            <EditText
                android:id="@+id/passwordEditText"
                android:layout_width="match_parent"
                android:layout_height="wrap_content" />

        </android.support.design.widget.TextInputLayout>

        <Button
            android:id="@+id/loginButton"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_below="@id/passwordEditTextInputLayout"
            android:layout_centerHorizontal="true"
            android:layout_marginBottom="10dp"
            android:layout_marginTop="20dp" />

        <Button
            android:id="@+id/forgotPasswordButton"
            android:layout_width="wrap_content"
            android:layout_height="40dp"
            android:layout_below="@id/loginButton"
            android:layout_centerHorizontal="true" />

    </RelativeLayout>

</android.support.constraint.ConstraintLayout>
Run Code Online (Sandbox Code Playgroud)


Coo*_*ind 6

很多答案都是对的。在AndroidManifest我写道:

<activity
    android:name=".SomeActivity"
    android:configChanges="orientation|keyboardHidden|screenSize" // Optional, doesn't affect.
    android:theme="@style/AppTheme.NoActionBar"
    android:windowSoftInputMode="adjustResize" />
Run Code Online (Sandbox Code Playgroud)

就我而言,我在 中添加了一个主题styles.xml,但您可以使用自己的主题:

<style name="AppTheme.NoActionBar" parent="AppTheme">
    <!--  Hide ActionBar -->
    <item name="windowNoTitle">true</item>
    <item name="windowActionBar">false</item>
</style>
Run Code Online (Sandbox Code Playgroud)

我注意到如果我使用全屏主题,则不会发生调整大小:

<style name="AppTheme.FullScreenTheme" parent="AppTheme">
    <!--  Hide ActionBar -->
    <item name="windowNoTitle">true</item>
    <item name="windowActionBar">false</item>
    <!--  Hide StatusBar -->
    <item name="android:windowFullscreen">true</item>
</style>
Run Code Online (Sandbox Code Playgroud)

在我的情况下也adjustResize有效,但adjustPan没有。

对于全屏布局,请参阅Android 如何在软键盘可见时或在https://gist.github.com/grennis/2e3cd5f7a9238c59861015ce0a7c5584 中以全屏模式调整布局中的解决方法。

https://medium.com/@sandeeptengale/problem-solved-3-android-full-screen-view-translucent-scrollview-adjustresize-keyboard-b0547c7ced32工作,但它的 StatusBar 是透明的,所以电池,时钟,Wi- Fi 图标可见。

如果您使用“文件”>“新建”>“活动”>“全屏活动”创建活动,则使用代码的位置:

fullscreen_content.systemUiVisibility =
    View.SYSTEM_UI_FLAG_LOW_PROFILE or
    View.SYSTEM_UI_FLAG_FULLSCREEN or
    View.SYSTEM_UI_FLAG_LAYOUT_STABLE or
    View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY or
    View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION or
    View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
Run Code Online (Sandbox Code Playgroud)

你也不会取得结果。您可以android:fitsSystemWindows="true"在根容器中使用,但会出现 StatusBar。因此,请使用第一个链接中的解决方法。


归档时间:

查看次数:

141644 次

最近记录:

6 年,6 月 前