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

android抽屉DrawerLayout在2025的沉浸式兼容

目前使用View的DrawerLayout+NavigationView实现抽屉似乎已经年久失修。官方已经逐渐转向compose的Drawer。本文暂时没有使用compose。

基本使用

布局如下:基本逻辑为DrawerLayout+底部你的主界面+一层遮罩+navigationView。
navigationView可以使用headerLayout和menu。自行查阅。这里我自定义一行title+recyclerView+底部登录设置样式。

<?xml version="1.0" encoding="utf-8"?>
<androidx.drawerlayout.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"xmlns:app="http://schemas.android.com/apk/res-auto"android:layout_width="match_parent"android:layout_height="match_parent"tools:openDrawer="start"><!-- 主屏幕显示内容 --><includeandroid:id="@+id/content"layout="@layout/activity_drawer_layout_content"android:layout_width="match_parent"android:layout_height="match_parent" /><Viewandroid:id="@+id/mask"android:alpha="0"android:background="#80000000"android:layout_width="match_parent"android:layout_height="match_parent"/><!-- 侧滑菜单显示内容 --><com.google.android.material.navigation.NavigationViewandroid:id="@+id/nav"app:drawerLayoutCornerSize="0dp"android:layout_gravity="start"android:layout_width="match_parent"android:layout_height="match_parent"><LinearLayoutandroid:orientation="vertical"android:layout_width="match_parent"android:layout_height="match_parent"><androidx.constraintlayout.widget.ConstraintLayoutandroid:layout_width="match_parent"android:layout_height="48dp"><TextViewandroid:text="DrawerLayout-Tester"app:layout_constraintTop_toTopOf="parent"app:layout_constraintStart_toStartOf="parent"app:layout_constraintEnd_toEndOf="parent"app:layout_constraintBottom_toBottomOf="parent"android:layout_width="match_parent"android:layout_height="wrap_content"/></androidx.constraintlayout.widget.ConstraintLayout><androidx.recyclerview.widget.RecyclerViewandroid:id="@+id/rcv"android:layout_weight="1"android:layout_width="match_parent"android:layout_height="0dp"/><androidx.constraintlayout.widget.ConstraintLayoutandroid:layout_width="match_parent"android:layout_height="64dp"><androidx.appcompat.widget.AppCompatImageViewandroid:id="@+id/headIcon"app:layout_constraintTop_toTopOf="parent"android:layout_marginStart="@dimen/ui_padding_edge"app:layout_constraintStart_toStartOf="parent"app:layout_constraintBottom_toBottomOf="parent"android:src="@drawable/ic_floating_wrap"android:tint="#111111"android:layout_width="48dp"android:layout_height="48dp"/><TextViewandroid:text="用户abc123"android:textSize="18sp"app:layout_constraintTop_toTopOf="parent"app:layout_constraintStart_toEndOf="@id/headIcon"android:layout_marginStart="8dp"app:layout_constraintBottom_toBottomOf="parent"android:layout_width="wrap_content"android:layout_height="wrap_content"/><androidx.appcompat.widget.AppCompatImageViewandroid:id="@+id/ivTag"app:layout_constraintTop_toTopOf="parent"android:layout_marginEnd="8dp"app:layout_constraintEnd_toStartOf="@id/ivMenu"app:layout_constraintBottom_toBottomOf="parent"android:src="@drawable/ic_floating_tag"android:tint="#111111"android:layout_width="36dp"android:layout_height="36dp"/><androidx.appcompat.widget.AppCompatImageViewandroid:id="@+id/ivMenu"app:layout_constraintTop_toTopOf="parent"android:layout_marginEnd="@dimen/ui_padding_edge"app:layout_constraintEnd_toEndOf="parent"app:layout_constraintBottom_toBottomOf="parent"android:src="@drawable/ic_floating_menu"android:tint="#111111"android:layout_width="36dp"android:layout_height="36dp"/></androidx.constraintlayout.widget.ConstraintLayout></LinearLayout></com.google.android.material.navigation.NavigationView>
</androidx.drawerlayout.widget.DrawerLayout>

请添加图片描述
上图为目标。
于是就开始踩坑了。

不要乱加fitsSystemWindows

android:fitsSystemWindows=“true” 会出现一个title栏。 不好。

主题圆角问题

如果你的activity或者application使用Theme.Material3.Light.NoActionBar 主题,抽屉打开就是圆角效果。
使用MaterialComponents(M2)就没有圆角。
可以在 NavigationView上添加 app:drawerLayoutCornerSize=“0dp” 去除圆角。

沉浸式处理

