任务一:项目初始化与UI设计

  • 使用DevEco Studio创建一个新的鸿蒙应用项目,选择 Empty Abi1ity 模板。
  • pages/Index.ets 文件中,设计并实现App的主界面。
  • 界面布局应包含:
    1. 一个顶部导航栏,标题为“学生信息管理”。
    2. 一个表单区域,包含输入框(学号、姓名、年龄、班级)和提交/重置按钮。学号在新增时应
      禁用或隐藏,修改时应禁用。
    3. 一个分割线或间距。
    4. 一个学生信息列表区域,使用 List 组件展示学生列表,每项包含学号、姓名、年龄、班级
      并有“编辑”和“删除”按钮。
  • 确保UI美观、布局合理、交互流畅。

任务二:数据模型定义

  • src/main/ets 目录下创建 mode1 文件夹
  • mode1文件夹中创建 student.ets 文件。
  • 定义一个名为Student的类或接口,包含一下属性:

id:number(主键,自增)
name:string(姓名)
oage:number(年龄)
oclass:string(班级)

任务三:内置数据库实现

  • src/main/ets 目录下创建 database 文件夹。
  • database 文件夹中创建 studentDatabase.ets 文件。

任务四: 代码实现过程

  1. 新建数据模型Student.ets
export  interface Student {
  id: number;
  name: string;
  age: number;
  class: string;
}
  1. 新建学生数据库类StudentDatabase.ets
import { relationalStore } from "@kit.ArkData";
import { Student } from "../model/Student";

/**
 * 学生数据库类
 */
export class StudentDatabase {
  private store: relationalStore.RdbStore | null = null;
  private context: Context;

  constructor(context: Context) {
    this.context = context;
  }

  /**
   * 初始化数据库
   */
  public async initialize(): Promise<void> {
    const config: relationalStore.StoreConfig = {
      name: 'StudentDB.db',
      securityLevel: relationalStore.SecurityLevel.S1
    };
    try {
      this.store = await relationalStore.getRdbStore(this.context, config);
      await this.createTables();
      console.log('------------ database initialized successfully');
    } catch (err) {
      console.error('Failed to initialize database:', err);
    }
  }

  /**
   * 创建学生表
   */

  private async createTables(): Promise<void> {
    if (!this.store) {
      return;
    }

    // 学生表
    const userTable = `CREATE TABLE IF NOT EXISTS student (
      id INTEGER PRIMARY KEY AUTOINCREMENT,
      name TEXT NOT NULL,
      age INTEGER NOT NULL,
      class TEXT NOT NULL
    )`;

    console.log('------------', 'create table success')

    try {
      await this.store.executeSql(userTable);
    } catch (err) {
      console.error('Failed to create tables:', err);
    }
  }

  /**
   * 添加学生
   * @param student
   * @returns
   */
  public async addStudent(student: Student): Promise<boolean> {
    if (!this.store) {
      return false;
    }

    const insertQuery = `INSERT INTO student (name, age, class) VALUES (?, ?, ?)`;
    try {
      await this.store.executeSql(insertQuery, [student.name, student.age, student.class]);
      return true;
    } catch (err) {
      console.error('Failed to add student:', err);
      return false;
    }
  }

  /**
   * 获取所有学生
   */
  public async getStudents(): Promise<Student[]> {
    if (!this.store) {
      console.log('------------', 'store is null');
      return [];
    }
    try {
      const sql = `SELECT * FROM student`;
      const resultSet = await this.store.querySql(sql);
      const students: Student[] = [];
      while (resultSet.goToNextRow()) {
        const student: Student = {
          id: resultSet.getLong(resultSet.getColumnIndex('id')),
          name: resultSet.getString(resultSet.getColumnIndex('name')),
          age: resultSet.getLong(resultSet.getColumnIndex('age')),
          class: resultSet.getString(resultSet.getColumnIndex('class')),
        }
        students.push(student);
      }
      return students;
    } catch (err) {
      console.error('------------', err);
    }

    return [];
  }

  /**
   * 修改学生信息
   */

  public async updateStudent(student: Student): Promise<boolean> {
    if (!this.store) {
      return false;
    }

    const updateQuery = `UPDATE student SET name = ?, age = ?, class = ? WHERE id = ?`;
    try {
      await this.store.executeSql(updateQuery, [student.name, student.age, student.class, student.id]);
      return true;
    } catch (err) {
      console.error('Failed to update student:', err);
      return false;
    }
  }

  /**
   * 删除学生
   */
  public async deleteStudent(id: number): Promise<boolean> {
    if (!this.store) {
      return false;
    }
    const deleteQuery = `DELETE FROM student WHERE id = ?`;
    try {
      await this.store.executeSql(deleteQuery, [id]);
      return true;
    } catch (err) {
      console.error('Failed to delete student:', err);
      return false;
    }
  }
}
  1. Index.ets页面的生命周期函数aboutToAppear中初始化数据库
  async aboutToAppear() {
    const context = getContext(this) as common.UIAbilityContext;
    this.studentDatabase = new StudentDatabase(context);
    //初始化数据库
    await this.studentDatabase.initialize();
    //加载学生数据
    await this.loadStudents();
  }
  1. 使用List组件来渲染学生列表信息
