我们继续学习使用ArkTS实现一个任务进度的统计功能。
1.公共的组件、样式
class Task{
static id: number = 1
// 任务名称
name: string = `任务${Task.id++}`
// 任务状态: 是否完成
finished: boolean = false
}
// 统计的卡片样式
@Styles function card(){
.width('95%')
.padding(20)
.backgroundColor(Color.White)
.borderRadius(15)
.shadow({radius: 6,color: '#1f0000',offsetX:2,offsetY:4})
}
// 任务完成样式
@Extend(Text) function finishedTask(){
.decoration({type:TextDecorationType.LineThrough})
.fontColor('#b1b2b1')
}
@Entry
@Component
struct PropPage {
// 总任务数量
@State totalTask: number = 0
// 已经完成数量
@State finishTask: number = 0
// 任务数量
@State tasks: Task[] = []
build() {
Column({space:10}) {
}
.width('100%')
.height('100%')
.backgroundColor('#f1f2f3')
}
}
整个Demo主要分为三部分完成,最上边的任务进度卡片、中间的新增按钮和下面的任务进度列表。我们分步骤来完成
2.任务进度卡片的制作
1.排版
我们使用行标签套两个text标签来完成数字的展示使用justifyContent(FlexAlign.SpaceEvenly)来做对齐处理
Row(){
Text("任务进度")
.fontSize(30)
.fontWeight(FontWeight.Bold)
Row(){
Text(this.finishTask.toString())
.fontSize(24)
.fontColor('#36d')
Text(' / ' +this.totalTask.toString())
.fontSize(24)
}
}
.card()
.margin({top:20,bottom:10})
.justifyContent(FlexAlign.SpaceEvenly)
2.任务条组件
我们在使用进度条组件的时候,可以查看ArkUI的官方文档。
文档中心
文档中有组件的使用方法和传值的类型。
3. 叠加容器
我们会发现数字没有嵌入我们的任务条组件内。我们需要用到叠加容器Stack。
具体文档可以参考ArkTS官方文档。就是把要叠加的容器放在Stack({
}) 中就可以了。
// 1.任务进度卡片
Row(){
Text("任务进度")
.fontSize(30)
.fontWeight(FontWeight.Bold)
Stack(){
Progress({
value:this.finishTask,
total:this.totalTask,
type:ProgressType.Ring
})
.width(100)
Row(){
Text(this.finishTask.toString())
.fontSize(24)
.fontColor('#36d')
Text(' / ' +this.totalTask.toString())
.fontSize(24)
}
}
}
这样我们的任务进度卡片就完成啦。
2.新增任务按钮的制作
// 2.新增任务按钮
Button('新增任务')
.width(200)
.onClick(()=>{
// 1.新增任务
this.tasks.push(new Task())
// 2.更新任务数组
this.totalTask = this.tasks.length
})
3.任务列表的制作
我们在进行任务列表的制作的时候,需要用到一个复选框,可以参考文档来使用。
文档中心
我们使用foreach来遍历数组完成任务列表的实现,使用checkbox 来完成复选框的逻辑,使用数组方法filter来过滤选中的也就是完成的个数来改变任务条组件的状态。
通过封装一个更新任务进度的函数,来提高代码的复用性
// 通过过滤方法 更新已完成的任务数量
handleTaskChange(){
// 更新任务总数量
this.totalTask = this.tasks.length
// 已经完成的任务数量
this.finishTask = this.tasks.filter(item => item.finished).length
}
// 3.卡片列表
ForEach(
this.tasks,
(item: Task,index)=>{
Row(){
Text(item.name)
.fontSize(20)
Checkbox()
.select(item.finished)
.onChange(val=>{
item.finished = val
// 通过过滤方法 更新已完成的任务数量
this.finishTask = this.tasks.filter(item => item.finished).length
this.handleTaskChange()
})
}
.card()
.justifyContent(FlexAlign.SpaceBetween)
}
)
我们的 任务进度管理初步样式就完成了。
4.滑动删除操作的实现
我们的功能需要一个向左滑动可以删除任务的按钮,并且下面应该是滚动的,我们将我们的任务列表改造成List来完成这个操作。
// 3.卡片列表
List({space:10}){
ForEach(
this.tasks,
(item: Task,index)=>{
ListItem(){
Row(){
Text(item.name)
.fontSize(20)
Checkbox()
.select(item.finished)
.onChange(val=>{
item.finished = val
// 通过过滤方法 更新已完成的任务数量
this.handleTaskChange()
})
}
.card()
.justifyContent(FlexAlign.SpaceBetween)
}
}
)
}
.width('100%')
.layoutWeight(1)
.alignListItem(ListItemAlign.Center)
使用了list 并且使用layoutWeight属性得到剩下的所有高度,可以保证我们的高度自适应,可以下拉,解决了任务太多看不见的问题。
向左滑动出现按钮,List有可以直接使用的属性swipeAction,可以查看文档他的使用方法。
class Task{
static id: number = 1
// 任务名称
name: string = `任务${Task.id++}`
// 任务状态: 是否完成
finished: boolean = false
}
// 统计的卡片样式
@Styles function card(){
.width('95%')
.padding(20)
.backgroundColor(Color.White)
.borderRadius(15)
.shadow({radius: 6,color: '#1f0000',offsetX:2,offsetY:4})
}
// 任务完成样式
@Extend(Text) function finishedTask(){
.decoration({type:TextDecorationType.LineThrough})
.fontColor('#b1b2b1')
}
@Entry
@Component
struct PropPage {
// 总任务数量
@State totalTask: number = 0
// 已经完成数量
@State finishTask: number = 0
// 任务数量
@State tasks: Task[] = []
// 通过过滤方法 更新已完成的任务数量
handleTaskChange(){
// 更新任务总数量
this.totalTask = this.tasks.length
// 已经完成的任务数量
this.finishTask = this.tasks.filter(item => item.finished).length
}
build() {
Column({space:10}) {
// 1.任务进度卡片
Row(){
Text("任务进度")
.fontSize(30)
.fontWeight(FontWeight.Bold)
Stack(){
Progress({
value:this.finishTask,
total:this.totalTask,
type:ProgressType.Ring
})
.width(100)
Row(){
Text(this.finishTask.toString())
.fontSize(24)
.fontColor('#36d')
Text(' / ' +this.totalTask.toString())
.fontSize(24)
}
}
}
.card()
.margin({top:20,bottom:10})
.justifyContent(FlexAlign.SpaceEvenly)
// 2.新增任务按钮
Button('新增任务')
.width(200)
.onClick(()=>{
// 1.新增任务
this.tasks.push(new Task())
// 2.更新任务数组
this.totalTask = this.tasks.length
})
// 3.卡片列表
List({space:10}){
ForEach(
this.tasks,
(item: Task,index)=>{
ListItem(){
Row(){
Text(item.name)
.fontSize(20)
Checkbox()
.select(item.finished)
.onChange(val=>{
item.finished = val
// 通过过滤方法 更新已完成的任务数量
this.handleTaskChange()
})
}
.card()
.justifyContent(FlexAlign.SpaceBetween)
}
.swipeAction({end:this.DeleteButton(index)})
}
)
}
.width('100%')
.layoutWeight(1)
.alignListItem(ListItemAlign.Center)
}
.width('100%')
.height('100%')
.backgroundColor('#f1f2f3')
}
@Builder DeleteButton(index: number){
Button("删除")
.onClick(()=>{
this.tasks.splice(index,1)
this.handleTaskChange()
})
}
}
至此,我们的任务统计案例 就学习完了。