鸿蒙开发小案例(名片管理))

鸿蒙开发小案例(名片管理)

  • 1、页面效果
    • [1.1 初始页面](#1.1 初始页面)
    • [1.2 点击名片展开](#1.2 点击名片展开)
    • [1.3 点击收藏](#1.3 点击收藏)
    • [1.4 点击编辑按钮](#1.4 点击编辑按钮)
  • 2、实现代码
    • [2.1 DataModel.ets](#2.1 DataModel.ets)
    • [2.2 RandomUtil.ets](#2.2 RandomUtil.ets)
    • [2.3 ContactList.ets](#2.3 ContactList.ets)

1、页面效果


1.1 初始页面

1.2 点击名片展开

1.3 点击收藏

1.4 点击编辑按钮

2、实现代码


2.1 DataModel.ets

java 复制代码
let nextId = 1;

@Observed
export class Person {
  id: number;
  name: string;
  phone: string;
  isStar: boolean = false;

  constructor(name, phone) {
    this.id = nextId++;
    this.name = name;
    this.phone = phone;
  }
}

2.2 RandomUtil.ets

java 复制代码
const names = [
  '张伟',
  '王芳',
  '李娜',
  '刘强',
  '陈军',
  '杨洋',
  '赵丽',
  '黄勇',
  '周雪',
  '吴宇',
  '徐鹏',
  '马丽',
  '孙建',
  '朱敏',
  '郭涛',
  '曹梅',
  '田亮',
  '林静',
  '范磊'
];

//随机抽取一个姓名
export function getRandomName() {
  let randomIndex = Math.floor(Math.random() * names.length);
  return names[randomIndex];
}

//随机生成一个年龄
export function getRandomAge() {
  return 10 + Math.floor(Math.random() * 30);
}

//随机生成一个手机号码
export function getRandomPhone() {
  const prefixArray = ['130', '131', '132', '133', '134', '135', '136', '137', '138', '139'];

  let phone = prefixArray[Math.floor(Math.random() * prefixArray.length)];

  // 生成后8位随机数字
  for (let i = 0; i < 8; i++) {
    phone += Math.floor(Math.random() * 10);
  }

  return phone;
}

2.3 ContactList.ets

java 复制代码
import { getRandomName, getRandomPhone } from '../../../../utils/RandomUtil';
import { Person } from './model/DataModel';

@Entry
@Component
struct ContactsPage {
  // 初始化列表数据
  @State persons: Person[] = [new Person(getRandomName(), getRandomPhone()), new Person(getRandomName(), getRandomPhone())];
  // 点击名片展开的 id
  @State isOpenId: number = -1;
  // 是否选中
  @State isShowCheck: boolean = false;
  // 选中的名片 ID
  @State selectIdList: number[] = [];

  build() {
    Column() {
      //标题
      Row({ space: 10 }) {
        Text('联系人').titleStyle()
        Blank()
        /**
         * 通过 isShowCheck 控制 选择和取消 按钮的切换
         */
        Button(this.isShowCheck ? '取消' : '选择')
          .buttonStyle(Color.Gray)
          .onClick(() => {
            this.isShowCheck = !this.isShowCheck
          })
        Button('+')
          .buttonStyle(Color.Gray)
          /**
           * 点击新增 新增联系人
           */
          .onClick(() => {
            this.persons.push(new Person(getRandomName(), getRandomPhone()))
          })
      }
      .width('100%')
      .height(60)

      //列表
      List({ space: 10 }) {
        ForEach(this.persons, (person: Person) => {
          ListItem() {
            // 联系人组件
            ContactItem({
              person: person,
              isOpenId: $isOpenId,
              isShowCheck: this.isShowCheck,
              selectIdList: $selectIdList })
          }
        })
      }
      .width('100%')
      .layoutWeight(1)

      //按钮
      if (this.isShowCheck) {
        Button('删除')
          .buttonStyle(Color.Red)
          .margin({ top: 10 })
          .onClick(() => {
            this.persons = this.persons.filter(person => !this.selectIdList.includes(person.id));
          })
      }
    }
    .width('100%')
    .height('100%')
    .backgroundColor('#EFEFEF')
    .padding(10)
  }
}

@Component
struct ContactItem {
  @ObjectLink person: Person;  // 双向绑定父组件的 person 对象
  @State isShowPhone: boolean = false;  // 定义是否展示 phone
  @Link @Watch("numberChanger") isOpenId: number;   // 监听点击打开的名片 实现只能打开一个 再打开会关闭其他名片
  @Prop isShowCheck: boolean; // 接收父组件的值是否选中
  @Link selectIdList: number[]  // 绑定父组件的选中 ID 列表

  /**
   * 监听函数
   * 监听当前选中的名片 id 是否为点击的名片 id
   */
  numberChanger() {
      this.person.id == this.isOpenId ? this.isShowPhone = true : this.isShowPhone = false;
  }

  build() {
    Column() {
      Row({ space: 10 }) {
        if (this.isShowCheck) {
          Toggle({
            type: ToggleType.Checkbox
          })
            /**
             * 删除函数
             * 当被选中时 将名片 id 添加到 绑定父组件的selectIdList中
             * 当未选中时 移除绑定父组件的selectIdList中的 名片 id
             */
            .onChange((value) => {
              value ? this.selectIdList.push(this.person.id) : this.selectIdList.slice(this.selectIdList.indexOf(this.person.id), 1)
          })
        }
        //头像
        Image($r('app.media.img_user_avatar'))
          .width(40)
          .height(40)
        //姓名
        Text(this.person.name)
          .fontSize(20)
          .fontWeight(500)

        Blank()
        //收藏
        /**
         * 双向绑定父组件的 person 对象中的 person.isStar 判断是否收藏
         */
        Image(this.person.isStar ? $r('app.media.ic_star_filled') : $r('app.media.ic_star_empty'))
          .width(30)
          .height(30)
          .onClick(() => {
            this.person.isStar = !this.person.isStar;
          })
      }.justifyContent(FlexAlign.SpaceBetween)
      .padding(10)
      .width("100%")
      /**
       * 点击
       * 1、改变展示名片 手机号
       * 2、记录正在展示的名片 id 用于给 numberChanger() 监听函数判断是否是当前名片展开 如果是则关闭其他名片
       */
      .onClick(() => {
        this.isShowPhone = !this.isShowPhone;
        this.isOpenId = this.person.id;
      })

      if (this.isShowPhone) {
        Divider()
        Row() {
          Text(this.person.name)
            .fontSize(20)
          Text(this.person.phone)
            .fontSize(20)
            .margin({ left: 20 })
        }
        .backgroundColor(Color.White)
        .width('100%')
        .height(70)
        .padding(10)
        .borderRadius(10)
      }
    }
    .backgroundColor(Color.White)
    .padding(10)
    .borderRadius(10)
  }
}

/**
 * 一些 css 样式
 */

@Extend(Text) function titleStyle() {
  .fontSize(30)
  .fontWeight(500)
}

@Extend(Button) function buttonStyle(color: ResourceColor) {
  .height(30)
  .backgroundColor(color)
}
相关推荐
大耳猫4 小时前
主动测量View的宽高
android·ui
帅次7 小时前
Android CoordinatorLayout:打造高效交互界面的利器
android·gradle·android studio·rxjava·android jetpack·androidx·appcompat
枯骨成佛8 小时前
Android中Crash Debug技巧
android
AI+程序员在路上8 小时前
鸿蒙系统(HarmonyOS)介绍
华为·harmonyos
lqj_本人9 小时前
鸿蒙next版开发:相机开发-录像(ArkTS)
数码相机·华为·harmonyos
23zhgjx-NanKon10 小时前
华为eNSP:MSTP
华为
bingw011410 小时前
华为机试HJ42 学英语
数据结构·算法·华为
流氓也是种气质 _Cookie11 小时前
鸿蒙HarmonyOS 网络请求获取数据Http
http·鸿蒙·鸿蒙系统
Swift社区11 小时前
HarmonyOS 如何获取设备信息(系统、版本、网络连接状态)
华为·harmonyos
kim565913 小时前
android studio 更改gradle版本方法(备忘)
android·ide·gradle·android studio