ScrollView仅能有一个直接子控件报错,尝试NestedScrollView未解决
解决ScrollView嵌套布局引发的崩溃问题
问题场景
Fragment嵌套在Activity中,使用ScrollView实现滚动效果。布局中计划让ScrollView仅包含一个RelativeLayout作为直接子控件,但应用打开页面5-6秒后崩溃,报错提示ScrollView只能容纳一个直接子控件。
相关布局代码
Fragment布局
<?xml version="1.0" encoding="utf-8"?> <layout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools"> <data> </data> <ScrollView android:layout_width="wrap_content" android:layout_height="wrap_content"> <!-- 此处错误:RelativeLayout使用自闭合标签,导致后续控件成为ScrollView的直接子View --> <RelativeLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@drawable"/> <com.google.android.material.appbar.AppBarLayout android:id="@+id/settingsAppBar" android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" > <androidx.constraintlayout.widget.ConstraintLayout android:layout_width="match_parent" android:layout_height="match_parent"> <androidx.appcompat.widget.Toolbar android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" /> <com.google.android.material.button.MaterialButton android:id="@+id/backButton" style="@style/back_arrow_button" /> </androidx.constraintlayout.widget.ConstraintLayout> </com.google.android.material.appbar.AppBarLayout> <androidx.cardview.widget.CardView > <LinearLayout > <RelativeLayout style="@style/settings_relative_layout_style"> <TextView /> <com.google.android.material.imageview.ShapeableImageView /> </RelativeLayout> <View android:layout_width="match_parent" /> <TextView style="@style/settings_text_style" /> <RelativeLayout style="@style/settings_relative_layout_style"> <TextView /> <ImageView /> </RelativeLayout> <RelativeLayout style="@style/settings_relative_layout_style"> <TextView /> <ImageView /> </RelativeLayout> <View android:layout_height="1dp" /> <TextView /> <RelativeLayout style="@style/settings_relative_layout_style"> <TextView /> <ImageView /> </RelativeLayout> <RelativeLayout style="@style/settings_relative_layout_style"> <TextView /> <ImageView /> </RelativeLayout> <RelativeLayout style="@style/settings_relative_layout_style"> <TextView /> <ImageView /> </RelativeLayout> <RelativeLayout style="@style/settings_relative_layout_style"> <TextView /> <ImageView style="@style/settings_image_view_style" /> </RelativeLayout> </LinearLayout> </androidx.cardview.widget.CardView> </RelativeLayout> </ScrollView> </layout>
Main Activity布局
<?xml version="1.0" encoding="utf-8"?> <layout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools"> <RelativeLayout android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".ui.presentations.activity.MainActivity"> <androidx.fragment.app.FragmentContainerView android:id="@+id/fragmentContainerView" android:name="androidx.navigation.fragment.NavHostFragment" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_above="@+id/bottomMenu" app:defaultNavHost="true" /> <me.ibrahimsn.lib.SmoothBottomBar android:visibility="gone" app:iconSize="@dimen/l" android:elevation="@dimen/xxxs" app:iconTintActive="@color/nav_icon_color" app:iconTint="#D0D0D0" android:id="@+id/bottomMenu" android:layout_width="match_parent" android:layout_height="@dimen/xxxxxxl" android:layout_alignParentBottom="true" app:menu="@menu/bottom_nav_menu" /> </RelativeLayout> </layout>
错误日志
FATAL EXCEPTION: main Process: ltd.tinkers.example, PID: 10147 java.lang.IllegalStateException: ScrollView can host only one direct child at androidx.core.widget.NestedScrollView.addView(NestedScrollView.java:515) at com.google.android.material.snackbar.BaseTransientBottomBar$SnackbarBaseLayout.addToTargetParent(BaseTransientBottomBar.java:1330) at com.google.android.material.snackbar.BaseTransientBottomBar.showView(BaseTransientBottomBar.java:757) at com.google.android.material.snackbar.BaseTransientBottomBar$1.handleMessage(BaseTransientBottomBar.java:263) at android.os.Handler.dispatchMessage(Handler.java:102) at android.os.Looper.loop(Looper.java:223) at android.app.ActivityThread.main(ActivityThread.java:7948) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:603) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)
解决方案
崩溃的核心原因是Fragment布局中的RelativeLayout标签错误:开头的<RelativeLayout .../>使用了自闭合标签,导致该RelativeLayout直接结束,后续的AppBarLayout、CardView都变成了ScrollView的直接子控件,违反了ScrollView只能有一个直接子View的规则。当Snackbar尝试向ScrollView添加视图时,触发了这个异常。
修复方法:将RelativeLayout的自闭合标签改为普通开标签,确保所有子控件都嵌套在RelativeLayout内部:
<ScrollView android:layout_width="wrap_content" android:layout_height="wrap_content"> <!-- 修正:去掉自闭合的/,改为普通开标签 --> <RelativeLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@drawable"> <!-- 所有子控件(AppBarLayout、CardView等)都放在这个RelativeLayout内部 --> <com.google.android.material.appbar.AppBarLayout ...> ... </com.google.android.material.appbar.AppBarLayout> <androidx.cardview.widget.CardView ...> ... </androidx.cardview.widget.CardView> </RelativeLayout> <!-- 此处闭合RelativeLayout --> </ScrollView>
修正后,ScrollView只有RelativeLayout这一个直接子控件,符合要求,崩溃问题即可解决。
内容的提问来源于stack exchange,提问作者Shakib hasan
相关产品推荐
相关产品推荐

