DEV Community

kouwei qing
kouwei qing

Posted on

Tab Switch Lifecycle, Complex JSON Assembly, Scroll Max Height, Reference Passing Error, Web Performance

[Daily HarmonyOS Next Knowledge] Tab Switch Lifecycle, Complex JSON Assembly, Scroll Max Height, Reference Passing Error, Web Performance

1. Components Embedded in Tabs Do Not Trigger onPageShow Method in HarmonyOS?

The onPageShow lifecycle method does not execute when switching tabs because onPageShow is a page-level lifecycle callback. Tab switching triggers the component-level lifecycle method aboutToAppear() for child components. You can call showPage() within this lifecycle. If you need the showPage method in TabContent to execute every time a tab is switched, use onTabBarClick(event: (index: number) => void) to get the currently clicked tab index in the parent component.

Define a currentTabIndex variable in the parent component using @State, assign the clicked index to currentTabIndex in the onTabBarClick callback, and pass this value to child components wrapped by TabContent. In child components, use @Props and @Watch to listen for changes to the value passed from the parent component and execute the showPage method in each TabContent.

Demo Reference:

// xxx.ets
import { FirstPage } from './FirstPage'

@Entry
@Component
struct TabsExample {
  @State fontColor: string = '#182431'
  @State selectedFontColor: string = '#007DFF'
  @State currentIndex: number = 0
  private controller: TabsController = new TabsController()
  @State mainPageState: boolean = false

  @Builder tabBuilder(index: number, name: string) {
    Column() {
      Text(name)
        .fontColor(this.currentIndex === index ? this.selectedFontColor : this.fontColor)
        .fontSize(16)
        .fontWeight(this.currentIndex === index ? 500 : 400)
        .lineHeight(22)
        .margin({ top: 17, bottom: 7 })
      Divider()
        .strokeWidth(2)
        .color('#007DFF')
        .opacity(this.currentIndex === index ? 1 : 0)
    }.width('100%')
  }

  build() {
    Column() {
      Tabs({ barPosition: BarPosition.Start, index: this.currentIndex, controller: this.controller }) {
        TabContent() {
          FirstPage({ mainPageState: this.mainPageState }).width('100%').height('100%').backgroundColor('#00CB87')
        }.tabBar(this.tabBuilder(0, 'green'))

        TabContent() {
          Column().width('100%').height('100%').backgroundColor('#007DFF')
        }.tabBar(this.tabBuilder(1, 'blue'))

        TabContent() {
          Column().width('100%').height('100%').backgroundColor('#FFBF00')
        }.tabBar(this.tabBuilder(2, 'yellow'))

        TabContent() {
          Column().width('100%').height('100%').backgroundColor('#E67C92')
        }.tabBar(this.tabBuilder(3, 'pink'))
      }
      .vertical(false)
      .barMode(BarMode.Fixed)
      .barWidth(360)
      .barHeight(56)
      .animationDuration(400)
      .onChange((index: number) => {
        this.currentIndex = index
      })
      .width('100%')
      .height('100%')
      .margin({ top: 52 })
      .backgroundColor('#F1F3F5')
    }.width('100%')
  }

  onPageShow(): void {
    console.log('index--- onPageShow')
    this.mainPageState = true
  }

  onPageHide(): void {
    console.log('index--- onPageHide')
    this.mainPageState = false
  }
}
Enter fullscreen mode Exit fullscreen mode
import { router } from '@kit.ArkUI';
import { FaultLogger } from '@kit.PerformanceAnalysisKit';

@Entry
@Component
export struct FirstPage {
  @State message: string = 'Hello World';
  @Link @Watch('mainIsShow') mainPageState: boolean

  build() {
    Row() {
      Column() {
        Text(this.message)
          .fontSize(50)
          .fontWeight(FontWeight.Bold)
          .onClick(() => {
            router.pushUrl({
              url: 'pages/DetailPage',
            })
          })
      }
      .width('100%')
    }
    .height('100%')
  }

  mainIsShow() {
    console.log('mainIsShow--', this.mainPageState)
  }

  aboutToAppear(): void {
    console.log('firstPAGE--- aboutToAppear')
  }

  onPageShow(): void {
    console.log('firstPAGE--- onPageShow')
  }

  onPageHide(): void {
    console.log('firstPAGE--- onPageHide')
  }

  aboutToRecycle(): void {
    console.log('firstPAGE--- aboutToRecycle')
  }
}
Enter fullscreen mode Exit fullscreen mode
import { Notification } from '@kit.NotificationKit';

@Entry
@Component
struct DetailPage {
  @State message: string = 'Detail';

  build() {
    Row() {
      Column() {
        Text(this.message)
          .fontSize(50)
          .fontWeight(FontWeight.Bold)
      }
      .width('100%')
    }
    .height('100%')
  }

