[文章]实现中间凹陷的异形tabbar

阅读量0
0
0

一、导入

  1. 直接拖入DevEco Studio中(提前解压好)(第一种打开方式)
    实现中间凹陷的异形tabbar-鸿蒙开发者社区
  2. 在DevEco Studio打开代码包(第二种打开方式)
    实现中间凹陷的异形tabbar-鸿蒙开发者社区
    实现中间凹陷的异形tabbar-鸿蒙开发者社区
  3. 第一次打开代码包时会有提示,选择第一个就行
    实现中间凹陷的异形tabbar-鸿蒙开发者社区
  4. 运行成功后,打开entry>src>main>ets>pages>Index.ets文件,然后打开本地模拟器查看
    实现中间凹陷的异形tabbar-鸿蒙开发者社区
    实现中间凹陷的异形tabbar-鸿蒙开发者社区!
  5. 打开项目根目录中的build-profile.json5文件,删除这段代码。
    实现中间凹陷的异形tabbar-鸿蒙开发者社区
  6. 击右上角的小三角icon,运行项目,展示效果
    实现中间凹陷的异形tabbar-鸿蒙开发者社区实现中间凹陷的异形tabbar-鸿蒙开发者社区
    二、代码结构
    实现中间凹陷的异形tabbar-鸿蒙开发者社区
    三、功能点分解
  7. 在画布组件Canvas中可以惊醒自定义图形绘制
    实现中间凹陷的异形tabbar-鸿蒙开发者社区
private settings: RenderingContextSettings = new RenderingContextSettings(true)
private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings)

Canvas(this.context)
  .width('100%')
  .height(70)
  .onReady(() => {
    this.context.lineWidth = 2  // 设置线宽  
    this.context.fillStyle = '#ffffff'  // 设置填充颜色为白色  
    this.context.strokeStyle = '#ffffff'  // 设置描边颜色为白色  



  })



1.2.3.4.5.6.7.8.9.10.11.12.13.14.15.16.17.
  1. 画布Canvas整体效果呈现代码实现
Canvas(this.context)
  .width('100%')
  .height(70)
  .onReady(() => {
    this.context.lineWidth = 2  // 设置线宽
    this.context.fillStyle = '#ffffff'  // 设置填充颜色为白色
    this.context.strokeStyle = '#ffffff'  // 设置描边颜色为白色

    let total_width = Math.sqrt(3) * 36 * 2  // 计算总宽度
    let radios: number = 36  // 圆的半径

    // 圆心1
    let p1: Point = {x: (this.screen_width - total_width) / 2, y: radios + this.padding_top}
    // 圆心2
    let p2: Point = {x: this.screen_width / 2, y: 0 + this.padding_top}
    // 圆心3
    let p3: Point = {x: (this.screen_width - total_width) / 2 + total_width, y: 36 + this.padding_top}

    this.context.moveTo(0, this.padding_top)  // 移动到起始点

    // 画到圆心1的顶点
    this.context.lineTo((this.screen_width - total_width) / 2, 0 + this.padding_top)
    // 画第一个圆弧
    this.context.arc(p1.x, p1.y, radios, 3.14 + 3.14 / 2, 3.14 + 3.14 / 2 + 3.14 / 3, false)

    // 画第二个圆弧
    this.context.arc(p2.x, p2.y, radios, 3.14 - 3.14 / 6, 3.14 / 6, true)

    // 画第三个圆弧
    this.context.arc(p3.x, p3.y, radios, 3.14 + 3.14 / 6, 3.14 + 3.14 / 2, false)

    // 右侧直线到达右边界
    this.context.lineTo(this.screen_width, 0 + this.padding_top)

    // 画从右侧向下的直线
    this.context.lineTo(this.screen_width, 64 + this.padding_top)

    // 画到底部并连接到左边
    this.context.lineTo(0, 64 + this.padding_top)
    this.context.lineTo(0, 0 + this.padding_top)

    // 设置阴影效果
    this.context.shadowOffsetY = 0
    this.context.shadowColor = '#949494'  // 阴影颜色
    this.context.shadowBlur = 12  // 阴影模糊度
    this.context.stroke();  // 描边
    this.context.fill();  // 填充

  })



