【每日学点HarmonyOS Next知识】点击事件不响应、软键盘弹出、动画效果、文本选择、设置状态栏字体

108 阅读4分钟

1、HarmonyOS 页面上创建两个button,只有一个可以收到click事件?

@Entry
@Component
struct SplashScreenPage {
  @State pageShowTime: number = CommonConstants.TIME_DEFAULT_VALUE;
  @State intervalID: number = CommonConstants.INTERVAL_ID_DEFAULT;

  build() {
    Column() {
      Stack({ alignContent: Alignment.TopStart }) {
        Image($r('app.media.ic_splash_page_background'))
          .width(CommonConstants.IMAGE_WIDTH)
          .height(CommonConstants.IMAGE_HEIGHT)

        HideButton();
        SkipButton({ secondsCount: (CommonConstants.DELAY_SECONDS - this.pageShowTime) });
      }
      .layoutWeight(CommonConstants.STACK_LAYOUT_WEIGHT)
      .width(CommonConstants.STACK_WIDTH);
    }
    .alignItems(HorizontalAlign.Start)
    .width(CommonConstants.COLUMN_WIDTH)
    .height(CommonConstants.COLUMN_HEIGHT)
  }
}

//其次分别创建两个button

@Component
struct SkipButton {
  @Prop secondsCount: number = 0;

  build() {
    Flex({
      direction: FlexDirection.Row,
      justifyContent: FlexAlign.End
    }) {
      Text($r('app.string.skip', this.secondsCount))
        .onClick(() => {
          console.log("EntryAbility Skip Button is clicked");
        })
    }
  }
}

@Component
struct HideButton {
  build() {
    Flex({
      direction: FlexDirection.Row,
      justifyContent: FlexAlign.Start
    }) {
      Text($r('app.string.hide'))
        .onClick(() => {
          console.log("EntryAbility Hide Button is clicked");
        })
    }
  }
}

可以加入属性 .hitTestBehavior(HitTestMode.Transparent),参考文档:developer.huawei.com/consumer/cn…

设置组件的触摸测试类型。ArkUI开发框架在处理触屏事件时,会在触屏事件触发前,进行按压点和组件区域的触摸测试来收集需要响应触屏事件的组件,然后基于触摸测试结果分发相应的触屏事件。hitTestBehavior属性可以设置不同的触摸测试响应模式,影响组件的触摸测试收集结果,最终影响后续的触屏事件分发

@Component
struct SkipButton {
  @Prop secondsCount: number = 0;

  build() {
    Flex({
      direction: FlexDirection.Row,
      justifyContent: FlexAlign.End
    }) {
      Text($r('app.string.app_name', this.secondsCount))
        .onClick(() => {
          console.log("EntryAbility Skip Button is clicked");
        })
    }
    .hitTestBehavior(HitTestMode.Transparent)
  }
}

2、HarmonyOS 软键盘弹出方式?

自定义@CustomDialog中添加TextArea,在TextArea获取焦点时软键盘弹出会把整个自定义@CustomDialog。如何让软键盘弹出时不要顶起整个自定义@CustomDialog,而是顶起的高度只到TextArea获取焦点的位置。

该问题是软键盘弹出的时候,软键盘会遮挡一部分组件的显示,需求是被遮挡部分想要被软键盘顶起来,在软键盘的上方。软件盘弹出的时候默认是顶起输入框,对于输入框以下的显示组件将被遮挡。可获取窗口内容规避的区域,规避区域的类型是软键盘区域TYPE_KEYBOARD,当软键盘弹出,获取规避区域的高度,通过margin-bottom来设置想要顶起组件。

代码示例:

import window from '@ohos.window';
@Entry
@Component
struct ScrollExample {
  scroller: Scroller = new Scroller()
  private arr: number[] = [0, 1, 2, 3, 4, 5]
  @State scrollHeight: number = 0;
  @State isRebuild: boolean = false;
  @State keyHeight: number =0;
  @State text: string = ''
  aboutToAppear() {
    window.getLastWindow(getContext(this)).then(currentWindow =>{
      let property = currentWindow.getWindowProperties();
      // init window height
      let avoidArea = currentWindow.getWindowAvoidArea(window.AvoidAreaType.TYPE_KEYBOARD);
      this.scrollHeight = px2vp(property.windowRect.height - avoidArea.bottomRect.height);
      // monitor the hiding and display of softKeyboard
      currentWindow.on('avoidAreaChange', async data => {
        if (data.type !== window.AvoidAreaType.TYPE_KEYBOARD) {
          this.keyHeight=avoidArea.bottomRect.height;
          return;
        }
        this.scrollHeight = px2vp(property.windowRect.height - data.area.bottomRect.height);
      })
    })
  }
  build() {
    Stack({ alignContent: Alignment.TopStart }) {
      Column() {
        Scroll(this.scroller) {
          Column() {
            TextInput({ text: this.text, placeholder: 'input your word...' })
              .placeholderFont({ size: 14, weight: 400 })
              .width(320)
              .height(40).margin(200)
              .fontSize(14)
              .fontColor(Color.Black)
              .backgroundColor(Color.White)
            ForEach(this.arr, (item:number) => {
              Text(item.toString())
                .width('90%')
                .height(150)
                .backgroundColor(0xFFFFFF)
                .borderRadius(15)
                .fontSize(16)
                .textAlign(TextAlign.Center)
                .margin({ top: 10 })
            })
          }.width('100%')
        }
        .width('100%').height(this.scrollHeight).layoutWeight(1)
        Text('这是一个测试文本')
          .width('100%')
          .height(50)
          .backgroundColor(Color.Red)
          .margin({bottom: this.scrollHeight})
      }.width('100%').height('100%').justifyContent(FlexAlign.Start)
    }.width('100%').height('100%').backgroundColor(0xDCDCDC)
  }
}

