简单的组件学习:
/**
* weip 自定义控件
* 自定义构建函数也是需要充电的地方,分全局和局部的
* 全局:需要添加function关键字 局部:不加function关键字
* @Styles function 自定义公共样式 分全局和局部
* @Extends(Text) 继承模式 只能写成全局的
* export:导出组件
*/
@Component
export struct Header {
private title: ResourceStr;
build() {
// 标题部分
Row() {
// 资源自行替换,返回icon
Image($r('app.media.app_icon'))
.width(30)
Text(this.title)
.fontSize(30)
.fontWeight(FontWeight.Bold)
Blank()
// 资源自行替换,分享icon
Image($r('app.media.app_icon'))
.width(30)
}
.width('100%')
.height(30)
}
}
ImagesPage.ets:
引用header组件
/**
* 导入head组件
*/
import { Header } from '../components/HeadComponents'
// 全局自定义构建函数 function:代表全局
@Builder function ItemCard() {
}
// 组件内的局部函数需要加this
// 自定义公共样式
@Styles function fillScreen() {
.width('100%')
.height('100%')
.backgroundColor('#EFEFEF')
.padding(20)
}
// 自定义字体样式 需使用Extend() 继承模式,只能写在全局位置
@Extend(Text) function priceText() {
.fontSize(18)
.fontColor('#F36')
}
@Entry
@Component
struct Index {
@State imageWidth: number = 150
// ForEach:循环遍历数组,根据数组内容渲染页面组件,超过屏幕的东西就看不到,也滑动不了,所以后面统一使用List组件
build() {
// 纵向布局 主轴/交叉轴,一般只设置主轴,不设置交叉轴
Column() {
// 标题
Header({title: "图片详情"})
.padding({left: 20, top: 20, right: 20, bottom: 20})
// 横向布局 主轴/交叉轴,一般只设置主轴,不设置交叉轴
Row(){
Image($r('app.media.icon'))
.width(this.imageWidth)
.interpolation(ImageInterpolation.High)
}
.width('100%')
.height(400)
.justifyContent(FlexAlign.Center)
// Row容器 放一行
Row() {
Text($r('app.string.width_label'))
.fontSize(20)
.fontWeight(FontWeight.Bold)
.fontColor('#663')
TextInput({ placeholder: '请输入图片宽度', text:this.imageWidth.toFixed(0) })
.width(150)
.backgroundColor('#FFF')
.type(InputType.Number)
.onChange(value => {
console.log(value)
this.imageWidth = parseInt(value)
})
}
.width('100%')
.padding({left: 14,right: 14})
.justifyContent(FlexAlign.SpaceBetween) // 中间留空
// 分割线
Divider()
.width('91%')
// 两个按钮
Row(){
Button('缩小')
.width(80)
.fontSize(20)
.onClick(() => {
if (this.imageWidth >= 10) {
this.imageWidth -= 10;
}
})
Button('放大')
.width(80)
.fontSize(20)
.onClick(() => {
if (this.imageWidth < 300) {
this.imageWidth += 10;
}
})
}
.width('100%')
.margin({top: 35, bottom: 35})
.justifyContent(FlexAlign.SpaceEvenly)
Slider({
min: 100,
max: 300,
value: this.imageWidth,
step: 10
})
.width('100%')
.blockColor('#36D')
.trackThickness(7)
.showTips(true)
.onChange(value => {
// value:当前滑块值
this.imageWidth = value;
})
}
.width('100%')
.height('100%')
}
}
/**
* struct:自定义组件 可复用的UI单元
* 装饰器:用来装饰类结构、方法、变量
* @Component:标记自定义组件
* @Entry:标记当前组件是入口组件
* @State:标记一个变量是状态变量,值变化时会触发UI更新
* build():UI描述,其内部以声明式方式描述UI结构
* 内置组件:ArkUI提供的组件,比如容器组件如Row、Column
* 基础组件:自带样式和功能的页面元素,如Text
* 属性方法:设置组件的UI样式
* 事件方法:设置组件的事件回调
* 组件通用属性、特有属性(图片插值)
*/
Index.ets:
一般是应用程序的入口
@Entry // 入口組件
@Component
struct Index {
@State message: string = 'Hello World'
build() {
Row() {
Column() {
Text(this.message)
.fontSize(50)
.fontWeight(FontWeight.Bold)
.fontColor('#36D')
.onClick(() => {
this.message = 'Hello ArkTS!';
})
// Image('https://bkimg.cdn.bcebos.com/pic/bd315c6034a85edf8db139b7db031e23dd54564edf55?x-bce-process=image/format,f_auto/quality,Q_70/resize,m_lfit,limit_1,w_536')
// .width('50%')
// 引用本地图片资源地址
Image($r('app.media.icon'))
.width(250)
.interpolation(ImageInterpolation.High)
}
.width('100%')
}
.height('100%')
}
}
/**
* struct:自定义组件 可复用的UI单元
* 装饰器:用来装饰类结构、方法、变量
* @Component:标记自定义组件
* @Entry:标记当前组件是入口组件
* @State:标记一个变量是状态变量,值变化时会触发UI更新
* build():UI描述,其内部以声明式方式描述UI结构
* 内置组件:ArkUI提供的组件,比如容器组件如Row、Column
* 基础组件:自带样式和功能的页面元素,如Text
* 属性方法:设置组件的UI样式
* 事件方法:设置组件的事件回调
* 组件通用属性、特有属性(图片插值)
*/
PropPage.ets:
/**
* 自定义任务类
*/
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: '#1F000000', offsetX: 2, offsetY: 4})
}
// 任务完成样式
@Extend(Text) function finishedTask() {
.decoration({type: TextDecorationType.LineThrough})
.fontColor('#B1B2B1')
}
// 任务统计信息的实体类【c】
class StaticInfo {
totalTask: number = 0;
finishTask: number = 0;
}
@Entry
@Component
struct PropPage {
// 总任务数量
@State totalTask: number = 0
// 已完成任务数量
@State finishTask: number = 0
build() {
Column({space: 10}){
// 任务进度卡片 子组件
TaskStatistics({finishTask:this.finishTask, totalTask: this.totalTask})
// 任务列表,包含新增任务 @Link totalTask:$finishTask:变量的引用
TaskList({finishTask:$finishTask, totalTask: $totalTask})
}
.width('100%')
.height('100%')
.backgroundColor('#F1F2F3')
}
}
@Component
struct TaskList {
// 总任务数量
@Link totalTask: number
// 已完成任务数量
@Link finishTask: number
// 任务数组
@State tasks: Task[] = []
handleTaskChange(){
// 更新任务总数量
this.totalTask = this.tasks.length
// 更新已完成任务数量
this.finishTask = this.tasks.filter(item => item.finished).length
}
build() {
Column() {
// 2、新增任务按钮
Button('新增任务')
.width(200)
.onClick(() => {
// 新增任务数据
this.tasks.push(new Task())
// 更新任务总数量
this.handleTaskChange()
})
// 3、任务列表
List({space: 10}) {
ForEach(
this.tasks,
(item: Task, index) => {
ListItem() {
Row() {
// 任务名
Text(item.name)
.fontSize(20)
// 任务复选框
Checkbox()
.select(item.finished)
.onChange(isSelected => {
// 任务状态发生变更,更新当前任务状态
item.finished = isSelected
// 更新已完成任务数量
this.handleTaskChange()
})
}
.card()
.justifyContent(FlexAlign.SpaceBetween)
}
.swipeAction({end: this.DeleteButton(index)})
}
)
}
.width('100%')
.layoutWeight(1)
.alignListItem(ListItemAlign.Center)
}
}
@Builder DeleteButton(index: number) {
Button(){
Image($r('app.media.icon'))
.fillColor(Color.White)
.width(20)
}
.width(40)
.height(40)
.type(ButtonType.Circle)
.backgroundColor(Color.Red)
.margin(5)
.onClick(() => {
// 从角标开始删 删1个
this.tasks.splice(index, 1)
this.handleTaskChange()
})
}
}
/**
* 任务进度卡片 子组件
* 子组件是TaskStatistics 此时父组件是PropPage.ets
* Prop:变量不能初始化 单向同步【父组件-->子组件】
* Link:支持传对象 Prop:不支持传对象
* provider 跨组件传输
* consume 跨组件传输
*/
@Component
struct TaskStatistics {
// 总任务数量
@Prop totalTask: number
// 已完成任务数量
@Prop finishTask: number
build() {
Row() {
// 任务进度
Text('任务进度')
.fontSize(30)
.fontWeight(FontWeight.Bold)
// 堆叠容器
Stack() {
// 进度条
Progress({
value: this.finishTask,
total: this.totalTask,
type: ProgressType.Ring
})
// 1/5
Row() {
Text(this.finishTask.toString())
.fontSize(24)
.fontColor('#36D')
Text(' / ' + this.totalTask.toString())
.fontSize(24)
}
}
}
.card()
.margin({top: 20, bottom: 20})
.justifyContent(FlexAlign.SpaceEvenly)
}
}
预览效果图:
注解的学习:
/**
* 自定义任务类
*/
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: '#1F000000', offsetX: 2, offsetY: 4})
}
// 任务完成样式
@Extend(Text) function finishedTask() {
.decoration({type: TextDecorationType.LineThrough})
.fontColor('#B1B2B1')
}
// 任务统计信息的实体类
class StatInfo {
totalTask: number = 0;
finishTask: number = 0;
}
/**
* 父组件
*/
@Entry
@Component
struct PropPage {
// 统计信息 【父亲】
@State stat: StatInfo = new StatInfo()
build() {
Column({space: 10}){
// 任务进度卡片 子组件
TaskStatistics({finishTask:this.stat.finishTask, totalTask: this.stat.totalTask})
// 任务列表,包含新增任务 @Link totalTask:$finishTask:变量的引用
TaskList({stat:$stat})
}
.width('100%')
.height('100%')
.backgroundColor('#F1F2F3')
}
}
@Component
struct TaskList {
// 统计信息【儿子】 Link可以传对象
@Link stat: StatInfo
// 任务数组
@State tasks: Task[] = []
handleTaskChange(){
// 更新任务总数量
this.stat.totalTask = this.tasks.length
// 更新已完成任务数量
this.stat.finishTask = this.tasks.filter(item => item.finished).length
}
build() {
Column() {
// 2、新增任务按钮
Button('新增任务')
.width(200)
.onClick(() => {
// 新增任务数据
this.tasks.push(new Task())
// 更新任务总数量
this.handleTaskChange()
})
// 3、任务列表
List({space: 10}) {
ForEach(
this.tasks,
(item: Task, index) => {
ListItem() {
Row() {
// 任务名
Text(item.name)
.fontSize(20)
// 任务复选框
Checkbox()
.select(item.finished)
.onChange(isSelected => {
// 任务状态发生变更,更新当前任务状态
item.finished = isSelected
// 更新已完成任务数量
this.handleTaskChange()
})
}
.card()
.justifyContent(FlexAlign.SpaceBetween)
}
.swipeAction({end: this.DeleteButton(index)})
}
)
}
.width('100%')
.layoutWeight(1)
.alignListItem(ListItemAlign.Center)
}
}
@Builder DeleteButton(index: number) {
Button(){
Image($r('app.media.icon'))
.fillColor(Color.White)
.width(20)
}
.width(40)
.height(40)
.type(ButtonType.Circle)
.backgroundColor(Color.Red)
.margin(5)
.onClick(() => {
// 从角标开始删 删1个
this.tasks.splice(index, 1)
this.handleTaskChange()
})
}
}
/**
* 任务进度卡片 子组件
* 子组件是TaskStatistics 此时父组件是PropPage.ets
* Prop:变量不能初始化 单向同步【父组件-->子组件】
* Link:支持传对象 Prop:不支持传对象
* provider 跨组件传输
* consume 跨组件传输
*/
@Component
struct TaskStatistics {
// 总任务数量
@Prop totalTask: number
// 已完成任务数量
@Prop finishTask: number
build() {
Row() {
// 任务进度
Text('任务进度')
.fontSize(30)
.fontWeight(FontWeight.Bold)
// 堆叠容器
Stack() {
// 进度条
Progress({
value: this.finishTask,
total: this.totalTask,
type: ProgressType.Ring
})
// 1/5
Row() {
Text(this.finishTask.toString())
.fontSize(24)
.fontColor('#36D')
Text(' / ' + this.totalTask.toString())
.fontSize(24)
}
}
}
.card()
.margin({top: 20, bottom: 20})
.justifyContent(FlexAlign.SpaceEvenly)
}
}
跨组件传输数据:
@Provider @Consume
这种相对比较费内存,非跨组件不建议使用
/**
* 自定义任务类
*/
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: '#1F000000', offsetX: 2, offsetY: 4})
}
// 任务完成样式
@Extend(Text) function finishedTask() {
.decoration({type: TextDecorationType.LineThrough})
.fontColor('#B1B2B1')
}
// 任务统计信息的实体类
class StatInfo {
totalTask: number = 0;
finishTask: number = 0;
}
/**
* 父组件
*/
@Entry
@Component
struct PropPage {
// 统计信息 【父亲】
@Provide stat: StatInfo = new StatInfo()
build() {
Column({space: 10}){
// 任务进度卡片 子组件
TaskStatistics()
// 任务列表,包含新增任务 @Link totalTask:$finishTask:变量的引用
TaskList()
}
.width('100%')
.height('100%')
.backgroundColor('#F1F2F3')
}
}
@Component
struct TaskList {
// 统计信息【儿子】 Link可以传对象
@Consume stat: StatInfo
// 任务数组
@State tasks: Task[] = []
handleTaskChange(){
// 更新任务总数量
this.stat.totalTask = this.tasks.length
// 更新已完成任务数量
this.stat.finishTask = this.tasks.filter(item => item.finished).length
}
build() {
Column() {
// 2、新增任务按钮
Button('新增任务')
.width(200)
.onClick(() => {
// 新增任务数据
this.tasks.push(new Task())
// 更新任务总数量
this.handleTaskChange()
})
// 3、任务列表
List({space: 10}) {
ForEach(
this.tasks,
(item: Task, index) => {
ListItem() {
Row() {
// 任务名
Text(item.name)
.fontSize(20)
// 任务复选框
Checkbox()
.select(item.finished)
.onChange(isSelected => {
// 任务状态发生变更,更新当前任务状态
item.finished = isSelected
// 更新已完成任务数量
this.handleTaskChange()
})
}
.card()
.justifyContent(FlexAlign.SpaceBetween)
}
.swipeAction({end: this.DeleteButton(index)})
}
)
}
.width('100%')
.layoutWeight(1)
.alignListItem(ListItemAlign.Center)
}
}
@Builder DeleteButton(index: number) {
Button(){
Image($r('app.media.icon'))
.fillColor(Color.White)
.width(20)
}
.width(40)
.height(40)
.type(ButtonType.Circle)
.backgroundColor(Color.Red)
.margin(5)
.onClick(() => {
// 从角标开始删 删1个
this.tasks.splice(index, 1)
this.handleTaskChange()
})
}
}
/**
* 任务进度卡片 子组件
* 子组件是TaskStatistics 此时父组件是PropPage.ets
* Prop:变量不能初始化 单向同步【父组件-->子组件】
* Link:支持传对象 Prop:不支持传对象
* provider 跨组件传输
* consume 跨组件传输
*/
@Component
struct TaskStatistics {
// 统计信息
@Consume stat: StatInfo
build() {
Row() {
// 任务进度
Text('任务进度')
.fontSize(30)
.fontWeight(FontWeight.Bold)
// 堆叠容器
Stack() {
// 进度条
Progress({
value: this.stat.finishTask,
total: this.stat.totalTask,
type: ProgressType.Ring
})
// 1/5
Row() {
Text(this.stat.finishTask.toString())
.fontSize(24)
.fontColor('#36D')
Text(' / ' + this.stat.totalTask.toString())
.fontSize(24)
}
}
}
.card()
.margin({top: 20, bottom: 20})
.justifyContent(FlexAlign.SpaceEvenly)
}
}
// bind(this)
/**
* 自定义任务类
*/
@Observed
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: '#1F000000', offsetX: 2, offsetY: 4})
}
// 任务完成样式
@Extend(Text) function finishedTask() {
.decoration({type: TextDecorationType.LineThrough})
.fontColor('#B1B2B1')
}
// 任务统计信息的实体类
class StatInfo {
totalTask: number = 0;
finishTask: number = 0;
}
/**
* 父组件
*/
@Entry
@Component
struct PropPage {
// 统计信息 【父亲】
@Provide stat: StatInfo = new StatInfo()
build() {
Column({space: 10}){
// 任务进度卡片 子组件
TaskStatistics()
// 任务列表,包含新增任务 @Link totalTask:$finishTask:变量的引用
TaskList()
}
.width('100%')
.height('100%')
.backgroundColor('#F1F2F3')
}
}
@Component
struct TaskList {
// 统计信息【儿子】 Link可以传对象
@Consume stat: StatInfo
// 任务数组
@State tasks: Task[] = []
handleTaskChange(){
// 更新任务总数量
this.stat.totalTask = this.tasks.length
// 更新已完成任务数量
this.stat.finishTask = this.tasks.filter(item => item.finished).length
}
build() {
Column() {
// 2、新增任务按钮
Button('新增任务')
.width(200)
.onClick(() => {
// 新增任务数据
this.tasks.push(new Task())
// 更新任务总数量
this.handleTaskChange()
})
// 3、任务列表
List({space: 10}) {
ForEach(
this.tasks,
(item: Task, index) => {
ListItem() {
// bind(this) 绑定父组件的this
TaskItem({item: item, onTaskChange: this.handleTaskChange.bind(this)})
}
.swipeAction({end: this.DeleteButton(index)})
}
)
}
.width('100%')
.layoutWeight(1)
.alignListItem(ListItemAlign.Center)
}
}
@Builder DeleteButton(index: number) {
Button(){
Image($r('app.media.icon'))
.fillColor(Color.White)
.width(20)
}
.width(40)
.height(40)
.type(ButtonType.Circle)
.backgroundColor(Color.Red)
.margin(5)
.onClick(() => {
// 从角标开始删 删1个
this.tasks.splice(index, 1)
this.handleTaskChange()
})
}
}
/**
* 自定义任务的item项
* 方法传递
*/
@Component
struct TaskItem {
@ObjectLink item: Task
// 变量的类型是个函数类型
onTaskChange: () => void
build() {
Row() {
// 任务名 如果完成,需要变灰
if (this.item.finished) {
Text(this.item.name)
.fontSize(20)
.finishedTask()
} else {
Text(this.item.name)
.fontSize(20)
}
// 任务复选框
Checkbox()
.select(this.item.finished)
.onChange(isSelected => {
// 任务状态发生变更,更新当前任务状态
this.item.finished = isSelected
// 更新已完成任务数量
//this.handleTaskChange()
this.onTaskChange()
})
}
.card()
.justifyContent(FlexAlign.SpaceBetween)
}
}
/**
* 任务进度卡片 子组件
* 子组件是TaskStatistics 此时父组件是PropPage.ets
* Prop:变量不能初始化 单向同步【父组件-->子组件】
* Link:支持传对象 Prop:不支持传对象
* provider 跨组件传输
* consume 跨组件传输
*/
@Component
struct TaskStatistics {
// 统计信息
@Consume stat: StatInfo
build() {
Row() {
// 任务进度
Text('任务进度')
.fontSize(30)
.fontWeight(FontWeight.Bold)
// 堆叠容器
Stack() {
// 进度条
Progress({
value: this.stat.finishTask,
total: this.stat.totalTask,
type: ProgressType.Ring
})
// 1/5
Row() {
Text(this.stat.finishTask.toString())
.fontSize(24)
.fontColor('#36D')
Text(' / ' + this.stat.totalTask.toString())
.fontSize(24)
}
}
}
.card()
.margin({top: 20, bottom: 20})
.justifyContent(FlexAlign.SpaceEvenly)
}
}