Android中如何让include布局内的Floating Button悬浮于其他内容之上?
问题描述
我用Android Studio结合Java开发应用,为了复用悬浮按钮,把它定义在trademark.xml中,通过<include>标签引入到activity_main.xml里,但这个按钮没法悬浮在布局内的其他内容上方,我不想在每个布局里重复声明按钮,求解决办法。
相关代码(activity_main.xml):
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout 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" android:id="@+id/main" android:layout_width="match_parent" android:layout_height="match_parent" android:backgroundTint="#747474" tools:context=".MainActivity" android:padding="10dp"> <ImageView android:layout_width="match_parent" android:layout_height="300dp" android:src="@drawable/happybirthday" android:layout_below="@id/fav" android:id="@+id/happyBirthday" android:layout_marginTop="10dp" android:clickable="true" android:focusable="true"/> <com.google.android.material.card.MaterialCardView android:layout_width="150dp" android:layout_height="100dp" android:contentDescription="Music Card" android:layout_below="@+id/happyBirthday" app:cardBackgroundColor="@color/white" android:layout_marginLeft="20dp" android:clickable="true" android:focusable="true" android:id="@+id/video" app:cardElevation="5dp"> <RelativeLayout android:layout_width="match_parent" android:layout_height="match_parent"> <ImageView android:layout_width="match_parent" android:layout_height="match_parent" android:src="@drawable/videoimage" /> </RelativeLayout> </com.google.android.material.card.MaterialCardView> <com.google.android.material.card.MaterialCardView android:id="@+id/music" android:layout_width="150dp" android:layout_height="100dp" android:layout_below="@+id/happyBirthday" android:layout_alignParentEnd="true" android:layout_marginRight="20dp" android:clickable="true" android:focusable="true" app:cardBackgroundColor="@color/white" app:cardElevation="5dp"> <RelativeLayout android:layout_width="match_parent" android:layout_height="match_parent"> <ImageView android:layout_width="match_parent" android:layout_height="match_parent" android:src="@drawable/musical_note" /> </RelativeLayout> </com.google.android.material.card.MaterialCardView> <com.google.android.material.card.MaterialCardView android:layout_width="150dp" android:layout_height="100dp" android:layout_below="@+id/video" android:layout_marginTop="20dp" android:layout_marginLeft="20dp" app:cardBackgroundColor="@color/white" android:id="@+id/notes" android:clickable="true" android:focusable="true" app:cardElevation="5dp"> <RelativeLayout android:layout_width="match_parent" android:layout_height="match_parent"> <ImageView android:layout_width="match_parent" android:layout_height="match_parent" android:src="@drawable/notes" /> </RelativeLayout> </com.google.android.material.card.MaterialCardView> <com.google.android.material.card.MaterialCardView android:layout_width="150dp" android:layout_height="100dp" android:layout_alignParentEnd="true" android:layout_marginEnd="20dp" android:layout_below="@+id/music" app:cardBackgroundColor="@color/white" android:layout_marginTop="20dp" android:id="@+id/resources" android:clickable="true" android:focusable="true" app:cardElevation="5dp"> <RelativeLayout android:layout_width="match_parent" android:layout_height="match_parent"> <ImageView android:layout_width="match_parent" android:layout_height="match_parent" android:src="@drawable/resources"/> </RelativeLayout> </com.google.android.material.card.MaterialCardView> <com.google.android.material.card.MaterialCardView android:layout_width="150dp" android:layout_height="100dp" android:layout_below="@+id/notes" android:layout_marginTop="20dp" android:layout_marginLeft="20dp" app:cardElevation="5dp" android:clickable="true" android:focusable="true" app:cardBackgroundColor="@color/white" android:id="@+id/contacts" app:cardCornerRadius="10dp"> <RelativeLayout android:layout_width="match_parent" android:layout_height="match_parent"> <ImageView android:layout_width="match_parent" android:layout_height="match_parent" android:src="@drawable/contacts"/> </RelativeLayout> </com.google.android.material.card.MaterialCardView> <com.google.android.material.card.MaterialCardView android:layout_width="150dp" android:layout_height="100dp" android:layout_below="@+id/resources" android:layout_alignParentEnd="true" android:layout_marginEnd="20dp" android:layout_marginTop="20dp" android:focusable="true" android:clickable="true" app:cardElevation="5dp" app:cardCornerRadius="10dp" android:id="@+id/mystery"> <RelativeLayout android:layout_width="match_parent" android:layout_height="match_parent"> <ImageView android:layout_width="match_parent" android:layout_height="match_parent" android:src="@drawable/mystery"/> </RelativeLayout> </com.google.android.material.card.MaterialCardView> <include layout="@layout/trademark"/> </RelativeLayout>
当前效果:悬浮按钮被下方的卡片遮挡,无法显示在所有内容最上层。
解决办法
方案1:调整层级与 elevation 值
在RelativeLayout中,控件绘制顺序遵循XML声明顺序,后声明的控件会覆盖前面的。同时要确保按钮的层级高于卡片:
- 确保
<include>标签在activity_main.xml的最后一行(当前已满足) - 打开
trademark.xml,给悬浮按钮设置更高的elevation值(比卡片的5dp大即可):
<com.google.android.material.floatingactionbutton.FloatingActionButton ... android:elevation="16dp" app:elevation="16dp" />
方案2:用 FrameLayout 包裹根布局
无需修改原有布局结构,套一层FrameLayout即可让按钮自动悬浮在最上层:
<?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <!-- 原有的RelativeLayout内容 --> <RelativeLayout android:id="@+id/main" android:layout_width="match_parent" android:layout_height="match_parent" android:backgroundTint="#747474" android:padding="10dp"> <!-- 所有卡片、ImageView等内容 --> </RelativeLayout> <!-- 悬浮按钮放在FrameLayout最后,自动显示在最上层 --> <include layout="@layout/trademark" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="bottom|end" android:layout_margin="16dp"/> </FrameLayout>
方案3:自定义基类Activity(多页面复用)
如果要在多个页面使用该悬浮按钮,可通过基类Activity实现彻底复用:
- 创建
activity_base.xml布局:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <!-- 子类Activity的内容容器 --> <FrameLayout android:id="@+id/content_container" android:layout_width="match_parent" android:layout_height="match_parent"/> <!-- 复用的悬浮按钮 --> <include layout="@layout/trademark" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="bottom|end" android:layout_margin="16dp"/> </FrameLayout>
- 编写
BaseActivity.java:
public class BaseActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_base); } // 子类调用此方法设置自己的布局 protected void setContentViewToContainer(int layoutResId) { FrameLayout container = findViewById(R.id.content_container); getLayoutInflater().inflate(layoutResId, container, true); } }
- 让
MainActivity继承BaseActivity:
public class MainActivity extends BaseActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentViewToContainer(R.layout.activity_main); } }
这样所有继承BaseActivity的页面都会自动带上悬浮按钮,且始终显示在最上层。
内容的提问来源于stack exchange,提问作者Ahmed abrar
相关产品推荐
相关产品推荐