3、HarmonyOS .scale没有动画效果?

.scale根本就没有动画效果

@Component ImageScale {

  @State scaleValue: ScaleOptions = { x: 1, y: 1, z: 1 }

  build() {
    Column() {
      Image(this.viewModel?.item?.image?.hdUrl)
        .width("100%")
        .aspectRatio(1.0)
        .animation({ duration: 200, curve: "ease" })
        .scale(this.scaleValue)
        .gesture(TapGesture({ count: 2 }).onAction((event: GestureEvent) => {
          let width = event.target.area.width.valueOf() as number
          let height = event.target.area.height.valueOf() as number
          let centerX = event.fingerList[0].localX / width
          let centerY = event.fingerList[0].localY / height

          if (this.scaleMode) {
            this.scaleMode = false
            this.scaleValue = {x : 1, y : 1}
          } else {
            this.scaleMode = true
            this.scaleValue = {x : 2, y : 2, centerX: `${centerX * 100}%`, centerY:`${centerY * 100}%`}
          }
        }))
    }
  }
}

参考此代码实现

@Entry
@Component
struct AnimationPage {
  @State message: string = 'Hello World fhlsfslfslfhklafhlaskhfkjsfhjksadfhlkjsafsafhkjsfhkljfhjksafhkjasfksfh';
  @State textY:number = 0

  build() {
    Row() {
      Column() {
        Text(this.message)
          .fontSize(20)
          .fontWeight(FontWeight.Bold)
          .scale({x:1,y:this.textY})
          .animation({
            duration:2000,
            curve: "linear"
          }).id("text")

        Button("点击动画展开").onClick((ele)=>{
          this.textY = 1
        }).width(200).height(50)
          .backgroundColor(Color.Pink).borderRadius(10)
      }
      .width('100%')
    }
    .height('100%')
  }
}

4、HarmonyOS 自定义Dialog情况下 TextPicker选中导致背景模糊属性失效?

自定义Dialog 给定backgroundColor以及backgroundBlurStyle后transition使用OPACITY做过度动画,TextPicker选中Item导致背景模糊属性失效。

在自定义Dialog时,如果设置了backgroundColor和backgroundBlurStyle,并且希望在transition中使用OPACITY进行过渡动画,可能会遇到TextPicker选中Item导致背景模糊属性失效的问题。这是因为在transition中使用OPACITY会影响到backgroundBlurStyle的生效。具体来说,OPACITY属性用于控制元素的透明度,而backgroundBlurStyle属性用于添加背景模糊效果。当同时使用这两个属性时,backgroundBlurStyle可能会被OPACITY所覆盖,导致背景模糊效果失效。要解决这个问题,可以考虑以下几种方法:

  1. 调整动画顺序:将OPACITY动画放置在backgroundBlurStyle之后,这样可以确保backgroundBlurStyle先生效,然后再应用OPACITY动画。
  2. 使用单独的动画:将OPACITY动画和背景模糊动画分开来,分别应用到不同的属性上,而不是合并在一起。
  3. 调整属性顺序:将backgroundBlurStyle的生效顺序调整到OPACITY之后,这样可以确保背景模糊效果在透明度变化之后生效。通过这些调整,可以确保在使用OPACITY进行过渡动画时,背景模糊效果仍然能够正常显示。

5、HarmonyOS 设置状态栏的字体颜色好像无效?

windowclass.setWindowSystemBarProperties({ //以下两个属性从API Version8开始支持 statusBarContentColor: '#000000' //状态栏字体颜色 }).then((d)=>{ console.debug("") },(e:BusinessError)=>{ console.debug("") }) 回调是成功的,但是状态栏并没有发生变化

目前设置状态栏颜色是使用窗口的API,调整维度是从整个窗口进行调整。需要做到页面的级别的话就需要在页面的生命周期中进行调整控制,在需要改变的页面直接调用setWindowSystemBarProperties方法。可以参考官方文档:developer.huawei.com/consumer/cn…

setWindowSystemBarProperties(systemBarProperties: SystemBarProperties): Promise

设置主窗口三键导航栏、状态栏的属性,使用Promise异步回调,

该接口在2in1设备上调用不生效,其他设备在分屏模式(即窗口模式为window.WindowStatusType.SPLIT_SCREEN)、自由悬浮窗口模式(即窗口模式为window.WindowStatusType.FLOATING)、自由多窗模式(可点击设备控制中心中的自由多窗按钮开启)下调用不会立刻生效,只有进入全屏主窗口才会生效。

参考如下代码:
  onPageShow(): void {
  window.getLastWindow(getContext(), (err, data) => {
  let win: window.Window;
  if (err.code) {
  console.error("error code :" + JSON.stringify(err.code))
  return;
}
try {
  win = data;
  //设置窗口为全屏模式
  win.setWindowLayoutFullScreen(true);
  // 设置状态栏
  win.setWindowSystemBarProperties({
    // 设置状态栏颜色为其他颜色
    statusBarColor: '#00ff00',
    // 设置状态栏文本颜色为白色
    statusBarContentColor: '#353535'
  })
  console.info('带状态栏沉浸式窗口设置完成')
} catch (expextion) {
  console.error("error cause :" + JSON.stringify(expextion))
}
})
}

##鸿蒙核心技术##鸿蒙开发工具##Arkcompiler# ##社交##