如何实现类似新版Google Tasks的重叠视图菜单?解决Elevation层级问题
解决Google Tasks风格菜单布局的按钮遮挡问题
我之前也碰到过一模一样的情况!想做那种像Google Tasks里的悬浮按钮,卡在底部白色栏和列表中间,但加了elevation之后按钮反而被底部栏挡住,哪怕给按钮设了更高的elevation也没用。其实问题出在View的层级关系和父布局的裁剪设置上,下面给你说具体的解决办法:
问题根源
Android里的elevation不是单纯比数值大小就管用的:如果你的按钮是放在RecyclerView或者它的子布局里面,那它的父布局可能开启了clipChildren或者clipToPadding属性,会把超出父布局范围的部分裁剪掉;另外如果底部栏和按钮不在同一个根布局层级,底部栏的父布局层级更高的话,也会把按钮盖住。
正确实现方案
最稳妥的方式是用ConstraintLayout作为根布局,直接管理RecyclerView、底部栏和悬浮按钮的层级关系,具体步骤如下:
- 调整布局层级:把RecyclerView、底部白色栏、悬浮按钮都放在同一个根布局(ConstraintLayout)下,并且在XML中把按钮写在底部栏的后面——因为XML中后声明的View默认层级更高,再配合
elevation就能确保按钮在底部栏之上。 - 设置正确的
elevation值:给底部栏设置一个基础elevation(比如4dp),按钮的elevation要比它高(比如8dp),这样阴影效果也能正确显示。 - 处理列表和按钮的重叠空间:给RecyclerView设置底部内边距,保证列表最后一项不会被按钮和底部栏挡住;同时给按钮设置
translationY向上偏移一半高度,让它刚好卡在底部栏和列表之间。
完整布局示例
<?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"> <!-- 列表RecyclerView --> <androidx.recyclerview.widget.RecyclerView android:id="@+id/tasksRecyclerView" android:layout_width="match_parent" android:layout_height="match_parent" app:layout_constraintTop_toTopOf="parent" app:layout_constraintBottom_toTopOf="@id/bottomActionBar" <!-- 给底部留足够空间,避免内容被按钮和底部栏遮挡 --> android:paddingBottom="80dp"/> <!-- 底部白色操作栏 --> <LinearLayout android:id="@+id/bottomActionBar" android:layout_width="match_parent" android:layout_height="60dp" android:background="@android:color/white" android:elevation="4dp" app:layout_constraintBottom_toBottomOf="parent" android:gravity="center" android:orientation="horizontal"> <!-- 底部栏里的按钮或其他控件 --> </LinearLayout> <!-- 悬浮按钮,放在底部栏之后确保层级更高 --> <com.google.android.material.floatingactionbutton.FloatingActionButton android:id="@+id/addTaskBtn" android:layout_width="wrap_content" android:layout_height="wrap_content" android:elevation="8dp" android:src="@drawable/ic_baseline_add_24" app:layout_constraintBottom_toTopOf="@id/bottomActionBar" app:layout_constraintStart_toStartOf="parent" app:layout_constraintEnd_toEndOf="parent" <!-- 向上偏移一半高度,实现和底部栏的重叠效果 --> android:translationY="-30dp"/> </androidx.constraintlayout.widget.ConstraintLayout>
额外注意事项
- 如果你的按钮不是FAB,是自定义的View,也要确保它的
elevation属性设置正确,并且它的直接父布局没有开启clipChildren="true"(默认是true,需要改成false)。 - 不要把按钮放在RecyclerView的item布局或者RecyclerView的直接子布局里,那样不管怎么设
elevation,都会被底部栏或者RecyclerView的父布局裁剪。
内容的提问来源于stack exchange,提问作者Jeremi
相关产品推荐
相关产品推荐

