鸿蒙Next开发-通讯录app,数据库实现联系人列表(六)

1. 前言导读

上一集文章中,已经通过query()实现了数据库的查询,这集我们学习如何将数据用List列表显示出来

2. 官方文档指南

  1. 列表 (List) : https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/arkts-layout-development-create-list-V5

  2. ForEach(循环渲染) : https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/arkts-rendering-control-foreach-V5

3. 概述

列表是一种复杂的容器,当列表项达到一定数量,内容超过屏幕大小时,可以自动提供滚动功能。它适合用于呈现同类数据类型或数据类型集,例如图片和文本。在列表中显示数据集合是许多应用程序中的常见要求(如通讯录、音乐列表、购物清单等)。


使用列表可以轻松高效地显示结构化、可滚动的信息。通过在List组件中按垂直或者水平方向线性排列子组件ListItemGroup或ListItem,为列表中的行或列提供单个视图,或使用循环渲染迭代一组行或列,或混合任意数量的单个视图和ForEach结构,构建一个列表。List组件支持使用条件渲染、循环渲染、懒加载等渲染控制方式生成子组件。

4. 布局与约束

列表作为一种容器,会自动按其滚动方向排列子组件,向列表中添加组件或从列表中移除组件会重新排列子组件。

如下图所示,在垂直列表中,List按垂直方向自动排列ListItemGroup或ListItem。

ListItemGroup用于列表数据的分组展示,其子组件也是ListItem。ListItem表示单个列表项,可以包含单个子组件

List、ListItemGroup和ListItem组件关系
在这里插入图片描述

说明
List的子组件必须是ListItemGroup或ListItem,ListItem和ListItemGroup必须配合List来使用。

温馨提示:列表控件一般都会配合ForEach来做循环渲染

5. 代码实现

  1. 写一个查询的联系人数据的方法,取名叫queryContactsListData好啦
queryContactsListData(): Array<ContactInfo> {
    this.contactsList = []
    let predicates = new relationalStore.RdbPredicates('Contacts_Table');
    storeDb?.query(predicates, ['contacts_id', 'ct_username', 'ct_mobile', 'ct_bg_color'],
      (err: BusinessError, resultSet) => {
        if (err) {
          console.error('--------------', `Failed to query data. Code:${err.code}, message:${err.message}`);
          return;
        }


        while (resultSet.goToNextRow()) {
          const contacts_id = resultSet.getLong(resultSet.getColumnIndex('contacts_id'));
          const ct_username = resultSet.getString(resultSet.getColumnIndex('ct_username'));
          const ct_mobile = resultSet.getString(resultSet.getColumnIndex('ct_mobile'));
          const ct_bg_color = resultSet.getString(resultSet.getColumnIndex('ct_bg_color'));
           //将数据封装成一个对象
          this.contactsList.push(new ContactInfo(contacts_id, ct_username, ct_mobile, ct_bg_color))
        }

        // 释放数据集的内存
        resultSet.close()

      });
    return this.contactsList

  }

请注意:在上面查询的方法中,获取到的是表里面应的字段数据,这样的数据不方便直接渲染在UI界面上,所以我们要将字段封装成一个对象,再把这个对象放在一个集合里面,这样在UI渲染的时候,就直接使用集合里面的数据进行渲染。所以在代码中,就有this.contactsList.push(new ContactInfo(contacts_id, ct_username, ct_mobile, ct_bg_color))

  1. ContactInfo数据实体类
export class ContactInfo {
  contacts_id: number = 0
  ct_username: string = ''
  ct_mobile: string = ''
  ct_bg_color: string = ''

  constructor(contacts_id: number, ct_username: string, ct_mobile: string,ct_bg_color:string) {
    this.contacts_id = contacts_id
    this.ct_username = ct_username
    this.ct_mobile = ct_mobile
    this.ct_bg_color =ct_bg_color
  }


}
  1. 使用ForEach循环渲染
          List() {
            ForEach(this.contactsList, (item: ContactInfo, index: number) => {
              ListItem() {
                Column() {
                  Row({ space: 10 }) {
                    Text(item.ct_username.substring(0, 1))
                      .width(44)
                      .height(44)
                      .borderRadius(22)
                      .backgroundColor(item.ct_bg_color)
                      .fontColor('#ffffff')
                      .textAlign(TextAlign.Center)
                      .fontSize(20)
                      .fontWeight(600)

                    Column() {
                      Text(item.ct_username)
                      Text(item.ct_mobile).fontColor('#999999').fontSize(14).margin({ top: 6 })

                    }
                    .alignItems(HorizontalAlign.Start)

                    Blank()
                    Image($r('app.media.img_more')).width(18).fillColor('#999999')
                      .onClick(() => {
                        ActionSheet.show({
                          title: '菜单选项',
                          message: '',
                          alignment: DialogAlignment.Bottom,
                          autoCancel: false,
                          confirm: {
                            value: '放弃操作',
                            action: () => {

                            }
                          },
                          sheets: [
                            {
                              title: '编辑\n',
                              action: () => {
                                router.pushUrl({
                                  url: 'pages/EditContactsPage',
                                  params: item

                                })
                              }
                            },
                            {
                              title: '\n 删除',
                              action: () => {
                                //删除条件
                                let predicates = new relationalStore.RdbPredicates('Contacts_Table');
                                predicates.equalTo('contacts_id', item?.contacts_id); // 根据contacts_id删除
                                storeDb?.delete(predicates, (err: BusinessError, rowId: number) => {
                                  if (err) {
                                    console.error(`------------Failed to insert data. Code:${err.code}, message:${err.message}`);
                                    return
                                  }
                                  promptAction.showToast({
                                    message: '删除成功'
                                  })
                                  this.queryContactsListData()

                                })
                              }
                            }
                          ]

                        })
                      })

                  }
                  .width('100%')

                  Blank().backgroundColor('#f5f5f5').height(1).margin(10)
                }

              }

            })
          }
  1. onPageShow()方面里面实现刷新

