0
0
Lập trình
Admin Team
Admin Teamtechmely

Tạo Giao Diện Camera Tùy Chỉnh Trên HarmonyOS

Đăng vào 7 tháng trước

• 7 phút đọc

Chủ đề:

KungFuTech

Tạo Giao Diện Camera Tùy Chỉnh Trên HarmonyOS Sử Dụng Stack và XComponent

Giới Thiệu

Trong nhiều ứng dụng di động, một bản xem trước camera cơ bản không đủ. Người dùng mong đợi một giao diện sạch sẽ và trực quan với các chỉ dẫn hình ảnh khi quét thẻ căn cước, thẻ tín dụng, hoặc xác thực khuôn mặt. Nhờ vào Camera Kit của Huawei và cấu trúc Stack + XComponent của ArkUI, chúng ta có thể xây dựng một màn hình camera với một khung tùy chỉnh mang lại cảm giác trực quan và chuyên nghiệp.

Trong bài viết này, chúng ta sẽ xây dựng một màn hình camera tùy chỉnh sử dụng Stack và XComponent, lý tưởng cho các trường hợp như nhận diện IBAN hoặc quét dựa trên OCR.

Bối Cảnh: Stack và XComponent Là Gì?

  • XComponent là cánh cửa đến các thành phần gốc như camera. Nó hiển thị bản xem trước camera trên màn hình.
  • Stack, ngược lại, cho phép tạo giao diện theo lớp — nghĩa là chúng ta có thể đặt các lớp phủ, văn bản, nút bấm hoặc khung lên trên luồng camera.

Sự kết hợp này mang lại cho chúng ta quyền kiểm soát hoàn toàn về mặt hình ảnh trên màn hình camera.

Trường Hợp Sử Dụng: Quét IBAN Trong Một Khung Tùy Chỉnh

Trong ví dụ này, chúng ta sẽ triển khai một màn hình mà:

  • Hiển thị luồng camera
  • Thêm khung viền gạch cho việc quét
  • Đặt hướng dẫn kiểm tra và nút chụp phía dưới màn hình camera
  • Cung cấp một giao diện hoàn toàn được thiết kế và tương tác sử dụng các thành phần ArkTS và ArkUI

Thực Hiện: Bố Cục ArkTS Với Khung Overlay Camera

Dưới đây là mã bố cục đầy đủ sử dụng ArkTS:

javascript Copy
build() {
  Row() {
    Column() {
      Stack() {
        // BẢN XEM TRƯỚC CAMERA
        XComponent({
          id: CommonConstants.XCOMPONENT_ID,
          type: XComponentType.SURFACE,
          controller: this.xcomponentController
        })
        .onLoad(async () => {
          await this.camera.releaseCamera();
          this.XComponentinit()
        })
        .width(CommonConstants.FULL_WIDTH)
        .height(this.xcomponentHeight)

        // KHUNG LỚP PHỦ
        if (this.showOverlay) {
          Column() {
            Row().height('25%').width('100%') // Khoảng trống trên cùng

            Column() {
              Row() {
                Row().width('2%') // Lề trái

                Column()
                  .width('96%')
                  .height('100%')
                  .border({
                    color: Color.Black,
                    width: '12px',
                    radius: '8px',
                    style: BorderStyle.Dashed
                  })

                Row().width('2%') // Lề phải
              }
              .height('95%') // Chiều cao khung
            }
            .width('100%')
            .height('50%')
            .justifyContent(FlexAlign.Center)
            .alignItems(HorizontalAlign.Center)

            Row().height('25%').width('100%') // Khoảng trống dưới cùng
          }
          .width('100%')
          .height('100%')
        }
      }
      .width(CommonConstants.FULL_WIDTH)
      .height(this.xcomponentHeight)
      .margin({ top: $r('app.float.top_height') })

      // NÚT + VĂN BẢN Ở DƯỚI
      Column() {
        Text($r('app.string.Recognize_text'))
          .fontSize($r('app.float.button_tip_size'))
          .fontColor(Color.White)
          .margin({ top: $r('app.float.indicate_upper_margin') })

        // Điểm trang trí
        Row()
          .backgroundColor($r('app.color.round_color'))
          .width($r('app.float.decorative_point_size'))
          .height($r('app.float.decorative_point_size'))
          .border({
            radius: $r('app.float.decorative_dots_rounded_corners')
          })
          .margin({
            top: $r('app.float.decorative_dots_upper_margin'),
            bottom: $r('app.float.decorative_dots_bottom_margin')
          })

        // NÚT CHỤP HÌNH
        Row() {
          Row()
            .backgroundColor(Color.White)
            .width($r('app.float.button_size'))
            .height($r('app.float.button_size'))
            .border({
              radius: $r('app.float.button_border_radius')
            })
        }
        .onClick(async () => {
          this.showOverlay = false;
          await this.camera.takePicture();
        })
        .backgroundColor(Color.Black)
        .width($r('app.float.button_border_size'))
        .height($r('app.float.button_border_size'))
        .border({
          color: Color.White,
          width: $r('app.float.button_border_width'),
          radius: $r('app.float.button_border_radius')
        })
        .justifyContent(FlexAlign.Center)
        .alignItems(VerticalAlign.Center)
      }
      .width(CommonConstants.FULL_WIDTH)
      .height($r('app.float.camera_lower_height'))
      .backgroundColor(Color.Black)
      .alignItems(HorizontalAlign.Center)
    }
    .width(CommonConstants.FULL_WIDTH)
    .height(CommonConstants.FULL_Height)
    .backgroundColor(Color.Black)
  }
  .height(CommonConstants.FULL_Height)
}

Kết Quả Thực Tế

Bố cục này cung cấp một màn hình camera sạch sẽ và chuyên nghiệp với:

  • Một khung lớp phủ được thiết kế (viền gạch)
  • Khu vực quét được căn giữa
  • Hướng dẫn rõ ràng
  • Các yếu tố trang trí
  • Một nút chụp hình hình tròn

Hoàn hảo cho các trường hợp sử dụng như:

  • Nhận diện IBAN
  • Quét khuôn mặt hoặc ID
  • Quét thẻ tín dụng bằng OCR
  • Quét mã QR/barcode với phản hồi UI

Giới Hạn và Cân Nhắc

  • Cần có một thiết bị HarmonyOS thực tế, XComponent và Camera Kit sẽ không hoạt động trên trình giả lập.
  • Đảm bảo rằng quyền truy cập camera được xử lý. Luôn kiểm tra quyền truy cập tại thời điểm chạy trước khi mở chế độ xem camera.

Kết Luận

Việc sử dụng XComponent + Stack trong HarmonyOS là một cách mạnh mẽ để xây dựng các giao diện camera tùy chỉnh, theo lớp, cảm giác hiện đại và trực quan. Dù bạn đang xây dựng một máy quét khuôn mặt, trình đọc IBAN, hay trình nhận diện thẻ, cấu trúc bố cục này mang lại cho bạn quyền kiểm soát hoàn toàn về trải nghiệm camera.

Tham Khảo

  • Camera Kit
  • Thành phần Stack

Tác giả: Mehmet Algul

Gợi ý câu hỏi phỏng vấn
Không có dữ liệu

Không có dữ liệu

Bài viết được đề xuất
Bài viết cùng tác giả

Bình luận

Chưa có bình luận nào

Chưa có bình luận nào