赞
踩
在ArkUI中,产生动画的方式是改变组件属性值并且指定相关的动画参数。当属性值发生变化后,按照动画参数,从原来的状态过渡到新的状态,就形成一个动画。
动画的相关参数如下:
属性名称 | 属性类型 | 描述 | |
---|---|---|---|
duration | number | 1000 | 动画时长,单位为毫秒,默认时长为1000毫秒。 |
tempo | number | 1.0 | 动画播放的速度,值越大则播放越快,值越小则播放越慢,0则表示没有动画效果 |
curve | Curve | Curve.Linear | 动画变化曲线,默认曲线为线性 其中可取值有如下一些 Liner:表示从头到尾的速度都是相同的 Ease:表示以低速开始,然后加快,在结束前变慢CubicBezier(0.25,0.1,0.25,1.0) EaseIn:表示以低速开始 CubicBezier(0.42,0.0,1.0,1.0) EaseOut:表示以低速结束 CubicBezier(0.0,0.0,0.58,1.0) EaseInOut:表示以低速开始和结束 CubicBezier(0.42,0.0,0.58,1.0) FastOutSlowIn:标准曲线 CubicBezier(0.4,0.0,0.2,1.0) LinearOutSlowIn:减速曲线 CubicBezier(0.0,0.0,0.2,1.0) FastOutSlowIn:加速曲线 CubicBezier(0.4,0.0,1.0,1.0) ExtremeDeceleratioin:急缓曲线 CubicBezier(0.0,0.0,0.0,1.0) sharp:锐利曲线 CubicBezier(0.33,0.0,0.67,1.0) Rhythm:节奏曲线 CubicBezier(0.7,0.0,0.2,1.0) Smooth:平滑曲线 CubicBezier(0.4,0.0,0.4,1.0) Friction:阻尼曲线 CubicBezier(0.2,0.0,0.2,1.0) |
delay | number | 0 | 延时播放时间,单位为毫秒,默认不延时播放 |
iterations | number | 1 | 播放次数,默认为1次,设置为-1则表示无限次播放 |
playMode | PlayMode | PlayMode.Normal | 设置动画播放模式,默认播放完后重头播放 Normal:正常播放 Reverse:动画反向播放 Alternate:动画在奇数次正向播放,偶数次反向播放 AlternateReverse:动画在奇数次反向播放,偶数次正向播放 |
onFinish | function | 动画播放结束时回调函数 |
显示动画(animateTo)和属性动画(animation)是ArkUI提供的最基础和常用的动画功能。
在布局属性(如:尺寸、位置等属性)发生变化时,可以通过属性动画或显示动画,按动画参数过渡到新的布局参数状态。
动画类型 | 特点 |
显示动画(函数) | 闭包内的变化均会触发动画,包含币数据变化引起的组件增删 |
属性动画(属性方法) | 属性变化自动触发动画。(注意:属性值的变化需要加在animation属性之前) |
显示动画的接口:
animateTo(value:AnimateParam, event: () => void): void
第一个参数:指定动画参数
第二个参数:动画的闭包函数
- @Entry
- @Component
- struct LayoutChangeTest {
- @State itemAlign: HorizontalAlign = HorizontalAlign.Start;
- aligns: HorizontalAlign[] = [HorizontalAlign.Start, HorizontalAlign.Center, HorizontalAlign.End];
- alignIndex: number = 0;
-
- build() {
- Column({space: 30}) {
- Text('修改布局位置')
- .fontSize(30)
- .margin({top: 100})
-
- Column({space: 25}) {
- Text("JavaScript").fontSize(20).fontWeight(FontWeight.Bolder).fontColor('#4e72b8')
- Text("TypeScript").fontSize(20).fontWeight(FontWeight.Bolder).fontColor('#6d8346')
- Text("ArkTS").fontSize(20).fontWeight(FontWeight.Bolder).fontColor('#69541b')
- }
- .margin(20)
- .alignItems(this.itemAlign)
- .justifyContent(FlexAlign.Center)
- .borderWidth(2)
- .width('90%')
- .height(200)
-
- Button('Click', {type: ButtonType.Capsule, stateEffect: true})
- .fontSize(18)
- .fontWeight(FontWeight.Bold)
- .width('50%')
- .onClick(() => {
- // 显示动画
- animateTo({duration: 1000, curve: Curve.EaseInOut},() => {
- // 在闭包函数中修改上方元素的对齐方式
- this.alignIndex = (this.alignIndex + 1) % this.aligns.length;
- this.itemAlign = this.aligns[this.alignIndex];
- })
- })
- }
- .width('100%')
- .height('100%')
- }
- }

