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

Android 软键盘出现时如何调整布局,android,android-layout,android-softkeyboard,Android,Android Layout,Android Softkeyboard,我想在激活软键盘时调整/重新调整布局,如下所示: 之前和之后: 在SO中找到多个资源: 但是问题和答案是相当模糊的,这里的问题更清楚地描述了我想要什么 要求: 它应该适用于任何屏幕大小的手机 注意到“FACEBOOK”和“注册 “脸谱”在这之前和之后都发生了变化 不涉及滚动视图 只需添加 android:windowSoftInputMode="adjustResize" 在AndroidManifest.xml中声明此特定活动,这将调整布局大小选项 下面是一些布局设计的源代码

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

之前和之后:


在SO中找到多个资源:


  • 但是问题和答案是相当模糊的,这里的问题更清楚地描述了我想要什么

    要求:

    • 它应该适用于任何屏幕大小的手机
    • 注意到“FACEBOOK”和“注册 “脸谱”在这之前和之后都发生了变化
    • 不涉及滚动视图
    只需添加

    android:windowSoftInputMode="adjustResize"
    
    在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>
    

    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>
    
    
    
    由您决定“滚动”和“页脚”部分使用什么视图。还要知道,您可能需要设置
    ScrollView
    s
    .

    在调用活动的清单中添加此行

    android:windowSoftInputMode="adjustPan|adjustResize"
    

    您可以在
    onCreate

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

    这一问题在几年前就被提出了,“秘密的雄性激素”有一个很好的基本解释,“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>
    
    // 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)
    }
    
    标签上,您需要这样的布局

    想法:

    我意识到,
    RelativeLayout
    是跨越所有可用空间的布局,然后在弹出键盘时调整大小

    LinearLayout
    是在调整大小过程中不会调整大小的布局

    这就是为什么您需要在
    ScrollView
    之后立即使用1
    RelativeLayout
    ,以跨越所有可用的屏幕空间。您需要在
    RelativeLayout
    内部有一个
    线性布局
    ,否则在调整大小时,您的内部会被压碎。“头部布局”就是一个很好的例子。如果里面没有
    线性布局
    ,那么
    RelativeLayout
    “facebook”文本将被压碎,不会显示

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

    android:layout_centerVertical="true"
    
    线性布局上。因为主布局在一个
    线性布局中,这意味着该部分不会被调整大小(再次参见有问题的图片)。

    在我的例子中,它有帮助

    main_layout.xml

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:id="@+id/activity_main2"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:paddingBottom="@dimen/activity_vertical_margin"
        android:paddingLeft="@dimen/activity_horizontal_margin"
        android:paddingRight="@dimen/activity_horizontal_margin"
        android:paddingTop="@dimen/activity_vertical_margin"
        android:orientation="vertical"
        tools:context="com.livewallpaper.profileview.loginact.Main2Activity">
    
    <TextView
        android:layout_weight="1"
        android:layout_width="match_parent"
        android:text="Title"
        android:gravity="center"
        android:layout_height="0dp" />
    <LinearLayout
        android:layout_weight="1"
        android:layout_width="match_parent"
        android:layout_height="0dp">
        <EditText
            android:hint="enter here"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />
    </LinearLayout>
    <TextView
        android:layout_weight="1"
        android:text="signup for App"
        android:gravity="bottom|center_horizontal"
        android:layout_width="match_parent"
        android:layout_height="0dp" />
    </LinearLayout>
    
    现在是最重要的部分! 在
    活动
    应用程序
    标记中使用类似的主题

    android:theme="@style/AppTheme"
    
    主题是这样的

    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
        <!-- Customize your theme here. -->
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>
        <item name="windowActionBar">false</item>
        <item name="windowNoTitle">true</item>
        <item name="windowActionModeOverlay">true</item>
    </style>
    
    
    @颜色/原色
    @颜色/原色暗
    @颜色/颜色重音
    假的
    真的
    真的
    

    所以我错过了主题。这让我一整天都很沮丧。

    您只需在AndroidManifest.xml文件中设置这些选项即可

    <activity
        android:name=".YourACtivityName"
        android:windowSoftInputMode="stateVisible|adjustResize">
    

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

  • 将其添加到AndroidManifest.xml中的活动标记中
  • android:WindowsOfInputMode=“调整大小”

    例如:

    <activity android:name=".ActivityLogin"
        android:screenOrientation="portrait"
        android:theme="@style/AppThemeTransparent"
        android:windowSoftInputMode="adjustResize"/>
    
    <RelativeLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_alignParentBottom="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>   
    
    
    
  • activitypage.xml中的布局标签上添加此项,将更改其位置
  • android:fitsSystemWindows=“true”

    android:layout\u alignParentBottom=“true”

    例如:

    <activity android:name=".ActivityLogin"
        android:screenOrientation="portrait"
        android:theme="@style/AppThemeTransparent"
        android:windowSoftInputMode="adjustResize"/>
    
    <RelativeLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_alignParentBottom="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>   
    

    对我来说,它与以下代码行一起工作:

    getActivity().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN);
    
    只需将其放入onCreate方法。
    最好的

    这样就可以显示以前被键盘隐藏的任何想要的布局

    将其添加到AndroidManifest.xml中的活动标记中

    <activity android:name=".signup.screen_2.SignUpNameAndPasswordActivity"
                      android:screenOrientation="portrait"
                      android:windowSoftInputMode="adjustResize">
    </activity>
    
    android:WindowsOfInputMode=“调整大小”


    用ScrollView环绕根视图,最好使用scrollbars=none。ScrollView不会对布局进行任何更改,除非用于解决此问题

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

    android:fitsSystemWindows=“true”

    例如:

    <activity android:name=".ActivityLogin"
        android:screenOrientation="portrait"
        android:theme="@style/AppThemeTransparent"
        android:windowSoftInputMode="adjustResize"/>
    
    <RelativeLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_alignParentBottom="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>   
    
    完整布局示例:

    <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>
    

    
    

    许多答案都是正确的。在
    AndroidManifest
    中,我写道:

    <activity
        android:name=".SomeActivity"
        android:configChanges="orientation|keyboardHidden|screenSize" // Optional, doesn't affect.
        android:theme="@style/AppTheme.NoActionBar"
        android:windowSoftInputMode="adjustResize" />
    
    我注意到,如果使用全屏主题,则不会发生大小调整:

    <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>
    

    你也不会有结果。您可以在根容器中使用android:fitsystemwindows=“true”
    ,但会出现状态栏。因此,请使用第一个链接中的变通方法。

    我使用这个扩展类框架 当我需要重新计算“仅限高度大小”布局时,我会覆盖“测量” 并使用getKeyboardHeight()减去keyboardHeight

    我的创建帧需要使用软键盘调整大小

    SizeNotifierFrameLayout frameLayout = new SizeNotifierFrameLayout(context) {
                private boolean first = true;
    
                @Override
                protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
                    super.onLayout(changed, left, top, right, bottom);
    
                    if (changed) {
                        fixLayoutInternal(first);
                        first = false;
                    }
                }
    
                @Override
                protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
                    super.onMeasure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(MeasureSpec.getSize(heightMeasureSpec) - getKeyboardHeight(), MeasureSpec.EXACTLY));
                }
    
                @Override
                protected boolean drawChild(Canvas canvas, View child, long drawingTime) {
                    boolean result = super.drawChild(canvas, child, drawingTime);
                    if (child == actionBar) {
                        parentLayout.drawHeaderShadow(canvas, actionBar.getMeasuredHeight());
                    }
                    return result;
                }
    
    
            };
    
    SizeNotifier框架布局

    public class SizeNotifierFrameLayout extends FrameLayout {
    
        public interface SizeNotifierFrameLayoutDelegate {
            void onSizeChanged(int keyboardHeight, boolean isWidthGreater);
        }
    
        private Rect                            rect            = new Rect();
        private Drawable                        backgroundDrawable;
        private int                             keyboardHeight;
        private int                             bottomClip;
        private SizeNotifierFrameLayoutDelegate delegate;
        private boolean                         occupyStatusBar = true;
    
        public SizeNotifierFrameLayout(Context context) {
            super(context);
            setWillNotDraw(false);
        }
    
        public Drawable getBackgroundImage() {
            return backgroundDrawable;
        }
    
        public void setBackgroundImage(Drawable bitmap) {
            backgroundDrawable = bitmap;
            invalidate();
        }
    
        public int getKeyboardHeight() {
            View rootView = getRootView();
            getWindowVisibleDisplayFrame(rect);
            int usableViewHeight = rootView.getHeight() - (rect.top != 0 ? AndroidUtilities.statusBarHeight : 0) - AndroidUtilities.getViewInset(rootView);
            return usableViewHeight - (rect.bottom - rect.top);
        }
    
        public void notifyHeightChanged() {
            if (delegate != null) {
                keyboardHeight = getKeyboardHeight();
                final boolean isWidthGreater = AndroidUtilities.displaySize.x > AndroidUtilities.displaySize.y;
                post(new Runnable() {
                    @Override
                    public void run() {
                        if (delegate != null) {
                            delegate.onSizeChanged(keyboardHeight, isWidthGreater);
                        }
                    }
                });
            }
        }
    
        public void setBottomClip(int value) {
            bottomClip = value;
        }
    
        public void setDelegate(SizeNotifierFrameLayoutDelegate delegate) {
            this.delegate = delegate;
        }
    
        public void setOccupyStatusBar(boolean value) {
            occupyStatusBar = value;
        }
    
        protected boolean isActionBarVisible() {
            return true;
        }
    
        @Override
        protected void onDraw(Canvas canvas) {
            if (backgroundDrawable != null) {
                if (backgroundDrawable instanceof ColorDrawable) {
                    if (bottomClip != 0) {
                        canvas.save();
                        canvas.clipRect(0, 0, getMeasuredWidth(), getMeasuredHeight() - bottomClip);
                    }
                    backgroundDrawable.setBounds(0, 0, getMeasuredWidth(), getMeasuredHeight());
                    backgroundDrawable.draw(canvas);
                    if (bottomClip != 0) {
                        canvas.restore();
                    }
                } else if (backgroundDrawable instanceof BitmapDrawable) {
                    BitmapDrawable bitmapDrawable = (BitmapDrawable) backgroundDrawable;
                    if (bitmapDrawable.getTileModeX() == Shader.TileMode.REPEAT) {
                        canvas.save();
                        float scale = 2.0f / AndroidUtilities.density;
                        canvas.scale(scale, scale);
                        backgroundDrawable.setBounds(0, 0, (int) Math.ceil(getMeasuredWidth() / scale), (int) Math.ceil(getMeasuredHeight() / scale));
                        backgroundDrawable.draw(canvas);
                        canvas.restore();
                    } else {
                        int actionBarHeight =
                                (isActionBarVisible() ? ActionBar.getCurrentActionBarHeight() : 0) + (Build.VERSION.SDK_INT >= 21 && occupyStatusBar ? AndroidUtilities.statusBarHeight : 0);
                        int   viewHeight = getMeasuredHeight() - actionBarHeight;
                        float scaleX     = (float) getMeasuredWidth() / (float) backgroundDrawable.getIntrinsicWidth();
                        float scaleY     = (float) (viewHeight + keyboardHeight) / (float) backgroundDrawable.getIntrinsicHeight();
                        float scale      = scaleX < scaleY ? scaleY : scaleX;
                        int   width      = (int) Math.ceil(backgroundDrawable.getIntrinsicWidth() * scale);
                        int   height     = (int) Math.ceil(backgroundDrawable.getIntrinsicHeight() * scale);
                        int   x          = (getMeasuredWidth() - width) / 2;
                        int   y          = (viewHeight - height + keyboardHeight) / 2 + actionBarHeight;
                        canvas.save();
                        canvas.clipRect(0, actionBarHeight, width, getMeasuredHeight() - bottomClip);
                        backgroundDrawable.setBounds(x, y, x + width, y + height);
                        backgroundDrawable.draw(canvas);
                        canvas.restore();
                    }
                }
            } else {
                super.onDraw(canvas);
            }
        }
    
        @Override
        protected void onLayout(boolean changed, int l, int t, int r, int b) {
            super.onLayout(changed, l, t, r, b);
            notifyHeightChanged();
        }
    }
    
    公共类SizeNotifierFrameLayout扩展了FrameLayout{
    公共接口SizeNotifierFrameLayoutDelegate{
    大小更改为空(整型键盘高度,布尔值大于等于);
    }
    private Rect Rect=new Rect();
    私人可提取背景可提取;
    私人int键盘高度;
    私有整数
    
    <?xml version="1.0" encoding="utf-8"?>
    <selector xmlns:android="http://schemas.android.com/apk/res/android">
        <item android:state_enabled="true" android:state_pressed="true">
            <shape android:shape="rectangle">
                <corners android:radius="3dp"/>
                <solid android:color="@color/colorBlueLight"/>
                <stroke android:width="1dp" android:color="@color/colorBlueLight"/>
            </shape>
        </item>
        <item android:state_enabled="true">
            <shape android:shape="rectangle">
                <corners android:radius="3dp"/>
                <solid android:color="@color/colorBlue"/>
                <stroke android:width="1dp" android:color="@color/colorBlue"/>
            </shape>
        </item>
        <item android:state_enabled="false">
            <shape android:shape="rectangle">
                <corners android:radius="3dp"/>
                <solid android:color="@color/colorBlueAlpha"/>
                <stroke android:width="0dp" android:color="@color/colorBlueAlpha"/>
            </shape>
        </item>
    </selector>
    
            <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"/>
    
            <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"/>
    
                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);
                }
            });
    
        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);
    }
    
    android:windowSoftInputMode="adjustResize"
    
     WindowSoftInputMode = Android.Views.SoftInput.AdjustResize | Android.Views.SoftInput.AdjustPan
    
          <activity
            android:name=".ActivityName"
            android:windowSoftInputMode="stateHidden|adjustResize"
            />
    
    requireActivity().window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE or WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN)
    
    android:fitsSystemWindows="true"