Android 7.0下ScrollView滚动异常求助(含Appbar Layout与Toolbar)
嗨,我之前也踩过Android 7.0软键盘适配的坑,结合你用AppBarLayout+Toolbar的场景,给你几个针对性的解决方案,按顺序排查应该能解决问题:
windowSoftInputMode的配置是否正确 虽然你说已经修改了AndroidManifest,但可能配置的参数不对。针对ScrollView+AppBarLayout的场景,Android 7.0+建议这样设置:
<activity android:name=".MainActivity" android:windowSoftInputMode="adjustResize|stateHidden"> <!-- 其他配置 --> </activity>
⚠️ 注意:如果你的Activity是全屏模式(比如用了NoActionBar.Fullscreen主题),adjustResize会直接失效——因为全屏状态下系统不会调整窗口大小。这种情况得先去掉全屏设置,或者用下面的自定义ScrollView方案。
AppBarLayout必须和CoordinatorLayout配合才能正常工作,ScrollView也需要绑定对应的滚动行为。正确的布局层级应该是这样:
<androidx.coordinatorlayout.widget.CoordinatorLayout 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"> <!-- AppBarLayout + Toolbar --> <com.google.android.material.appbar.AppBarLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:theme="@style/YourAppBarTheme"> <androidx.appcompat.widget.Toolbar android:id="@+id/toolbar" android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" android:background="?attr/colorPrimary" app:popupTheme="@style/YourPopupTheme"/> </com.google.android.material.appbar.AppBarLayout> <!-- ScrollView必须加上app:layout_behavior --> <ScrollView android:layout_width="match_parent" android:layout_height="match_parent" app:layout_behavior="@string/appbar_scrolling_view_behavior"> <!-- 你的表单内容,比如AutoCompleteTextView这些 --> </ScrollView> </androidx.coordinatorlayout.widget.CoordinatorLayout>
关键是给ScrollView加上app:layout_behavior="@string/appbar_scrolling_view_behavior"——这个属性会让ScrollView和AppBarLayout联动,同时修复高版本系统中软键盘弹出时的滚动异常。
如果上面的配置还是没效果,那可能是Android 7.0+对ScrollView的测量逻辑做了修改。可以自定义一个ScrollView强制适配:
public class ResizableScrollView extends ScrollView { public ResizableScrollView(Context context) { super(context); } public ResizableScrollView(Context context, AttributeSet attrs) { super(context, attrs); } public ResizableScrollView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { // 强制使用AT_MOST模式,让ScrollView能自适应软键盘弹出后的窗口高度 int customHeightSpec = MeasureSpec.makeMeasureSpec( Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST); super.onMeasure(widthMeasureSpec, customHeightSpec); ViewGroup.LayoutParams params = getLayoutParams(); params.height = getMeasuredHeight(); } }
然后把布局里的<ScrollView>替换成<your.package.name.ResizableScrollView>即可。
如果你的应用开启了透明状态栏(比如设置了android:fitsSystemWindows="true"或者代码里调用了WindowCompat.setDecorFitsSystemWindows(getWindow(), false)),在Android 7.0+中可能会打乱软键盘的滚动逻辑。可以尝试调整:
- 给AppBarLayout设置
android:fitsSystemWindows="true" - 给ScrollView设置
android:fitsSystemWindows="false"
或者根据你的实际布局反向调整,多试几次就能找到合适的配置。
内容的提问来源于stack exchange,提问作者Nuwan Withanage

