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

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

  • 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)
}
相关推荐
落落落sss16 分钟前
sharding-jdbc分库分表
android·java·开发语言·数据库·servlet·oracle
张帅涛_6662 小时前
HarmonyOS ArkUI 构建布局
华为·harmonyos
消失的旧时光-19432 小时前
kotlin的密封类
android·开发语言·kotlin
服装学院的IT男4 小时前
【Android 13源码分析】WindowContainer窗口层级-4-Layer树
android
可惜已不在4 小时前
华为 HCIP-Datacom H12-821 题库 (25)
网络·华为
CCTV果冻爽5 小时前
Android 源码集成可卸载 APP
android
码农明明5 小时前
Android源码分析:从源头分析View事件的传递
android·操作系统·源码阅读
秋月霜风6 小时前
mariadb主从配置步骤
android·adb·mariadb
Python私教7 小时前
Python ORM 框架 SQLModel 快速入门教程
android·java·python
编程乐学8 小时前
基于Android Studio 蜜雪冰城(奶茶饮品点餐)—原创
android·gitee·android studio·大作业·安卓课设·奶茶点餐