  onPageShow(): void {
  }

  onPageHide(): void {
    console.log('firstPAGE--- onPageHide')
  }

  onBackPress(): boolean | void {
    console.log('firstPAGE--- onBackPress')
  }
}
Enter fullscreen mode Exit fullscreen mode

2. How to Assemble Complex JSON Data?

Reference Demo:

jsonObject: Record<string, Object> = {}

aboutToAppear(): void {
  this.jsonObject["k1"] = "v1"
  this.jsonObject["k2"] = 20
  let json: string = JSON.stringify(this.jsonObject)
  console.log(json)
}
Enter fullscreen mode Exit fullscreen mode

3. How to Limit the Maximum Height of a Scroll Component in HarmonyOS?

When displaying text in the middle of a layout with other UI elements above and below, wrap the Text component with a Scroll component. To prevent other UI elements from being pushed off-screen when the text is too long, set a maximum height for the Scroll component.

Reference Demo:

@Entry
@Component
struct NestedScroll {
  @State listPosition: number = 0; // 0: scroll to top, 1: middle, 2: scroll to bottom
  private arr: number[] = [1]
  private scrollerForList: Scroller = new Scroller()

  build() {
    Flex() {
      Column() {
        Text("Header")
          .width("100%")
          .height("20%")
          .backgroundColor(0X330000FF)
          .fontSize(16)
          .textAlign(TextAlign.Center)

        List({ space: 20, scroller: this.scrollerForList }) {
          ForEach(this.arr, (item: number) => {
            ListItem() {
              Text("This is a very long text...") // Omitted for brevity
                .borderRadius(15)
                .fontSize(16)
                .backgroundColor(Color.White)
            }.width("100%")
          }, (item: string) => item)
        }
        .borderColor(Color.Green)
        .borderWidth(2)
        .width("100%")
        .edgeEffect(EdgeEffect.None)
        .friction(0.6)
        .onReachStart(() => {
          this.listPosition = 0
        })
        .onReachEnd(() => {
          this.listPosition = 2
        })
        .onScrollFrameBegin((offset: number) => {
          if ((this.listPosition == 0 && offset <= 0) || (this.listPosition == 2 && offset >= 0)) {
            return { offsetRemain: 0 }
          }
          this.listPosition = 1
          return { offsetRemain: offset };
        })
        .constraintSize({ maxHeight: 400 })

        Text("Footer")
          .width("100%")
          .height("20%")
          .backgroundColor(0X330000FF)
          .fontSize(16)
          .textAlign(TextAlign.Center)
      }
    }.width('100%').height('100%').backgroundColor(0xDCDCDC)
  }
}
Enter fullscreen mode Exit fullscreen mode

4. Compilation Error When Passing Parameters by Reference in @builder in HarmonyOS?

Compilation Error:

Object literals cannot be used as type declarations (ArkTS-no-obj-literals-as-types) <ArkTSCheck>

Code:

@Builder overBuilder($$: { paramA1: string }) {
  Row() {
    Text(`UseStateVarByReference: ${$$.paramA1} `)
  }
}
Enter fullscreen mode Exit fullscreen mode

Solution:

class Tmp {
  paramA1: string = ''
}

@Builder function overBuilder($$: Tmp) {
  Text($$.paramA1)
    .width(400)
    .height(50)
    .backgroundColor(Color.Blue)
}
Enter fullscreen mode Exit fullscreen mode

5. Does Nested H5 Pages in HarmonyOS Cause Page Lag? How to Optimize?

Best Practices Reference:

https://developer.huawei.com/consumer/cn/doc/best-practices-V5/bpta-web-develop-optimization-V5

ArkWeb is a Web component platform designed to display Web content in applications and provide developers with capabilities such as page loading, interaction, and debugging. In the digital age, page loading speed directly impacts app fluency, user perception, and experience. Fast-loading pages reduce wait times and improve satisfaction.

The Web page display process involves multiple stages: DNS resolution, connection establishment, request sending, response receiving, HTML parsing, and resource downloading. Factors affecting page speed include network latency, server response time, page size, and resource compression. To enhance performance, optimize page loading, resource downloading, and rendering.

Common Optimization Methods:

  • Web Page Loading Optimization: Critical for user experience; faster loading improves app fluency.
  • JSBridge: Reduces redundant ArkTS environment switches and avoids UI blockages.
  • Same-Layer Rendering: Renders page elements in layers to minimize repaints and reflows, improving rendering efficiency.

ArkWeb provides methods to optimize page display speed. These optimizations enhance app performance and user experience, enabling faster, smoother Web browsing and increasing user satisfaction and retention.

Top comments (0)