List() {
                ForEach(this.students, (student: Student) => {
                  ListItem() {
                    Column({ space: 12 }) {
                      // 第一行:学号和姓名
                      Row() {
                        Column() {
                          Text('学号:')
                            .fontSize(14)
                            .fontColor('#999999')
                            .alignSelf(ItemAlign.Start)
                          Text(`2023000${student.id}`)
                            .fontSize(14)
                            .fontColor('#333333')
                            .alignSelf(ItemAlign.Start)
                            .margin({ top: 2 })
                        }
                        .alignItems(HorizontalAlign.Start)
                        .layoutWeight(1)

                        Column() {
                          Text('姓名:')
                            .fontSize(14)
                            .fontColor('#999999')
                            .alignSelf(ItemAlign.Start)
                          Text(student.name)
                            .fontSize(14)
                            .fontColor('#333333')
                            .alignSelf(ItemAlign.Start)
                            .margin({ top: 2 })
                        }
                        .alignItems(HorizontalAlign.Start)
                        .layoutWeight(1)

                        // 按钮组
                        Row({ space: 8 }) {
                          Button('编辑')
                            .type(ButtonType.Normal)
                            .backgroundColor('#007AFF')
                            .fontColor(Color.White)
                            .fontSize(12)
                            .borderRadius(4)
                            .padding({
                              left: 12,
                              right: 12,
                              top: 6,
                              bottom: 6
                            })
                            .onClick(() => {
                              this.editStudent(student);
                            })

                          Button('删除')
                            .type(ButtonType.Normal)
                            .backgroundColor('#FF3B30')
                            .fontColor(Color.White)
                            .fontSize(12)
                            .borderRadius(4)
                            .padding({
                              left: 12,
                              right: 12,
                              top: 6,
                              bottom: 6
                            })
                            .onClick(() => {
                              this.deleteStudent(student.id);
                            })
                        }
                        .alignItems(VerticalAlign.Top)
                        .margin({ right: 16 })
                        .layoutWeight(1)
                      }
                      .width('100%')
                      .alignItems(VerticalAlign.Top)

                      // 第二行:年龄和班级
                      Row() {
                        Column() {
                          Text('年龄:')
                            .fontSize(14)
                            .fontColor('#999999')
                            .alignSelf(ItemAlign.Start)
                          Text(student.age.toString())
                            .fontSize(14)
                            .fontColor('#333333')
                            .alignSelf(ItemAlign.Start)
                            .margin({ top: 2 })
                        }
                        .alignItems(HorizontalAlign.Start)
                        .layoutWeight(1)

                        Column() {
                          Text('班级:')
                            .fontSize(14)
                            .fontColor('#999999')
                            .alignSelf(ItemAlign.Start)
                          Text(student.class)
                            .fontSize(14)
                            .fontColor('#333333')
                            .alignSelf(ItemAlign.Start)
                            .margin({ top: 2 })
                        }
                        .alignItems(HorizontalAlign.Start)
                        .layoutWeight(1)

                        // 占位空间,保持与第一行对齐
                        Row()
                          .layoutWeight(1)
                          .margin({ left: 16 })
                      }
                      .width('100%')
                      .alignItems(VerticalAlign.Top)
                    }
                    .width('100%')
                    .padding({
                      left: 16,
                      right: 16,
                      top: 16,
                      bottom: 16
                    })
                    .backgroundColor(Color.White)
                    .borderRadius(8)
                    .margin({ bottom: 12 })
                    .shadow({
                      radius: 2,
                      color: '#1A000000',
                      offsetX: 0,
                      offsetY: 1
                    })
                  }
                })
              }

运行效果图

在这里插入图片描述

关于作者其它项目视频教程介绍

本人在b站录制的一些视频教程项目,免费供大家学习

  1. Android新闻资讯app实战:https://www.bilibili.com/video/BV1CA1vYoEad/?vd_source=984bb03f768809c7d33f20179343d8c8
  2. Androidstudio开发购物商城实战:https://www.bilibili.com/video/BV1PjHfeXE8U/?vd_source=984bb03f768809c7d33f20179343d8c8
  3. Android开发备忘录记事本实战:https://www.bilibili.com/video/BV1FJ4m1u76G?vd_source=984bb03f768809c7d33f20179343d8c8&spm_id_from=333.788.videopod.sections
  4. Androidstudio底部导航栏实现:https://www.bilibili.com/video/BV1XB4y1d7et/?spm_id_from=333.337.search-card.all.click&vd_source=984bb03f768809c7d33f20179343d8c8
  5. Android使用TabLayout+ViewPager2实现左右滑动切换:https://www.bilibili.com/video/BV1Mz4y1c7eX/?spm_id_from=333.337.search-card.all.click&vd_source=984bb03f768809c7d33f20179343d8c8
Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