《仿盒马》app开发技术分享-- 分类模块顶部导航列表(15)

举报
yd_215151764 发表于 2025/06/30 10:23:48 2025/06/30
【摘要】 ## 技术栈Appgallery connect## 开发准备上一节我们实现了购物车商品列表的大部分功能,实现了商品的添加、删除、增减、价格计算等业务,并且都跟云端进行通信。现在我们继续对项目进行改造,这一节我们要改造的内容是分类页,这个页面我们在之前的非端云一体化项目中实现过。现在要改造成端云一体的模式,并且我们的金刚区也要实现分类页的点击联动## 功能分析1.分类列表分类列表我们要注意首...


## 技术栈

Appgallery connect
## 开发准备

上一节我们实现了购物车商品列表的大部分功能,实现了商品的添加、删除、增减、价格计算等业务,并且都跟云端进行通信。现在我们继续对项目进行改造,这一节我们要改造的内容是分类页,这个页面我们在之前的非端云一体化项目中实现过。现在要改造成端云一体的模式,并且我们的金刚区也要实现分类页的点击联动

## 功能分析

1.分类列表
分类列表我们要注意首页跳入切换到对应item的情况,点击时item对应的字体、背景色等状态的变化,以及list的切换


## 代码实现
首先我们要对金刚区的数据进行一个改造

{
  "objectTypeName": "split_layout",
  "fields": [
    {"fieldName": "split_id", "fieldType": "Integer", "notNull": true, "belongPrimaryKey": true},
    {"fieldName": "txt", "fieldType": "String"},
    {"fieldName": "url", "fieldType": "String"},
    {"fieldName": "router", "fieldType": "String"},
    {"fieldName": "is_login", "fieldType": "Boolean"},
    {"fieldName": "child_id", "fieldType": "Integer"},
    {"fieldName": "bt_state", "fieldType": "Integer"}
  ],
  "indexes": [
    {"indexName": "splitId_Index", "indexList": [{"fieldName":"split_id","sortType":"ASC"}]}
  ],
  "permissions": [
    {"role": "World", "rights": ["Read"]},
    {"role": "Authenticated", "rights": ["Read", "Upsert"]},
    {"role": "Creator", "rights": ["Read", "Upsert", "Delete"]},
    {"role": "Administrator", "rights": ["Read", "Upsert", "Delete"]}
  ]
}
我们加上了child_id,有了这个参数能更好的去查询对应的数据

实体类

export class SplitLayoutModel {
    split_id: number;
    txt: string;
    url: string;
    router: string;
    is_login: boolean;
    child_id: number;
    bt_state: number;

    constructor() {
    }

    getFieldTypeMap():  Map<string, string> {
        let fieldTypeMap = new Map<string, string>();
        fieldTypeMap.set('split_id', 'Integer');
        fieldTypeMap.set('txt', 'String');
        fieldTypeMap.set('url', 'String');
        fieldTypeMap.set('router', 'String');
        fieldTypeMap.set('is_login', 'Boolean');
        fieldTypeMap.set('child_id', 'Integer');
        fieldTypeMap.set('bt_state', 'Integer');
        return fieldTypeMap;
    }

    getClassName(): string {
        return 'split_layout';
    }

    getPrimaryKeyList(): string[] {
        let primaryKeyList: string[] = [];
        primaryKeyList.push('split_id');
        return primaryKeyList;
    }

    getIndexList(): string[] {
        let indexList: string[] = [];
        indexList.push('split_id');
        return indexList;
    }

    getEncryptedFieldList(): string[] {
        let encryptedFieldList: string[] = [];
        return encryptedFieldList;
    }

    setSplit_id(split_id: number): void {
        this.split_id = split_id;
    }

    getSplit_id(): number  {
        return this.split_id;
    }

    setTxt(txt: string): void {
        this.txt = txt;
    }

    getTxt(): string  {
        return this.txt;
    }

    setUrl(url: string): void {
        this.url = url;
    }

    getUrl(): string  {
        return this.url;
    }

    setRouter(router: string): void {
        this.router = router;
    }

    getRouter(): string  {
        return this.router;
    }

    setIs_login(is_login: boolean): void {
        this.is_login = is_login;
    }

    getIs_login(): boolean  {
        return this.is_login;
    }

    setChild_id(child_id: number): void {
        this.child_id = child_id;
    }

    getChild_id(): number  {
        return this.child_id;
    }

    setBt_state(bt_state: number): void {
        this.bt_state = bt_state;
    }

    getBt_state(): number  {
        return this.bt_state;
    }

