该效果使用 共享元素转场功能完成。
涉及到模态转场的使用,出现/消失转场的使用。
源码地址
顶部搜索栏:
Column() {
Row({ space: 5 }) {
Image($r('app.media.icon_search')).height(12).width(12).fillColor(Color.Black)
Swiper() {
Repeat<string>(searchList).each((item) => {
Text(item.item)
.fontSize(12).fontColor(Color.Gray).margin({ left: 5 })
})
}
.onChange((value: number) => {
this.searchContext = searchList[value]
})
.width("80%")
.autoPlay(true)
.vertical(true)
.indicator(false)
.interval(1500)
}
.padding({ left: 15, right: 15 })
.margin({ top: 15 })
.height(40)
.borderRadius(20)
.backgroundColor("#f8f4f4")
//geometryId用于设置绑定关系
.geometryTransition(this.geometryId, { follow: true })
.onClick(() => {
this.onSearchClicked()
})
//全屏模态转场,绑定全屏转场内容页
.bindContentCover(this.showContentCover, this.searchContentCover(), {
//设置转场动画,此处使用透明度动画
transition: TransitionEffect.OPACITY.animation({
duration: this.duration,
curve: Curve.Linear
}),
// onDisappear: () => {
// this.onArrowClicked();
// }
})
}
全屏模态页面:
@Builder
searchContentCover() {
Column({ space: 10 }) {
Row() {
Image($r('sys.media.ohos_ic_back'))
.padding(10)
.onClick(() => {
this.onArrowClicked();
})
//组件内转场动画
.transition(TransitionEffect.opacity(0)
.animation({ curve: Curve.Linear, duration: this.duration }))
.width(40)
.height(40)
.borderRadius("100%")
.backgroundColor('#E5E7E9')
TextInput({ placeholder: '请输入搜索内容', text: this.searchContext })
.placeholderFont({ size: 13 })
.onChange((value: string) => {
//光标变化时,返回当前输入框内容
console.info(value);
})
.onSubmit((EnterKeyType) => {
console.info(EnterKeyType + '输入法回车键的类型值')
})
.width(300)
.borderRadius(24)//geometryId用于设置绑定关系
.geometryTransition(this.geometryId, { follow: true })
.layoutWeight(1)
.height(40)
.margin({ left: 15 })
.backgroundColor("#f8f4f4")
}
.width('93%')
this.searchHistory()
}
//组件内转场动画
.transition(TransitionEffect.opacity(0))
.width('100%')
.height('100%')
.alignItems(HorizontalAlign.Start)
.padding({ top: 54, left: 10 })
.backgroundColor(Color.White)
}
private onArrowClicked(): void {
this.geometryId = 'search';
animateTo({
duration: this.duration,
// 构造插值器弹簧曲线对象,生成一条从0到1的动画曲线
curve: Curve.Linear
}, () => {
console.error("返回")
this.showContentCover = false;
})
}
/**
* 1.搜索框进入搜索页面animateTo显式动画。
* 2.两个搜索框同时绑定同一个geometryId。
*/
private onSearchClicked(): void {
this.geometryId = 'search';
animateTo({
duration: this.duration,
// 构造插值器弹簧曲线对象,生成一条从0到1的动画曲线
curve: Curve.Linear,
}, () => {
this.showContentCover = true;
})
}
通用样式:
@Extend(Text)
function itemStyle() {
.padding({
left: 10,
right: 10,
top: 8,
bottom: 8
})
.fontSize(12)
.borderRadius(15)
.backgroundColor(Color.White)
.margin(5)
}
测试数据
export const searchList: string[] = [
'深水炸弹', '天地龙鳞', '归去来兮', '塞北江南', 'Mamma voglio anchio la '
]
相关api:
全屏模态转场
组件内转场 (transition)