- @Entry
- @Component
- struct LayoutChangeTest1 {
- @State mySize: number = 30;
- // 标志位,用来控制组件的大小
- @State flag: boolean = false;
-
- build() {
- Column( {space: 20} ) {
- Text('HarmonyOS')
- .fontColor('#ed1941')
- .fontWeight(FontWeight.Bolder)
- .fontSize(this.mySize)
- .margin(10)
-
- Button(this.flag ? '缩小': '放大', {type:ButtonType.Capsule,stateEffect:true})
- .width('50%')
- .fontSize(16)
- .onClick(() => {
- animateTo({duration: 1000, curve: Curve.Ease}, () => {
- if(this.flag) {
- this.mySize = 30;
- } else {
- this.mySize = 50;
- }
- this.flag = !this.flag;
- });
- })
- }
- .justifyContent(FlexAlign.Center)
- .width('100%')
- .height('100%')
- }
- }

- @Entry
- @Component
- struct LayoutPage2 {
- @State message: string = '改变角度';
- @State rotateAngle: number = 0;
- @State flag: boolean = false;
-
- build() {
- Row() {
- Column({space:15}) {
- Text(this.message)
- .fontSize(50)
- .fontWeight(FontWeight.Bold)
- Image($r('app.media.image2'))
- .width(200)
- .height(200)
- .borderRadius(100)
- .rotate({
- x: 1,
- y: 1,
- z: 1,
- angle: this.rotateAngle
- })
- .onClick(() => {
- animateTo({},() => {
- if(this.flag) {
- this.rotateAngle = 0;
- } else {
- this.rotateAngle = 640;
- }
- this.flag = !this.flag;
- })
- })
- }
- .width('100%')
- }
- .height('100%')
- }
- }

显示动画是把要执行动画的属性修改放在闭包函烽中触发动画,而属性动画则不需要使用闭包,只需要把animation属性加在要做属性动画的组件的属性后就可以了。
属性动画接口
animation(value: AnimateParam)
参数value表示动画参数。
注意:如果希望某个属性值的变化而产生动画,则需要此属性需要加到animation属性之前。
- @Entry
- @Component
- struct AttrAnimationTest1 {
- @State widthSize: number = 250;
- @State heightSize: number = 100;
- @State rotateAngle: number = 0;
- @State flag: boolean = true;
-
- build() {
- Row() {
- Column() {
- Button('change size')
- .onClick(() => {
- if(this.flag) {
- this.widthSize = 150;
- this.heightSize = 50;
- } else {
- this.widthSize = 250;
- this.heightSize = 100;
- }
- this.flag = !this.flag;
- })
- .margin(30)
- .width(this.widthSize)
- .animation({
- duration:2000,
- iterations:3,
- curve: Curve.Linear,
- playMode: PlayMode.Alternate
- })
- .height(this.heightSize)
- .animation({
- duration:1000,
- curve: Curve.Linear,
- playMode:PlayMode.Alternate
- })
-
- Button('change rotate angle')
- .onClick(() => {
- this.rotateAngle = 90;
- })
- .margin(50)
- .rotate({angle: this.rotateAngle})
- .animation({
- duration:1000,
- iterations:-1,
- curve:Curve.Linear,
- playMode:PlayMode.Alternate
- })
-
- }
- .width('100%')
- }
- .height('100%')
- }
- }

