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

【每日学点鸿蒙知识】长按动画、Canvas与底部导航重叠、Grid拖动、Web宽度自适应

1、HarmonyOS 实现按钮长按动画效果?

怎么实现一个按钮长按+动画效果

类似效果可以参考以下代码

// ets
@Entry
@Component
struct Progress_Ring {
  @State progressValue: number = 0
  @State animationId: number | null = null
  build() {
    Column({ space: 15 }) {
      Stack(){
        Progress({ value: 0, total: 100, type: ProgressType.Ring })
          .color("red")
          .value(this.progressValue)
          .width(120)
          .style({ strokeWidth: 5, scaleCount: 20, scaleWidth: 5, enableSmoothEffect: true })
          .backgroundColor('#00000000')

        Button('test').gesture(
          LongPressGesture({ repeat: true,duration:10 })
            .onAction((event: GestureEvent|undefined) => {
              if(event && this.progressValue<=100){
                clearInterval(this.animationId)
                this.animationId = null
                this.progressValue ++
              }
            })
            .onActionEnd(() => {
              this.animationId = setInterval(()=>{
                this.progressValue --
                if(this.progressValue <=0){
                  clearInterval(this.animationId)
                }
              },10)
            })
        )
      }

    }.width('100%').padding({ top: 5 })
  }
}
2、HarmonyOS 手机竖屏->横屏->竖屏,Canvas底部与导航条重叠的区域出现拖影问题?

在Canvas组件是全屏绘制的情况下,先旋转一次屏幕,再旋转回来。在Canvas的上下滚动刷新绘制过程中,会出现底部导航条区域渲染不及时,出现拖影的问题。

Canvas组件不是全屏的,却又进行全屏绘制。将Canvas组件调整成全屏的

3、HarmonyOS grid 触发拖拽的中途, 怎么才可以做到禁止修改第1个和最后一个item的位置?

参考代码

