再次吐槽鸿蒙

上次吐槽鸿蒙还是是刚刚读完官网文档。

最近尝试利用鸿神的玩安卓开放 API 写一个 WanHarmony,也是遇到了一些设计上的不合理,或者是我没有 get 到设计精髓的地方,记录一下。

没有全局 Style

在安卓中,遇到需要公共的样式,一般会抽取全局 Style,鸿蒙也提供了类似的能力 @Style 装饰器。例如宽高都是 100% :

less 复制代码
@Styles function matchSize() {
  .width('100%')
  .height('100%')
}

文档中说是支持 组件内全局 重用。但实际测试,所谓的全局仅仅支持单个文件内的不同组件可以引用到,一旦跨文件就无法引用。

这个还挺不方便的,希望后续得到修复。

费解的 LazyForEach

LazyForEach 从提供的数据源中按需迭代数据,并在每次迭代过程中创建相应的组件。当在滚动容器中使用了 LazyForEach,框架会根据滚动容器可视区域按需创建组件,当组件滑出可视区域外时,框架会进行组件销毁回收以降低内存占用。

显而易见,LazyForEach 是 RecyclerView 的替代品,甚至连用法都有一些类似。

typescript 复制代码
LazyForEach(
    dataSource: IDataSource,             // 需要进行数据迭代的数据源
    itemGenerator: (item: any, index?: number) => void,  // 子组件生成函数
    keyGenerator?: (item: any, index?: number) => string // 键值生成函数
): void

数据源需要实现 IDataSource 接口:

scss 复制代码
interface IDataSource {
    totalCount(): number; // 获得数据总数
    getData(index: number): Object; // 获取索引值对应的数据
    registerDataChangeListener(listener: DataChangeListener): void; // 注册数据改变的监听器
    unregisterDataChangeListener(listener: DataChangeListener): void; // 注销数据改变的监听器
}

这个 Listener 也是一堆接口方法:

php 复制代码
interface DataChangeListener {
    onDataReloaded(): void; // 重新加载数据完成后调用
    onDataAdded(index: number): void; // 添加数据完成后调用
    onDataMoved(from: number, to: number): void; // 数据移动起始位置与数据移动目标位置交换完成后调用
    onDataDeleted(index: number): void; // 删除数据完成后调用
    onDataChanged(index: number): void; // 改变数据完成后调用
    onDataAdd(index: number): void; // 添加数据完成后调用
    onDataMove(from: number, to: number): void; // 数据移动起始位置与数据移动目标位置交换完成后调用
    onDataDelete(index: number): void; // 删除数据完成后调用
    onDataChange(index: number): void; // 改变数据完成后调用
}

乍看起来,跟 RecyclerView.Adapter 差不多。等等,ArkUI 不应该是声明式 UI 吗?为什么还要用这种写法来实现列表呢。

其实 ArkUI 也有声明式的 List 组件:

scss 复制代码
    List({ scroller: this.scroller }) {
      ForEach(this.articleList, (item: ArticleEntity) => {
        ListItem() {
            ArticleView({ article: item })
              .onClick(() => {
                router.pushUrl({
                  url: 'pages/WebPage',
                  params: item
                }, router.RouterMode.Single)
              })
          }
      })
    }
    .height('100%')
    .width('100%')

但是呢,默认会加载所有数据,不支持预加载,不支持 item 的回收复用。所以,屏蔽实现细节,直接让 List 支持回收复用会不会更好呢?

费解的 Dialog

期望的声明式 Dialog 写法:

javascript 复制代码
.dialog($isShow) {
	// 自定义 dialog 布局
}

鸿蒙需要通过一个神奇的 CustomDialogController 来处理。

先通过 @CustomDialog 定义自定义 Dialog,

scss 复制代码
@CustomDialog
struct CustomDialogExample {
  controller: CustomDialogController = new CustomDialogController({
    builder: CustomDialogExample({}),
  })

  build() {
    Column() {
      Text('自定义 Dialog')
        .fontSize(20)
        .margin({ top: 10, bottom: 10 })
    }
  }
}

然后声明一个 CustomDialogController,调用其 open() 方法来展示弹窗。

less 复制代码
@Entry
@Component
struct CustomDialogUser {
  dialogController: CustomDialogController = new CustomDialogController({
    builder: CustomDialogExample(),
  })

  build() {
    Column() {
      Button('click me')
        .onClick(() => {
          this.dialogController.open()
        })
    }.width('100%').margin({ top: 5 })
  }
}

官网示例中还有一个更加晦涩难懂的 一个 dialog 中弹出另一个 dialog 的场景示例。

能用,但没那么好用。

硬编码

良好的设计应该避免让程序员硬编码,以尽量减少犯错的可能性。

当我第一次看到下面这个代码,有点懵。

scss 复制代码
Grid() {
	...
}
.rowsTemplate('1fr 1fr 1fr')
.columnsTemplate('1fr 2fr 1fr')

这种相比 GridLayoutManager.SpanSizeLookUp 的写法,效率确实得到了很大的提升,但可读性就降低了。

还有宽高的硬编码,

arduino 复制代码
.width('100%')
.height('100%')

我一直期望可以有个类似 fillWidth/fillHeight 的装饰器可以代替一下。

最后

以上吐槽基于 API 10 版本。另外希望早日可以有 API 9 以上版本的虚拟机可以使用。

今天是鸿蒙生态千帆启航仪式,目前已经参与鸿蒙原生开发的 App 数量比我想象的还要多一些,官方也给出了 Q4 正式商用的计划。可以想象,今年肯定是鸿蒙 App 井喷的一年。

相关推荐
Rattenking1 分钟前
node - npm常用命令和package.json说明
前端·npm·json
Easonmax1 分钟前
【HTML5】html5开篇基础(1)
前端·html·html5
xiaoduyyy3 分钟前
【Android】ToolBar,滑动菜单,悬浮按钮和可交互提示等的使用方法
android
For. tomorrow5 分钟前
Vue3中el-table组件实现分页,多选以及回显
前端·vue.js·elementui
liyy61418 分钟前
Android架构组件:MVVM模式的实战应用与数据绑定技巧
android
布瑞泽的童话32 分钟前
无需切换平台?TuneFree如何搜罗所有你爱的音乐
前端·vue.js·后端·开源
白鹭凡44 分钟前
react 甘特图之旅
前端·react.js·甘特图
2401_862886781 小时前
蓝禾,汤臣倍健,三七互娱,得物,顺丰,快手,游卡,oppo,康冠科技,途游游戏,埃科光电25秋招内推
前端·c++·python·算法·游戏
OH五星上将1 小时前
OpenHarmony(鸿蒙南向开发)——小型系统内核(LiteOS-A)【扩展组件】上
linux·嵌入式硬件·harmonyos·openharmony·鸿蒙开发·liteos-a·鸿蒙内核