组件内转场动画使用transition,它常见的用法如下:
1、if/else产生组件内转场动画
2、ForEach产生组件内转场动画
组件的插入、删除过程即为组件本身的转场过程,通过设置转场动画,可以定义组件出现、消失的效果。
组件内转场动画的接口:
transition(value: TransitionOptions)
transition函数的入参为组件内转场的效果,可以定义平移、透明度、旋转、缩放这几种转场样式的单个或者组件的转场效果,必须和animateTo一起使用才能产生组件转场效果。
transition常见用法
1、组件的插入、删除使用同一个动画效果
- Button()
- .transition({type: TransitionType.All, scale: {x: 0, y: 0 }})
当type属性为TransitionType.All时,表示指定转场动效生效在组件的所有变化(插入和删除)场景,这个时候删除动画和插入动画是相反的过程。
2、组件的插入、删除使用不同的动画效果
- Button()
- .transition({type: TransitionType.Insert, translate: {x: 200, y: -200}, opacity: 0})
- .transition({type: TransitionType.Delete, rotate: {x: 0, y:0, z:1, angle:360}})
3、只定义组件的插入或删除其中一种动画效果
- Button()
- .transition({type: TransitionType.Delete, translate:{x: 200,y: -200}})
- @Entry
- @Component
- struct TransitionTest {
- @State flag: boolean = true;
-
- build() {
- Row() {
- Column() {
- Button(this.flag ? '隐藏' : '显示')
- .fontSize(20)
- .margin(30)
- .width(150)
- .height(50)
- .onClick(() => {
- // 在animateTo闭包中改变flag的值
- animateTo({duration:1500},() => {
- // 点击按钮来控制标记变量
- this.flag = !this.flag;
- })
- })
- if(this.flag) {
- Text('HarmonyOS')
- .fontSize(20)
- .fontWeight(FontWeight.Bolder)
- .fontColor('#008792')
- // 添加转场效果
- .transition({type: TransitionType.Insert, translate: {x: 200, y: -200}})
- .transition({type: TransitionType.Delete, opacity: 0, scale: {x: 0, y: 0}})
- }
-
- }
- .width('100%')
- }
- .height('100%')
- }
- }

ForEach可通过控制数组中的元素个数,来控制组件的插入和删除。通过ForEach来产生组件内转场动画,需要两个条件
1、ForEach里的组件配置了transition效果
2、在animateTo的闭包中控制组件的插入或删除,即控制数组的元素添加和删除
- @Entry
- @Component
- struct ForEachTest {
-
- @State books :string[] = [
- '《JavaScript学习指南》',
- '《TypeScript从入门到精通》',
- '《ArkTS学习手册》',
- '《JAVA核心卷》'
- ];
-
- num: number = 0;
-
- build() {
- Column({space: 10}) {
- Column(){
- // 注意 这里遍历的key是使用item,所以我们在添加时加上一个num来区分内容
- ForEach(this.books, (item) => {
- Text(item).textStyle()
- .transition({type: TransitionType.All, translate: {x: 200},scale:{x:0,y:0}})
- },item => JSON.stringify(item))
- }.columnStyle()
-
- Button('头部添加元素').ButtonStyle('#375830', () => {
- animateTo({}, () => {
- this.num++;
- this.books.unshift(`《C语言编程思想》_${this.num}`)
- })
- })
-
- Button('头部删除元素').ButtonStyle('#b64533', () => {
- animateTo({}, () => {
- this.books.shift()
- })
- })
-
- Button('尾部删除元素').ButtonStyle('#dea32c', () => {
- animateTo({}, () => {
- this.books.pop()
- })
- })
-
- }
- .width('100%')
- .height('100%')
- }
- }
-
- // 相关样式信息
- @Extend(Text) function textStyle() {
- .width(300)
- .height(60)
- .fontSize(18)
- .margin({top: 3})
- .backgroundColor('#d3c6a6')
- .textAlign(TextAlign.Start)
- .fontColor(Color.White)
- }
-
- @Extend(Column) function columnStyle() {
- .margin(10)
- .justifyContent(FlexAlign.Start)
- .alignItems(HorizontalAlign.Center)
- .width('90%')
- .height('50%')
- }
-
- @Extend(Button) function ButtonStyle(color: string|Color, click: Function) {
- .width(200)
- .height(50)
- .fontSize(18)
- .backgroundColor(color)
- .onClick(() => {
- // click代表的就是调用时具体传入进来的函数
- click()
- })
- }

