鸿蒙应用开发从入门到入行 - 篇 6: 数据监听器、滚动、侧滑功能
![鸿蒙应用开发从入门到入行 - 篇6:数据监听器、滚动、侧滑功能](https://static001.geekbang.org/infoq/39/39725b12ad4636a594b1321d14c31137.png)
鸿蒙应用开发从入门到入行
第六天 - 数据监听器、滚动、侧滑功能
导读:在本篇文章里,您将掌握监听器、滚动、侧滑等相关内容,助力你开发出更具交互的案例。
本次整体学习目标介绍
我们本次继续完成这个
年度计划
案例,并依然通过需求驱动的方式学习新知识点,整体效果如下回顾:上一篇文章我们已经完成了
TodoMain
的显示,并且完成了从TodoItem
里修改完成状态后,也能同步到TodoMain
,目前案例还差TodoHeader
与TodoInput
部分未完成
对上篇文最后留下的互动问题做解答
上篇问到:在本案例中
TodoItem
里的数据打勾变化后(完成状态变化),TodoMain
已经能成功收到改动了。那么它的父组件,最早持有数组的Index
有收到改动吗?并说出理由相信到这篇文章的时候,大家已经有正确答案了,这里猫林也做个解答:
Index
里的数组也跟着变了。因为TodoMain
接收Index
传递过来的数组时用的是@Link
装饰器。而@Link
具有父子同步的效果,因此子里TodoMain
对数组改动,也能同步到父的Index
年度目标案例 - 统计总量
此时头部的
TodoHeader
里,需要显示总目标数以及已完成数。也就意味着依赖了存放目标列表的数组步骤如下
来到
TodoHeader
里声明一个成员变量接收数组,因为这个组件里仅仅只需要展示,无需改动数组。所以用@Prop
修饰即可,并再声明个变量用来记录已完成数量,并把数组长度与已完成数量渲染到进度条与 Text 里,代码如下
来到
Index
做传递
经过以上两步此时已能显示出总目标量,并且不管将来是添加了新目标还是删除了旧目标,这里的总量都会跟着变
因为 @Prop 修饰后,父的数组有改变会自动同步到子,所以子里也会有最新数组数据
年度目标案例 - 统计已完成数 - 监听器的使用
到目前为止,统计已完成数,也即我们在
TodoHeader
里声明的成员变量finishedCount
依然保持着初始化值:0此时我们需要想办法统计出已完成数,并且随着数组的改变,已完成数也要重新统计
例如:数组里打勾或者取消打勾、删除打勾项等都要实时统计
所以,我们需要的是一种监听数据是否有变化,一旦变化就能执行我们预设的逻辑的机制
鸿蒙开发里提供了这种机制,就叫数据监听器
语法
释意:
代表监听
todoList
是否有更改,一旦有更改就调用getFinished
这个方法进行处理注意:
使用监听器时,请记得必须要声明它绑定的方法,像上面代码,我们需要声明成员方法,如下
此时来到界面我们随便找几个目标打勾,会发现在控制台成功输出
数组改变了
此时,已成功监听到数组变动,所以只需在这个方法里,统计出数组里一共有多少个已完成的数量,然后赋值给 finishedCount 即可
代码如下(注意:这里为了照顾所有编程语言使用者,我用最简单的 for 循环统计。如懂 JS 可以使用 reduce)
恭喜,至此头部的统计部分我们全部完成
年度目标案例 - 添加新目标
此时完成
TodoInput
里的添加新目标功能:整体思路为
把数组传递给
TodoInput
,然后给输入框加输入完成事件,在事件里把输入的内容加到数组里即可(用@Link
装饰,子里变了也能同步到父)步骤:
来到
TodoInput
,声明一个状态变量接收父的数组
来到
Index
做传递
这个时候,只需要输入框加输入完成事件,事件里做非空判断,不为空把输入内容加入到数组里,再清空输入框即可
输入完成即按下输入法的回车键。事件为:
onSubmit
提示:这里想做的更严谨的同学还可以做去重处理
年度目标案例 - 目标列表滚动
此时本案例存在一个问题:当数据过多,一页无法展示时,居然没有出现滚动条
大家可以通过输入一些新目标来测试,你会发现铺满页面后发现无法滚动
如下图
原因:
在鸿蒙应用开发中,不是所有组件都具备内容滚动功能。
本例中,包住每一项目标的是
Column
(如下代码),而Column
不具备滚动功能
所以可以给
Column
外面包一个Scroll
组件,如
这样即具备了滚动功能。
这里为什么还给
Scroll
设置了高度呢如果不设置高度,将无法滚动
原因:
当内容超出容器大小时,我们才需要滚动以及才能拥有滚动。所以,如果内容并没有超出容器,是不具备滚动功能的。
而如果你不给
Scroll
设置高度,它的高度就是根据内容自动计算得来,内容一共有多高,它就有多少高度。这样就导致内容永远没超出 Scroll,就不具备滚动功能思考:高度写死 300 合理吗?
肯定不合理,就拿本案例来说,
TodoMain
是这个页面最后一个组件,它如果高度设小了,就导致后面留了很多空,比较丑,如下图但是数字写高了又不好,有可能在其他小屏幕会超出,在大屏幕也不够
所以我们希望 Scroll 这个容器的高度能占用剩余高度
这时候可以用
LayoutWeight
属性,设置这个容器在父容器里主轴方向剩余空间的占比故代码改动如下
这里再稍微说明一下
Scroll
组件其他特点能让自己的子组件具备滚动功能,且它里面只能放一个子组件。
它自己一般不直接存放内容,而是让子组件存放内容。
上面虽然用
Scroll
能起到滚动效果,但我们这里不用它。因为,我们还需要具备侧滑功能,Scroll 并不方便事实上
Scroll
开发中也相对用的少如果既要能滚动,又要具备侧滑效果,应该用
List
组件
知识点 - List 组件
List 组件称之为列表组件,专门用来展示一堆相同宽度的列表项(例如 TodoItem)。适合连续、多行呈现同类数据(例如我们本案例里的数组)
特点:当列表项达到一定数量,内容超过屏幕大小时,可以自动提供滚动功能
使用语法
说明:List 里仅能放 ListItem(每一项)或 ListGroup(分组),组件关系如下图
例如:
虽然
List
里组件只能放ListItem
与ListItemGroup
,但它内部可以使用if-else
和ForEach
语法做条件渲染、循环渲染List
像Row
、Column
这些容器一样,也可以设置space
参数来控制每一个列表项之间的间距并且通过
List
里的ListItem
能设置侧滑具体的关于 List 还有一些特点,将在下面把它用在本案例里再具体讲解,这里仅仅解释基本作用
年度目标案例 - 使用 List 改写 TodoMain
注意:在开始之前,如果你按照上面的学习在案例 TodoMain 组件里使用过
Scroll
来学习它,那记得把 Scroll 删掉
很简单,其实就是把原来的
Column
改成List
,再把ForEach
里的TodoItem
用ListItem
包起来即可,代码如下
注意:记得给
List
高度,否则也一样无法滚动。我们这里依然是让它占用剩余高度这个时候,我们的新年目标列表即具备滚动功能了,大家可以自行添加新目标任务直到超出显示范围,再试试看是否具备滚动到底的效果
知识点 - @Builder 装饰器
接下来要讲的侧滑用的上它,所以先对它进行介绍
@Builder 是用来装饰函数的,被它装饰的函数称之为自定义构造函数,
作用:有些时候,一段 UI 元素可能需要被复用。即可使用
@Builder
装饰的函数进行封装语法
例:
使用时直接像调用函数一样用即可,例如
效果如下
跟组件的区别:
@Builder 更轻量,一般只封装本页面里的 UI 元素。而组件可能有自己的状态数据且能复用在多个页面
年度目标案例 - 实现侧滑删除
首先,我们需要给每一项加侧滑功能
上面讲解
List
时,已经说过ListItem
可以方便添加侧滑功能实现方式也很简单,就是给
ListItem
添加swipeAction
属性即可用法:
start:设置左侧侧滑
end:设置右侧侧滑
可以同时写,代表左侧、右侧都具备侧滑效果(即可以左滑,也可以右滑)
也可以根据业务需求,决定单独要哪边的侧滑,像本案例仅需要右侧的侧滑,因此写 end 即可
自定义构造函数是用来传入侧滑出来的小界面,例如我们本案例右侧出来的部分即是一个小界面,如下图
那如何把这个小界面传递给
ListItem
呢?就是通过自定义构造函数传入,也就是用@Builder
封装的函数完成功能:
先来定义侧滑出来的小界面(来到
TodoMain
)
然后给
ListItem
添加SwipeAction
属性,并给 end 属性(因为需要右侧出现),然后传入上面的自定义构造函数
经过以上两步后,我们拖拽每一项往左滑动即可出现红色的删除图标,但此时点击图片没有任何反应
所以,我们还需要给
@Builder
里的删除图标加点击事件,但此时问题来了。点击事件里我们需要:点哪行的删除,就把这行删掉,也即把数组里这一行的数据删除。所以,我们还需要给@Builder
的函数传入当前这行的下标当参数,如下
最后回到
@Builder
,添加形参接收,并完成点击事件即可
因为之前解释过,todoList 是用
@Link
装饰,所以TodoMain
里改变了,也会影响到Index
,既而影响到其他用到同数据的地方所以到此为止,本案例算完整结束
总结
用文字讲解案例着实麻烦。因为需要大量截图、以及代码解释。以后如果要分享实战项目,猫林老师还是尽量以视频教学为主吧。
到本篇文章结束,如果各位都有每篇认真阅读,其实就已经具备了入门能力。以后几乎遇到任何需求的案例和交互都能实现。
所以后续,猫林老师打算后续的系列文章,都是以分享某一个实战技巧、技术点的形式来写。例如:如何发送请求、如何沉浸式布局、如何多端适配、如何性能分析与优化等,敬请期待
评论