鸿蒙自定义DrawerLayout侧滑菜单实现原理

前言

DevEcoStudio版本:

DrawerLayout如何使用:鸿蒙自定义侧滑菜单布局(DrawerLayout)-CSDN博客

实现原理

1、Library创建

新建module选择static library,命名为DrawerLibrary

2、DrawerLayout原理分析

复制代码
import { DrawerController } from './DrawerController'

/**
 * 自定义抽屉布局
 */
@Component
export struct DrawerLayout {
   @State offsetX: number = 0
   //缩放比例
   @State scaleX: number = 1
   //是否显示侧边栏
   @Link isShowSideBar: boolean
   //侧边栏的宽度
   private sideBarWidth: number = 300
   // 按下的x坐标
   private downX = 0
   @BuilderParam
   leftView: () => void
   @BuilderParam
   rightView: () => void
   //控制器
   @Link controller: DrawerController;

   aboutToAppear() {
      if (this.isShowSideBar) {
         this.offsetX = this.sideBarWidth
         this.scaleX = 0.8
      } else {
         this.offsetX = 0
         this.scaleX = 1
      }
      this.controller.showSideBar = () => {
         this.showSideBar();
      };
      this.controller.hideSideBar = () => {
         this.hideSideBar();
      };
   }

   build() {
      Row() {
         Stack() {
            this.leftView()
         }
         .backgroundColor(Color.White)
         .width(this.sideBarWidth)
         .height('100%')
         .offset({ x: this.offsetX - this.sideBarWidth, y: 0 })

         Stack() {
            this.rightView()
         }
         .backgroundColor(Color.White)
         .width(`${this.scaleX * 100}%`)
         .height(`${this.scaleX * 100}%`)
         .margin({ left: (1 - this.scaleX) * 180 })
         .offset({ x: this.offsetX - this.sideBarWidth, y: 0 })
         .onClick(() => {
            this.controller.hideSideBar()
         })
      }
      // .onTouch((event) => this.touchEvent(event)) //留的手指滑动的口子,大家根据下面原理自己实现
      .backgroundColor('#CCCCCCCC')
      .width('100%')
      .height('100%')
   }

 
   /**
    * 显示侧边栏
    */
   private showSideBar() {
      animateTo({ duration: 300 }, () => {
         this.offsetX = this.sideBarWidth
         this.scaleX = 0.8
         this.isShowSideBar = true
      })
   }

   /**
    * 隐藏侧边栏
    */
   private hideSideBar() {
      animateTo({ duration: 300 }, () => {
         this.offsetX = 0
         this.scaleX = 1
         this.isShowSideBar = false
      })
   }
}
复制代码
DrawerController类:
复制代码
/**
 * 抽屉布局控制器
 */
export class DrawerController {
   showSideBar: () => void;
   hideSideBar: () => void;
}

a:偏移量

通过offset({ x: this.offsetX - this.sideBarWidth, y: 0 })动态调整左右视图在x轴方向的偏移量,有两种状态:显示和隐藏侧边栏,在显示状态下通过animateTo动画将offsetX=0在300ms内改变成offsetX = sideBarWidth(侧边栏宽度),同理在隐藏状态下通过animateTo动画将offsetX = sideBarWidth(侧边栏宽度)在300ms内改变成 offsetX = 0。

b:右侧内容缩放

通过动态调整右侧内容的width和height值来实现缩放效果。在显示状态下通过animateTo动画将scaleX = 1在300ms内改变成scaleX = 0.8,同理在隐藏状态下通过animateTo动画将scaleX = 0.8在300ms内改变成 scaleX = 1。

复制代码
.width(`${this.scaleX * 100}%`)
.height(`${this.scaleX * 100}%`)

c:右侧内容距离左侧侧边栏的距离

通过动态调整右侧内容的的外边距左侧距离margin({ left: (1 - this.scaleX) * 180 })

通过以上的原理就能实现侧边栏效果了。

思考:

上面的实现原理没有实现通过手指滑动来控制侧边栏的隐藏和显示,通过下图的示意图分析下了手指滑动的原理,这里给大家留一个自己动手的机会,自己实现下如何通过手指控制侧边栏的显示和隐藏。

提示下:通过给最外层Row()设置触摸监听

复制代码
Row(){}.onTouch((event) => this.touchEvent(event))
相关推荐
不会写代码0006 小时前
Flutter 框架跨平台鸿蒙开发 - 手写笔记工具开发教程
笔记·flutter·华为·harmonyos
小风呼呼吹儿6 小时前
Flutter 框架跨平台鸿蒙开发 - 老年便捷助手:打造适合老年人的智能工具箱
flutter·华为·harmonyos
lbb 小魔仙6 小时前
【Harmonyos】开源鸿蒙跨平台训练营DAY3:为开源鸿蒙跨平台工程集成网络请求能力,实现数据清单列表的完整构建与开源鸿蒙设备运行验证(及常见问题与方法)
windows·开源·harmonyos·鸿蒙·开源鸿蒙·鸿蒙开平台应用
奔跑的露西ly6 小时前
【HarmonyOS NEXT】Stage模型与FA模型对比
华为·harmonyos·鸿蒙
小雨下雨的雨7 小时前
禅息:在鸿蒙与 Flutter 之间寻找呼吸的艺术
算法·flutter·华为·重构·交互·harmonyos
[H*]7 小时前
Flutter框架跨平台鸿蒙开发——Image综合应用
flutter·华为·harmonyos
小风呼呼吹儿7 小时前
Flutter 框架跨平台鸿蒙开发 - 倒计时秒表:打造多功能计时工具
网络·flutter·华为·harmonyos
AI_零食7 小时前
鸿蒙跨端框架 Flutter 学习 Day 4:异步编程基础——Future 与非阻塞执行的物理真相
学习·flutter·harmonyos
摘星编程7 小时前
React Native鸿蒙版:Bluetooth扫描蓝牙设备
react native·react.js·harmonyos
lqj_本人7 小时前
Kuikly 框架架构与目录导览(HarmonyOS 视角)
华为·架构·harmonyos