import curves from '@ohos.curves'
@Entry
@Component
struct GridItemExample {
  @State numbers: number[] = []
  @State dragItem: number = -1
  @State scaleItem: number = -1
  @State item: number = -1
  private dragRefOffsetx: number = 0
  private dragRefOffsety: number = 0
  @State offsetX: number = 0
  @State offsetY: number = 0
  private FIX_VP_X: number = 108
  private FIX_VP_Y: number = 120
  aboutToAppear() {
    for (let i = 1; i <= 11; i++) {
      this.numbers.push(i)
    }
  }
  itemMove(index: number, newIndex: number): void {
    console.info('index:' + index + ' newIndex:' + newIndex)
    if (!this.isDraggable(newIndex)) {
      return
    }
    let tmp = this.numbers.splice(index, 1)
    this.numbers.splice(newIndex, 0, tmp[0])
  }
  //向下滑
  down(index: number): void {
    // 指定固定GridItem不响应事件
    if (!this.isDraggable(index + 3)) {
      return
    }
    this.offsetY -= this.FIX_VP_Y
    this.dragRefOffsety += this.FIX_VP_Y
    this.itemMove(index, index + 3)
  }
  //向下滑(右下角为空)
  down2(index: number): void {
    if (!this.isDraggable(index + 3)) {
      return
    }
    this.offsetY -= this.FIX_VP_Y
    this.dragRefOffsety += this.FIX_VP_Y
    this.itemMove(index, index + 3)
  }
  //向上滑
  up(index: number): void {
    if (!this.isDraggable(index - 3)) {
      return
    }
    this.offsetY += this.FIX_VP_Y
    this.dragRefOffsety -= this.FIX_VP_Y
    this.itemMove(index, index - 3)
  }
  //向左滑
  left(index: number): void {
    if (!this.isDraggable(index - 1)) {
      return
    }
    this.offsetX += this.FIX_VP_X
    this.dragRefOffsetx -= this.FIX_VP_X
    this.itemMove(index, index - 1)
  }
  //向右滑
  right(index: number): void {
    if (!this.isDraggable(index + 1)) {
      return
    }
    this.offsetX -= this.FIX_VP_X
    this.dragRefOffsetx += this.FIX_VP_X
    this.itemMove(index, index + 1)
  }
  //向右下滑
  lowerRight(index: number): void {
    if (!this.isDraggable(index + 4)) {
      return
    }
    this.offsetX -= this.FIX_VP_X
    this.dragRefOffsetx += this.FIX_VP_X
    this.offsetY -= this.FIX_VP_Y
    this.dragRefOffsety += this.FIX_VP_Y
    this.itemMove(index, index + 4)
  }
  //向右上滑
  upperRight(index: number): void {
    if (!this.isDraggable(index - 2)) {
      return
    }
    this.offsetX -= this.FIX_VP_X
    this.dragRefOffsetx += this.FIX_VP_X
    this.offsetY += this.FIX_VP_Y
    this.dragRefOffsety -= this.FIX_VP_Y
    this.itemMove(index, index - 2)
  }
  //向左下滑
  lowerLeft(index: number): void {
    if (!this.isDraggable(index + 2)) {
      return
    }
    this.offsetX += this.FIX_VP_X
    this.dragRefOffsetx -= this.FIX_VP_X
    this.offsetY -= this.FIX_VP_Y
    this.dragRefOffsety += this.FIX_VP_Y
    this.itemMove(index, index + 2)
  }
  //向左上滑
  upperLeft(index: number): void {
    if (!this.isDraggable(index - 4)) {
      return
    }
    this.offsetX += this.FIX_VP_X
    this.dragRefOffsetx -= this.FIX_VP_X
    this.offsetY += this.FIX_VP_Y
    this.dragRefOffsety -= this.FIX_VP_Y
    this.itemMove(index, index - 4)
  }
  isDraggable(index: number): boolean {
    console.info('index:' + index)
    return index > 0 && index!= this.numbers.length -1;
  }
  build() {
    Column({space:10}) {
      Column({space:5}) {
        Text("Grid拖拽排序动效")
        Text("第一个和最后一个组件不可拖拽")
      }
      Grid() {
        ForEach(this.numbers, (item: number) => {
          GridItem() {
            Text(item + '')
              .fontSize(16)
              .width('100%')
              .textAlign(TextAlign.Center)
              .height(100)
              .borderRadius(10)
              .backgroundColor(0xFFFFFF)
              .shadow(this.scaleItem == item ? {
                radius: 70,
                color: '#15000000',
                offsetX: 0,
                offsetY: 0
              } :
                {
                  radius: 0,
                  color: '#15000000',
                  offsetX: 0,
                  offsetY: 0
                })
              .animation({ curve: Curve.Sharp, duration: 300 })
          }
          // 指定固定GridItem不响应事件
          .hitTestBehavior(this.isDraggable(this.numbers.indexOf(item)) ? HitTestMode.Default : HitTestMode.None)
          .scale({ x: this.scaleItem == item ? 1.05 : 1, y: this.scaleItem == item ? 1.05 : 1 })
          .zIndex(this.dragItem == item ? 1 : 0)
          .translate(this.dragItem == item ? { x: this.offsetX, y: this.offsetY } : { x: 0, y: 0 })
          .padding(10)
          .gesture(
            // 以下组合手势为顺序识别,当长按手势事件未正常触发时则不会触发拖动手势事件
            GestureGroup(GestureMode.Sequence,
              LongPressGesture({ repeat: true })
                .onAction((event?: GestureEvent) => {
                  animateTo({ curve: Curve.Friction, duration: 300 }, () => {
                    this.scaleItem = item
                  })
                })
                .onActionEnd(() => {
                  animateTo({ curve: Curve.Friction, duration: 300 }, () => {
                    this.scaleItem = -1
                  })
                }),
              PanGesture({ fingers: 1, direction: null, distance: 0 })
                .onActionStart(() => {
                  this.dragItem = item
                  this.dragRefOffsetx = 0
                  this.dragRefOffsety = 0
                })
                .onActionUpdate((event: GestureEvent) => {
                  this.offsetY = event.offsetY - this.dragRefOffsety
                  this.offsetX = event.offsetX - this.dragRefOffsetx
                  animateTo({ curve: curves.interpolatingSpring(0, 1, 400, 38) }, () => {
                    let index = this.numbers.indexOf(this.dragItem)
                    if (this.offsetY >= this.FIX_VP_Y / 2 && (this.offsetX <= 44 && this.offsetX >= -44)
                      && ![8, 9, 10].includes(index)) {
                      //向下滑
                      this.down(index)
                    } else if (this.offsetY <= -this.FIX_VP_Y / 2 && (this.offsetX <= 44 && this.offsetX >= -44)
                      && ![0, 1, 2].includes(index)) {
                      //向上滑
                      this.up(index)
                    } else if (this.offsetX >= this.FIX_VP_X / 2 && (this.offsetY <= 50 && this.offsetY >= -50)
                      && ![2, 5, 8, 10].includes(index)) {
                      //向右滑
                      this.right(index)
                    } else if (this.offsetX <= -this.FIX_VP_X / 2 && (this.offsetY <= 50 && this.offsetY >= -50)
                      && ![0, 3, 6, 9].includes(index)) {
                      //向左滑
                      this.left(index)
                    } else if (this.offsetX >= this.FIX_VP_X / 2 && this.offsetY >= this.FIX_VP_Y / 2
                      && ![2, 5, 7, 8, 9, 10].includes(index)) {
                      //向右下滑
                      this.lowerRight(index)
                    } else if (this.offsetX >= this.FIX_VP_X / 2 && this.offsetY <= -this.FIX_VP_Y / 2
                      && ![0, 1, 2, 5, 8].includes(index)) {
                      //向右上滑
                      this.upperRight(index)
                    } else if (this.offsetX <= -this.FIX_VP_X / 2 && this.offsetY >= this.FIX_VP_Y / 2
                      && ![0, 3, 6, 9, 10].includes(index)) {
                      //向左下滑
                      this.lowerLeft(index)
                    } else if (this.offsetX <= -this.FIX_VP_X / 2 && this.offsetY <= -this.FIX_VP_Y / 2
                      && ![0, 1, 2, 3, 6, 9].includes(index)) {
                      //向左上滑
                      this.upperLeft(index)
                    } else if (this.offsetX >= this.FIX_VP_X / 2 && this.offsetY >= this.FIX_VP_Y / 2
                      && [7].includes(index)) {
                      //向右下滑(右下角为空)
                      this.down2(index)
                    }
                  })
                })
                .onActionEnd(() => {
                  animateTo({ curve: curves.interpolatingSpring(0, 1, 400, 38) }, () => {
                    this.dragItem = -1
                  })
                  animateTo({
                    curve: curves.interpolatingSpring(14, 1, 170, 17), delay: 150
                  }, () => {
                    this.scaleItem = -1
                  })
                })
            )
              .onCancel(() => {
                animateTo({ curve: curves.interpolatingSpring(0, 1, 400, 38) }, () => {
                  this.dragItem = -1
                })
                animateTo({
                  curve: curves.interpolatingSpring(14, 1, 170, 17)
                }, () => {
                  this.scaleItem = -1
                })
              })
          )
        }, (item: number) => item.toString())
      }
      .width('90%')
      .editMode(true)
      .scrollBar(BarState.Off)
      .columnsTemplate("1fr 1fr 1fr")
    }.width('100%').height('100%').backgroundColor('#0D182431').padding({ top: 5 })
  }
}
4、HarmonyOS 使用Webview加载huawei首页出现操作条,且宽度不能自适应?
import web_webview from '@ohos.web.webview';
@Entry
@Component
struct WebComponent {
  controller: web_webview.WebviewController = new web_webview.WebviewController();
  @State userAgent: string =
    'Mozilla/5.0 (Phone; OpenHarmony 4.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36 ArkWeb/4.1.6.1 Mobile automobile/792'
  aboutToAppear() {
    web_webview.WebviewController.setWebDebuggingAccess(true);
  }
  build() {
    Column() {
      Web({ src: "", controller: this.controller })
        .javaScriptAccess(true)
        .domStorageAccess(true)
        .width("100%")
        .height("100%")
        .onControllerAttached(() => {
          this.controller.setCustomUserAgent(this.userAgent);
          this.controller.loadUrl("www.huawei.com")
        })
    }
  }
}
5、HarmonyOS Grid拖拽,让部分item不响应拖拽?

