鸿蒙开发HarmonyOS NEXT (四) 熟悉ArkTs (下)

news2024/11/26 21:30:30

一、动画

1、属性动画

animation,可以通过配置动画时间duration等参数,实现移动时的平滑过度

写了个小鱼游动的小案例

@Entry
@Component
struct ActionPage {
  @State fish: Resource = $r('app.media.fish_right') //小鱼图片
  @State fishX: number = 200 //初始化小鱼横坐标
  @State fishY: number = 100 //初始化小鱼纵坐标

  build() {
    Stack(){ //层叠布局组件
      Image($r('app.media.fish_back')).width('100%').height('100%') //背景
      RelativeContainer() {
        Image(this.fish) //小鱼
          .position({
            x: this.fishX - 30,
            y: this.fishY - 40
          })
          .rotate({
            angle: 0,
            centerX: "50%",
            centerY: "50%"
          })
          .width(40)
          .height(40)
          .animation({
            duration: 500, //动画时长,单位毫秒
            curve: Curve.EaseInOut
          })

        Row() { //操作区
          Button('←').backgroundColor('#20101010')
            .onClick(() => {
              animateTo(
                { duration: 500 },
                () => {
                  this.fishX -= 20
                  this.fish = $r('app.media.fish_left')
                }
              )
            })
          Column({ space: 40 }) {
            Button('↑').backgroundColor('#20101010')
              .onClick(() => {
                this.fishY -= 20
              })
            Button('↓').backgroundColor('#20101010')
              .onClick(() => {
                this.fishY += 20
              })
          }

          Button('→').backgroundColor('#20101010')
            .onClick(() => {
              animateTo(
                { duration: 500 },
                () => {
                  this.fishX += 20
                  this.fish = $r('app.media.fish_right')
                }
              )
            })
        }
        .height(240)
        .width(240)
        .justifyContent(FlexAlign.Center)
        .position({x:0,y:120})
      }
      .height('100%')
      .width('100%')
    }
  }
}

2、组件转场动画

组件插入或者移除时的动画,通过transition属性来配置

可修改上面的小鱼案例,添加小鱼入场动画

通过isBegin变量控制小鱼组件的加载

官网动画相关文档,可以多看看

应用开发导读-基础入门 | 华为开发者联盟 (huawei.com)

3、摇杆扩展小案例

改造上述小鱼游戏案例,将移动操作区域改成摇杆控制

思路:

1、定义摇杆区域,大圆套小圆

2、根据手指移动计算出小球移动,并且不超出大圆

3、根据小球移动角度,和小鱼移动速度,计算出小鱼的角度和最终坐标

ps:本案例是根据B站 黑马程序员_鸿蒙课程案例写的,可以帮助理解

import { curves } from '@kit.ArkUI'

@Entry
@Component
struct ActionPage {
  @State fish: Resource = $r('app.media.fish_right')
  //小鱼坐标
  @State fishX: number = 200
  @State fishY: number = 100
  //小鱼角度
  @State angle: number = 0
  //开始游戏
  @State isBegin: boolean = false
  // 摇杆中心区域坐标
  private centerX: number = 120
  private centerY: number = 120
  //大、小圈半径
  private maxRadius: number = 100
  private radius: number = 20
  //摇杆小球的初始位置
  @State positionX: number = this.centerX;
  @State positionY: number = this.centerY;
  // 角度正弦和余弦
  sin: number = 0
  cos: number = 0
  //小鱼的移动速度
  speed: number = 0
  //任务id
  taskId: number = -1

