openHarmony的UI开发

news2025/3/13 2:57:39

自适应布局

拉伸能力

Blank在容器主轴方向上,空白填充组件具有自动填充容器空余部分的能力。仅当父组件为Row/Column时生效,即是线性布局。这样便可以在两个固定宽度或高度的组件中间添加一个Blank(),将剩余空间占满,从而实现占两头的效果

在这里插入图片描述

​ 而在使用弹性布局中,可以使用flexBasis设置子组件在父容器主轴方向上的基准尺寸,还可以使用flexGrow来设置父容器的剩余空间分配给此属性所在组件的比例。最后还有flexShrink,它可以在父容器空间不足时,压缩子组件的比例。

缩放能力

​ 自适应缩放是指在各种不同大小设备中,子组件按照预设的比例,尺寸随容器尺寸的变化而变化。有两种方法可以实现。

1、使用layoutWeight属性

​ 父容器尺寸确定时,设置了layoutWeight属性的子组件与兄弟元素占主轴尺寸按照权重进行分配,忽略元素本身尺寸设 置,在任意尺寸设备下,自适应占满剩余空间

2、使用百分比设置

​ 父容器尺寸确定时,使用百分比设置子组件以及兄弟组件的width宽度,可以保证各自元素在任意尺寸下的自适应占比

定位能力

1、相对定位

​ 使用组件的offset属性进行相对定位,会根据初始位置按照设定好的偏移量进行位置调整。使用线性布局和offset可以实现大部 分布局的开发

2、绝对定位

​ 使用positon属性实现绝对布局,设定左上角为(0,0)位置,可以设置x和y坐标进行位置调整。但是对于不同尺寸的设备,使 得很多时候用绝对定位的适应性会比较差,在屏幕的适配上有缺陷

延伸能力

​ 容器在一个屏幕下无法展示所有内容的时候,就需要通过滚动条拖动展示,方法有两种:List组件和Scroll组件。list和scroll纵向 和横向均可以。用循环渲染进行渲染,若数据量过多,超过了一个屏幕,便可以通过滚动条拖动显示。

均分能力

线性布局

在这里插入图片描述

​ 通过上图的三个参数设置,实现了布局的自适应均分能力

弹性布局

​ 相比于前者,弹性布局少了space参数,但是directionwrapalignContent的加入,更加能体现出布局的自适应均分能力

网格布局

​ 网格布局具备较强的页面均分能力,它可以按行按列将容器均分成n块,然后再按列按行将子组件一个个放进去。例如在计算器 应用,可以将网格布局的页面均分能力充分地体现出来。

占比能力

​ 网格布局具备较强的子组件占比控制能力,支持自定义网格布局行数和列数,以及每行每列尺寸占比,支持设置子组件横跨几行 或者几列

隐藏能力

1、条件渲染

2、显隐控制

拆行能力

​ 网格布局支持设置子组件横跨几行或者几列

响应式布局

断点

栅格系统断点

​ 栅格系统通过监听窗口或容器的尺寸变化进行断点,通过reference设置断点切换参考物,从而实现了根据断点来判断采用哪 种设备的布局设置,最多可以设置六种设备。

		{ //  设栅格系统有12列,断点有五个,可以判断六种设备
		columns:  12,
        breakpoints: {
          value: ['200vp', '300vp', '400vp', '500vp', '1200vp'],
          reference: BreakpointsReference.ComponentSize
        }
        
        span: {  // 第一个种设备每个栅格子元素占用两列,第二种3列,第三种四列,以此类推
         xs: 2,
         sm: 3,
         md: 4,
         lg: 6,
         xl: 8,
         xxl: 12
       }

上面参数的设置的效果如下图所示:

在这里插入图片描述

媒体查询

媒体查询(Media Query)作为响应式设计的核心,在移动设备上应用十分广泛。它根据不同设备类型或同设备不同状态修改应用的样式。媒体查询的优势有:

  1. 提供丰富的媒体特征监听能力,针对设备和应用的属性信息(比如显示区域、深浅色、分辨率),设计出相匹配的布局。
  2. 当屏幕发生动态改变时(比如分屏、横竖屏切换),同步更新应用的页面布局。

官方例子:

import mediaquery from '@ohos.mediaquery'

let portraitFunc = null

@Entry
@Component
struct MediaQueryExample {
  @State color: string = '#DB7093'
  @State text: string = 'Portrait'
  listener = mediaquery.matchMediaSync('(orientation: landscape)') // 当设备横屏时条件成立

  onPortrait(mediaQueryResult) {
    if (mediaQueryResult.matches) {
      this.color = '#FFD700'
      this.text = 'Landscape'
    } else {
      this.color = '#DB7093'
      this.text = 'Portrait'
    }
  }

  aboutToAppear() {
    portraitFunc = this.onPortrait.bind(this) // 绑定当前应用实例
    this.listener.on('change', portraitFunc)
  }

  build() {
    Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
      Text(this.text).fontSize(50).fontColor(this.color)
    }
    .width('100%').height('100%')
  }
}

