当前位置:网站首页>Material Design组件 - 使用BottomSheet展现扩展内容(二)
Material Design组件 - 使用BottomSheet展现扩展内容(二)
2022-07-05 20:39:00 【卡卡爾】
Material Design组件 - 使用BottomSheet展现扩展内容(二)
上篇文章中我们使用在XML中配置bottom_sheet_behavior的方式实现了简单的BottomSheet,并说明了在XML中能够去配置的一些参数做了详细的说明,这篇文章我们会说明一下如何在代码中动态的去设置BottomSheet的一些行为
代码中动态设置BottomSheet
我们先来想一下,如果我们要实现一开始BottomSheet就是展开的状态,而不是折叠状态,那我们要怎么做呢?我们可以在代码中实现这个需求,代码很简单,如下
class OcrResultActivity : AppCompatActivity(R.layout.ocr_result_layout) {
val mBottomSheetBehavior: BottomSheetBehavior<View> by lazy {
BottomSheetBehavior.from(bottom_sheet)
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
mBottomSheetBehavior.state = BottomSheetBehavior.STATE_COLLAPSED
mBottomSheetBehavior.peekHeight = 200
}
}
我们使用BottomSheetBehavior类的from方法从我们页面上获取到我们的BottomSheetBehavior实例对象,然后我们就能对其进行各种各样的设置了,这边的设置包括了我们之前在xml的方式中能够配置的所有参数,并且这边还能设置BottomSheet的state,那么这个state又是什么呢?简单来说state就是说明当前BottomSheet的一个状态,其是展开还是折叠都属于其状态,有以下几种状态
- STATE_COLLAPSED:折叠状态,这个状态下BottomSheet会始终显示出来,高度的话会是peek height的高度
- STATE_EXPANDED:展开状态,在这个状态下,BottomSheet会展示其最大的高度
- STATE_HALF_EXPANDED:半展开状态,官网说明这个状态只有设置fitToContents为false时候才适用,但其实就算设置为true,使用代码方式修改BottomSheet的状态为STATE_HALF_EXPANDED的时候,也会触发这一状态
- STATE_HIDDEN:隐藏状态,这个状态下BottomSheet不可见,并且只能以代码设置的方式才能让其再次可见,经过试验,需要注意以下几点:
- 设置其hidden为true,将BottomSheet向下滑动变为隐藏状态后,再次动态设置其hidden为false会立即将BottomSheet再次展示,不需要重新设置其状态
- 设置其hidden为true,将BottomSheet向下滑动变为隐藏状态后,可设置其状态为STATE_COLLAPSED或STATE_HALF_EXPANDED或STATE_HALF_EXPANDED重新使其展现
- 可通过直接设置其状态为STATE_HIDDEN来直接隐藏BottomSheet
- STATE_DRAGGING:用户主动的向上或者向下拖动BottomSheet的时候
- STATE_SETTLING:这个状态是用户在拖动后,手指离开屏幕了,然而BottomSheet还在继续移动到指定高度的时候的那一小段时间即为这个状态,更像是STATE_COLLAPSED和STATE_HALF_EXPANDED的一个中间过渡状态
这边注意STATE_DRAGGING和STATE_SETTLING不能以代码方式进行设定,BottomSheet内部自行处理的,其余状态均可主动设置
我们可以给BottomSheetBehavior设置一个回调方法来接收上面的这些状态
mBottomSheetBehavior.addBottomSheetCallback(object :
BottomSheetBehavior.BottomSheetCallback() {
override fun onStateChanged(bottomSheet: View, newState: Int) {
Log.d("mBottomSheetBehavior", "newState = $newState")
}
override fun onSlide(bottomSheet: View, slideOffset: Float) {
}
})
onStateChanged方法会在状态改变的时候给你回调一个新的状态,我们就可以在这边做各种自己想要的处理,比如我们可以在每次展开的时候,都改变一下我们的BottomSheet背景颜色,就可以这样写
mBottomSheetBehavior.addBottomSheetCallback(object : BottomSheetBehavior.BottomSheetCallback() { override fun onStateChanged(bottomSheet: View, newState: Int) { when (newState) { BottomSheetBehavior.STATE_DRAGGING -> { val colorR = (0..255).random() val colorG = (0..255).random() val colorB = (0..255).random() bottomSheet.setBackgroundColor( Color.argb( 255, colorR, colorG, colorB ) ) } else -> { } } } override fun onSlide(bottomSheet: View, slideOffset: Float) { } })效果如下:

- onSlide方法就更为有用了,其slideOffset是一个比例,其值从-1到0到1,0到1说明的是BottomSheet在滑动过程中,从折叠状态到完全展开状态的中间过程的一个比例,折叠状态为0,向上滑动会不断的从0变大,直到完全展开状态变为1为止,0到-1说明了BottomSheet在从折叠状态向隐藏状态滑动的一个比例,-1即说明BottomSheet被隐藏了,该回调在直接设置BottomSheet状态使BottomSheet展开或者折叠的过程中,会有多次的回调,返回的是一个过程性的比例关系,大家可以亲自试一下就知道了,这边不再过多展示了,之后会有一个实战Demo中会用到这个来做一些效果
模态BottomSheet
自此,BottomSheet的状态我们也都了解清楚了,那么也许有人会有另一种需求,即我想要那种和Dialog一样的,后面有蒙版的,专业点叫模态窗口哈,官方也很贴心,为我们直接提供了BottomSheetDialog和BottomSheetDialogFragment,其实这两个就是将BottomSheetBehavior与Dialog相结合的产物,用法也相当简单,我们有了前面的基础,再看这个就简单多了哈
BottomSheetDialog
我们先来看一个BottomSheetDialog的简单用法
class ModalBottomActivity : AppCompatActivity(R.layout.ocr_result_layout) {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val bsd = BottomSheetDialog(this)
bsd.setContentView(R.layout.modal_buttom_sheet_content)
bsd.behavior.peekHeight = 200
// bsd.behavior.isHideable = false //注意,这边BottomSheetDialog默认的hideable行为是true,与BottomSheetBehavior不同,毕竟Dialog默认就是应该可以隐藏才对
bsd.show()
button_1.setOnClickListener {
bsd.show()
}
}
}
BottomSheetDialog内部给我们创建了BottomSheetBehavior,所以我们不需要关心BottomSheetBehavior,直接使用即可,XML中我们也只需要实现我们自己的布局即可,XML中的布局如下
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content">
<TextView android:layout_width="match_parent" android:layout_height="200dp" android:text="aaaaaaaaaaaaaaabbbbbbbbbbbbbccccccccccccc" />
</LinearLayout>
这样,我们的BottomSheetDialog就显示出来了,看看效果

你也可以继承BottomSheetDialog和普通Dialog的用法一样,来自定义你自己的Dialog,其行为和Dialog几乎一样的,所以这边只是简单演示一下,其余的就不在这边细说了
BottomSheetDialogFragment
接下来我们来看一下BottomSheetDialogFragment,这个Fragment内部给我们创建了BottomSheetDialog,所以我们用起来可以更加的方便,代码如下
class ModalBottomActivity : AppCompatActivity(R.layout.ocr_result_layout) {
val modalBottomSheet = ModalBottomSheet()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
modalBottomSheet.show(supportFragmentManager, ModalBottomSheet.TAG)
button_1.setOnClickListener {
modalBottomSheet.show(supportFragmentManager, ModalBottomSheet.TAG)
}
}
}
class ModalBottomSheet : BottomSheetDialogFragment() {
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? = inflater.inflate(
R.layout.modal_buttom_sheet_content,
container,
false
)
companion object {
const val TAG = "ModalBottomSheet"
}
}
这样我们就实现了BottomSheetDialogFragment的展现,另外,我们如果想要对BottomSheet进行设置的话,可以这样获取BottomSheetBehavior对象,就能够自由的进行设置了
class ModalBottomSheet : BottomSheetDialogFragment() {
lateinit var behavior: BottomSheetBehavior<FrameLayout>
override fun onCreateView ...
//注意需要在onStart的时候才能正常获取到BottomSheetBehavior
override fun onStart() {
super.onStart()
val bottomSheet: FrameLayout =
dialog?.findViewById(R.id.design_bottom_sheet) ?: return
behavior = BottomSheetBehavior.from(bottomSheet)
behavior.peekHeight = 400
}
companion object {
const val TAG = "ModalBottomSheet"
}
}

好了,BottomSheet的基本使用已经都说完了,大家理解了吗?另外,在最后推荐给大家一个非常好的类似BottomSheet效果的第三方库SlidingUpPanelLayout,大家可以了解下并尝试使用下,看看哪个更适合你自己的需求,再来选择使用
下回我们会用一个Demo来让BottomSheet嵌套一个列表来实现更好的效果,希望大家喜欢
最后还望各位兄弟姐妹们点个赞,关个注,更多的我理解的内容我还会陆续和大家分享的,谢谢大家!
边栏推荐
- Rainbow 5.7.1 supports docking with multiple public clouds and clusters for abnormal alarms
- 手机开户股票开户安全吗?我家比较偏远,有更好的开户途径么?
- Leetcode (695) - the largest area of an island
- 证券开户选择哪个证券比较好?网上开户安全么?
- 渗透创客精神文化转化的创客教育
- Typhoon is coming! How to prevent typhoons on construction sites!
- Where is a good stock account? Is online account manager safe to open an account
- 欢迎来战,赢取丰厚奖金:Code Golf 代码高尔夫挑战赛正式启动
- PyTorch 1.12发布,正式支持苹果M1芯片GPU加速,修复众多Bug
- Schema and model
猜你喜欢
随机推荐
Abnova maxpab mouse derived polyclonal antibody solution
物联网智能家居基本方法实现之经典
When JS method passes long type ID value, precision loss will occur
Duchefa MS medium contains vitamin instructions
mongodb基操的练习
Abnova丨E (DIII) (WNV) 重组蛋白 中英文说明书
Duchefa丨MS培养基含维生素说明书
Redis唯一ID生成器的实现
Abnova 环孢素A单克隆抗体,及其研究工具
Classic implementation method of Hongmeng system controlling LED
Duchefa丨低熔点琼脂糖 PPC中英文说明书
清除app data以及获取图标
Leetcode (347) - top k high frequency elements
Dry goods navigation in this quarter | Q2 2022
【愚公系列】2022年7月 Go教学课程 004-Go代码注释
Wanglaoji pharmaceutical's public welfare activity of "caring for the most lovely people under the scorching sun" was launched in Nanjing
插值查找的简单理解
[quick start of Digital IC Verification] 2. Through an example of SOC project, understand the architecture of SOC and explore the design process of digital system
14、Transformer--VIT TNT BETR
Nprogress plug-in progress bar