在不同的页面间,有使用相同元素的场景,可以使用共享元素转场动画衔接。
共享元素转场的接口:
sharedTransition(id: string, options?: sharedTransitionOptions)
其中id为指定共享元素的组件id
根据sharedTransitionOptions中的type参数,可以把共享元素转场分为Exchange类型和Static类型。
交换型共享元素转场。
这种类共享元素转场适用于两个页面间相同元素的衔接,从起始页共享元素的位置、大小过渡到目标页面的共享元素的位置、大小。
当不指定type时,默认就是Exchange类型的共享转场
使用Exchange类型的共享转场时,共享元素转场的动画参数由目标页面options中的动画参数决定。
静态类型的共享元素转场常用于页面跳转时,标题的渐入淡出,只需要在一个页面中有Static的共享元素,不能在两个页面中出现相同id的Static类型的共享元素。
- // Src.ets
- import router from '@ohos.router';
-
- @Entry
- @Component
- struct Src {
-
- build() {
- Column({ space: 30 }) {
- // Exchange类型共享转场
- Image($r('app.media.image2'))
- .width(50)
- .height(50)
- .opacity(.3)
- .borderRadius(75)
- .sharedTransition('img1',{
- duration: 1000,
- curve: Curve.Linear
- })
- }
- .onClick(() => {
- // 路由跳转
- router.pushUrl({url: "pages/SharedTransition/Dest"});
- })
- .padding(10)
- .width('100%')
- .height('100%')
- .alignItems(HorizontalAlign.Start)
- }
- }

- // Dest.ets
- import router from '@ohos.router';
-
- @Entry
- @Component
- struct Dest {
-
- build() {
- Column({ space: 30 }) {
- // 配置Static类型的共享元素转场
- Text('鸿蒙系统')
- .fontSize(20)
- .fontColor('#6d8346')
- .opacity(.8)
- .fontWeight(FontWeight.Bold)
- .margin({ top: 10 })
- .sharedTransition('text',{
- duration: 500,
- curve: Curve.Linear,
- type: SharedTransitionEffectType.Static
- })
- // 配置Exchange类型的共享元素转场,id是'img1'
- Image($r('app.media.image2'))
- .width(150)
- .height(150).opacity(1)
- .borderRadius(75)
- .sharedTransition('img1',{
- duration: 500,
- curve: Curve.Linear
- })
- }
- .width('100%')
- .height('100%')
- .alignItems(HorizontalAlign.Center)
- .onClick(() => {
- // 返回
- router.back();
- })
- }
- }