横屏下文本内容为Landscape,颜色为#FFD700

在这里插入图片描述

非横屏下文本内容为Portrait,颜色为#DB7093

在这里插入图片描述

栅格布局

​ 栅格布局的总列数可以参考断点处,就是要设置好一共有多少行,还有每个栅格子元素占用多少行

​ 栅格子组件间距也很简单,就设置一下gutter就可以了,gutter: 10是水平间距,gutter: { x: 20, y: 50 } 是水平垂直间距

​ 排列方向有从左往右和从右往左

​ 而对于栅格子组件GridCol,有spanoffsetorder三个参数可以设置

span:子组件占栅格布局的列数,可以统一设置,也可以分设备类型设置不同占比

offset:就是偏移列数,就是可以起到拆列的作用

order:栅格子组件的序号,决定子组件排列次序。当子组件不设置order或者设置相同的order, 子组件按照代码顺序展示。当子组件设置不同的order时,order较小的组件在前,较大的在后。 当子组件部分设置order,部分不设置order时,未设置order的子组件依次排序靠前,设置了order的子组件按照数值从小到大排列。

动画

属性动画

​ 这个可以直接跟在组件的属性方法里面进行填写,不过只支持width、height、backgroundColor、opacity、scale、rotate、translate等部分通用属性变化时生效

 		.animation({
          duration: 2000,
          curve: Curve.EaseOut,
          iterations: 3,
          playMode: PlayMode.Normal
        })

显式动画

​ 提供全局animateTo显式动画接口来指定由于闭包代码导致的状态变化插入过渡动效。

和前者不同的是,这里可以在全局对设定好的参数进行改变便可以触发动画的执行

 		.onClick(() => {
          if (this.flag) {
            animateTo({
              duration: 2000,
              curve: Curve.EaseOut,
              iterations: 3,
              playMode: PlayMode.Normal,
              onFinish: () => {
                console.info('play end')
              }
            }, () => {
              this.widthSize = 100
              this.heightSize = 50
            })
          } else {
            animateTo({}, () => {
              this.widthSize = 250
              this.heightSize = 100
            })
          }
          this.flag = !this.flag
        })

转场动画

页面间转场

​ 在全局pageTransition方法内配置页面入场和页面退场时的自定义转场动效。

​ 官方例子:配置了当前页面的入场动画为淡入,退场动画为缩小。

// index.ets
@Entry
@Component
struct PageTransitionExample1 {
  @State scale1: number = 1
  @State opacity1: number = 1

  build() {
    Column() {
      Navigator({ target: 'pages/page1', type: NavigationType.Push }) {
        Image($r('app.media.bg1')).width('100%').height('100%')    // 图片存放在media文件夹下
      }
    }.scale({ x: this.scale1 }).opacity(this.opacity1)
  }
  // 自定义方式1:完全自定义转场过程的效果
  pageTransition() {
    PageTransitionEnter({ duration: 1200, curve: Curve.Linear })
      .onEnter((type: RouteType, progress: number) => {
        this.scale1 = 1
        this.opacity1 = progress
      }) // 进场过程中会逐帧触发onEnter回调,入参为动效的归一化进度(0% -- 100%)
    PageTransitionExit({ duration: 1500, curve: Curve.Ease })
      .onExit((type: RouteType, progress: number) => {
        this.scale1 = 1 - progress
        this.opacity1 = 1
      }) // 退场过程中会逐帧触发onExit回调,入参为动效的归一化进度(0% -- 100%)
  }
}

// page1.ets
@Entry
@Component
struct AExample {
  @State scale2: number = 1
  @State opacity2: number = 1

