DEV Community

Cover image for 【Daily HarmonyOS Next Knowledge】Listening to Returns in HSP, Title Being Pushed Up, List Swipe Parameters, Canvas Text Alignment
kouwei qing
kouwei qing

Posted on

【Daily HarmonyOS Next Knowledge】Listening to Returns in HSP, Title Being Pushed Up, List Swipe Parameters, Canvas Text Alignment

【Daily HarmonyOS Next Knowledge】Listening to Returns in HSP, Title Being Pushed Up, List Swipe Parameters, Canvas Text Alignment, Build Parameter Crash

1. How to listen for system back button and Navigation return events in a Component of an HSP module in HarmonyOS?

Reference demo:

import { PageOneTmp } from './PageOne'
import { pageTwoTmp } from 'library'
import { Pages } from 'library'

@Entry
@Component
struct NavigationExample {
  @Provide('pageInfos') pageInfos: NavPathStack = new NavPathStack()

  onPageShow(): void {
    console.log('Navigation Index show')
  }

  onPageHide(): void {
    console.log('Navigation Index hide')
  }

  @Builder
  PageMap(name: string) {
    if (name === 'pageOne') {
      PageOneTmp()
    } else if (name === 'pageTwo') {
      pageTwoTmp({ names: name, values: this.pageInfos } as Pages)
    }
  }

  build() {
    Navigation(this.pageInfos) {
      Column() {
        Button('pushPath', { stateEffect: true, type: ButtonType.Capsule })
          .width('80%')
          .height(40)
          .margin(20)
          .onClick(() => {
            this.pageInfos.pushPath({
              name: 'pageOne'
            })
            // Push the page information of the NavDestination specified by name onto the stack
          })
      }
    }
    .hideNavBar(true)
    .onNavBarStateChange((flag: boolean) => {
      if (flag) {
        console.log('Navigation Index change,now is show')
      } else {
        console.log('Navigation Index change,now is hide')
      }
    }).title('NavIndex').navDestination(this.PageMap)
  }
}
Enter fullscreen mode Exit fullscreen mode

2. The HarmonyOS navigation title is pushed up by the keyboard?

When there is a large amount of text, opening the keyboard pushes up the title in the non-scrollable area. How to avoid this?

Navigation(){
  Scroll(){
    Column(){
      ......
      TextArea()...
    }
  }
}.title(appbar()...)
Enter fullscreen mode Exit fullscreen mode

Solution: Use the expandSafeArea attribute to allow components to extend their safe area.

Reference documentation: https://developer.huawei.com/consumer/cn/doc/harmonyos-references-V5/ts-universal-attributes-expand-safe-area-V5

  • The safe area refers to the page display area, which does not overlap with system-set non-safe areas (e.g., status bar, navigation bar) by default.
  • The expandSafeArea attribute allows components to extend their drawing area beyond the safe area without changing the layout.
  • Use setKeyboardAvoidMode to configure the avoidance mode when the virtual keyboard pops up. For titles that should not overlap with non-safe areas, set expandSafeArea for an immersive effect, or use the window interface setWindowLayoutFullScreen.

3. The second parameter edgeEffect of HarmonyOS ListItem.swipeAction() is not working?

@Entry
@Component
struct ListItemExample2 {
  @State arr: number[] = [0, 1, 2, 3, 4]
  @State enterEndDeleteAreaString: string = "not enterEndDeleteArea"
  @State exitEndDeleteAreaString: string = "not exitEndDeleteArea"
  @State isShow: boolean = true;

  @Builder itemEnd() {
    Row() {
      Button("Delete").margin("4vp")
      Button("Set").margin("4vp")
    }.padding("4vp").justifyContent(FlexAlign.SpaceEvenly)
  }
  build() {
    Column() {
      Button("Click").onClick(() => {
        this.isShow = !this.isShow
        console.log(this.isShow + "111111111")
      })
      List({ space: 10 }) {
        ForEach(this.arr, (item: number) => {
          ListItem() {
            Text("item" + item)
              .width('100%')
              .height(100)
              .fontSize(16)
              .textAlign(TextAlign.Center)
              .borderRadius(10)
              .backgroundColor(0xFFFFFF)
          }
          .transition({ type: TransitionType.Delete, opacity: 0 })
          .swipeAction({
            end: this.isShow ? {
              builder: () => { this.itemEnd() },
              onAction: () => {
                animateTo({ duration: 1000 }, () => {
                  let index = this.arr.indexOf(item)
                  this.arr.splice(index, 1)
                })
              },
              actionAreaDistance: 56,
              onEnterActionArea: () => {
                this.enterEndDeleteAreaString = "enterEndDeleteArea"
                this.exitEndDeleteAreaString = "not exitEndDeleteArea"
              },
              onExitActionArea: () => {
                this.enterEndDeleteAreaString = "not enterEndDeleteArea"
                this.exitEndDeleteAreaString = "exitEndDeleteArea"
              }
            } : undefined
          , edgeEffect: SwipeEdgeEffect.None
          })
        }, (item: string) => item)
      }
      Text(this.enterEndDeleteAreaString).fontSize(20)
      Text(this.exitEndDeleteAreaString).fontSize(20)
    }
    .padding(10)
    .backgroundColor(0xDCDCDC)
    .width('100%')
    .height('100%')
  }
}
Enter fullscreen mode Exit fullscreen mode

Key points:

  1. SwipeEdgeEffect.None: Restricts the swipe distance to the size of the swiped component. If a delete area is set, the swipe distance cannot exceed the delete threshold, and releasing the touch after reaching the threshold triggers the delete callback.
  2. SwipeEdgeEffect.Spring: Allows swiping beyond the component size. After exceeding the delete threshold, releasing the touch causes the list item to rebound with a spring damping effect.

Solution: The actionAreaDistance: 56 is too small, leading to accidental deletions. Increase this value for better control.

4. How to solve the issue that the textAlign method for setting text alignment in HarmonyOS Canvas is not effective?

Reference demo:

// xxx.ets
@Entry
@Component
struct CanvasExample {
  private settings: RenderingContextSettings = new RenderingContextSettings(true)
  private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings)

  build() {
    Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
      Canvas(this.context)
        .width('100%')
        .height('100%')
        .backgroundColor('#ffff00')
        .onReady(() => {
          this.context.fillStyle = '#0000ff'
          this.context.font = '18vp'
          this.context.fillStyle = Color.Black
          this.context.textAlign = 'center'
          this.context.textBaseline = 'middle'
          let str = (-10.3456).toFixed(2)
          let metrics = this.context.measureText(str)
          this.context.fillStyle = Color.Green // Draw the text display area
          this.context.fillRect(10, (this.context.height - metrics.height) / 2, metrics.width, metrics.height)
          this.context.fillStyle = Color.Black // Draw the text
          this.context.fillText(str, 10 + (metrics.width / 2), (this.context.height) / 2)
        })
    }
    .width('100%')
    .height('100%')
  }
}
Enter fullscreen mode Exit fullscreen mode

5. After passing components using BuilderParam in HarmonyOS, calling methods causes a crash?

When passing a component to a child control via BuilderParam and handling its click events on the current page, the this keyword in the event method refers to the child control instead of the current page, causing a crash.

Solution: Modify how custom components pass parameters:

NavigationView({title:"小标题",rightRowElement:() => {this.navRightBtn()}})
Enter fullscreen mode Exit fullscreen mode

Top comments (0)