软键盘弹出时布局上移原因及EditText获焦防滚动方案(含Fragment/ConstraintLayout)
Hey there, let's tackle your questions step by step, considering your project setup (two Fragments, ConstraintLayout, no ScrollView):
This is actually Android's default behavior tied to the windowSoftInputMode setting. When the soft keyboard pops up, the system automatically tries to adjust the window content to ensure the focused EditText isn't blocked. Even without a ScrollView, if your layout's bottom elements would be covered by the keyboard, the system will shift the entire layout upward—this gives the appearance of scrolling, but it's actually the window itself being repositioned.
Since you're using ConstraintLayout with match_parent height, the system detects that the focused view might be obscured and triggers this adjustment to keep it visible.
Here are targeted solutions based on your setup:
1. Adjust the Activity's windowSoftInputMode (most effective)
Modify your Activity entry in AndroidManifest.xml to control how the system handles the soft keyboard:
<activity android:name=".MainActivity" android:windowSoftInputMode="adjustPan|stateHidden"> <!-- ... other attributes ... --> </activity>
adjustPan: The system shifts the window up (instead of resizing it) to keep the focused view visible. Unlike resizing, this won't cause "scroll-like" behavior for the rest of the layout.- If you want the system to do no adjustment at all (the keyboard will overlay the layout), use
adjustNothinginstead. Just make sure yourEditTextis positioned high enough that it won't be blocked by the keyboard (you can use ConstraintLayout guidelines to lock its position above the typical keyboard height).
2. Optimize ConstraintLayout and focus behavior
Since you're using ConstraintLayout, pair the window setting with these tweaks:
- Ensure your root ConstraintLayout uses
android:height="match_parent"and has proper bottom constraints for all elements. For example, anchor bottom UI elements to the parent's bottom withapp:layout_constraintBottom_toBottomOf="parent"—this keeps the layout anchored even if the window shifts. - Prevent automatic focus on
EditText(which triggers the adjustment):
In your Fragment'sonViewCreatedmethod, make the root layout focusable so it grabs focus first:@Override public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); // Make root layout focusable to prevent EditText from auto-focusing view.setFocusableInTouchMode(true); view.requestFocus(); }
3. Handle Fragment switch focus issues
When using replace to switch Fragments, the new Fragment's EditText might auto-focus and trigger the layout shift. Fix this by:
- Adding the above focus code to every Fragment's
onViewCreatedmethod. - If you need the
EditTextto gain focus but not trigger scrolling, combine theadjustPansetting with a focus listener that avoids unnecessary layout shifts:EditText yourEditText = view.findViewById(R.id.your_edittext_id); yourEditText.setOnFocusChangeListener((v, hasFocus) -> { if (hasFocus) { // Optional: Manually adjust layout if needed, but we're preventing extra scrolling here } });
内容的提问来源于stack exchange,提问作者chari sharma