  build() {
    Column() {
      Navigator({ target: 'pages/index', type: NavigationType.Push }) {
        Image($r('app.media.bg2')).width('100%').height('100%')   // 图片存放在media文件夹下
      }
    }.width('100%').height('100%').scale({ x: this.scale2 }).opacity(this.opacity2)
  }
  // 自定义方式1:完全自定义转场过程的效果
  pageTransition() {
    PageTransitionEnter({ duration: 1200, curve: Curve.Linear })
      .onEnter((type: RouteType, progress: number) => {
        this.scale2 = 1
        this.opacity2 = progress
      }) // 进场过程中会逐帧触发onEnter回调,入参为动效的归一化进度(0% -- 100%)
    PageTransitionExit({ duration: 1500, curve: Curve.Ease })
      .onExit((type: RouteType, progress: number) => {
        this.scale2 = 1 - progress
        this.opacity2 = 1
      }) // 退场过程中会逐帧触发onExit回调,入参为动效的归一化进度(0% -- 100%)
  }
}

在这里插入图片描述

组件内转场

​ 组件内转场主要通过transition属性配置转场参数,在组件插入和删除时显示过渡动效,主要用于容器组件中的子组件插入和删除时,提升用户体验(需要配合animateTo才能生效,动效时长、曲线、延时跟随animateTo中的配置)。

​ 官方实例:点击消失时,在预览器中无法看到生效效果,但其实已经生效了,需要在开发板或真机中才能看到

// xxx.ets
@Entry
@Component
struct TransitionExample {
  @State flag: boolean = true
  @State show: string = 'show'

  build() {
    Column() {
      Button(this.show).width(80).height(30).margin(30)
        .onClick(() => {
          // 点击Button控制Image的显示和消失
          animateTo({ duration: 1000 }, () => {
            if (this.flag) {
              this.show = 'hide'
            } else {
              this.show = 'show'
            }
            this.flag = !this.flag
          })
        })
      if (this.flag) {
        // Image的显示和消失配置为不同的过渡效果
        Image($r('app.media.testImg')).width(300).height(300)
          .transition({ type: TransitionType.Insert, scale: { x: 0, y: 1.0 } })
          .transition({ type: TransitionType.Delete, rotate: { angle: 180 } })
      }
    }.width('100%')
  }
}

共享元素转场

​ 设置页面间转场时共享元素的转场动效

官方实例:点击图片跳转页面时,显示共享元素图片的自定义转场动效。

// xxx.ets
@Entry
@Component
struct SharedTransitionExample {
  @State active: boolean = false

  build() {
    Column() {
      Navigator({ target: 'pages/PageB', type: NavigationType.Push }) {
        Image($r('app.media.ic_health_heart')).width(50).height(50)
          .sharedTransition('sharedImage', { duration: 800, curve: Curve.Linear, delay: 100 })
      }.padding({ left: 20, top: 20 })
      .onClick(() => {
        this.active = true
      })
    }
  }
}

// PageB.ets
@Entry
@Component
struct pageBExample {
  build() {
    Stack() {
      Image($r('app.media.ic_health_heart')).width(150).height(150)
        .sharedTransition('sharedImage', { duration: 800, curve: Curve.Linear, delay: 100 })
    }.width('100%').height('100%')
  }
}

在这里插入图片描述

路径动画

​ 设置组件进行位移动画时的运动路径

toggle作为参数,当它改变的时候,组件的位置会发生改变从而触发了动画的执行,而motionPath可以将它的路径规划出来。

在这里插入图片描述

弹窗

警告弹窗

​ 显示警告弹窗组件,可设置文本内容与响应回调

​ 里面可以填写一些与用户交互的信息,并通过确认或取消按钮触发一个回调,从而完成一定的目的

列表选择弹窗

​ 里面有可滑动选择的信息,并通过确认或取消按钮触发一个回调,从而完成一定的目的

自定义弹窗

​ 通过CustomDialogController类显示自定义弹窗。使用弹窗组件时,可优先考虑自定义弹窗,便于自定义弹窗的样式与内容。

​ 这可以给开发者自定义更多弹窗样式,开发出弹窗更加多的功能

日期滑动选择器弹窗

根据指定的日期范围创建日期滑动选择器,展示在弹窗上。

时间滑动选择器弹窗

以24小时的时间区间创建时间滑动选择器,展示在弹窗上。

文本滑动选择器弹窗

根据指定的选择范围创建文本选择器,展示在弹窗上。

手势处理

绑定手势方法

​ 为组件绑定不同类型的手势事件,并设置事件的响应方法。

​ 绑定方式有三种,gesture绑定手势,priorityGesture绑定优先识别手势,parallelGesture绑定可与子组件手势同时触发的手势(手势事件为非冒泡事件,通过这个可以改成冒泡事件)。另外,可以通过更改GestureMask的参数来选择是否屏蔽掉子组件的手势。最后,onAction为响应手势事件,即为Tap手势识别成功回调。

