1.啥都别扯,先看效果:
2.扯扯原因
谷歌在2021年底宣布韩国谷歌商店应用支持多种支付方式,但前提是得满足一些开发规范,并且要求使用SheetBottom来开发支付弹出框,我也是第一次接触这玩意儿,所以就开始怼啊,怼完发现还真比自定义的底部弹出Dialog好使。就想分享下这几天的开发过程以及踩的坑,希望能够帮到你。
3.细细分说
急需解决标题中问题的童鞋看这里:
圆角矩形实现:3.2+3.3
展开状态:3.4(直接搜behavior)
3.1 SheetBottom依赖
只要在App级build.gradle中添加依赖:
//material design 依赖库
implementation 'androidx.compose.material:material:1.2.0-beta01'
官方文档需要在build.gradle添加:buildFeatures和composeOptions配置,但我加了就编译失败,不加反而OK,先忽略,如果有大神知道原因可以留言哈。
3.2 圆角矩形实现
layout可以自由发挥,我就先忽略了,需要的可以私信我。但需要注意的是弹窗上半部分是圆角矩形,可以在drawable中新建一个xml文件,代码如下:
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<!-- 设置圆角半径 -->
<corners android:topLeftRadius="8dp"
android:topRightRadius="8dp"/>
<!-- 设置背景颜色 -->
<solid android:color="#FFFFFF"/>
</shape>
然后设置layout文件:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
...
设置背景为刚刚的drawable文件
android:background="@drawable/gocross_google_learn_bg"
>
...
3.3 Style设置
有些同学应该踩过坑:明明设置了圆角矩形,咋就是不生效呢?我也踩过。。。原因是BottomSheetDialog默认的背景颜色就是白色,所以并不是设置的圆角矩形没有生效,而是因为Dialog的背景覆盖了,导致看上去还是一个矩形,我们在values/styles下设置一下Dialog样式,将他的背景颜色改成透明就可以解决了:
<style name="BottomSheetDialogStyle" parent="Theme.Design.BottomSheetDialog">
<!--是否有边框-->
<item name="android:windowFrame">@null</item>
<!--是否浮在窗口之上-->
<item name="android:windowIsFloating">true</item>
<!--半透明-->
<item name="android:windowIsTranslucent">true</item>
<!--关键的一步:设置背景颜色为透明 -->
<item name="android:background">@android:color/transparent</item>
<!--是否充许对话框的背景变暗。为true则充许变暗-->
<item name="android:backgroundDimEnabled">true</item>
</style>
3.4 BottomSheetDialog调用
刚刚把布局搞定了,接下来就是怎么实现底部弹窗了。不逼逼,上核心代码,代码里有很多注释:
fun payConfirmDialog(activity: Activity) {
//新建一个BottomShDialog对象
//BottomSheetDialogStyle就是上面自定义的style
//由于是做的sdk,所以不能直接使用R.style,改用获取id的方法
val payConfirmBottomDialog = BottomSheetDialog(activity, ResourceUtils.getStyleId("BottomSheetDialogStyle"))
//获取dialog的view,后面用于监听事件和自定义状态
val view = LayoutInflater.from(activity)
.inflate(ResourceUtils.getLayoutId("gocross_pay_alert_dialog"), null)
payConfirmBottomDialog.setContentView(view)
//BottomSheetDialog有五种状态:
//STATE_COLLAPSED: 折叠状态
//STATE_EXPANDED: 展开状态
//STATE_DRAGGING : 过渡状态
//STATE_SETTLING: 视图从脱离手指自由滑动到最终停下的这一小段时间
//STATE_HIDDEN :启用后用户将能通过向下滑动完全隐藏 bottom sheet
//由于我们支持横屏状态,横屏状态下布局高度会超过屏幕的高,可以将
//behavior设置为STATE_EXPANDED,然后在Layout中添加一个ScrollView
val behavior: BottomSheetBehavior<*> = BottomSheetBehavior.from(view.parent as View)
behavior.state = STATE_EXPANDED
//和Dialog一样,要先show,再去设置弹窗大小
payConfirmBottomDialog.show()
//监听按钮点击事件
val learnMoreTV: TextView = view.findViewById(ResourceUtils.getId("gc_learn_more_btn"))
val continueTV: TextView = view.findViewById(ResourceUtils.getId("gc_continue_pay_btn"))
learnMoreTV.setOnClickListener {
//自定义了解更多按钮事件
}
continueTV.setOnClickListener {
//自定义继续按钮事件
}
payConfirmBottomDialog.setOnDismissListener {
if (isPayCancel) {
//dialog关闭监听,可以调用支付失败等
}
}
//判断当前Activity是横屏还是竖屏
if (activity.resources.configuration.orientation == Configuration.ORIENTATION_PORTRAIT) {
//今日头条的屏幕适配思路,自定义弹窗的宽
DensityUtils.setSheetDialog(payConfirmBottomDialog, activity, 360)
} else {
DensityUtils.setSheetDialog(payConfirmBottomDialog, activity, 500)
}
}
再贴一下setSheetDialog方法的代码:
//动态设置SheetBottomDialog大小
fun setSheetDialog(dialog: BottomSheetDialog, activity: Activity, wight: Int) {
setCustomDensity(activity)
val layoutParams = dialog.window!!.attributes
val window = dialog.window
//设置dailog的默认内边距都为0
window!!.decorView.setPadding(0, 0, 0, 0)
//dp转px,还是建议去看看今日头条的屏幕适配方案
layoutParams.width = ((dp2px(activity, wight)))
window.attributes = layoutParams
}
赶紧去run一下试试效果吧,是不是很满意~
4. 唠唠闲嗑
怎么样是不是比自定义Dialog,然后设置底部弹出的效果要好而且更简单。但用法其实是和Dialog很像的的,因为BottomSheetDialog是继承于AppCompatDialog, 而AppCompatDialog是继承Dialog的,所以大家都是一家人~
最后如果有关于这方面的疑问或者建议,欢迎留言哈,layout代码太长就不贴了,可以私我获取哈。对SDK屏幕适配感兴趣的也可以私我一起讨论讨论~