现在android最难兼容的就是沉浸式。
通过如下代码获取statusBar和navBar的高度进行padding操作。

 rootDrawer.post {if (rootDrawer.isAttachedToWindow) {val heights = this@AgentChatActivity.currentStatusBarAndNavBarHeight()heights?.let { pair->val statusBarHeight = pair.firstval navBarHeight = pair.secondnavigationView.updatePadding(top = statusBarHeight, bottom = navBarHeight)navigationView.layoutParams = navigationView.layoutParams.apply {width = rootDrawer.width * 2 / 3}}}}
fun Activity.currentStatusBarAndNavBarHeight() : Pair<Int, Int>? {val insets = ViewCompat.getRootWindowInsets(window.decorView) ?: return nullval nav = insets.getInsets(WindowInsetsCompat.Type.navigationBars()).bottomval sta = insets.getInsets(WindowInsetsCompat.Type.statusBars()).topreturn sta to nav
}

沉浸式后出现navigationView上方StatusBar遮罩

<!-- 侧滑菜单显示内容 追加layout_marginTop="0.1dp" 解决status bar背景overlay-->
<com.google.android.material.navigation.NavigationViewandroid:id="@+id/navigationView"android:layout_gravity="start"android:layout_marginTop="0.1dp"

发现侧滑过来,抽屉的上方被statusBar遮挡。通过尝试,给出一点点marginTop就能解决。谁知道什么原因呢。

实现推拉的效果

很多app有左右推拉效果,比如腾讯元宝,DeepSeek。

第一步移除自带的黑色遮罩 drawer.setScrimColor(Color.TRANSPARENT)
第二步 addDrawerListener mask+translation实现右侧跟随

		rootDrawer.addDrawerListener(object : DrawerListener {override fun onDrawerSlide(drawerView: View, slideOffset: Float) {// slideOffset: 0(完全关闭)到 1(完全打开)// 计算主内容应该平移的距离:抽屉宽度 * 滑动比率val moveX = drawerView.width * slideOffsetchatLayout.mask.alpha = slideOffset * 0.5f// 如果是左侧抽屉,主内容应向右平移if (drawerView.layoutDirection == View.LAYOUT_DIRECTION_LTR) {chatLayout.translationX = moveX} else {chatLayout.translationX = -moveX}}override fun onDrawerOpened(drawerView: View) {}override fun onDrawerClosed(drawerView: View) {// 抽屉关闭后,将主内容复位chatLayout.translationX = 0f// 清除遮罩chatLayout.mask.alpha = 0f}override fun onDrawerStateChanged(newState: Int) {}})//沉浸式处理

屏幕内左滑

主要就是实现在主界面上左滑能触发左边的抽屉拉出。
如果你的主界面很复杂,有一些嵌套的左滑操作就不要搞这个。
参考:
https://github.com/PureWriter/FullDraggableDrawer
实现逻辑就是touch事件检测,浏览了下代码中写了不少忽略的逻辑,避免与主界面冲突减少误触的风险。

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

相关文章:

  • 美颜SDK性能优化实战:GPU加速与AI人脸美型的融合开发
  • AndroidStudio历史版本下载
  • Mac抹除重装卡在激活锁?两步快速解锁
  • Java语言是编译型还是解释型| 探究Java的运行机制与性能优化
  • 网站发语音功能如何做广州比较好的网站建设公司
  • 公司网站域名更改怎么做建设行业协会网站发展的建议
  • 【ZeroRange WebRTC】Kinesis Video Streams WebRTC Data Plane WebSocket API 深度解析
  • Docker核心概念、常用命令与实战指南
  • 交换机安全基线整改方式-华为S5700系列
  • Django 接口文档生成:Swagger 与 ReDoc 全面说明
  • Docker K8s VM 简介
  • FPGA教程系列-Vivado中读取ROM中数据
  • 网站怎么添加模块鹿寨建设局网站
  • 响应式外贸网站案例国外ps网站
  • springcloud feign远程调用请求参数对象变成linkhashmap处理
  • “耐达讯自动化Profibus总线光端机在化工变频泵控制系统中的应用与价值解析”
  • centos7.2安装cacti1.2.27
  • 将 vue3 项目打包后部署在 springboot 项目运行
  • 福州短视频seo网站建筑网站首页大图
  • 阿根廷网站后缀毕业设计网站成品
  • 性能相关指标
  • 数据结构--6:优先级队列(堆)
  • ESP32 Wsl2 环境搭建
  • Elasticsearch:如何创建知识库并使用 AI Assistant 来配置连接器
  • Blender学习笔记(04)-- 选中实体的一部分,单独设置颜色
  • 哪个网站做攻略比较好品牌vi设计案例欣赏ppt
  • 珠海市网站建设企业网站编辑给续南明做的封面
  • 国产化Excel开发组件Spire.XLS教程:Python将列表导出为CSV文件(含一维/二维/字典列表)
  • 接口自动化测试框架实战(Pytest+Allure+Excel)
  • 苹果质量检测与分类 - YOLO13结合RFCAConv实现