当前位置: 首页 > news >正文

【Android】BottomSheet的三种使用

BottomSheet

BottomSheet的介绍?

看本文之前,我们得先了解一下什么是 BottomSheet,什么情况下我们会使用?

BottomSheet(底部弹窗/底部面板) 是 Android 提供的一种交互控件;

它以 从屏幕底部滑出的方式 展示内容,用户可以拖拽、点击操作,适合做 信息展示、菜单、操作列表 等;

举个很简单的例子,抖音评论区大概率就是使用BottomSheet;

BottomSheet的分类

大致可以分为两类,分别是:

  1. Persistent BottomSheet(嵌入式底部表单)

大家从名字上也可以看出来,嵌入式,顾名思义就是写在xml文件中的,通过 CoordinatorLayout + BottomSheetBehavior 实现;

我的理解就是写在布局中,只是决定了它拖出来的方式而已;

2. Modal BottomSheet(模态式底部表单)

表现形式:像一个对话框(Dialog)一样,从底部滑出,遮住上面的内容;弹出时,背景会有一层阴影,我们可以点击空白处或下滑来关闭(通过后续的设置);通过 BottomSheetDialogBottomSheetDialogFragment 实现;

适合不是那么复杂场景下的,而且交互灵活,生命周期和普通 Dialog/Fragment 一样,显示时才创建,关闭后就销毁;

Persistent BottomSheet

Behavior

大家可能知道的是Behavior要设置在CoordinatorLayout布局中;其实Behavior的作用是来协调CoordinatorLayout布局中的直接子view的交互行为,包括滑动拖拽等等,我们可以用来进行可折叠式标题栏的实现或者底部表单的实现;

CoordinatorLayout布局

一个可以协调子视图之间交互行为的布局容器,通过behavior的设置明确了如何交互,两者联合以到达预期效果;

BottomSheetBehavior的几种模式

为什么要学习它的几种模式?

因为BottomSheetBehavior因为xml中是写死的,我们必须通过代码的逻辑来达到实现我们想要的效果;那么学习几种模式,能帮助我们更好的理解和使用;

STATE_HIDDEN:隐藏

此时我们可以类比理解成View.INVISABLE,它仍在存在但是在屏幕以外而已;

在这里插入图片描述

STATE_COLLAPSED :折叠状态,一般是一种半屏形态;

在这里插入图片描述

STATE_EXPANDED:完全展开,完全展开的高度是可配置,默认即屏幕高度;

在这里插入图片描述

STATE_DRAGGING:拖拽状态,标识人为手势拖拽中(手指未离开屏幕);

STATE_SETTLING :视图从脱离手指自由滑动到最终停下的这一小段时间,与STATE_DRAGGING差异在于当前并没有手指在拖拽。主要表达两种场景:初始弹出时动画状态、手指手动拖拽释放后的滑动状态;

BottomSheetBehavior的使用

xml文件中,设置需要弹出的控件设置behavior

<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout 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"tools:context=".MainActivity"><LinearLayoutandroid:layout_width="match_parent"android:orientation="vertical"android:layout_height="wrap_content"><Buttonandroid:layout_width="wrap_content"android:text="按钮一"android:id = "@+id/buttom"android:layout_height="100dp"android:layout_gravity="center"></Button><Buttonandroid:layout_marginTop="100dp"android:layout_width="wrap_content"android:layout_height="100dp"android:text="按钮二"android:layout_gravity="center"></Button><Buttonandroid:layout_height="100dp"android:text="按钮"android:layout_width="wrap_content"android:layout_marginTop="50dp"android:layout_gravity="center"></Button></LinearLayout><LinearLayoutandroid:id = "@+id/bottombehavior"app:layout_behavior="com.google.android.material.bottomsheet.BottomSheetBehavior"android:layout_width="match_parent"android:background="#000000"app:behavior_skipCollapsed = "true"app:behavior_peekHeight = "100dp"app:behavior_fitToContents = "true"android:layout_height="100dp"><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:text="Hello World!"app:layout_constraintBottom_toBottomOf="parent"app:layout_constraintEnd_toEndOf="parent"app:layout_constraintStart_toStartOf="parent"app:layout_constraintTop_toTopOf="parent" /></LinearLayout></androidx.coordinatorlayout.widget.CoordinatorLayout>

主要是通过 app:layout_behavior="com.google.android.material.bottomsheet.BottomSheetBehavior"来设置的;

我们还可以定义一些相关的属性:

app:behavior_skipCollapsed = "true":定义是否允许滑动到peekheight以下高度;true代表关闭

app:behavior_peekHeight = "100dp":定义折叠时的高度;

app:behavior_fitToContents = "true":定义会不会完全展开;

在主活动中这样设置:

