鸿蒙开发
在开发项目中,我们经常会发现系统提供的UI界面无法满足我们的业务需求,因此需要自定义UI组件。在我开发鸿蒙(API 11)项目时,发现官方提供的原生扫码页面无法满足我们的需求,因此需要自定义扫码页面。这种情况下,我们需要重新定义UI组件来满足我们的业务需求,确保项目能够顺利进行。
实现步骤:
1.绘制页面相机数据预览组件和遮罩组件
import { common } from '@kit.AbilityKit'; import { detectBarcodeFromAlbum, ScanAnimation, ResultCode, ScanComponent } from './ScanComponent'; import { Toast } from '../utils/Toast'; import {CommonUtil} from '../utils/CommonUtil' import { TitleViewLayout } from './TitleViewLayout'; @Preview @Entry @Component export struct ScanViewPage { context: common.UIAbilityContext = getContext(this) as common.UIAbilityContext @State result: string = '' @State startScan: boolean = false; scanRectSize: number = 0; @State Number: String[] = ['0', '1', '2', '3', '4'] aboutToAppear(): void { } onPageShow(): void { this.startScan = true; } onPageHide(): void { this.startScan = false; } build() { RelativeContainer() { /* * 标题头 * */ TitleViewLayout({ leftIcon: $r('app.media.back_white'), title: '扫一扫', textColor: Color.White, layoutColor: Color.Black }).alignRules({ top: { anchor: '__container__', align: VerticalAlign.Top }, left: { anchor: '__container__', align: HorizontalAlign.Start } }).id("title") /* * 扫码页面 * */ ScanComponent({ onShow: $startScan, screenWidth: CommonUtil.SCREEN_WIDTH, screenHeight: CommonUtil.SCREEN_HEIGHT, scanRectSize: 0.68, scanRectMarginTop: 0.17, scanAnimation: ScanAnimation.TRANSLATE, resultCallback: (value: string, code: number)=>{ Toast.showLong(value) } }).width("100%") .height(px2vp(CommonUtil.SCREEN_HEIGHT) - 44 - px2vp(CommonUtil.TITLE_BAR_HEIGHT + CommonUtil.TITLE_BOTTOM_HEIGHT)) .alignRules({ top: { anchor: 'title', align: VerticalAlign.Bottom }, left: { anchor: 'title', align: HorizontalAlign.Start } }).id("ScanView") Column() { Row() { Column() { Image($r('app.media.icon_photo_album')) .width(42) .height(42) .margin({ bottom: 4 }) Text('相册') .fontSize(12) .fontColor('#FFFFFF') .fontWeight(400) Button("点击").fontSize(10) .fontColor("#000000") .backgroundColor('#098990') .onClick(()=>{ Toast.showLong("点击我了...") }) } .alignItems(HorizontalAlign.Center) .onClick(() => { detectBarcodeFromAlbum( (value: string, code: number)=>{ Toast.showLong(value) }); }) } .margin({ left: 32, right: 32, top: 24 }) } .alignRules({ top: { anchor: 'title', align: VerticalAlign.Bottom }, }) .alignItems(HorizontalAlign.Center) .width("100%") .height(153) .margin({ top: px2vp(0.62 * CommonUtil.SCREEN_HEIGHT) }) .id("cardRect") } } aboutToDisappear(): void { } }
在自定义扫码页面的开发过程中,我们可以采用以下步骤:
首先,使用最底层的Stack容器作为底部容器。然后在Stack容器上添加相机数据预览组件XComponent。接着,在预览组件上层添加一个透明的RelativeContainer容器。最后,在RelativeContainer容器上叠加一个遮罩层,来定义扫码区域。
需要注意的是,XComponent UI组件的.onLoad()方法执行存在一定的延时,类似于Android中SurfaceView的初始化过程。因此,在XComponent的onLoad()方法执行完毕后才能启动扫码相机,否则可能会导致surfaceId为undefined的情况发生。
总的来说,通过以上步骤和注意事项,我们可以比较简单地实现自定义扫码页面的绘制。流程相对简单,需要确保在适当的时机启动扫码相机,以避免出现问题。