尝试用 ArkUI 做一个相册应用

时间:2022-06-12 15:49:44

尝试用 ArkUI 做一个相册应用

前言

今年的HDC华为开发者大会2021,华为又双叒推出新的声明式UI开发框架(ArkUI),咋说呢,学无止境啊,更新速度堪比坐火箭。虽然没能到发布的现场比较遗憾,但是这并不妨碍我们撸代码的热情。我也是第一时间更新IDE,使用新的开发框架尝试开发一款图库应用。先看效果:

尝试用 ArkUI 做一个相册应用

一、基本语法

新的编译框架基于TS,相比于之前的JS代码更简洁,将原来的js、hml、css合并为了*.ets一个文件,而且更接近自然语义,学习成本很低。基本是下面的写法:

  1. @装饰器
  2. struct 组件名 {
  3. build(){
  4. //一个根容器组件,比如:
  5. Flex (接口){
  6. //内容
  7. }.属性
  8. Tabs (接口){
  9. TabContent(接口) {
  10. //内容
  11. }
  12. }.属性
  13. List (接口){
  14. ListItem(接口) {
  15. //内容
  16. }
  17. }.属性
  18. }
  19. }

详细的内容可以参考官方文档:https://developer.harmonyos.com/cn/docs/documentation/doc-references/ts-general-ui-concepts-0000001215268053

目前支持的装饰器:

尝试用 ArkUI 做一个相册应用

二、实现一个菜单栏

尝试用 ArkUI 做一个相册应用
尝试用 ArkUI 做一个相册应用

上面2个图片使用了两种不同的实现方式,第一种使用的是Tabs + TabContent,现成的组件实现也比较简单,代码如下:

  1. Tabs(
  2. { barPosition: BarPosition.End } //指定页签位置
  3. ) {
  4. TabContent() {
  5. Photo() //要实现的内容
  6. }.tabBar({
  7. icon: this.menuData[0].url,
  8. text: this.menuData[0].text
  9. })
  10. ... ...
  11. }

不过也有点问题。第一个就是图一中的icon和text有点小,想把尺寸调大却发现各种不支持,只能是这样默认大小,不知道是不是我设置有问题,有知道怎么操作的大佬欢迎留言指点迷津。第二个问题,按理说TabContent内容是一样的,可以使用ForEach+数组,但是也没有成功。最终Tabs实现的效果着实让人不太满意,所以我使用了Flex基本布局 + ForEach 重新实现了图二中的效果,代码如下:

  1. Flex({
  2. direction: FlexDirection.Row, // 主轴:横向布局
  3. alignItems: ItemAlign.Center, // 主轴:
  4. justifyContent: FlexAlign.SpaceEvenly
  5. }) {
  6. ForEach(this.menuData, (item) => {
  7. Column() { //列方向布局容器
  8. this.MenuItem(item.url, item.text)
  9. }
  10. .onClick(() => {
  11. console.info("memememe")
  12. })
  13. })
  14. }

源数据:

  1. //State:数据变化触发build(),实现UI更新
  2. @State menuData: Array<any> = [
  3. { url: $r("app.media.0"), text: "照片" },
  4. { url: $r("app.media.1blue"), text: "相册" },
  5. { url: $r("app.media.2"), text: "时刻" },
  6. { url: $r("app.media.3"), text: "发现" }

菜单项:

  1. @Builder MenuItem(url, text) {
  2. Column() {
  3. Image(url)
  4. .objectFit(ImageFit.Contain) // 保持长宽比缩小或放大,以便图像完全显示在显示边界内。
  5. .width('60%').height('60%')
  6. Text(text)
  7. .fontSize(14)
  8. }
  9. }

总体来看Flex + ForEach效果的实现更*一些,但是点击交互切换标签等操作都需要手动实现,不如组件化的Tabs方便,或许以后会支持把。

三、实现照片区域

首先照片区域使用了下面的数据格式:

  1. @State photoData: Array<any> = [
  2. {
  3. date: "昨天",
  4. photos: [{ src: $r("app.media.today1") }, { src: $r("app.media.today2") }, { src: $r("app.media.today3") }]
  5. },
  6. {
  7. date: "2021年10月27日",
  8. photos: [{ src: $r("app.media.today4") }, { src: $r("app.media.today5") }, { src: $r("app.media.today6") }, {
  9. src: $r("app.media.today7")
  10. }]
  11. },
  12. {
  13. date: "2021年10月26日",
  14. photos: [{ src: $r("app.media.today8") }]
  15. },
  16. {
  17. date: "2021年10月25日",
  18. photos: [{ src: $r("app.media.today9") },{ src: $r("app.media.today11") }]
  19. },
  20. {
  21. date: "2021年10月24日",
  22. photos: [{ src: $r("app.media.today10") }]
  23. }
  24. ,
  25. {
  26. date: "2021年10月23日",
  27. photos: [{ src: $r("app.media.today1") }]
  28. }
  29. ]

所以可以使用ForEach循环嵌套的方式,只需要简单的代码,就可以实现照片列表的效果。

  1. // 照片区
  2. List() {
  3. ForEach(this.photoData, (item) => {
  4. ListItem() {
  5. Flex({ direction: FlexDirection.Column }) {
  6. Text(item.date).fontSize(18).margin({ top: 20,left:15,bottom:5 })
  7. Flex({ direction: FlexDirection.Row }) {
  8. ForEach(item.photos, (item) => {
  9. Image(item.src).objectFit(ImageFit.Cover).width(80).height(80).margin({right:2})
  10. })
  11. }
  12. }
  13. }
  14. })

代码打包上传了,感兴趣的小伙伴,可以下载源码查看。时间有限,先体验这么多,有新的心得再来发帖和大家交流。

https://harmonyos.51cto.com/resource/1585

原文链接:https://harmonyos.51cto.com