Button button = findViewById(R.id.buttom);
View view = findViewById(R.id.bottombehavior);
BottomSheetBehavior bottomSheetBehavior = BottomSheetBehavior.from(view);
bottomSheetBehavior.setState(BottomSheetBehavior.STATE_HIDDEN);
button.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {if(bottomSheetBehavior.getState()== BottomSheetBehavior.STATE_HIDDEN){bottomSheetBehavior.setState(BottomSheetBehavior.STATE_EXPANDED);}else{bottomSheetBehavior.setState(BottomSheetBehavior.STATE_HIDDEN);}}
});

先得到具有behavior属性的父布局view,然后通过BottomSheetBehavior.from(view)获得behavior的实例;可以动态实现我们想要的效果;

Modal BottomSheet

BottomSheetDialog的使用

我们首先定义一个简单的布局,此处省略,

        BottomSheetDialog bottomSheetDialog = new BottomSheetDialog(this);bottomSheetDialog.setContentView(R.layout.ttt);bottomSheetDialog.setCanceledOnTouchOutside(true);View bottomSheetView = bottomSheetDialog.findViewById(R.id.tttt);BottomSheetBehavior<View> behavior = BottomSheetBehavior.from(bottomSheetView);behavior.setPeekHeight(500);Button button2 = findViewById(R.id.button_2);button2.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {//         显示 BottomSheetDialogbottomSheetDialog.show();}});

代码讲解部分:

  1. 创建好布局之后,我们看第一行代码new了一个对话框,那么怎么把布局和new好的对话框关联到一起呢?

bottomSheetDialog.setContentView(R.layout.ttt);通过这行代码,我们将布局设置进对话框的视图;、

  1. 对话框的一些属性,比如是否允许触碰对话框外部关闭?

bottomSheetDialog.setCanceledOnTouchOutside(true);

  1. 怎么设置对话框的高度?
        View bottomSheetView = bottomSheetDialog.findViewById(R.id.tttt);BottomSheetBehavior<View> behavior = BottomSheetBehavior.from(bottomSheetView);behavior.setPeekHeight(500);

跟behavior的逻辑相似,这里不做过多解释;

  1. 怎么显示视图?

show() dismiss()来分别控制视图的开启和关闭;

此外还有显示和关闭对话框的监听器;

BottomSheetDialogFragment

这个的话,从名字上来看包含碎片,所以它包括了碎片的生命周期;

使用如下:

根据碎片的使用,BottomSheetDialogFragment的使用是建立xml文件,然后新建一个类

oncreatedialog方法中,我们需要返回一个dialog,通常在这里我们设置一些是否可关闭的属性;但是如果和外观有关的比如高度,就不能在这里设置了;

public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {BottomSheetDialog bottomSheetDialog = new BottomSheetDialog(getContext());bottomSheetDialog.setCanceledOnTouchOutside(true);bottomSheetDialog.setCancelable(true);return bottomSheetDialog;
}

createview方法中;

@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {warningBottomdialogBinding = WarningBottomdialogBinding.inflate(inflater,container,false);return warningBottomdialogBinding.getRoot();
}

本次分享就到这里!

http://www.dtcms.com/a/394035.html

相关文章:

  • Spring MVC 九大组件源码深度剖析(八):RequestToViewNameTranslator - 视图名转换的奥秘
  • 在Linux环境下安装和卸载DMETL5数据迁移工具
  • 《计算》第五六章读书笔记
  • daily notes[47]
  • 模电基础:放大电路的分析方法---图解法
  • Windows10系统Web UI自动化测试学习系列1--介绍(序章-万事开头难)
  • 安装vllm的艰苦过程
  • 探索 Event 框架实战指南:微服务系统中的事件驱动通信:
  • FPGA超高速接口GTP_GTY_GTX使用说明
  • Blender常用第三方插件总结
  • Kurt-Blender零基础教程:第2章:建模篇——第3节:陈列/父子级/蒙皮/置换修改器与小狐狸角色建模
  • npm启动项目报错“无法加载文件……”
  • 从 0 到 1 精通 Nacos:服务发现与配置中心的实战指南
  • 基于DrissionPage的趣易百影院数据采集实战指南
  • github十大开源FPGA项目
  • R语言 csv新增一列 dplyr操作
  • IDEA创建Module子项目后,只有一个普通的文件夹
  • 支持向量机深度解析:从数学原理到工程实践的完整指南
  • 2025华为杯研究生数学建模竞赛B题及求解思路
  • 三星CIS全球产能布局解析:本土根基、海外扩张与策略雄心
  • js集装箱号校验算法
  • 【机器学习】最优传输(OT)和 KL散度的区别
  • 推荐一个随机生成图片的网站: Lorem Picsum
  • APE自动化提示词工程
  • 探究某黄鱼x-sign生成算法——终极篇
  • 霍尔传感器安装错位下的FOC控制:线性插值与锁相环(PLL)算法的抉择
  • FFmpeg 深入精讲(三)FFmpeg 中级开发
  • AI驱动下的蛋白质设计
  • ARM基本汇编操作指令
  • 电商搜索 API 的优化与性能提升:从瓶颈突破到体验升级