两个页面之间发生跳转,一个页面消失,另一个页面出现,此时可以配置各自页面的页面转场参数实现自定义的页面转场效果。
页面转场效果写在pageTransition函数中,通过PageTransitionEnter和PageTransitionExit来指定页面进入和退出时的动画效果。
pageTransitionEnter接口
PageTransitionEnter({type?: RouteType, duration?: number, curve?: Curve | string, delay: number})
pageTransitionEnter提供了onEnter接口进行自定义页面入场动画的回调
pageTransitionExit接口
PageTransitionExit({type?: RouteType, duration?: number, curve?: Curve | string, delay: number})
pageTransitionExit提供了onExit接口进行自定义页面退场动画的回调
关于RouteType表示路由生效类型,从一个页面到另一个页面有两人种方式,一种是push,一种是back(pop出栈),那么type参数就可以由开发者指定哪种类型的路由来定义转场效果。对于push和back会有一些区别,比如A页面到B页面push时,A页面是退场,B页面是入场,如果B页面back回A页面则是B页面退场,A页面入场。
type参数的默认值是RouteType.None表示对页面的push和pop都生效
如果我们把页面转场时长设置为0(duration参数值为0)则无页面转场动画。
- // Src2.est
- import router from '@ohos.router';
-
- @Entry
- @Component
- struct Src2 {
- @State scale1: number = 1;
- @State opacity1: number = 1;
-
- build() {
- Column({ space: 30}) {
- Text('Src2...')
- .fontSize(30)
- .opacity(this.opacity1)
- .margin({bottom: 15})
- Image($r('app.media.image2'))
- .width(300)
- .height(400)
- .scale({x: this.scale1})
- .opacity(this.opacity1)
- }
- .width('100%')
- .height('100%')
- .onClick(() => {
- router.pushUrl({
- url: "pages/pageTransition/Dest2"
- })
- })
- }
-
- pageTransition() {
- PageTransitionEnter({}).onEnter((type: RouteType, progress: number) => {
- this.scale1 = 1;
- this.opacity1 = progress;
- })
-
- PageTransitionExit({}).onExit((type: RouteType, progress: number) => {
- this.scale1 = 1 - progress;;
- this.opacity1 = 1 - progress;
- })
- }
-
- }

- // Dest2.est
- import router from '@ohos.router';
-
- @Entry
- @Component
- struct Dest2 {
- @State scale1: number = 1;
- @State opacity1: number = 1;
-
- build() {
- Column(){
- Text('Dest2...')
- .fontSize(30)
- .opacity(this.opacity1)
- .margin({bottom: 15})
- Image($r('app.media.image2'))
- .width(300)
- .height(400)
- .scale({y: this.scale1})
- .opacity(this.opacity1)
- }
- .width('100%')
- .height('100%')
- .onClick(() => {
- router.back()
- })
- }
-
- pageTransition() {
- PageTransitionEnter({}).onEnter((type: RouteType, progress: number) => {
- this.scale1 = progress;
- this.opacity1 = progress;
- })
-
- PageTransitionExit({}).onExit((type: RouteType, progress: number) => {
- this.scale1 = 1 - progress;
- this.opacity1 = 1 - progress;
- })
-
- }
-
- }

当需要访问网络资源的时候需要在module.json5中申请网络访问权限:ohos.permission.INTERNET
Web组件的使用只需要ArkTS文件中创建一个Web组件,传入两个参数就可以了。
src:指定了网页的路径
controller:组件控制器,绑定web组件,实现对web组件的控制
- import webview from '@ohos.web.webview';
-
- @Entry
- @Component
- struct WebComp {
-
- controller: WebviewController = new webview.WebviewController();
-
- build() {
- Row() {
- Column() {
- Web({
- src: 'https://www.baidu.com',
- controller: this.controller
- })
- }
- .width('100%')
- }
- .height('100%')
- }
- }

首先本的网页文件可以放在rawfile目录中
- <!-- index.html -->
- <!doctype html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport"
- content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
- <meta http-equiv="X-UA-Compatible" content="ie=edge">
- <title>Document</title>
- </head>
- <body>
- <div>
- <h2>加载本地网页</h2>
- </div>
- <div>
- <img src="../base/media/img1.png" width="300" height="400">
- </div>
-
- </body>
- </html>

在ets文件中对这个页面进行加载展示
- import webview from '@ohos.web.webview'
-
- @Entry
- @Component
- struct WebComp2 {
- controller: WebviewController = new webview.WebviewController();
-
- build() {
- Row() {
- Column() {
- Web({
- src: $rawfile('index.html'),
- controller: this.controller
- })
- }
- .width('100%')
- }
- .height('100%')
- }
- }