​ 手势类型有七种

名称描述
TapGesture点击手势,支持单次点击、多次点击识别。
LongPressGesture长按手势。
PanGesture平移手势,滑动最小距离为5vp时识别成功。
PinchGesture捏合手势。
RotationGesture旋转手势。
SwipeGesture滑动手势,滑动最小速度为100vp/s时识别成功。
GestureGroup手势识别组,多种手势组合为复合手势,支持连续识别、并行识别和互斥识别。

每种手势类型都有一个fingers参数用来限制可以几指触发,另外还有各种独有的参数,有directionspeedangledistancedirectionrepeatrepeat

组合手势

手势识别组合,即多种手势组合为复合手势,支持连续识别、并行识别和互斥识别。

mode设置组合手势识别模式,有顺序识别、并发识别和互斥识别

s时识别成功。 |
| GestureGroup | 手势识别组,多种手势组合为复合手势,支持连续识别、并行识别和互斥识别。 |

每种手势类型都有一个fingers参数用来限制可以几指触发,另外还有各种独有的参数,有directionspeedangledistancedirectionrepeatrepeat

组合手势

手势识别组合,即多种手势组合为复合手势,支持连续识别、并行识别和互斥识别。

mode设置组合手势识别模式,有顺序识别、并发识别和互斥识别

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

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

相关文章

通过python 调用OpenAI api_key提交问题解答

通过python 调用OpenAI api_key提交问题解答✨可以通过网页版的jupyter notebook调用,也可以通过spyder窗口等IDE窗口. 🌼通过python 调用OpenAI api_key接口,可以避免国内网页不能访问的问题。前提是需要自己已经注册了OpenAI帐号&#xff…

linux中crontab定时任务导致磁盘满和云监控未报警的的坑

一个后台开发者,兼职运维工作中,配置linux中crontab定时任务,导致磁盘满和云监控未报警的问题的坑。 1.磁盘满 使用命令 df -h2.问题排查 2.1排查日志 命令 cat /var/log/messages日志文件的默认路径是:/var/log 下面是几个…

外贸常用工具(建议顶置收藏)

领英精灵 推荐理由:可批量群发消息并单独显示,相当于20人的发送效率。 做外贸的人一定会在Linkedin平台开发客户,但Linkedin平台没有提供群发消息的功能,如果要快速发消息的话,只能一个一个发,这种发送效…

使用Lame库实现wav、pcm转mp3

文章目录 前言 一、Lame库是什么? 二、使用步骤 0.创建native项目 1.下载Lame库 2.pcm转MP3 3.wav转MP3 4、native方法如下 三、注意 总结 前言 因为使用android录音后生成的文件是wav或者pcm格式,项目要求最后的文件需要是mp3格式,于…

tomcat10部署报错WebStatFilter cannot be cast to jakarta.servlet.Filter

异常信息09-Feb-2023 23:08:49.946 严重 [main] org.apache.catalina.core.StandardContext.filterStart 启动过滤器异常[DruidWebStatFilter]java.lang.ClassCastException: com.alibaba.druid.support.http.WebStatFilter cannot be cast to jakarta.servlet.Filterat org.ap…

上科大最新工作!实时面捕天花板,微表情像素级一致,AI让你告别手Key|SIGGRAPH Asia 2022

驱动一个数字人往往被拆分为追踪 (Tracking) 与重定向 (Retargeting) 两个环节。 追踪由专业的面部捕捉设备及其辅助算法完成,负责记录演员的面部动作信息,重定向则是将捕捉到的动作信息迁移到新的角色。 在传统的流程中,这两个环节往往是分…

全价值链赋能,数字化助力营销价值全力释放 | 爱分析报告

报告编委 张扬 爱分析联合创始人&首席分析师 文鸿伟 爱分析高级分析师 王鹏 爱分析分析师 外部专家(按姓氏拼音排序) 黄洵 客易达 联合创始人 毛健 云徙科技 副总裁 & COO 特别鸣谢(按拼音排序) 报告摘要 在…

SpringSecurity前后端分离(一篇就够了)

SpringSecurity前后端分离 从上至下操作,直接上手SpringSecurity 文章目录SpringSecurity前后端分离1、项目环境maven依赖数据库表2、自定义UserService接口3、屏蔽Spring Security默认重定向登录页面以实现前后端分离功能1、实现登录成功/失败、登出处理逻辑1、表…

