DEV Community

Cover image for Custom Pop-up Background, State Management V2 Practices, Bottom Safe Height, OCR Recognition Result Processing, Grid Divider
kouwei qing
kouwei qing

Posted on

Custom Pop-up Background, State Management V2 Practices, Bottom Safe Height, OCR Recognition Result Processing, Grid Divider

[Daily HarmonyOS Next Knowledge] Custom Pop-up Background, State Management V2 Practices, Bottom Safe Height, OCR Recognition Result Processing, Grid Divider

1. When using promptAction to display a custom pop-up in HarmonyOS, why is there a white background with a fixed width at the bottom?

Reference demo:

import promptAction from '@ohos.promptAction'
@Builder function HWUIToastBuilder() {
  Column() {
    Text('弹窗')
      .fontSize(16)
      .fontWeight(FontWeight.Medium)
      .fontColor(Color.White)
      .textAlign(TextAlign.Center)
      .padding(16)
  }
  .constraintSize({
    minWidth: 100,
    maxWidth: 200,
    minHeight: 56
  })
  .backgroundColor(Color.Black)
  .borderRadius(8)
}
@Entry
@Component
struct Index {
  @State message: string = 'Hello World'
  build() {
    Row() {
      Column() {
        Text(this.message)
          .fontSize(50)
          .fontWeight(FontWeight.Bold)
          .onClick(() => {
            promptAction.openCustomDialog({
              builder: HWUIToastBuilder.bind(this),
              // isModal: false,
              alignment: DialogAlignment.Center
            }).then((id: number) => {
              // HWUIToast.toastId = id
            })
          })
      }
      .width('100%')
    }
    .height('100%')
  }
}
Enter fullscreen mode Exit fullscreen mode

The width of the pop-up window opened by promptAction.openCustomDialog is fixed at 4 grid units in portrait mode and 5 grid units in landscape mode. For custom pop-up styles, it is recommended to use CustomDialogController.

Reference link: https://developer.huawei.com/consumer/cn/doc/harmonyos-references-V5/ts-methods-custom-dialog-box-V5

2. Are there any excellent practices or priority cases for HarmonyOS State Management V2?

Reference code:

@ObservedV2
class BasicPickData {
  @Trace fundName: string = ''
  @Trace plateName: string = ''
}

@ObservedV2
class SubPickData {
  @Trace subCardData: string = ''
  @Trace cell: BasicPickData[] = []
}

@ObservedV2
class MergeCellData {
  @Trace title: string = ''
  key: string = ''
  @Trace items: SubPickData[] = []
}

@Entry
@Component
struct HomeMainPage {
  @State testListData: MergeCellData[] = []

  aboutToAppear() {
    let mergeCellData: MergeCellData = new MergeCellData()
    mergeCellData.title = 'swiper 0'
    mergeCellData.key = 'swiperKey'
    for (let i = 0; i < 4; i++) {
      let swiperItem: SubPickData = new SubPickData()
      swiperItem.subCardData = 'subCardData'+ i
      for (let j = 0; j < 4;j++) {
        let cellData: BasicPickData = new BasicPickData()
        cellData.fundName = 'cell_' + j + '_fundName'
        cellData.plateName = 'cell_' + j + '_plateName'
        swiperItem.cell.push(cellData)
      }
      mergeCellData.items.push(swiperItem)
    }
    this.testListData.push(mergeCellData)
  }

  // Generate a random number between 1 and 100
  getRandomVal() {
    const min = 1;
    const max = 100;
    const randomInt = Math.floor(Math.random() * (max - min + 1)) + min;
    return randomInt
  }