整个页面都是使用Grid来布局,其中拖拽过程中如何让部分item不响应,例如下面的布局: 1 2 3 4 5 6 7 8 9 第1个元素占据一整行,其余元素4个一行,拖动第8个元素,预期能够和2,3,4,5,6,7,8进行交换,即使拖动元素到1的位置,第1个元素也不响应交换动画

参考如下Demo:

@Entry
@Component
struct GridExample {
  @State numbers: string[] = []
  scroller: Scroller = new Scroller()
  layoutOptions1: GridLayoutOptions = {
    regularSize: [1, 1], // 只支持[1, 1]
    irregularIndexes: [0], // 索引为0的GridItem占用一行
  }
  @State text: string = 'drag'

  @Builder pixelMapBuilder() { //拖拽过程样式
    Column() {
      Text(this.text)
        .fontSize(16)
        .backgroundColor(0xF9CF93)
        .width(80)
        .height(80)
        .textAlign(TextAlign.Center)
    }
  }

  aboutToAppear() {
    for (let i = 1;i <= 9; i++) {
      this.numbers.push(i + '')
    }
  }

  changeIndex(index1:number, index2:number) { //交换数组中的位置
    const temp = this.numbers[index1];
    if (index1 > index2) {
      this.numbers.splice(index2, 0, temp);
      this.numbers.splice(index1 + 1, 1);
    } else {
      this.numbers.splice(index2 + 1, 0, temp);
      this.numbers.splice(index1, 1);
    }
  }