  build() {
    Stack() {
      Image($r('app.media.fish_back')).width('100%').height('100%')
      RelativeContainer() {
        if (!this.isBegin) {
          Button('开始游戏')
            .onClick(() => {
              animateTo(
                { duration: 1000 },
                () => {
                  this.isBegin = true
                }
              )
            })
            .position({ x: 335, y: 130 })
        } else {
          Image(this.fish)
            .position({
              x: this.fishX - 30,
              y: this.fishY - 40
            })
            .rotate({
              angle: this.angle,
              centerX: "50%",
              centerY: "50%"
            })
            .width(40)
            .height(40)
            .animation({
              duration: 500, //动画时长,单位毫秒
              curve: Curve.EaseInOut
            })
            .transition({
              type: TransitionType.Insert,
              opacity: 0,
              translate: { x: -220 }
            })
        }

        //摇杆
        Row() {
          Circle({ width: this.maxRadius * 2, height: this.maxRadius * 2 })
            .fill('#20101010')
            .position({ x: this.centerX - this.maxRadius, y: this.centerY - this.maxRadius })
          Circle({ width: this.radius * 2, height: this.radius * 2 })
            .fill('#20101010')
            .position({ x: this.positionX - this.radius, y: this.positionY - this.radius })
        }
        .onTouch(this.handleTouchEvent.bind(this))
        .height(240)
        .width(240)
        .justifyContent(FlexAlign.Center)
        .position({ x: 0, y: 120 })
      }
      .height('100%')
      .width('100%')
    }
  }

  /**处理手指移动*/
  handleTouchEvent(event: TouchEvent) {
    switch (event.type) {
      case TouchType.Up:
      //清除定时任务
        clearInterval(this.taskId)
        this.speed = 0
        animateTo(
          { curve: curves.responsiveSpringMotion() },
          () => {
            this.positionX = this.centerX
            this.positionY = this.centerY
          }
        )
        this.angle = 0
        break;
      case TouchType.Down:
      //开始定时任务,为了保证按下时小鱼坐标的持续变化
        this.taskId = setInterval(() => {
          this.fishX += this.speed * this.cos
          this.fishY += this.speed * this.sin
        }, 40)
        break;
      case TouchType.Move:
      //1、获取手指坐标
        let x = event.touches[0].x
        let y = event.touches[0].y
      //2、手指与中心点的坐标差值
        let vx = x - this.centerX
        let vy = y - this.centerY
      //3、手指和中心的连线与X轴正半轴的夹角
        let angles = Math.atan2(vy, vx)
      //4、手指与中心的的距离
        let distance = this.getDistance(vx, vy)
      //5、摇杆小球的坐标
        this.cos = Math.cos(angles)
        this.sin = Math.sin(angles)
        animateTo(
          { curve: curves.responsiveSpringMotion() },
          () => {
            this.positionX = this.centerX + distance * this.cos
            this.positionY = this.centerY + distance * this.sin

            //小鱼转向角度
            if (Math.abs(angles * 2) < Math.PI) {
              this.fish = $r('app.media.fish_right')
            } else {
              this.fish = $r('app.media.fish_left')
              angles = angles < 0 ? angles + Math.PI : angles - Math.PI
            }
            //修改小鱼的坐标
            this.angle = angles * 100 / Math.PI
            this.speed = 5
          }
        )
        break;
    }

  }

  //已知直角边,计算斜边长
  getDistance(x: number, y: number) {
    let d = Math.sqrt(x * x + y * y)
    return Math.min(d, this.maxRadius)
  }
}

二、stage模型

1、基本概念

stage是一种应用模型

应用模型:系统为开发者提供的应用程序必备的组件和运行机制。相当于一个模板,基于统一的模型进行应用开发,使应用开发更简单、高效

目前有两种应用模型:FA 和 Stage

此处,我们先了解stage,它由于提供了AbilityStage、WindowStage等类作为应用组件和Window窗口的“舞台”,因此得名

2、应用配置文件

有两种:全局配置app.json5、模块的配置modle.json5

应用配置文件_鸿蒙官网有对配置中各个属性的详细描述,查询很方便

3、UIAbility生命周期

ForegroundBackground状态分别在UIAbility实例切换至前台和切换至后台时触发

在代码里可以找到对应描述

可以试着在日志中查看生命周期的打印顺序

4、页面及组件的生命周期

注意页面生命周期函数得在像@entry这样修饰的页面使用

