Android布局适配需求:软键盘弹出控件贴底,收起时居中
Alright, let's figure out how to get this layout behaving exactly as you want—input field centered when the keyboard's hidden, stuck to the bottom when it pops up, and that first Space getting compressed first. Here's the breakdown:
First, Critical Setup
Make sure your target Activity has android:windowSoftInputMode="adjustResize" added in your AndroidManifest.xml. This tells the system to resize your layout (instead of panning it) when the soft keyboard appears—this is non-negotiable for the behavior you want.
Recommended Solution: ConstraintLayout (Most Reliable)
ConstraintLayout gives you precise control over which views get resized when the layout changes. Here's the revised layout that meets all your requirements:
<?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent" android:fitsSystemWindows="true"> <!-- First Space: Gets compressed first when keyboard pops up --> <android.support.v4.widget.Space android:id="@+id/space_top" android:layout_width="match_parent" android:layout_height="0dp" app:layout_constraintTop_toTopOf="parent" app:layout_constraintBottom_toTopOf="@id/input_container" app:layout_constraintVertical_weight="1"/> <!-- Container for input field and button --> <LinearLayout android:id="@+id/input_container" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" android:paddingHorizontal="16dp" app:layout_constraintTop_toBottomOf="@id/space_top" app:layout_constraintBottom_toTopOf="@id/space_bottom" app:layout_constraintVertical_bias="0.5"> <!-- Centers container when keyboard is hidden --> <android.support.design.widget.TextInputLayout android:id="@+id/walletPasswordEditLayout" android:layout_width="match_parent" android:layout_height="wrap_content"> <android.support.design.widget.TextInputEditText style="@style/AppEditText" android:layout_width="match_parent" android:layout_height="wrap_content" android:inputType="textPassword"/> </android.support.design.widget.TextInputLayout> <Button style="@style/AppButton.Black" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="16dp" android:text="Submit"/> </LinearLayout> <!-- Second Space: Maintains its height when keyboard appears --> <android.support.v4.widget.Space android:id="@+id/space_bottom" android:layout_width="match_parent" android:layout_height="0dp" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintTop_toBottomOf="@id/input_container" app:layout_constraintVertical_weight="0"/> </androidx.constraintlayout.widget.ConstraintLayout>
Key Details:
- Top Space: The
layout_constraintVertical_weight="1"makes it take up all available vertical space above the input container when the keyboard is hidden. When the keyboard pops up and the layout shrinks, this space gets compressed first (since it has a higher weight than the bottom space). - Input Container:
layout_constraintVertical_bias="0.5"keeps it perfectly centered vertically when both spaces are active. As the top space shrinks, the container naturally shifts toward the bottom. - Bottom Space: With
layout_constraintVertical_weight="0", it stays at a minimal height (you can set a fixedlayout_heighthere if you want a specific gap at the bottom) and never gets compressed.
Alternative: LinearLayout (Simpler but Less Flexible)
If you want to stick with LinearLayout, here's an approach that works—though it's a bit less precise for centering:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:fitsSystemWindows="true"> <!-- First Space: Prioritized for compression --> <android.support.v4.widget.Space android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" android:minHeight="0dp"/> <!-- Input and button container --> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" android:paddingHorizontal="16dp"> <android.support.design.widget.TextInputLayout android:id="@+id/walletPasswordEditLayout" android:layout_width="match_parent" android:layout_height="wrap_content"> <android.support.design.widget.TextInputEditText style="@style/AppEditText" android:layout_width="match_parent" android:layout_height="wrap_content" android:inputType="textPassword"/> </android.support.design.widget.TextInputLayout> <Button style="@style/AppButton.Black" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="16dp" android:text="Submit"/> </LinearLayout> <!-- Second Space: Fixed minimal height, won't compress --> <android.support.v4.widget.Space android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="0"/> </LinearLayout>
LinearLayout Caveat:
To get perfect centering when the keyboard is hidden, you'd need to set the bottom space to also have layout_weight="1", but that would make both spaces compress equally when the keyboard pops up. The above setup prioritizes the top space but centers the input close enough for most use cases.
内容的提问来源于stack exchange,提问作者nutella_eater