    static parseFrom(inputObject: any): SplitLayoutModel {
        let result = new SplitLayoutModel();
        if (!inputObject) {
            return result;
        }
        if (inputObject.split_id) {
            result.split_id = inputObject.split_id;
        }
        if (inputObject.txt) {
            result.txt = inputObject.txt;
        }
        if (inputObject.url) {
            result.url = inputObject.url;
        }
        if (inputObject.router) {
            result.router = inputObject.router;
        }
        if (inputObject.is_login) {
            result.is_login = inputObject.is_login;
        }
        if (inputObject.child_id) {
            result.child_id = inputObject.child_id;
        }
        if (inputObject.bt_state) {
            result.bt_state = inputObject.bt_state;
        }
        return result;
    }
}

然后我们在金刚区的点击事件里传递当前点击的下标
先定义
 @State pos_check:number=0
 我们在金刚区组件内定义一个带参数的回调
   private  onItemClick?: (pos:number) => void
调用
 .onClick(()=>{
                this.onItemClick!(index)
              })

在index页面拿到下标后控制tabs切换到分类,并且传入下标
 SplitLayout({listData:this.splitList,onItemClick:(pos)=>{
                      this.controller.changeIndex(1);
                      this.pos_check=pos
                    }})
分类页顶部导航列表自定义组件
import { CustomImageGridDialog } from "../dialog/CustomImageGridDialog";
import { cloudDatabase } from "@kit.CloudFoundationKit";
import { split_layout } from "../clouddb/split_layout";
import { SplitLayoutModel } from "../entity/SplitLayoutModel";
import { hilog } from "@kit.PerformanceAnalysisKit";


@Preview
@Component
export struct Classification {
  private listScroller: Scroller = new Scroller();
  @Link selectedIndex: number
  @State list: SplitLayoutModel[] = []
  @State flag:boolean=false
  private  onItemClick?: (child_id:number) => void

  async aboutToAppear(): Promise<void> {
    let databaseZone = cloudDatabase.zone('default');
    let condition = new cloudDatabase.DatabaseQuery(split_layout);
    let listData = await databaseZone.query(condition);
    let json = JSON.stringify(listData)
    let data2:SplitLayoutModel[]= JSON.parse(json)
    this.list=data2
    hilog.error(0x0000, 'testTag', `Failed to query data, code: ${this.list}`);
    this.flag=true
  }

  private dialogController: CustomDialogController = new CustomDialogController({
    builder: CustomImageGridDialog({
      select:this.selectedIndex,
      dataSource: this.list,
      onItemSelected: (item: number) => {
        this.listScroller.scrollToIndex(item, true, ScrollAlign.CENTER)
      }
    }),
    alignment: DialogAlignment.Top,
    customStyle:true
  });

  build() {
    Row() {
      List({scroller:this.listScroller,space:10}){
        ForEach(this.list, (item:SplitLayoutModel,index:number) => {
          ListItem(){
            Column(){
              Image(item.url)
                .width(40)
                .height(40)
                .borderRadius(20)
                .border({width:this.selectedIndex === index?2:0,color:"#409EFF"})
              Text(item.txt)
                .textAlign(TextAlign.Center)
                .fontColor(Color.Black)
                .fontSize(10)
                .padding(2)
                .margin({top:5})
                .fontColor(this.selectedIndex === index?"#FFFFFF":"#000000")
                .backgroundColor(this.selectedIndex === index ? '#409EFF' : '#FFFFFF')
                .borderRadius(this.selectedIndex === index ? 15:0)
            }
            .onClick(()=>{
              if (this.selectedIndex === index) {
                this.selectedIndex = 0
              } else {
                this.selectedIndex = index
              }

         
              this.listScroller.scrollToIndex(index, true, ScrollAlign.CENTER)
            })


          }

        })
      }
      .scrollBar(BarState.Off)
      .height(65)
      .width('90%')
      .listDirection(Axis.Horizontal)

      Blank()

      Column(){
        Text("全")
          .fontSize(14)
          .fontColor(Color.Black)
        Text("部")
          .fontColor(Color.Black)
          .fontSize(14)
        Image($r('app.media.all'))
            .height(20)
            .width(20)
      }
      .onClick(()=>{
        this.dialogController.open()
      })
      .padding(5)
    }
    .justifyContent(FlexAlign.SpaceBetween)
    .height(90)
    .width('100%')
    .margin({top:20})
  }

}
index页面引用
Classification({selectedIndex:this.pos_check})

到这里我们的就全部实现了

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。