有时网页可能不能与手机屏幕很好地适配,需要对其缩放才能有更好的效果,这个时候可以给Web组件zoomAccess属性,它用来设置是否支持手势 进行缩放,默认是行缩放的。
- Web({ src:'www.example.com', controller:this.controller })
- .zoomAccess(true)
还可以使用zoom(factor: number)方法用于设置网站的缩放比例,参数factor表示缩放的倍数
- import webview from '@ohos.web.webview';
-
- @Entry
- @Component
- struct WebComp {
-
- controller: WebviewController = new webview.WebviewController();
-
- build() {
- Row() {
- Column() {
- Button('zoom+')
- .width('50%')
- .onClick(() => {
- this.controller.zoom(1.5)
- })
- Web({
- src: 'https://www.baidu.com',
- controller: this.controller
- })
-
- }
- .width('100%')
- }
- .height('100%')
- }
- }

上面示例每次点击zoom+时会把页面放大为原来的1.5倍。
如果需要对文本进行缩放,可以使用textZoomAtio(textZoomAtio: number)方法
textZoomRatio为缩放的百分比,默认值是100,表示100%
- import webview from '@ohos.web.webview';
-
- @Entry
- @Component
- struct WebComp {
- @State textZoom: number = 100;
- controller: WebviewController = new webview.WebviewController();
-
- build() {
- Row() {
- Column() {
- Button('文大文本+')
- .width('50%')
- .onClick(() => {
- this.textZoom += 20;
- })
- Web({
- src: 'https://www.baidu.com',
- controller: this.controller
- }).textZoomRatio(this.textZoom)
-
- }
- .width('100%')
- }
- .height('100%')
- }
- }

web组件还提供了处理JavaScript的对话框、网页加载进度及各种通知与请求事件的方法。
onProgressChange 监听网页的加载进度
onPageEnd 在网页加载完时触发此回调
onConfirm 在网页触发confirm告警弹窗时触发回调
- <!-- index.html -->
- <!doctype html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport"
- content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
- <meta http-equiv="X-UA-Compatible" content="ie=edge">
- <title>Document</title>
- </head>
- <body>
- <div>
- <h2>加载本地网页</h2>
- </div>
- <div>
- <img src="../base/media/img1.png" width="300" height="400">
- </div>
-
- <script type="text/javascript">
- confirm('confirm message from html')
- </script>
- </body>
- </html>

- import webview from '@ohos.web.webview'
-
- @Entry
- @Component
- struct WebComp2 {
- controller: WebviewController = new webview.WebviewController();
-
- build() {
- Row() {
- Column() {
- Web({
- src: $rawfile('index.html'),
- controller: this.controller
- })
- .zoomAccess(true)
- .onConfirm((event) =>{
- AlertDialog.show({
- title: 'title',
- message: event.message,
- confirm: {
- value: 'onAlert',
- action: () => {
- event.result.handleConfirm();
- }
- },
- cancel: () => {
- event.result.handleCancel();
- }
- })
- return true;
- })
- }
- .width('100%')
- }
- .height('100%')
- }
- }

web组件可以调用JavaScript方法,JavaScript也可以调用Web组件里的方法
web组件启用javascript
如果在web组件中运行javascript,则必须要在web组件中启用javascript功能,默认情况下是不可以执行javascript的。
- Web({src: 'https://www.example.com', controller: this.controller})
- .javaScriptAccess(true)
web组件调用JS方法
比如在web组件onPageEnd事件中添加runJavaScript方法,这个事件是在网页加载完成时的回调,runJavaScript方法可以执行HTML中的JavaScript脚本
- <!-- index.html -->
- <!doctype html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport"
- content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
- <meta http-equiv="X-UA-Compatible" content="ie=edge">
- <title>Document</title>
- </head>
- <body>
- <div>
- <h2>加载本地网页</h2>
- </div>
- <div>
- <img src="../base/media/img1.png" width="300" height="400">
- </div>
-
- <script type="text/javascript">
- function test() {
- return "this value is from index.html"
- }
- </script>
- </body>
- </html>