鉴源论坛 ·观擎丨民机机载软件的开发与验证

作者 | 蔡喁 上海控安可信软件创新研究院副院长 版块 | 鉴源论坛 观擎 01 机载软件过程保证的目的和背景 民机机载软件研制过程一直是行业内公认的要求最为严苛、开发验证难度最大的软件开发实例之一。由于其高安全以及严格的政府监管特性,使得传统其他领域的软件…

1. 用Qt开发的十大理由

用Qt的十大理由 原因最主要的是很多大公司都在用,有钱景。 先来看看各大公司的评价: 奔驰:们用 Qt 开发了绝大部分的UI体验和软件,包括屏幕动画,屏幕间的过渡和小组件。 FORMLABS:凭借Qt的快速迭代&…

记录一下slf4j2打印一直不成功

整理一个之前的老项目问题,发现日志一直打印不出来,本地启动发现了第一个问题日志如下:此处可发现,jar包冲突问题,去掉冲突的jar包即可,此处不做过多赘述。然后发现了重新启动项目,发现jar包冲突…

工业废水的种类及其处理工艺简析

随着工业的迅速发展,工业废水的种类和数量随之增加,对水体的污染也日趋严重,威胁人类的健康和正常生活。所以工业废水的处理对于环保至关重要。 保护生态环境、更好地做好工业废水的处理,了解工业废水及其种类与处理非常必要。 工…

国内chatgpt 在VRAR上的应用场景

人工智能不鸣则已,一鸣惊人! 近日OpenAI发布了聊天AI ChatGPT,短短几天,其用户量直冲百万级,甚至服务器一度被注册用户挤爆了。 这种被网友惊叹“超越谷歌搜索”的神器究竟是怎么做到的? ChatGPT 简而言之:ChatGPT是一…

三行按键扫描详细解析

三行按键扫描基础 核心算法: unsigned char trg; unsigned char cont; void KeyRead( void ) {unsigned char readDate P3^0xff; // 第一行trg readDate & (ReadData ^ cont); // 第二行cont readDate; // 第三行 }用定时器每隔10ms执行一次按键扫描读取函…

C++:类和对象(上)

文章目录1 面向过程与面向对象的初步认识2 类的引入3 类的定义4 类的访问限定符及封装4.1 访问限定符4.2 封装5 类的实例化6 类对象模型6.1 如何计算类的大小6.2 类对象的存储方式猜测7 this指针7.1 this指针的引出7.2 this指针的特性8 C语言和C栈(Stack&#xff09…

J-Tech Talk|如何使用Grafana Cloud Alert进行实时监控

J-Tech Talk由 Jina AI 社区为大家带来的技术分享围绕 Python 的相关话题工程师们将深入细节地讲解具体的问题分享 Jina AI 在开发过程中所积累的经验在新一代基于云原生的微服务架构中,不管是业务还是基础设施,服务的可观测性 至关重要!它涵…

git、gitee、github关系梳理及ssh不对称加密大白话解释

温馨提示:本文不会讲解如何下载、安装git,也不会讲解如何注册、使用gitee或GitHub,这些内容网上一大把,B站上的入门课程也很多,自己看看就好了。 本文仅对 git、gitee、github的关系梳理及ssh公钥私钥授权原理用白话讲…

whistle 一个神奇的前端调试工具(抓包\代理工具)

在进行前端开发过程中,我们常常需要对一些接口进行处理,以及当后端接口没有弄好需要我们mock一些假数据,针对这些场景,我们就可以使用whistle 来解决。首先,我们要知道能满足我们需求的工具有很多,例如&…

第十五章 栅格数据重分类、栅格计算器、插值分析

文章目录第十五章 栅格数据分析第一章 栅格数据重分类第一节 栅格数据重分类第二节 栅格重分类的使用第三节 重分类的使用中的空值使用第四节 重分类的案例:分类统计面积第五节 坡度矢量分级图生成第二章 栅格计算器第一节 栅格计算器介绍第二节 栅格计算器使用第三…

操作系统题目收录(六)

1、某系统采用基于优先权的非抢占式进程调度策略,完成一次进程调度和进程切换的系统时间开销为1us。在T时刻就绪队列中有3个进程P1P_1P1​、P2P_2P2​和P3P_3P3​,其在就绪队列中的等待时间、需要的CPU时间和优先权如下表所示。若优先权值大的进程优先获…