  build() {
    Column() {
      Button('refresh').onClick(() => {
        setTimeout(() => {
          this.testListData[0].title = 'new swiper' + this.getRandomVal()
          for (let i = 0; i < this.testListData.length; i++) {
            this.testListData[i].title = 'new swiper' + this.getRandomVal()
            for (let j = 0; j < this.testListData[i].items.length; j++) {
              this.testListData[i].items[j].subCardData = 'new subCardData'+ j + this.getRandomVal()
              for (let x = 0; x < this.testListData[i].items[j].cell.length; x++) {
                this.testListData[i].items[j].cell[x].fundName = 'cell_' + x + 'new fundName' + x+ this.getRandomVal()
                this.testListData[i].items[j].cell[x].plateName = 'cell_' + j + 'new plateName' + j + this.getRandomVal()
              }
            }
          }
        }, 1000)
      })

      List() {
        ForEach(this.testListData, (item: MergeCellData) => {
          ListItem() {
            SwiperCom({swiperData: item})
          }
        }, (item: MergeCellData, index: number) => item.key + index)
      }
      .width('100%')
      .height('calc(100% - 56vp - 32vp)')
      .padding({ left: 14, right: 14 })
    }
    .width('100%')
    .height('100%')
  }
}

@Component
struct ListCom {
  listData?: SubPickData

  build() {
    Column() {
      Text(this.listData?.subCardData)

      List() {
        ForEach(this.listData?.cell, (item: BasicPickData, index: number) => {
          ListItem() {
            Text(item?.fundName)
          }
        }, (item: BasicPickData, index: number) => index + '')
      }
      .width('100%')
    }
  }
}

@Component
struct SwiperCom {
  swiperData: MergeCellData = new MergeCellData()

  build() {
    Column() {
      Text(this.swiperData?.title)

      Swiper() {
        ForEach(this.swiperData?.items, (item: SubPickData, index: number) => {
          ListCom({listData: item})
        }, (item: SubPickData, index: number) => index + '')
      }
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

3. When getting the bottom safe height in HarmonyOS, why is bottomRect.height 0?

Use the following type: windowClass.getWindowAvoidArea(window.AvoidAreaType.TYPE_NAVIGATION_INDICATOR).

https://developer.huawei.com/consumer/cn/doc/harmonyos-references-V5/js-apis-window-V5#ZH-CN_TOPIC_0000001884757714__avoidareatype7

4. How to convert the OCR result URI to an image.PixelMap for display on the page in HarmonyOS?

Reference demo:

import { CardRecognition, CallbackParam, CardType, CardSide } from "@kit.VisionKit";
import { image } from '@kit.ImageKit'
import fs from '@ohos.file.fs';


@Entry
@Component
struct Index {

  @State showOCR:boolean = false
  @State src?: image.PixelMap = undefined
  build() {
    Stack() {
      Column(){
        Button('click me')
          .onClick(()=>{
            this.showOCR = true
          })
        Image(this.src)
      }
      if(this.showOCR) {
        this.CardOCRPage()
      }
    }
    .width('100%')
    .height('100%')
  }
  @Builder
  CardOCRPage() {
    // Stack({ alignContent: Alignment.Top }) {
    CardRecognition({
      // Select ID card type as an example here
      supportType: CardType.CARD_ID,
      cardSide:CardSide.FRONT,
      callback: async (params:CallbackParam)=>{
        this.showOCR = false
        if(params.cardInfo) {
          let imageUri = params.cardInfo['front']['cardImageUri'];
          let file = fs.openSync(imageUri, fs.OpenMode.READ_ONLY);
          console.info('file fd:' + file.fd);
          const imageSource: image.ImageSource = image.createImageSource(file.fd);
          let decodingOptions: image.DecodingOptions = {
            editable: true,
            desiredPixelFormat: 3,
          }
          this.src = await imageSource.createPixelMap(decodingOptions);
        }
      }
    })
      // }
      .width('100%')
      .height('100%')
  }
}
Enter fullscreen mode Exit fullscreen mode

5. How to set dividers for a HarmonyOS Grid?

Currently, the Grid does not have a dedicated divider setting. You can achieve the divider effect by setting borders for GridItem or using the Divider component in GridItem.

Top comments (0)