当新建联系人成功返回,需要主动刷新页面

 onPageShow(): void {
    //当新建联系人成功返回,需要主动刷新页面
    this.resultParams = router.getParams() as ResultParams
    if (this.resultParams != null && this.resultParams.result_code == 200) {
      this.queryContactsListData()
    }
  }
  1. 在aboutToAppear()方法里面调用查询方法
 aboutToAppear(): void {
    setTimeout(() => {
      console.error('--------------', `aboutToAppear 2000 `);
      this.queryContactsListData()
    }, 800)
  }
  1. 联系人首页Index.ets 整个代码实现过程
import { promptAction, router } from '@kit.ArkUI';
import { storeDb } from '../entryability/EntryAbility';
import { BusinessError } from '@kit.BasicServicesKit';
import { relationalStore } from '@kit.ArkData';
import { ContactInfo } from '../viewmodel/ContactInfo';

interface ResultParams {
  result_code: number
}

@Entry
@Component
struct Index {
  @State contactsList: Array<ContactInfo> = []
  @State resultParams: ResultParams | null = null

  onPageShow(): void {
    //当新建联系人成功返回,需要主动刷新页面
    this.resultParams = router.getParams() as ResultParams
    if (this.resultParams != null && this.resultParams.result_code == 200) {
      this.queryContactsListData()
    }
  }

  aboutToAppear(): void {
    setTimeout(() => {
      console.error('--------------', `aboutToAppear 2000 `);
      this.queryContactsListData()
    }, 800)
  }

  queryContactsListData(): Array<ContactInfo> {
    this.contactsList = []
    let predicates = new relationalStore.RdbPredicates('Contacts_Table');
    storeDb?.query(predicates, ['contacts_id', 'ct_username', 'ct_mobile', 'ct_bg_color'],
      (err: BusinessError, resultSet) => {
        if (err) {
          console.error('--------------', `Failed to query data. Code:${err.code}, message:${err.message}`);
          return;
        }


        while (resultSet.goToNextRow()) {
          const contacts_id = resultSet.getLong(resultSet.getColumnIndex('contacts_id'));
          const ct_username = resultSet.getString(resultSet.getColumnIndex('ct_username'));
          const ct_mobile = resultSet.getString(resultSet.getColumnIndex('ct_mobile'));
          const ct_bg_color = resultSet.getString(resultSet.getColumnIndex('ct_bg_color'));
           //将数据封装成一个对象
          this.contactsList.push(new ContactInfo(contacts_id, ct_username, ct_mobile, ct_bg_color))
        }

        // 释放数据集的内存
        resultSet.close()

      });
    return this.contactsList

  }

  build() {
    Column() {
      Text('通讯录').width('100%').padding({ left: 16 }).fontSize(20).fontWeight(500)


      RelativeContainer() {
        Column() {
          List() {
            ForEach(this.contactsList, (item: ContactInfo, index: number) => {
              ListItem() {
                Column() {
                  Row({ space: 10 }) {
                    Text(item.ct_username.substring(0, 1))
                      .width(44)
                      .height(44)
                      .borderRadius(22)
                      .backgroundColor(item.ct_bg_color)
                      .fontColor('#ffffff')
                      .textAlign(TextAlign.Center)
                      .fontSize(20)
                      .fontWeight(600)

                    Column() {
                      Text(item.ct_username)
                      Text(item.ct_mobile).fontColor('#999999').fontSize(14).margin({ top: 6 })

                    }
                    .alignItems(HorizontalAlign.Start)

                    Blank()
                    Image($r('app.media.img_more')).width(18).fillColor('#999999')
                      .onClick(() => {
                        ActionSheet.show({
                          title: '菜单选项',
                          message: '',
                          alignment: DialogAlignment.Bottom,
                          autoCancel: false,
                          confirm: {
                            value: '放弃操作',
                            action: () => {

                            }
                          },
                          sheets: [
                            {
                              title: '编辑\n',
                              action: () => {
                                router.pushUrl({
                                  url: 'pages/EditContactsPage',
                                  params: item

                                })
                              }
                            },
                            {
                              title: '\n 删除',
                              action: () => {
                                //删除条件
                                let predicates = new relationalStore.RdbPredicates('Contacts_Table');
                                predicates.equalTo('contacts_id', item?.contacts_id); // 根据contacts_id删除
                                storeDb?.delete(predicates, (err: BusinessError, rowId: number) => {
                                  if (err) {
                                    console.error(`------------Failed to insert data. Code:${err.code}, message:${err.message}`);
                                    return
                                  }
                                  promptAction.showToast({
                                    message: '删除成功'
                                  })
                                  this.queryContactsListData()

                                })
                              }
                            }
                          ]

                        })
                      })

                  }
                  .width('100%')

                  Blank().backgroundColor('#f5f5f5').height(1).margin(10)
                }

              }

            })
          }

        }
        .width('100%')

        Image($r('app.media.img_create'))
          .width(58)
          .fillColor('#44bf02')
          .alignRules({
            bottom: { anchor: '__container__', align: VerticalAlign.Bottom },
            right: { anchor: '__container__', align: HorizontalAlign.End }
          })
          .margin({ right: 16, bottom: 60 })
          .onClick(() => {
            router.pushUrl({
              url: 'pages/CreateContactsPage'
            })
          })

      }
      .padding(10)
      .height('100%')
      .width('100%')

    }
    .height('100%')
    .width('100%')
  }
}

6. 运行效果图

在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

浩宇软件开发

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值