- import webview from '@ohos.web.webview'
-
- @Entry
- @Component
- struct WebComp2 {
- controller: WebviewController = new webview.WebviewController();
- @State webResult: string = ''
-
- build() {
- Row() {
- Column() {
- Text(this.webResult)
- .fontSize(16)
- Web({
- src: $rawfile('index.html'),
- controller: this.controller
- })
- .zoomAccess(true)
- .javaScriptAccess(true)
- .onPageEnd(e => {
- this.controller.runJavaScript('test()',(err,data)=>{
- if(!err) {
- this.webResult = data;
- }
- })
- // promise化的写法
- // let promise = this.controller.runJavaScript('test()');
- // promise.then((data) => {
- // this.webResult = data;
- // })
- })
- }
- .width('100%')
- }
- .height('100%')
- }
- }

js调用web组件方法
开发者者使用Web组件把应用侧代码注册到前端页面中,注册完成之后,前端页面中使用注册的对象名称就可以调用应用侧的函数,从而实现前端页面中调用应用侧的方法。
注册应用侧代码有两种方式:
一种是Web组件初始化使用调用,使用javaScriptProxy()接口。
一种是在Web组件初始化完成后调用,使用registerJavaScriptProxy()接口
javaScriptProxy()接口使用示例:
- // xxx.ets
- import web_webview from '@ohos.web.webview';
-
- @Entry
- @Component
- struct WebComponent {
- webviewController: web_webview.WebviewController = new web_webview.WebviewController();
- // 声明需要注册的对象
- testObj = {
- test: () => {
- return 'ArkTS Hello World!';
- }
- }
-
- build() {
- Column() {
- // web组件加载本地index.html页面
- Web({ src: $rawfile('index.html'), controller: this.webviewController})
- // 将对象注入到web端
- .javaScriptProxy({
- object: this.testObj,
- name: "testObjName",
- methodList: ["test"],
- controller: this.webviewController
- })
- }
- }
- }

应用侧使用registerJavaScriptProxy()接口注册
- // xxx.ets
- import web_webview from '@ohos.web.webview';
-
- @Entry
- @Component
- struct Index {
- webviewController: web_webview.WebviewController = new web_webview.WebviewController();
- testObj = {
- test: (data) => {
- return "ArkUI Web Component";
- },
- toString: () => {
- console.info('Web Component toString');
- }
- }
-
- build() {
- Column() {
- Button('refresh')
- .onClick(() => {
- try {
- this.webviewController.refresh();
- } catch (error) {
- console.error(`Errorcode: ${error.code}, Message: ${error.message}`);
- }
- })
- Button('Register JavaScript To Window')
- .onClick(() => {
- try {
- this.webviewController.registerJavaScriptProxy(this.testObj, "testObjName", ["test", "toString"]);
- } catch (error) {
- console.error(`Errorcode: ${error.code}, Message: ${error.message}`);
- }
- })
- Web({ src: $rawfile('index.html'), controller: this.webviewController })
- }
- }
- }

