赞
踩
介绍
本篇Codelab将介绍如何使用弹窗功能,实现四种类型弹窗。分别是:警告弹窗、自定义弹窗、日期滑动选择器弹窗、文本滑动选择器弹窗。需要完成以下功能:
源码下载
我们首先需要完成HarmonyOS开发环境搭建,可参照如下步骤进行。
代码结构解读
本篇Codelab只对核心代码进行讲解,对于完整代码,我们会在源码下载或gitee中提供。
- ├──entry/src/main/ets // 代码区
- │ ├──common
- │ │ ├──constants
- │ │ │ └──CommonConstants.ets // 常量类
- │ │ └──utils
- │ │ ├──CommonUtils.ets // 弹窗操作工具类
- │ │ └──Logger.ets // 日志打印工具类
- │ ├──entryability
- │ │ └──EntryAbility.ets // 程序入口类
- │ ├──pages
- │ │ └──HomePage.ets // 主页面
- │ ├──view
- │ │ ├──CustomDialogWidget.ets // 自定义弹窗组件
- │ │ ├──TextCommonWidget.ets // 自定义Text组件
- │ │ └──TextInputWidget.ets // 自定义TextInput组件
- │ └──viewmodel
- │ └──HobbyItem.ets // 兴趣爱好类
- └──entry/src/main/resources // 资源文件目录
构建主页面
应用主页面采用Column容器嵌套自定义组件形式完成页面整体布局,效果如图所示:
从上面效果图可以看出,主界面由2个相同样式的文本输入框和3个相同样式的文本布局组成。我们可以将文本输入框抽取成TextInputWidget子组件。再将文本布局抽取成TextCommonWidget子组件。
在ets目录下,点击鼠标右键 > New > Directory,新建名为view的自定义子组件目录。然后在view目录下,点击鼠标右键 > New > ArkTS File,新建两个ArkTS文件,分别为TextInputWidget子组件、TextCommonWidget子组件。
文本输入框抽取成TextInputWidget子组件,效果如图所示:
- // TextInputWidget.ets
- @Component
- export default struct TextInputWidget {
- // 文本框左侧图片
- private inputImage?: Resource;
- // 文本框提示
- private hintText?: Resource;
-
- build() {
- Row() {
- Image(this.inputImage !== undefined ? this.inputImage : '')
- ...
- TextInput({ placeholder: this.hintText })
- ...
- }
- ...
- }
- }
文本布局抽取成TextCommonWidget子组件,效果如图所示:
- // TextCommonWidget.ets
- @Component
- export default struct TextCommonWidget {
- // 显示内容
- @Link content: string;
- // 文字标题左侧图片
- private textImage?: Resource;
- // 文本标题
- private title?: Resource;
- // 点击事件回调
- onItemClick = () => {};
-
- build() {
- Row() {
- Image(this.textImage !== undefined ? this.textImage : '')
- ...
- Text(this.title)
- ...
- Text(this.content)
- ...
- Image($r('app.media.ic_arrow'))
- ...
- }
- .onClick(this.onItemClick)
- ...
- }
- }
在HomePage主界面引用TextInputWidget和TextCommonWidget子组件,然后初始化出生日期、性别、兴趣爱好默认数据。
- // HomePage.ets
- @Entry
- @Component
- struct HomePage {
- @State birthdate: string = '';
- @State sex: string = '';
- @State hobbies: string = '';
- ...
-
- build() {
- Column() {
- ...
- TextInputWidget({
- inputImage: $r('app.media.ic_nickname'),
- hintText: $r('app.string.text_input_hint')
- })
- TextCommonWidget({
- textImage: $r('app.media.ic_birthdate'),
- title: $r('app.string.title_birthdate'),
- content: $birthdate,
- onItemClick: () => {
- CommonUtils.datePickerDialog((birthValue: string) => {
- this.birthdate = birthValue;
- });
- }
- })
- TextCommonWidget({
- textImage: $r('app.media.ic_sex'),
- title: $r('app.string.title_sex'),
- content: $sex,
- onItemClick: () => {
- CommonUtils.textPickerDialog(this.sexArray, (sexValue: string) => {
- this.sex = sexValue;
- });
- }
- })
- TextInputWidget({
- inputImage: $r('app.media.ic_signature'),
- hintText: $r('app.string.text_input_signature')
- })
- TextCommonWidget({
- textImage: $r('app.media.ic_hobbies'),
- title: $r('app.string.title_hobbies'),
- content: $hobbies,
- onItemClick: () => {
- this.customDialogController.open();
- }
- })
- }
- ...
- }
- }
警告弹窗
点击主页面左上角返回按钮,通过CommonUtils.alertDialog方法弹出警告弹窗,提醒用户是否进行当前操作,效果如图所示:
- // CommonUtils.ets
- alertDialog(context: Context.UIAbilityContext) {
- AlertDialog.show({
- // 提示信息
- message: $r('app.string.alert_dialog_message'),
- // 弹窗显示位置
- alignment: DialogAlignment.Bottom,
- // 弹窗偏移位置
- offset: {
- dx: 0,
- dy: CommonConstants.DY_OFFSET
- },
- primaryButton: {
- value: $r('app.string.cancel_button'),
- action: () => {
- ...
- }
- },
- secondaryButton: {
- value: $r('app.string.definite_button'),
- action: () => {
- // 退出应用
- context.terminateSelf();
- ...
- }
- }
- });
- }
日期滑动选择器弹窗
点击出生日期选项,通过CommonUtils.datePickerDialog方法弹出日期选择器弹窗,根据需要选择相应时间,效果如图所示:
- // CommonUtils.ets
- datePickerDialog(dateCallback: Function) {
- DatePickerDialog.show({
- // 开始时间
- start: new Date(CommonConstants.START_TIME),
- // 结束时间
- end: new Date(),
- // 当前选中时间
- selected: new Date(CommonConstants.SELECT_TIME),
- // 是否显示农历
- lunar: false,
- onAccept: (value: DatePickerResult) => {
- let year: number = Number(value.year);
- let month: number = Number(value.month) + CommonConstants.PLUS_ONE;
- let day: number = Number(value.day);
- let birthdate: string = this.getBirthDateValue(year, month, day);
- dateCallback(birthdate);
- }
- });
- }
-
- // 获取出生日期值
- getBirthDateValue(year: number, month: number, day: number): string {
- let birthdate: string = `${year}${CommonConstants.DATE_YEAR}${month}` +
- `${CommonConstants.DATE_MONTH}${day}${CommonConstants.DATE_DAY}`;
- return birthdate;
- }
-
- // HomePage.ets
- build() {
- Column() {
- ...
- TextCommonWidget({
- textImage: $r('app.media.ic_birthdate'),
- title: $r('app.string.title_birthdate'),
- content: $birthdate,
- onItemClick: () => {
- CommonUtils.datePickerDialog((birthValue: string) => {
- this.birthdate = birthValue;
- });
- }
- })
- ...
- }
- ...
- }
文本滑动选择器弹窗
点击性别选项,通过CommonUtils.textPickerDialog方法弹出性别选择器弹窗,根据需要选择相应性别,效果如图所示:
- // CommonUtils.ets
- textPickerDialog(sexArray: Resource, sexCallback: Function) {
- ...
- TextPickerDialog.show({
- range: sexArray,
- selected: 0,
- onAccept: (result: TextPickerResult) => {
- sexCallback(result.value);
- },
- onCancel: () => {
- ...
- }
- });
- }
-
- // HomePage.ets
- build() {
- Column() {
- ...
- TextCommonWidget({
- textImage: $r('app.media.ic_sex'),
- title: $r('app.string.title_sex'),
- content: $sex,
- onItemClick: () => {
- CommonUtils.textPickerDialog(this.sexArray, (sexValue: string) => {
- this.sex = sexValue;
- });
- }
- })
- ...
- }
- ...
- }
自定义弹窗
点击兴趣爱好选项,通过customDialogController.open方法弹出自定义弹窗,根据需要选择相应的兴趣爱好,效果如图所示:
在view目录下,点击鼠标右键 > New > ArkTS File,新建一个ArkTS文件,然后命名为CustomDialogWidget子组件。
在CustomDialogWidget的aboutToAppear方法,通过manager.getStringArrayValue方法获取本地资源数据进行初始化。
- // CustomDialogWidget.ets
- @State hobbyItems: HobbyItem[] = [];
- ...
- aboutToAppear() {
- let context: Context = getContext(this);
- if (CommonUtils.isEmpty(context) || CommonUtils.isEmpty(context.resourceManager)) {
- Logger.error(CommonConstants.TAG_CUSTOM, 'context or resourceManager is null');
- return;
- }
- let manager = context.resourceManager;
- manager.getStringArrayValue($r('app.strarray.hobbies_data').id, (error, hobbyArray) => {
- if (!CommonUtils.isEmpty(error)) {
- Logger.error(CommonConstants.TAG_CUSTOM, 'error = ' + JSON.stringify(error));
- } else {
- hobbyArray.forEach((hobby: string) => {
- let hobbyItem = new HobbyItem();
- hobbyItem.label = hobby;
- hobbyItem.isChecked = false;
- this.hobbyItems.push(hobbyItem);
- });
- }
- });
- }
当用户点击确定按钮时,通过setHobbiesValue方法处理自定义弹窗选项结果。
- // CustomDialogWidget.ets
- @State hobbyItems: HobbyItem[] = [];
- @Link hobbies: string;
- private controller?: CustomDialogController;
-
- // 处理自定义弹窗选项结果
- setHobbiesValue(hobbyItems: HobbyItem[]) {
- if (CommonUtils.isEmptyArr(hobbyItems)) {
- Logger.error(CommonConstants.TAG_HOME, 'hobbyItems length is 0');
- return;
- }
- let hobbiesText: string = '';
- hobbiesText = hobbyItems.filter((isCheckItem: HobbyItem) => isCheckItem?.isChecked)
- .map<string>((checkedItem: HobbyItem) => {
- return checkedItem.label!;
- })
- .join(CommonConstants.COMMA);
- if (hobbiesText.length > 0) {
- this.hobbies = hobbiesText;
- }
- }
-
- build() {
- Column() {
- ...
- Row() {
- Button($r('app.string.cancel_button'))
- .dialogButtonStyle()
- .onClick(() => {
- this.controller?.close();
- })
- Blank()
- ...
- Button($r('app.string.definite_button'))
- .dialogButtonStyle()
- .onClick(() => {
- this.setHobbiesValue(this.hobbyItems);
- this.controller?.close();
- })
- }
- }
- ...
- }
-
- @Extend(Button) function dialogButtonStyle() {
- ....
- }
通过@Link修饰的hobbies把值赋给HomePage的hobbies,然后hobbies刷新显示内容。
- // HomePage.ets
- @State hobbies: string = '';
- customDialogController: CustomDialogController = new CustomDialogController({
- builder: CustomDialogWidget({
- hobbies: $hobbies
- }),
- alignment: DialogAlignment.Bottom,
- customStyle: true,
- offset: {
- dx: 0,
- dy: CommonConstants.DY_OFFSET
- }
- });
-
- build() {
- Column() {
- ...
- TextCommonWidget({
- textImage: $r('app.media.ic_hobbies'),
- title: $r('app.string.title_hobbies'),
- content: $hobbies,
- onItemClick: () => {
- // 打开自定义弹窗
- this.customDialogController.open();
- }
- })
- }
- ...
- }
总结
您已经完成了本次Codelab的学习,并了解到以下知识点:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。