另外两种aboutToAppear、aboutToDisappear则可以在自定义组件中使用

  aboutToAppear(): void {
    console.log("组件加载时触发")
  }
  onPageShow(): void {
    console.log("页面每次显示时触发一次,
包括路由过程、应用进入前台等场景,仅@Entry装饰的自定义组件生效")
  }
  onBackPress(): boolean | void {
    console.log("用户点击返回按钮时触发")
  }
  onPageHide(): void {
    console.log("页面隐藏,应用进入后台")
  }
  aboutToDisappear(): void {
    console.log("组件销毁时触发")
  }

三、网络连接

1、http请求数据

可参考HTTP数据请求-鸿蒙官方文档

官网文档描述的非常细致,包含了使用案例和对应的具体参数含义

还是常规步骤,先引入再使用即可

// 引入包名
import { http } from '@kit.NetworkKit';
// 引入返回报错类
import { BusinessError } from '@kit.BasicServicesKit';
// 每一个httpRequest对应一个HTTP请求任务,不可复用
let httpRequest = http.createHttp();
// 用于订阅HTTP响应头,此接口会比request请求先返回。可以根据业务需要订阅此消息

httpRequest.on('headersReceive', (header: Object) => {
  console.info('header: ' + JSON.stringify(header));
});

class Header {
  public contentType: string;

  constructor(contentType: string) {
    this.contentType = contentType;
  }
}
httpRequest.request(
// 填写HTTP请求的URL地址,可以带参数也可以不带参数。URL地址需要开发者自定义。请求的参数可以在extraData中指定
  "EXAMPLE_URL",
  {
    method: http.RequestMethod.POST, // 可选,默认为http.RequestMethod.GET
    // 当使用POST请求时此字段用于传递请求体内容,具体格式与服务端协商确定,可以是字符串或者对象
    extraData: 'data to send',
    expectDataType: http.HttpDataType.STRING, // 可选,指定返回数据的类型
    usingCache: true, // 可选,默认为true
    priority: 1, // 可选,默认为1
    // 开发者根据自身业务需要添加header字段
    header: new Header('application/json'),
    readTimeout: 60000, // 可选,默认为60000ms
    connectTimeout: 60000, // 可选,默认为60000ms
  },
  (err: BusinessError, data: http.HttpResponse) => {
    if (!err) {
      // data.result为HTTP响应内容,可根据业务需要进行解析
      console.info('Result:' + JSON.stringify(data.result));
      // 取消订阅HTTP响应头事件
      httpRequest.off('headersReceive');
      // 当该请求使用完毕时,开发者务必调用destroy方法主动销毁该JavaScript Object。
      httpRequest.destroy();
    } else {
      console.info('error:' + JSON.stringify(err));
      // 取消订阅HTTP响应头事件
      httpRequest.off('headersReceive');
      // 当该请求使用完毕时,开发者务必调用destroy方法主动销毁该JavaScript Object。
      httpRequest.destroy();
    }
  });

2、第三方库axios

因为axios是第三方库,所以需要三方库的包管理工具ohpm来管理

2.1  检查ohpm

终端中输入命令 

ohmp -v

可以看的ohmp的版本号

(注意:比较旧的版本可能需要自己下载安装ohmp,但版本为“HarmonyOS NEXT Developer Beta1”,版本文档更新于2024-06-25的肯定已经自动配置好了的)

2.2  下载安装axios

也是可以参考OpenHarmony三方库中心仓

里面包含了常用三方库的配置和使用说明

1、module.json5中要配置允许访问网络

2、输入安装命令:ohpm install @ohos/axios

3、安装完成,使用axios

import axios from '@ohos/axios'
interface userInfo{
  id: number
  name: string,
  phone: number
}

// 向给定ID的用户发起请求
axios.get<userInfo, AxiosResponse<userInfo>, null>('/user?ID=12345')
.then((response: AxiosResponse<userInfo>)=> {
  // 处理成功情况
  console.info("id" + response.data.id)
  console.info(JSON.stringify(response));
})
.catch((error: AxiosError)=> {
  // 处理错误情况
  console.info(JSON.stringify(error));
})
.then(()=> {
  // 总是会执行
});

四、数据持久化

概念:将内存中的数据通过文件或数据库的形式保存到设备上。目的是为了常用的数据能方便的存取

1、用户首选项

全局唯一存储的地方,轻量级的,所以不能存放太多数据,也不支持通过配置加密,一般存放“字体大小设置、是否开启夜间模式”等

通过用户首选项实现数据持久化-官网文档

2、关系型数据库

存储包含复杂关系数据,比如一个班级的学生信息,需要包括姓名、学号、各科成绩等

通过关系型数据库实现数据持久化-官网文档


六、通知

可借助Notification Kit将应用产生的通知直接在客户端本地推送给用户,本地通知根据通知类型及发布场景会产生对应的铃声、震动、横幅、锁屏、息屏、通知栏提醒和显示。

Notification Kit简介-Notification Kit(用户通知服务)-应用服务 | 华为开发者联盟 (huawei.com)

  • 基础通知: 发送短信息、提示信息等
  • 进度条通知:应用于文件下载、事务处理进度显示
  • 通知行为意图:当发布通知时,如果期望用户可以通过点击通知栏拉起目标应用组件或发布公共事件

详细使用可参考发布通知-官网文档

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1929845.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Day07-员工管理-上传下载

1.员工管理-导出excel 导出员工接口返回的是二进制axios配置responseType为blob接收二进制流文件为Blob格式按装file-saver包&#xff0c;实现下载Blob文件npm install add file-saver导出员工excel的接口 (src/api/employee.js) export function exportEmployee(){return req…

【区块链 + 智慧政务】涉税行政事业性收费“e 链通”项目 | FISCO BCOS应用案例

国内很多城市目前划转至税务部门征收的非税收入项目已达 17 项&#xff0c;其征管方式为行政主管部门核定后交由税务 部门征收。涉税行政事业性收费受限于传统的管理模式&#xff0c;缴费人、业务主管部门、税务部门、财政部门四方处于 相对孤立的状态&#xff0c;信息的传递靠…

【Diffusion学习】【生成式AI】Diffusion Model 原理剖析 (2/4) (optional)【公式推导】

文章目录 影像生成模型本质上的共同目标【拟合分布】Maximum Likelihood Estimation VAE 影像生成模型本质上的共同目标【拟合分布】 Maximum Likelihood Estimation VAE

图片服务器是什么?常见的图片服务器是哪几种?图片服务器的要求是什么?

什么是图片服务器 图片服务器&#xff0c;顾名思义就是专门用于处理图片的服务器&#xff0c;向外提供图片的上传&#xff0c;下载&#xff0c;图片展示等服务 为什么我们要使用专门的服务器处理图片 图片的数据量比文字展示高得多&#xff0c;图片的上传下载展示一系列操作…

Linux进程——进程优先级与僵尸进程孤儿进程

文章目录 僵尸进程变成僵尸状态的过程 孤儿进程进程优先级如何修改进程优先级为什么优先级有范围 僵尸进程 僵尸状态进程本质上就是死亡状态 在进程死亡之后&#xff0c;不会直接对进程进行释放&#xff0c;而是先会处理一些后事 进程在结束退出的时候&#xff0c;也会有一些…

介绍 Elasticsearch 中的 Learning to Tank - 学习排名

作者&#xff1a;来自 Elastic Aurlien Foucret 从 Elasticsearch 8.13 开始&#xff0c;我们提供了原生集成到 Elasticsearch 中的学习排名 (learning to rank - LTR) 实现。LTR 使用经过训练的机器学习 (ML) 模型为你的搜索引擎构建排名功能。通常&#xff0c;该模型用作第二…

CSA笔记1-基础知识和目录管理命令

[litonglocalhost ~]$ 是终端提示符&#xff0c;类似于Windows下的cmd的命令行 litong 当前系统登录的用户名 分隔符 localhost 当前机器名称&#xff0c;本地主机 ~ 当前用户的家目录 $ 表示当前用户为普通用户若为#则表示当前用户为超级管理员 su root 切换root权限…

我利用ChatGPT开发了一个网盘资源搜索神器APP

首先声明,本文不是买东西,仅分享个人利用ChatGPT开发项目的个人经验分享。 之前已经开发完Web端网盘资源搜索引擎,而在安卓平台使用浏览器访问总是有点不方便,于是考虑开发一个安卓端APP。 可是,自己并没有开发APP经验,那怎么办? 都说AI可以帮你搞定一切,那就用一用…

python项目读取oracle数据库方法(cx_Oracle库实现)

目录 创建一个python项目&#xff0c;并配置运行环境 查看oracle对应数据库版本&#xff08;该标题下内容只是为了查看版本&#xff0c;不用在意&#xff09; 从oracle官网下载对应版本的oracle客户端 解压下载的压缩包&#xff0c;并获取依赖 将依赖文件导入python项目运…

Perl之正则表达式

正则表达式(regular expression)描述了一种字符串匹配的模式&#xff0c;可以用来检查一个串是否含有某种子串、将匹配的子串做替换或者从某个串中取出符合某个条件的子串等。   Perl语言的正则表达式功能非常强大&#xff0c;基本上是常用语言中最强大的&#xff0c;很多语言…

论 Suspense 组件在 Vue 3 中的重要性

大家好,我是CodeQi! 一位热衷于技术分享的码仔。 你是否曾经遇到过在加载大量数据时,界面卡顿或是空白的问题? 如果你正在开发一个复杂的前端项目,那么一定需要处理很多异步数据请求。而异步请求太多就会导致用户看到空白屏幕时间变长,这对用户体验非常不友好。🤔 在…

【C++】C++11的新特性 --- 列表初始化,auto关键字,decltype关键字

人的理想与成就之间有一段距离 只有靠他的热情才能跨越。 -- 纪伯伦 C11特性 1 C 11介绍2 列表初始化3 声明3.1 auto关键字3.2 decltype关键字3.3 nullptr3.4 总结 4 STL中的新容器4.1 array4.2 forward_list4.3 unordered系列 Thanks♪(&#xff65;ω&#xff65;)&#x…

springboot项目 导入 maven坐标 错误 Could not transfer artifact XXX

1.报错原因 当时导入的是 redis坐标 &#xff0c;导入jar 包报错&#xff08;当时是网速太慢了&#xff0c;一直卡着不动 就关了 idea 重新下载&#xff09;结果报错 之前的redis 项目都可以的&#xff0c;网上找了一下 都没解决 2.解决办法 既然说不能传输&#xff0c; 就说…

玩转HarmonyOS NEXT之AppStorage应用全局UI状态存储

概述 AppStorage是应用全局的UI状态存储&#xff0c;是和应用的进程绑定的&#xff0c;由UI框架在应用程序启动时创建&#xff0c;为应用程序UI状态属性提供中央存储。 AppStorage是在应用启动的时候会被创建的单例。它的目的是为了提供应用状态数据的中心存储&#xff0c;这…

【Pytorch】数据集的加载和处理(一)

Pytorch torchvision 包提供了很多常用数据集 数据按照用途一般分为三组&#xff1a;训练&#xff08;train&#xff09;、验证&#xff08;validation&#xff09;和测试&#xff08;test&#xff09;。使用训练数据集来训练模型&#xff0c;使用验证数据集跟踪模型在训练期间…

Andriod Stdio新建Kotlin的Jetpack Compose简单项目

1.选择 No Activity 2.选择kotlin 4.右键选择 在目录MyApplication下 New->Compose->Empty Project 出现下面的画面 Finish 完成

SpringAI简单使用

Ollama 简介 Ollama是一个开源的大型语言模型服务工具&#xff0c;它允许用户在本地机器上构建和运行语言模型&#xff0c;提供了一个简单易用的API来创建、运行和管理模型&#xff0c;同时还提供了丰富的预构建模型库&#xff0c;这些模型可以轻松地应用在多种应用场景中。O…

数据库第6次作业

内容 1、创建视图v_emp_dept_id_1&#xff0c;查询销售部门的员工姓名和家庭住址 2、创建视图v_emp_dept&#xff0c;查询销售部门员工姓名和家庭住址及部门名称。 3、创建视图v_dept_emp_count(dept_name,emp_count,avg_salay)&#xff0c;统计每个部门人数并计算平均工资。 …

【漏洞复现】泛微e-cology9 WorkflowServiceXml SQL注入漏洞

文章目录 前言漏洞描述影响范围 漏洞复现nuclei脚本 安全修复 前言 泛微协同管理应用平台e-cology是一套兼具企业信息门户、知识文档管理、工作流程管理、人力资源管理、客户关系管理、项目管理、财务管理、资产管理、供应链管理、数据中心功能的企业大型协同管理平台。 漏洞…

03MFC画笔/画刷/画椭圆/圆/(延时)文字

文章目录 画实心矩形自定义画布设计及使用连续画线及自定义定义变量扇形画椭圆/圆输出颜色文本定时器与定时事件画实心矩形 自定义画布设计及使用 连续画线及自定义定义变量 扇形 画椭圆/圆 输出颜色文本