注意: 使用registerJavaScriptProxy()接口注册方法时,注册后需调用refresh()接口生效
- <!-- index.html -->
- <!DOCTYPE html>
- <html>
- <body>
- <button type="button" onclick="callArkTS()">Click Me!</button>
- <p id="demo"></p>
- <script>
- function callArkTS() {
- let str = objName.test();
- document.getElementById("demo").innerHTML = str;
- console.info('ArkTS Hello World! :' + str);
- }
- </script>
- </body>
- </html>
当使用浏览器浏览网页时,可以执行返回、前进、刷新等操作,Web组件也支持这些操作。可以使用backward()回到上一个页面,forward()前进一个页面,refresh()刷新页面,clearHistory()清除历史记录。
- import webview from '@ohos.web.webview'
- @Entry
- @Component
- struct NavigatorTest {
- controller: WebviewController = new webview.WebviewController();
-
- build() {
- Row() {
- Column() {
- Row() {
- Button('前进').onClick(() => {
- this.controller.forward();
- })
- Button('后退').onClick(() => {
- this.controller.backward();
- })
- Button('刷新').onClick(() => {
- this.controller.refresh();
- })
- Button('停止').onClick(() => {
- this.controller.stop();
- })
- Button('清理历史').onClick(() => {
- this.controller.stop();
- })
- }
- .padding(5)
- .backgroundColor(Color.Gray)
- .width('100%')
- .justifyContent(FlexAlign.SpaceAround)
-
- Web({src: 'https://www.baidu.com', controller: this.controller})
- }
- .width('100%')
- }
- .height('100%')
- }
- }

开发的应用需要通过HTTP发送一个数据请求,支持的情求方式有:GET、POST、OPTIONS、HEAD、PUT、DELETE、TRACE、CONNECT
HTTP数据请求功能主要由http模块提供,这个功能也需要申请ohos.permission.INTERNET权限
相关的方法说明:
方法名称 | 功能描述 |
createHttp() | 创建一个http请求 |
request() | 根据URL地址,发起HTTP网络请求 |
destroy() | 中断请求任务 |
on(type: 'headerReceive') | 订阅HTTP Response Header 事件 |
off(type: 'headerReceive') | 取消订阅HTTP Response Header事件 |
1、导入http模块
import http from '@ohos.net.http';
2、创建HTTP请求实例,生成HttpRequest对象
let httpRequest = http.createHttp();
注意:每一个httpRequest对应一个http请求任务,不可以复用
3、订阅HTTP响应头(可选)
4、根据URL地址,发起HTTP网络请求
5、处理HTTP响应头和HTTP网络请求的返回结果(可选)
- // 导入模块
- import http from '@ohos.net.http';
-
- @Entry
- @Component
- struct HttpTest {
- url: string = 'https://mock.apifox.com/m1/3690335-0-default/getHot'
- @State titles: string[] = [];
-
- build() {
- Row() {
- Column() {
- Button('获取数据')
- .width('50%')
- .margin({bottom: 15})
- .onClick(() => {
- // 创建请求对象
- let httpReq = http.createHttp();
- // 发起请求
- httpReq.request(this.url,{
- method: http.RequestMethod.GET,
- }, (err,data) => {
- // 处理结果
- if(!err) {
- // this.titles = JSON.parse(`${data}`).values['title']
- let arr = JSON.parse(`${data.result}`).values
- for(let item of arr) {
- this.titles.push(item['title']);
- }
- }
- })
- })
- ForEach(this.titles, (item) =>{
- Text(item)
- .fontSize(14)
- .margin({bottom:5})
- },item => item)
- }
- .width('100%')
- }
- .height('100%')
- }
- }

使用这种方式是为了避免地狱回调的问题。
- // 导入模块
- import http from '@ohos.net.http';
-
- @Entry
- @Component
- struct HttpPromiseTest {
-
- url: string = 'https://mock.apifox.com/m1/3690335-0-default/getHot'
- @State titles: string[] = [];
-
- build() {
- Row() {
- Column() {
- Button('获取数据')
- .width('50%')
- .margin({bottom: 15})
- .onClick(() => {
- // 创建http请求
- let httpReq = http.createHttp();
- // 发起请求
- let promise = httpReq.request(this.url)
- promise.then((data) => {
- let arr = JSON.parse(`${data.result}`).values
- for(let item of arr) {
- this.titles.push(item['title']);
- }
- })
- })
-
- ForEach(this.titles, (item) =>{
- Text(item)
- .fontSize(14)
- .margin({bottom:5})
- },item => item)
- }
- .width('100%')
- }
- .height('100%')
- }
- }

Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。