款式处理
1. 款式-语法(链式&枚举)
ArkTS以声明办法组合和扩展组件来描述运用程序的UI 一起还供给了基本的特点、事情和子组件装备办法,协助开发者完成运用交互逻辑。
1.款式特点
- 特点办法以
.
链式调用的办法装备体系组件的款式和其他特点,主张每个特点办法单独写一行。
@Entry
@Component
struct Index {
build() {
Text('演示')
.backgroundColor('red')
.fontSize(50)
.width('100%')
.height(100)
}
}
2.枚举值
- 关于体系组件,ArkUI还为其特点预界说了一些枚举类型。
@Entry
@Component
struct Index {
build() {
Text('演示')
.fontSize(50)
.width('100%')
.height(100)
.backgroundColor(Color.Blue)
.textAlign(TextAlign.Center)
.fontColor(Color.White)
}
}
- 款式相关特点通过链式函数的办法进行设置
- 假如类型是枚举的,通过枚举传入对应的值
2. 款式-单位 vp
和适配
-
vp
是什么?virtual pixel
-
屏幕密度相关像素,依据屏幕像素密度转换为屏幕物理像素,当数值不带单位时,默许单位
vp
;在实践宽度为1440物理像素的屏幕上,1vp
约等于3px
(物理像素) -
上图的意思是,运用这个单位在不同屏幕物理分辨率的实践尺寸一致(A设备1英寸,B设备1英寸)。
2.之前 vw
、rem
和 rpx
相关于屏幕宽度的单位,能够完成等比例适配,vp
能够吗?
import promptAction from '@ohos.promptAction'
@Entry
@Component
struct Index {
build() {
Text('演示')
.width('100%')
.backgroundColor('red')
.onAreaChange((oldArea, newArea) => {
promptAction.showToast({
// 1. onAreaChange改动尺寸后会触发
// 2. newArea为现在元素尺寸
message: newArea.width.toString()
})
})
}
}
我们发现:不同的设备屏幕的宽度 vp
是不一致的,那怎么适配呢?
- 依据官方的文档,结合自己的了解,选用:弹性布局,网格体系,栅格体系进行布局适配。
弹性 layoutWeight(flex: number)
占剩下空间多少份,能够了解成CSS的 flex: 1
@Entry
@Component
struct Index {
build() {
Row(){
Text('left')
.layoutWeight(1)
.backgroundColor('red')
Text('right')
.layoutWeight(2)
.backgroundColor('green')
}
.width('100%')
}
}
等比例,设置元素宽高比 aspectRatio(ratio: number)
@Entry
@Component
struct Index {
build() {
Text('left')
.width('50%')
// 宽高比例
.aspectRatio(1)
.backgroundColor('red')
}
}
-
vp
是鸿蒙默许单位,和屏幕像素有关,终究体现视觉大小在任何设备一致 - 鸿蒙一般以弹性
layoutWeight
、网格、栅格进行布局适配,如要等比例缩放能够设置高宽比aspectRatio
事例→完成知乎谈论回复-谈论区域
设计稿一般是1080px:(这儿没有设计稿,供给了一些尺寸)
- Nav
- 左边回来按钮
24vp
高宽背景色彩#f5f5f5
,图标12vp尺寸色彩#848484
- 标题
18vp
- 左边回来按钮
- Comment
- 头像尺寸32vp高宽,右侧距离10vp
- 标题15vp,色彩默许
- 内容16vp,色彩
#565656
- 底部12vp,色彩
#c3c4c5
@Entry
@Component
struct Index {
build() {
Column(){
// 导航
Row(){
Row(){
Image($r('app.media.ic_public_arrow_left'))
.width(16)
.aspectRatio(1)
// svg 图标能够运用填充色彩
// .fillColor('red')
}
.width(24)
.aspectRatio(1)
.backgroundColor('#f5f5f5')
.borderRadius(12)
.justifyContent(FlexAlign.Center)
.margin({ left: 16 })
Text('谈论回复')
.layoutWeight(1)
.textAlign(TextAlign.Center)
.padding({ right: 40 })
}
.height(40)
.border({ width: { bottom: 0.5 }, color: '#e4e4e4' })
// 谈论
Row(){
Image($r('app.media.avatar'))
.width(32)
.aspectRatio(1)
.borderRadius(16)
Column({ space: 5 }){
Text('周杰伦')
.width('100%')
.fontWeight(FontWeight.Bold)
.fontSize(15)
Text('大理石能雕刻出肌肉和皮肤的质感,那个时代的工匠好牛啊')
.width('100%')
Row(){
Text('10-21 IP属地北京')
.fontSize(12)
.fontColor('#c3c4c5')
Row({ space: 4 }){
Image($r('app.media.ic_public_heart'))
.width(14)
.aspectRatio(1)
.fillColor('#c3c4c5')
Text('100')
.fontSize(12)
.fontColor('#c3c4c5')
}
}
.width('100%')
.justifyContent(FlexAlign.SpaceBetween)
}
.layoutWeight(1)
.padding({ left: 10 })
}
.padding(15)
.alignItems(VerticalAlign.Top)
}
}
}
款式-@Styles 复用
在开发进程中会出现很多代码在进行重复款式设置,@Styles 能够帮我们进行款式复用
- 当时
@Styles
仅支撑 通用特点 和 通用事情。 - 支撑 大局 界说和 组件内 界说,一起存在组件内掩盖大局生效。
// 大局
@Styles
function functionName() { ... }
@Entry
@Component
sturt Index{
// 组件内
@Styles
functionName() { ... }
build() {
Text('Text')
.functionName()
}
}
事例:文字和按钮相同背景,点击+1
- 大局
@Styles function sameStyle() {
.backgroundColor(Color.Green)
.onClick(() => {
this.count++
})
}
@Entry
@Component
struct Index {
@State
count: number = 10
build() {
Column() {
Text(this.count.toString())
.width(100)
.height(50)
.margin({ bottom: 10 })
.textAlign(TextAlign.Center)
.sameStyle()
Button('+1')
.sameStyle()
}
.height('100%')
.width('100%')
.justifyContent(FlexAlign.Center)
}
}
- 组件内
@Entry
@Component
struct Index {
@State
count: number = 10
// 不需要 `function` 关键字,掩盖大局
@Styles
sameStyle (){
.backgroundColor(Color.Pink)
.onClick(() => {
this.count += 10
})
}
build() {
Column() {
Text(this.count.toString())
.width(100)
.height(50)
.margin({ bottom: 10 })
.textAlign(TextAlign.Center)
.sameStyle()
Button('+1')
.sameStyle()
}
.height('100%')
.width('100%')
.justifyContent(FlexAlign.Center)
}
}
练习事例-登录表单-款式优化
import promptAction from '@ohos.promptAction'
@Entry
@Component
struct Index {
@State
mobile: string = ''
@State
code: string = ''
@Styles
inputStyle () {
.border({ width: 1, color: Color.Gray })
.layoutWeight(1)
.margin({ left: 10, bottom: 10, top: 10 })
.backgroundColor(Color.White)
}
build() {
Column(){
Row(){
Text('手机号')
TextInput({ text: this.mobile })
.inputStyle()
.onChange((value)=>this.mobile = value)
}
Row(){
Text('验证码')
TextInput({ text: this.code })
.inputStyle()
.onChange((value)=>this.code = value)
}
Row({ space: 15 }){
Button('重置')
.backgroundColor('#ccc')
.onClick(()=>{
this.mobile = ''
this.code = ''
})
Button('登录')
.onClick(()=>{
if (this.mobile && this.code) {
promptAction.showToast({ message: `${this.mobile} 登录成功` })
} else {
promptAction.showToast({ message: `请输入手机号或验证码` })
}
})
}
}
.padding({ left: 15, right: 15 })
}
}
款式-@Extends 复用
@Extend 用于扩展原生组件款式,通过传参供给更灵活的款式复用
- 运用
@Extend
装饰器润饰的函数只能是大局
- 函数能够进行
传参
,假如参数是状况变量,状况更新后会改写UI - 且参数能够是一个函数,完成复用事情且可处理不同逻辑
// 大局 原生组件 参数
// ↓ ↓ ↓
@Extend(Text) function functionName(w: number) {
.width(w)
}
需求:把 Text 改成按钮款式,且绑定 click 事情履行不同逻辑
import promptAction from '@ohos.promptAction'
@Extend(Text) function myClick(color: string, cb: () => void) {
.backgroundColor(color)
.width(100)
.height(50)
.textAlign(TextAlign.Center)
.borderRadius(25)
.onClick(() => cb())
}
@Entry
@Component
struct Other {
@State
color: string = '#ccc'
build() {
Column({ space: 20 }) {
Text('Text1')
.myClick(this.color, () => {
this.color = '#069'
})
Text('Text2')
.myClick('green', () => {
promptAction.showToast({ message: '做其他事~' })
})
}
.width('100%')
.height('100%')
.justifyContent(FlexAlign.Center)
}
}
款式-多态
stateStyles
是特点办法,能够依据UI内部状况来设置款式,类似于 css 伪类,但语法不同。ArkUI 供给以下四种状况:
-
focused:获焦态。
-
normal:正常态。
-
pressed:按压态。
-
disabled:不可用态。
import promptAction from '@ohos.promptAction'
// 胶囊按钮
@Extend(Text)
function capsule(){
.height(40)
.borderRadius(20)
.backgroundColor(Color.Gray)
.padding({ left: 15, right: 15 })
.margin({ bottom: 15 })
}
@Entry
@Component
struct Index {
@State
disabled: boolean = false
@State
focused: boolean = false
build() {
Column() {
// Button TextInput 默许敞开获取焦点,页面中默许第一个这样的元素获取焦点
// Button 比较多约束,一个是默许敞开获取焦点能看,二是禁用状况下款式无法修改
// Button('Button').focusable(false)
Text('toggle disabled:' + this.disabled)
.capsule()
.onClick(()=>{
this.disabled = !this.disabled
})
Text('toggle focused:' + this.focused)
.capsule()
.onClick(()=>{
this.focused = !this.focused
})
Text('clickMe')
.capsule()
.enabled(!this.disabled)
.focusable(this.focused)
.onClick(() => {
promptAction.showToast({ message: 'click' })
})
.fontColor('#fff')
.stateStyles({
normal: {
.backgroundColor(Color.Blue)
},
focused: {
.backgroundColor(Color.Red)
},
disabled: {
.backgroundColor(Color.Black)
},
pressed: {
.backgroundColor(Color.Orange)
}
})
}
}
}
- 运用比较多的应该是
norma
pressed
结合下的按压效果 -
enabled(true|false)
敞开|禁用focusable(true|false)
敞开获取焦点才能|封闭
留意:
- 页面初始化的时分,默许第一个能获取焦点的元素,会自动获取焦点
关注大众号:Android老皮!!!欢迎大家来找我探讨交流