  build() {
    Column({ space: 5 }) {
      Grid(this.scroller, this.layoutOptions1) {
        ForEach(this.numbers, (day: string) => {
          GridItem() {
            if (day == "1") {
              Text(day)
                .fontSize(16)
                .backgroundColor(0xF9CF93)
                .width("100%")
                .height(80)
                .textAlign(TextAlign.Center)
            } else {
              Text(day)
                .fontSize(16)
                .backgroundColor(0xF9CF93)
                .width(80)
                .height(80)
                .textAlign(TextAlign.Center)
            }
          }
        })
      }
      .columnsTemplate('1fr 1fr 1fr 1fr')
      .columnsGap(10)
      .rowsGap(10)
      .onScrollIndex((first: number) => {
        console.info(first.toString())
      })
      .width('100%')
      .backgroundColor(0xFAEEE0)
      .height(300)
      .editMode(true) //设置Grid是否进入编辑模式,进入编辑模式可以拖拽Grid组件内部GridItem
      .onItemDragStart((event: ItemDragInfo, itemIndex: number) => { //第一次拖拽此事件绑定的组件时,触发回调。
        if (itemIndex == 0) {
          return;
        }
        this.text = this.numbers[itemIndex]
        return this.pixelMapBuilder() //设置拖拽过程中显示的图片。
      })
      .onItemDrop((event: ItemDragInfo, itemIndex: number, insertIndex: number, isSuccess: boolean) => { //绑定此事件的组件可作为拖拽释放目标,当在本组件范围内停止拖拽行为时,触发回调。
        // isSuccess=false时,说明drop的位置在grid外部;insertIndex > length时,说明有新增元素的事件发生
        if (!isSuccess || insertIndex >= this.numbers.length || insertIndex == 0) {
          return
        }
        console.info('tag' + itemIndex + '', insertIndex + '') //itemIndex拖拽起始位置,insertIndex拖拽插入位置
        this.changeIndex(itemIndex, insertIndex)
      })
    }.width('100%').margin({ top: 5 })
  }
}

http://www.kler.cn/a/458114.html

相关文章:

  • # 【超全面了解鸿蒙生命周期】-生命周期补充
  • 快速打造智能应用:从设计到上线的全流程指南
  • LeetCode 82:删除排序链表中的重复元素 II
  • 【MySql】2020-03-12 Windows安装MySQL5.7.28
  • Microi吾码|.NET、VUE快速搭建项目,低代码便捷开发教程
  • QML学习(五) 做出第一个简单的应用程序
  • 【Linux网络编程】第五弹---构建基于UDP的简单聊天室系统:代码结构与功能模块详解
  • 评分模型在路网通勤习惯分析中的应用——提出问题(1)
  • 【docker系列】创建博客 halo 2.11
  • 【yolov5】实现FPS游戏人物检测,并定位到矩形框上中部分,实现自瞄
  • 项目实践-贪吃蛇小游戏
  • 基于Resnet、LSTM、Shufflenet及CNN网络的Daily_and_Sports_Activities数据集仿真
  • 机器人骑自行车过程的MATLAB建模与数值仿真模拟
  • Linux之ARM(MX6U)裸机篇----1.开发环境搭建
  • C语言基础——指针(5)
  • MySQL基础-常见的增删改查操作语句总结
  • 【实习】面经:海康威视-软件开发工程师(嵌入式)
  • App信息收集(小迪网络安全笔记~
  • [Unity Shader] [图形渲染]Shader数学基础18-内置变量
  • git 在windows上显示很多文件有改动实际没有变化