目录
1. 属性动画
组件的某些通用属性变化时,可以通过属性动画实现渐变过渡效果,提升用户体验。
- 支持的属性包括width、height、backgroundColor、opacity、scale、rotate、translate等。
@Entry
@Component
struct Index {
@State
widthSize: number = 100
@State
heightSize: number = 40
build() {
Column({ space: 15 }) {
Button('元素动画')
.width(this.widthSize)
.height(this.heightSize)
.onClick(() => {
this.widthSize = 200
this.heightSize = 100
})
.animation({
// 动画时间
duration: 1000,
// 执行次数
iterations: -1,
// 动画曲线
curve: Curve.Ease,
// 延时时间
delay: 1000,
// 播放模式
playMode: PlayMode.Alternate
})
}
.height('100%')
.width('100%')
.justifyContent(FlexAlign.Center)
}
}
2. 显示动画
提供全局animateTo显式动画接口来指定由于闭包代码导致的状态变化插入过渡动效。
@Entry
@Component
struct Index {
@State
heightSize: number = 40
build() {
Column() {
Text('一级菜单')
.height(40)
.onClick(() => {
animateTo({
duration: 200
}, () => {
this.heightSize = this.heightSize === 40 ? 0 : 40
})
})
Column() {
Text('一级菜单')
.height(this.heightSize)
Text('一级菜单')
.height(this.heightSize)
}
}
.backgroundColor('#069')
}
}
3. 元素共享转场
当路由进行切换时,可以通过设置组件的 sharedTransition 属性将该元素标记为共享元素并设置对应的共享元素转场动效。
- Index.ets
import router from '@ohos.router'
@Entry
@Component
struct Index {
build() {
Row({ space: 15 }) {
Column({ space: 10 }){
Image($rawfile('apple.png'))
.width('100%')
.aspectRatio(1)
.sharedTransition('apple', { duration: 500 })
Text('鸣春谷 正宗甘肃特产花牛水果苹果 【天水直发】 4.5-5斤中果A(约13-16个)')
.sharedTransition('text', { duration: 500 })
}
.padding(15)
.width('50%')
.onClick(() => {
router.pushUrl({
url: 'pages/DetailPage'
})
})
}
.width('100%')
}
}
- DetailPage.ets
@Entry
@Component
struct DetailPage {
build() {
Column({ space: 15 }) {
Column({ space: 10 }){
Image($rawfile('apple.png'))
.width('100%')
.aspectRatio(1)
.sharedTransition('apple', { duration: 500 })
Text('鸣春谷 正宗甘肃特产花牛水果苹果 【天水直发】 4.5-5斤中果A(约13-16个)')
.fontSize(18)
.sharedTransition('text', { duration: 500 })
}
.padding(15)
}
.height('100%')
.width('100%')
}
}
4. 拖动手势-阻尼和磁吸
拖动手势(PanGesture)
- 拖动手势用于触发拖动手势事件,滑动达到最小滑动距离(默认值为5vp)时拖动手势识别成功。
实现下拉刷新效果:
1.使用 Stack
堆叠下拉刷新容器和列表容器
2.使用手势事件 PanGesture
实现拖动列表容器
3.使用 animateTo
实现磁吸动画效果
4.拖动距离超出阀值,模拟开启加载效果,控制文字显示和动画
import promptAction from '@ohos.promptAction'
@Entry
@Component
struct Index {
@State
translateY: number = 0
@State
text: string = '下拉即可刷新'
@State
loading: boolean = false
ease (originValue: number = 0) {
const space = 60
const damp = 0.3
if ( originValue > space ) {
return space + ( originValue - space ) * damp
}
return originValue
}
build() {
Stack({ alignContent: Alignment.Top }) {
Row() {
if (this.loading) {
LoadingProgress()
.width(32)
.aspectRatio(1)
}
Text(this.text)
.fontColor('#999')
.width(100)
}
.height(100)
List() {
}
.backgroundColor('#fff')
.height('100%')
.width('100%')
.translate({ y: this.translateY })
.gesture(
PanGesture()
.onActionUpdate((event: GestureEvent) => {
this.translateY = this.ease(event.offsetY)
if ( this.translateY > 100 ) {
this.text = '释放立即刷新'
}
})
.onActionEnd((event: GestureEvent) => {
if (this.translateY > 100) {
this.loading = true
this.text = '正在刷新中...'
animateTo({ duration: 300 }, () => {
this.translateY = 100
})
// 加载数据
setTimeout(() => {
this.loading = false
this.text = ''
animateTo({ duration: 300, onFinish: () => this.text = '下拉即可刷新' }, () => {
this.translateY = 0
})
promptAction.showToast({ message: '刷新成功' })
}, 2000)
} else {
animateTo({ duration: 300 }, () => {
this.translateY = 0
})
}
})
)
}
.height('100%')
.width('100%')
.backgroundColor('#f3f4f5')
}
}