HarmonyOS 咨询共享元素动态转场示例

请求提供在Navigation模式下的共享元素动态转场示例。

HarmonyOS
2024-08-30 12:56:34
浏览
收藏 0
回答 1
待解决
回答 1
按赞同
/
按时间
zxjiu

示例:第一页代码

import { Constants } from '../../common/Constants' 
import curves from '@ohos.curves'; 
import { SearchPageExtraInfo } from '../../common/ExtraInfo'; 
const TRANSITION_ID = 'SEARCH_ONE_SHOT_DEMO_TRANSITION_ID'; 
@Component 
export default struct SearchOneShotDemo { 
  @Consume('mainPathStack') mainPathStack: NavPathStack; 
  @State translateY: number = 0; 
  @State transitionEffect: TransitionEffect = TransitionEffect.IDENTITY; 
  // 以一镜到底形式弹出搜索页 
  private showSearchPage(): void { 
    this.transitionEffect = TransitionEffect.OPACITY; 
    let param = new SearchPageExtraInfo(); 
    param.geometryId = TRANSITION_ID; 
    param.onBackClicked = () => { this.onBackClickedCallBack() }; 
    animateTo({ 
      curve: curves.interpolatingSpring(0, 1, 342, 38) 
    }, () => { 
      // 需要使用一镜到底效果的话此处pushPath需要传false 
      this.mainPathStack.pushPath({ name: 'SearchPage', param: param }, false); 
      this.translateY = -100; 
    }) 
  } 
  private onBackClickedCallBack(): void { 
    animateTo({ 
      curve: curves.interpolatingSpring(0, 1, 342, 38) 
    }, () => { 
      this.translateY = 0; 
    }) 
  } 
  build() { 
    NavDestination() { 
      Column({ space: 20 }) { 
        Search({ placeholder: '搜索' }) 
          .width('100%') 
            // 需要消失的搜索框绑定geometryTransition id 
          .geometryTransition(TRANSITION_ID, { follow: true }) 
          .backgroundColor(Color.White) 
          .defaultFocus(false) 
          .focusOnTouch(false) 
          .focusable(false) 
          .border({ width: 1, color: Color.Black }) 
          .onTouch((event: TouchEvent) => { 
            if (event.type === TouchType.Up) { 
              this.showSearchPage(); 
            } 
          }) 
        Column() 
          .width('100%') 
          .height('50%') 
          .backgroundColor(Color.White) 
          .borderRadius(20) 
          .translate({ y: this.translateY }) 
      } 
      .size({ width: '90%', height: '100%' }) 
    } 
    .transition(TransitionEffect.OPACITY) 
    .backgroundColor(Constants.MAIN_BG_COLOR) 
    .title('搜索一镜到底') 
    .onBackPressed(() => { 
      this.transitionEffect = TransitionEffect.IDENTITY; 
      this.mainPathStack.pop(true); 
      return true; 
    }) 
  } 
}

弹出页代码

import curves from '@ohos.curves' 
import { Constants } from '../../common/Constants'; 
import { DisplayUtils } from '../../common/DisplayUtils'; 
import { SearchPageExtraInfo } from '../../common/ExtraInfo'; 
@Component 
export default struct SearchPage { 
  @Consume('mainPathStack') mainPathStack: NavPathStack; 
  @Prop param: SearchPageExtraInfo; 
  private onArrowClicked(): void { 
    animateTo({ 
      curve: curves.interpolatingSpring(0, 1, 342, 38) 
    }, () => { 
      this.mainPathStack.pop(false); 
    }) 
    this.param.onBackClicked(); 
  } 
  build() { 
    NavDestination() { 
      Column({ space: 20 }) { 
        Row({ space: 10 }) { 
          Image($r('app.media.ic_public_back')) 
            .width(24) 
            .height(24) 
            .onClick(() => { 
              this.onArrowClicked(); 
            }) 
            .transition(TransitionEffect.asymmetric( 
              TransitionEffect.OPACITY 
                .animation({ duration: 200, delay: 150, curve: curves.cubicBezierCurve(0.33, 0, 0.67, 1) }), 
              TransitionEffect.OPACITY 
                .animation({ duration: 200, curve: curves.cubicBezierCurve(0.33, 0, 0.67, 1) }) 
            )) 
          Search({ placeholder: '王牌部队' }) 
            .width('80%') 
            .height(40) 
              // 需要出现的搜索框绑定geometryTransition id,由pushPath传入 
            .geometryTransition(this.param.geometryId) 
            .backgroundColor(Color.White) 
            .border({ width: 1, color: Color.Black }) 
            .transition(TransitionEffect.opacity(0.99)) 
        } 
        .width('100%') 
        .height(50) 
        .alignItems(VerticalAlign.Center) 
        .padding({ left: 20 }) 
 
        Column() 
          .width('100%') 
          .height('50%') 
          .backgroundColor(Color.White) 
          .borderRadius(20) 
          .transition(TransitionEffect.translate({ y: 100 })) 
      } 
      .size({ width: '100%', height: '100%' }) 
      .margin({ top: 20 }) 
    } 
    .transition(TransitionEffect.OPACITY) 
    .hideTitleBar(true) 
    .backgroundColor(Constants.MAIN_BG_COLOR) 
    // 点击返回箭头返回/侧滑返回触发,做一镜到底返回动效 
    .onBackPressed(() => { 
      animateTo({ 
        curve: curves.interpolatingSpring(0, 1, 342, 38), 
      }, () => { 
        // 与pushPath对应,此处的pop同样需要传false 
        this.mainPathStack.pop(false); 
      }) 
      this.param.onBackClicked(); 
      return true; 
    }) 
  } 
}

Constants.ts

export class Constants { 
  public static MAIN_BG_COLOR: string = '#F1F3F5'; 
}

ExtraInfo.ts

export class ExtraInfo { 
} 
export class NormalPageExtraInfo extends ExtraInfo { 
  public geometryId: string; 
} 
export class SearchPageExtraInfo extends NormalPageExtraInfo { 
  public onBackClicked: () => void; 
}

DisplayUtils.ts

export class DisplayUtils { 
  public static screenWidth: number; 
  public static screenHeight:number; 
}
分享
微博
QQ
微信
回复
2024-08-30 17:44:43
相关问题
如何实现共享元素转场
502浏览 • 1回复 待解决
HarmonyOS 动态隐藏页面元素
46浏览 • 1回复 待解决
HarmonyOS Navigation转场?
139浏览 • 0回复 待解决