鸿蒙Next转场动画,搜索功能一镜到底

188 阅读1分钟

该效果使用 共享元素转场功能完成。 涉及到模态转场的使用,出现/消失转场的使用。
源码地址

顶部搜索栏:

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)