Android如何实现AppBarLayout可滚动,触摸AppBar/ImageView显示RecyclerView
核心问题排查
你遇到的滑不动、AppBar占满整屏的问题,都是CoordinatorLayout联动体系的经典踩坑点,根因基本是几个配置错误:
- 给RecyclerView加了
android:layout_below——这是RelativeLayout的专属属性,在CoordinatorLayout里完全不生效,白写 - RecyclerView高度设为
wrap_content:CoordinatorLayout的AppBar联动要求关联的滚动视图必须是match_parent高度,不然滑动坐标计算全乱,根本触发不了联动 - CollapsingToolbarLayout没设最小折叠高度:你虽然写了
exitUntilCollapsed的滚动flag,但没有明确告诉系统折叠到最小状态是多高,这个flag等于白设,AppBar会一直滚动直到完全消失 - ImageView默认不消费触摸事件:你在AppBar的ImageView区域滑动时,事件穿不到CoordinatorLayout的滚动调度层,系统根本识别不到你要滚动的意图
具体修复步骤
- 删掉RecyclerView上无效的
android:layout_below属性,把它的高度从wrap_content改成match_parent——这是联动生效的硬性要求,改完这步至少能保证触摸RecyclerView区域时,AppBar可以跟着收缩 - 给CollapsingToolbarLayout加
app:minHeight="?attr/actionBarSize",明确折叠后的最小高度,让exitUntilCollapsed的flag真正生效,不会出现AppBar滑没了的情况 - 给CollapsingToolbarLayout开
android:nestedScrollingEnabled="true",给内部的ImageView加android:clickable="true"、android:focusable="true",让AppBar区域的触摸事件能顺着View层级传到滚动调度层,实现“摸在AppBar/ImageView上往下滑,也能带着列表联动、收缩AppBar”的效果 - 检查滚动flag的位置:
app:layout_scrollFlags必须写在CollapsingToolbarLayout本身的节点上,不要写在内层的ImageView上,不然折叠逻辑会完全错乱
修复后的核心布局代码参考:
<androidx.coordinatorlayout.widget.CoordinatorLayout android:id="@+id/coordinatorLayout2" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@color/view_background_dark" android:fitsSystemWindows="true"> <com.google.android.material.appbar.AppBarLayout android:id="@+id/app_bar" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@color/view_background_dark"> <com.multilinecollapsingtoolbar.CollapsingToolbarLayout android:id="@+id/toolbar_layout" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@color/view_background_dark" android:nestedScrollingEnabled="true" app:collapsedTitleGravity="left" app:collapsedTitleTextAppearance="@style/Toolbar.CollapsedTitleText" app:contentScrim="@color/view_background_dark" app:defaultParallaxMultiplier="0.75" app:expandedTitleGravity="center_horizontal|bottom" app:expandedTitleMarginBottom="120dp" app:expandedTitleTextAppearance="@style/Toolbar.TitleText" app:layout_scrollFlags="scroll|exitUntilCollapsed" app:minHeight="?attr/actionBarSize" app:maxLines="2" app:toolbarId="@+id/toolbar1"> <ImageView android:id="@+id/player_min_max_btn" android:layout_width="match_parent" android:layout_height="500dp" android:layout_gravity="right" android:layout_marginTop="30dp" android:layout_marginRight="@dimen/page_left_right_margin_half" android:clickable="true" android:focusable="true" app:layout_collapseMode="parallax" /> </com.multilinecollapsingtoolbar.CollapsingToolbarLayout> </com.google.android.material.appbar.AppBarLayout> <androidx.recyclerview.widget.RecyclerView android:id="@+id/rv_next_in_queue" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@color/view_background_dark" app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior" /> </androidx.coordinatorlayout.widget.CoordinatorLayout>
补充:如果改完后在小尺寸设备上,500dp的ImageView还是把整个屏幕占满、导致初始状态看不到RecyclerView,可以把ImageView的固定高度和CollapsingToolbarLayout的展开高度做适配:比如给CollapsingToolbarLayout设一个适配小屏的展开高度,或者把ImageView高度改成
match_parent适配父布局,不要硬写500dp的固定值,避免不同尺寸屏幕上溢出。
内容的提问来源于stack exchange,提问作者RahulS
相关产品推荐
相关产品推荐

