Android Kotlin实现SnackBar宽度不设为match_parent的方法
自定义SnackBar宽度适配问题
背景
原本想制作自定义布局的Toast,但Android 11开始不推荐该做法,且setView()方法已废弃,转而尝试自定义SnackBar。
自定义布局代码(component_toast_message.xml)
<?xml version="1.0" encoding="utf-8"?> <androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="wrap_content" android:layout_height="wrap_content" app:cardBackgroundColor="@color/blue" app:cardCornerRadius="20dp" app:contentPaddingBottom="4dp" app:contentPaddingLeft="12dp" app:contentPaddingRight="12dp" app:contentPaddingTop="4dp"> <com.google.android.material.textview.MaterialTextView android:id="@+id/text_message" android:layout_width="wrap_content" android:layout_height="wrap_content" android:drawableEnd="@drawable/ic_vector_check_mark_white" android:drawablePadding="4dp" android:fontFamily="@font/tt_hoves_medium" android:text="Copied" android:textAlignment="center" android:textColor="@color/white" android:textSize="10sp" /> </androidx.cardview.widget.CardView>
显示SnackBar的Kotlin代码
private fun showSnack() { val snackbar = Snackbar.make(binding.root, "", Snackbar.LENGTH_SHORT) snackbar.view.setBackgroundColor(Color.TRANSPARENT) val customSnackView: View = layoutInflater.inflate(R.layout.component_toast_message, null) val snackbarLayout = snackbar.view as Snackbar.SnackbarLayout snackbarLayout.setPadding(0, 0, 0, 0) snackbarLayout.addView(customSnackView) snackbar.show() }
当前问题
SnackBar默认宽度为match_parent,需要调整为wrap_content以适配自身视图大小,尝试多种方法未解决。
当前显示效果

期望显示效果

解决方案
要实现SnackBar宽度为wrap_content,需修改SnackbarLayout的布局参数并清理原有默认视图,具体调整如下:
调整后的Kotlin代码
private fun showSnack() { val snackbar = Snackbar.make(binding.root, "", Snackbar.LENGTH_SHORT) snackbar.view.setBackgroundColor(Color.TRANSPARENT) val snackbarLayout = snackbar.view as Snackbar.SnackbarLayout // 清空SnackbarLayout原有默认视图,避免占位影响宽度收缩 snackbarLayout.removeAllViews() snackbarLayout.setPadding(0, 0, 0, 0) // 加载自定义视图时指定父容器,确保布局参数生效 val customSnackView = layoutInflater.inflate(R.layout.component_toast_message, snackbarLayout, false) snackbarLayout.addView(customSnackView) // 修改SnackbarLayout宽度为wrap_content,并设置水平居中 val layoutParams = snackbarLayout.layoutParams as ViewGroup.LayoutParams layoutParams.width = ViewGroup.LayoutParams.WRAP_CONTENT snackbarLayout.layoutParams = layoutParams snackbarLayout.gravity = Gravity.CENTER_HORIZONTAL snackbar.show() }
关键注意点
- 必须调用
removeAllViews()清空SnackbarLayout的默认子视图,否则默认TextView会占据空间导致宽度无法收缩。 - 修改SnackbarLayout的布局参数为
WRAP_CONTENT,同时设置gravity = CENTER_HORIZONTAL让SnackBar居中显示,符合期望效果。 - Inflate自定义视图时指定父容器为SnackbarLayout,确保自定义布局的
wrap_content参数正确生效。
内容的提问来源于stack exchange,提问作者onesector
相关产品推荐
相关产品推荐