1.2.3.4.5.6.7.8.9.10.11.12.13.14.15.16.17.18.19.20.21.22.23.24.25.26.27.28.29.30.31.32.33.34.35.36.37.38.39.40.41.42.43.44.45.46.47.48.49.50.51.52.
  1. 底部tabbar整体效果呈现代码实现
    实现中间凹陷的异形tabbar-鸿蒙开发者社区
    实现中间凹陷的异形tabbar-鸿蒙开发者社区
import { TabItem } from "./NormalClass"  // 导入 TabItem 类型  
import { Rectangle } from "./Rectangle"  // 导入 Rectangle 组件  
import { display } from "@kit.ArkUI"  // 导入显示相关功能  

@Component
export struct Tabbar {
  @Prop tabItems: TabItem[]  // 定义 tabItems,传入的 TabItem 数组  
  @Link currentIndex: number  // 当前选中的索引,链接到外部状态  
  @State fontColor: string = '#949494'  // 默认字体颜色  
  @State selectedFontColor: string = 'rgb(61,141,255)'  // 选中时字体颜色  
  @State screen_width: number = px2vp(display.getDefaultDisplaySync().width)  // 计算屏幕宽度  

  build() {
    Stack() {  // 创建一个 Stack 组件  
      Rectangle()  // 绘制一个矩形背景  
      Row() {  // 创建一个行布局  
        // 检查 tabItems 数组的长度,确保是偶数且大于等于2  
        if (this.tabItems.length % 2 == 0 && this.tabItems.length >= 2) {
          // 遍历 tabItems  
          ForEach(this.tabItems, (item: TabItem, index) => {
            // 判断当前索引是否为中间索引  
            if (index == this.tabItems.length / 2) {
              Image($r('app.media.middle'))  // 中间图像  
                .width(60)  // 设置宽度  
                .height(60)  // 设置高度  
                .borderRadius(30)  // 设置圆角  
                .offset({ y: -30 })  // 垂直偏移  
                .borderWidth(4)  // 边框宽度  
                .borderColor(Color.White)  // 边框颜色  
                .borderStyle(BorderStyle.Solid)  // 边框样式  
                .shadow({  // 添加阴影效果  
                  radius: 20,
                  color: Color.Gray,
                  offsetX: 0,
                  offsetY: 0
                })
                .onClick(() => {
                  this.currentIndex = -1  // 点击时重置 currentIndex  
                })
            }
            Column() {  // 创建垂直布局  
              Image(this.currentIndex == index ? item.selectImage : item.image)  // 根据当前索引选择图像  
                .width(22)  // 设置图像宽度  
                .height(22)  // 设置图像高度  
                .objectFit(ImageFit.Contain)  // 设置图像适配方式  
              Text(item.title)  // 显示文本  
                .fontSize(13)  // 设置字体大小  
                .fontColor(this.currentIndex == index ? this.selectedFontColor : this.fontColor)  // 根据选择状态设置字体颜色  
            }
            .width((this.screen_width - 60) / this.tabItems.length)  // 设置列宽度  
            .alignItems(HorizontalAlign.Center)  // 设置对齐方式  
            .onClick(() => {
              this.currentIndex = index  // 点击时更新 currentIndex  
            })
          })
        }
      }
      .width('100%')  // 设置行的总宽度  
      .height('100%')  // 设置行的总高度  
      .justifyContent(FlexAlign.SpaceAround)  // 设置对齐方式  
    }
    .width(px2vp(display.getDefaultDisplaySync().width))  // 设置 Stack 的宽度  
    .height(64)  // 设置 Stack 的高度  
  }
}  

回帖

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容图片侵权或者其他问题,请联系本站作侵删。 侵权投诉
链接复制成功,分享给好友