首页 > 其他分享 >小案例---商城列表案例

小案例---商城列表案例

时间:2024-07-01 14:30:03浏览次数:3  
标签:10 item media app 列表 --- 案例 华为 Text

一、项目描述

本案例包含标题栏,返回键,刷新键,商品卡片等元素构成。

该案例主要为了查看商品图片、商品名称、商品价格。可以支持滑动。

该案例效果图如上图所示。

二、项目准备

2.1初始代码

去除无效代码保存以下代码:

@Entry
@Component
struct Text001 {
  build() {
    Column(){
     
    }.width("100%").height("100%")
    .backgroundColor(0xDCDCDC)
  }
}

2.2导入图片

将实现准备好的图片导入entry/src/main/resources/base/media目录下。

如下图所示 ,将需要的图片均已导入目录中。

三、页面绘制

利用线性布局中的Row和Column容器组件进行页面绘制。

由分析可知,本案例可以通过Image、Text组件构建了商品栏。通过ForEach循环可将一个商品栏渲染成商品列表。为商品列表加入List即可实现滑动效果。

3.1 标题栏的绘制

由分析可知标题栏主要由返回按钮、标题名称、留白、刷新按钮四部分组成。

四个元素之间采用Row容器布局,具体代码如下。

Row(){
  Image($r('app.media.back'))
  Text("华为商城")
  Blank()
  Image($r('app.media.refresh'))
}

上述代码并不能实现图示效果,还需对其美化,具体代码如下:

Row(){
  Image($r('app.media.back'))
    .width(30)
    .height(30)
  Text("华为商城")
    .fontSize(30)
  Blank()
  Image($r('app.media.refresh'))
    .height(30)
    .width(30)
}.width("98%").alignItems(VerticalAlign.Top).margin(10)

至此,标题栏绘制完毕。

3.2商品栏的绘制

由分析可知,商品栏采用了Row和Column两种布局容器,两个文本之间用Column容器包裹,图片与文本之间用Row容器包裹。

代码如下:

Row(){
  Image($r('app.media.huaweimatebookxpro'))
  Column(){
    Text("华为Matebook X Pro")
    Text("¥ 14999")
  }
}

此时布局效果还不能显现,还需对其加入属性进行美化,代码如下:

Row(){
  Image($r('app.media.huaweimatebookxpro'))
    .width(100)
    .height(100)
    .padding({left:10,top:10})
  Column(){
    Text("华为Matebook X Pro")
      .fontSize(20)
    Text("¥ 14999")
      .fontSize(20)
      .fontColor(Color.Red)
  }.margin({left:10,top:20}).alignItems(HorizontalAlign.Start)
}.width("96%").height("15%").alignItems(VerticalAlign.Top).borderRadius(10)

.backgroundColor(Color.White)
.margin(5)

至此,商品栏的效果就实现了。

四、循环渲染

并定义item类,建立数组items用于储存商品名称、商品图片、商品价格等信息。利用ForEach对商品栏进行循环渲染,使其成为商品列表。

4.1定义变量

在全局建立item类,在item类中建立变量name、image、price,分别用于储存商品名称,商品图片,商品价格。并实例化这些变量。代码如下:

class item{
  name:string
  image:ResourceStr
  price:number

  constructor(name:string,image:ResourceStr,price:number){
    this.name=name
    this.image=image
    this.price=price
  }
}

4.2建立数组

在Text001内建立items数组,用于存放商品名称、商品图片、商品价钱。

代码如下:

private items:Array<item>=[
  new item("华为nova12",$r("app.media.huaweinova12"),4399),
  new item("华为Mate60",$r("app.media.huaweimate60"),5499),
  new item("华为Matebookxpro",$r("app.media.huaweimatebookxpro"),14999),
  new item("华为Matebook14",$r("app.media.huaweimatebook14"),8499),
  new item("华为Matebookxpro",$r("app.media.huaweimatebookxpro"),14999),
  new item("华为Mate60",$r("app.media.huaweimate60"),5499),
  new item("华为Matex5",$r("app.media.huaweimatex5"),14399),
  new item("华为freebuds4e",$r("app.media.huaweifreebuds4e"),399),
  new item("华为Matebook14",$r("app.media.huaweimatebook14"),8499)
]

4.3渲染商品

利用ForEach循环,将商品栏作为循环体放入其中,并将image变量传给Image组件,name、price变量同理传给两个Text组件。

代码如下:

ForEach(
  this.items,
  (item:item)=>{
    Row(){
      Image(item.image)
        .width(100)
        .height(100)
        .padding({left:10,top:10})
      Column(){
        Text(item.name)
          .fontSize(20)
        Text("¥

"+item.price)
          .fontSize(20)
          .fontColor(Color.Red)
      }.margin({left:10,top:20}).alignItems(HorizontalAlign.Start)
    }.width("96%").height("15%").alignItems(VerticalAlign.Top).borderRadius(10)
    .backgroundColor(Color.White)
    .margin(5)
  }
)

效果图如下:

通过使用ForEach,首先拿到items数组,并指定数组类型为Item类型。并将商品栏写入循环体中。

从而依次渲染了华为Nova12、华为Mate60…等商品。

效果图如下图:

4.4实现滑动

通过加入List组件和List的子组件ListItem来实现滑动效果。并为其设置权重layoutweight来实现滑动触底。

代码如下:

List(){
  ForEach(
    this.items,
    (item:item)=>{
      ListItem(){
        Row(){
          Image(item.image)
            .width(100)
            .height(100)
            .padding({left:10,top:10})
          Column(){
            Text(item.name)
              .fontSize(20)
            Text("¥ "+item.price)
              .fontSize(20)
              .fontColor(Color.Red)
          }.margin({left:10,top:20}).alignItems(HorizontalAlign.Start)
        }.width("96%").height("15%").alignItems(VerticalAlign.Top).borderRadius(10)
        .backgroundColor(Color.White)
        .margin(5)
      }
    }
  )
} .layoutWeight(1)

五、封装

对上述代码分析可知,虽然实现了基本功能,但代码的结构并不清晰,所以需要对代码进行封装处理。

5.1封装标题组件

建立subassembly包用来存放自定义组件。并建立Header标题组件。

在Header文件中,创建自定义组件Header用于封装标题组件并对其进行导出处理。代码如下:

@Component
export struct Header {
  title: string

  build() {
    Row() {
      Image($r('app.media.back'))
        .width(30)
        .height(30)
      Text(this.title)
        .fontSize(30)
      Blank()
      Image($r('app.media.refresh'))
        .height(30)
        .width(30)
    }.width("98%").alignItems(VerticalAlign.Top).margin(10)
  }
}

删除pages包下的标题组件部分,调用自定义组件Header,并为其title变量传值。代码如下:

build() {
  Column(){
    Header({title:"华为商城"})

List(){…}.layoutweight(1)

  }.width("100%").height("100%")
  .backgroundColor(0xDCDCDC)
}

5.2构建自定义函数

由于618马上来了,现在开始华为商城平台准备对个别商品进行打折促销,为此新增变量subsidy记录折扣价格。并构建自定义函数用于封装打折和不打折两种状态的卡片。具体代码如下:

5.2.1新增折扣变量

新增折扣价格变量subsidy,用于记录折扣价,subsidy为可选可不选参数,代码如下:

class item {
  name: string
  image: ResourceStr
  price: number
  subsidy: number

  constructor(name: string, image: ResourceStr, price: number, subsidy?: number) {
    this.name = name
    this.image = image
    this.price = price
    this.subsidy = subsidy
  }
}

由于618的到来部分商品打折,所以商品数组变化如下:

private items: Array<item> = [
  new item("华为nova12", $r("app.media.huaweinova12"), 4399,200),
  new item("华为Mate60", $r("app.media.huaweimate60"), 5499),
  new item("华为Matebookxpro", $r("app.media.huaweimatebookxpro"), 14999,500),
  new item("华为Matebook14", $r("app.media.huaweimatebook14"), 8499),
  new item("华为Matebookxpro", $r("app.media.huaweimatebookxpro"), 14999),
  new item("华为Mate60", $r("app.media.huaweimate60"), 5499,100),
  new item("华为Matex5", $r("app.media.huaweimatex5"), 14399),
  new item("华为freebuds4e", $r("app.media.huaweifreebuds4e"), 399,50),
  new item("华为Matebook14", $r("app.media.huaweimatebook14"), 8499)
]

5.2.2封装商品栏

由于618的到来,部分商品会进行打折处理,所以分别对是否打折两种卡片利用自定义构建函数进行封装。

创建自定义属性方法用于封装组件样式

1.商品名称自定义样式:

@Extend(Text) function fancy () {
  .fontWeight(FontWeight.Bold)
  .fontSize(20)
}

2.商品栏属性样式:

@Styles function globalFancy() {
  .backgroundColor(Color.White).width("95%").padding(10).margin({left:10}).borderRadius(20).height(120)
}

3.纵向主容器属性样式

@Styles function globalFancy2() {
  .backgroundColor("#ffeff2f6").width("100%").height("100%").padding(10)
}

对有折扣的商品进行封装:

@Builder ModuleCard1(item:item){
  Row() {
    Image(item.image)
      .width(100)
      .height(100)
      .padding({ left: 10, top: 10 })
    Column() {
      Text(item.name)
        .fancy()
      Text("原价:¥ " + item.price)
        .fontColor(Color.Grey)
        .decoration({type:TextDecorationType.LineThrough})
      Text("折扣价:¥" + (item.price - item.subsidy))
        .fontColor(Color.Red)
      Text("补贴:¥" + item.subsidy)
        .fontColor(Color.Red)
    }.margin({ left: 10, top: 20 }).alignItems(HorizontalAlign.Start)
  }.globalFancy()
}

对未打折的商品进行封装:

@Builder ModuleCard2(item:item){
  Row() {
    Image(item.image)
      .width(100)
      .height(100)
      .padding({ left: 10, top: 10 })
    Column() {
      Text(item.name)
        .fancy()
      Text("¥ " + item.price)
        .fontSize(20)
        .fontColor(Color.Red)
    }.margin({ left: 10, top: 20 }).alignItems(HorizontalAlign.Start)
  }.globalFancy()
}

六、调用

上述,已经将常用到的组件和方法进行了封装处理,这里要对其进行调用。

通过if..else..语句判断是否折扣,并调用封装好的组件,完成页面绘制。

代码如下:

build() {
  Column() {

    Header({title:"华为商城"})

    List({space:12}) {
      ForEach(
        this.items,
        (item: item) => {
          ListItem() {
            if (item.subsidy!=null) {
              this.ModuleCard1(item)
            }else {
              this.ModuleCard2(item)
            }
          }
        }
      )
    }.layoutWeight(1)
  }.globalFancy2()
}

七、源码

//Header

//自定义标题组件
@Component
export struct Header {
  title: string

  build() {
    Row() {
      Image($r('app.media.back'))//返回按钮图片
        .width(30)
        .height(30)//宽高
      Text(this.title)//标题提示文本
        .fontSize(30)
      Blank()//留白
      Image($r('app.media.refresh'))//刷新图片
        .height(30)
        .width(30)
    }.width("98%").alignItems(VerticalAlign.Top).margin(10)//布局属性
  }
}

//Text001

import { Header } from '../subassembly/Header'

//定义类,存放变量
class item {
  name: string
  image: ResourceStr
  price: number
  subsidy:number


  constructor(name: string, image: ResourceStr, price: number,subsidy?:number) {
    this.name = name
    this.image = image
    this.price = price
    this.subsidy=subsidy
  }
}

//自定义属性方法
//文字属性
@Extend(Text) function fancy () {
  .fontWeight(FontWeight.Bold)
  .fontSize(20)
}
//商品栏属性
@Styles function globalFancy() {
  .backgroundColor(Color.White).width("95%").padding(10).margin({left:10}).borderRadius(20).height(120)
}
//容器属性
@Styles function globalFancy2() {
  .backgroundColor("#ffeff2f6").width("100%").height("100%").padding(10)
}


@Entry
@Component
struct Text001 {
  //自定义构造函数打折商品栏
  @Builder ModuleCard1(item:item){
    Row() {
      Image(item.image)
        .width(100)
        .height(100)
        .padding({ left: 10, top: 10 })
      Column() {
        Text(item.name)
          .fancy()
        Text("原价:¥ " + item.price)
          .fontColor(Color.Grey)
          .decoration({type:TextDecorationType.LineThrough})
        Text("折扣价:¥" + (item.price - item.subsidy))
          .fontColor(Color.Red)
        Text("补贴:¥" + item.subsidy)
          .fontColor(Color.Red)
      }.margin({ left: 10, top: 20 }).alignItems(HorizontalAlign.Start)
    }.globalFancy()
  }

//自定义构建函数未打折商品栏
  @Builder ModuleCard2(item:item){
    Row() {
      Image(item.image)
        .width(100)
        .height(100)
        .padding({ left: 10, top: 10 })
      Column() {
        Text(item.name)
          .fancy()
        Text("¥ " + item.price)
          .fontSize(20)
          .fontColor(Color.Red)
      }.margin({ left: 10, top: 20 }).alignItems(HorizontalAlign.Start)
    }.globalFancy()
  }

//商品数组
  private items: Array<item> = [
    new item("华为nova12", $r("app.media.huaweinova12"), 4399,200),
    new item("华为Mate60", $r("app.media.huaweimate60"), 5499),
    new item("华为Matebookxpro", $r("app.media.huaweimatebookxpro"), 14999,500),
    new item("华为Matebook14", $r("app.media.huaweimatebook14"), 8499),
    new item("华为Matebookxpro", $r("app.media.huaweimatebookxpro"), 14999),
    new item("华为Mate60", $r("app.media.huaweimate60"), 5499,100),
    new item("华为Matex5", $r("app.media.huaweimatex5"), 14399),
    new item("华为freebuds4e", $r("app.media.huaweifreebuds4e"), 399,50),
    new item("华为Matebook14", $r("app.media.huaweimatebook14"), 8499)
  ]

  //布局
  build() {
    Column() {

      Header({title:"华为商城"})

      //列表,条件判断、循环渲染
      List({space:12}) {
        ForEach(
          this.items,
          (item: item) => {
            ListItem() {
              if (item.subsidy!=null) {
                this.ModuleCard1(item)
              }else {
                this.ModuleCard2(item)
              }
            }
          }
        )
      }.layoutWeight(1)
    }.globalFancy2()
  }
}

至此,封装完成,效果实现,任务完成。耶✌!!!

标签:10,item,media,app,列表,---,案例,华为,Text
From: https://blog.csdn.net/2402_84136989/article/details/139669312

相关文章

  • PagePlug企业版案例(二)—表单生成Excel文件并发送至邮箱中
    一、背景PagePlug是appsmith中国化项目,一款面向研发开发使用、开源的、前后端一体的低代码工具,拥有强大的可视化建模、数据库和API集成能力,目前已有将近超千家企业将PagePlug低代码开发工具融入内部研发体系,相较于传统的产研开发,使用PagePlug可大幅提升研发效率,节省项目迭代维......
  • 高级java每日一道面试题-2024年7月1日
    题目:请解释Java中的内存泄漏,并说明如何检测和避免内存泄漏。答案:内存泄漏指的是程序中不再使用的对象,由于某些原因没有被垃圾回收器回收,仍然占据着内存空间,导致可用内存逐渐减少,最终可能会导致程序性能下降甚至崩溃。常见的导致内存泄漏的原因包括:长生命周期的对象持......
  • 007-GeoGebra基础篇-构建等边三角形
    今天继续来一篇尺规作图,可以跟着操作一波,刚开始我写的比较细一点,每步都有截图,后续内容逐渐复杂后我就只放置算式咯。目录一、先看看一下最终效果二、本次涉及的内容三、开始尺规画图1.绘制定点A和B2.绘制线段AB3.以点A为圆心经过点B的圆4.以点B为圆心经过点A的圆5.......
  • 大模型在医疗行业中的应用及案例分享
    大模型在医疗行业中的应用正在逐步深入,其强大的数据处理能力和深度学习能力为医疗领域带来了革命性的变化。以下是关于​​​​​​​大模型在医疗行业中应用的详细介绍:一、疾病诊断和预测精准诊断:大模型通过分析大量的医疗数据,如病人的病例、病理图像和基因组数据,能够辅助医......
  • 游戏AI的创造思路-技术基础-关于艾宾浩斯遗忘曲线的迷思
    对于艾宾浩斯遗忘曲线和函数,我一直都有小小的迷思,总想实验下用艾宾浩斯函数来替换sigmoid函数作为激活函数,打造更接近人类的AI算法,这篇文章旨在讨论下目录3.10.艾宾浩斯曲线3.10.1.定义3.10.1.1.曲线计算公式3.10.1.2.曲线计算的python实现3.10.2.历史发展3.10.3......
  • 若依RuoYi-Vue分离版—PageHelper分页的坑
    若依RuoYi-Vue分离版—PageHelper分页的坑(一)读取分页属性(pageNum、pageSize)只支持Parameter对象(二)PageHelper分页本身的使用方式的坑(一)读取分页属性(pageNum、pageSize)只支持Parameter对象若依中的PageHelper的分页读取只支持get请求的Parameter对象例如:http://local......
  • 前后端分离项目实现CI-CD
    Ruoyi-VueCI/CD主机IP说明K8sMaster节点*310.0.0.103-105(VIP10.0.0.236)管理nodeK8snode节点*310.0.0.106-108部署前端+后端storage10.0.0.144MySQL、Redis、NFSJenkins(master01)10.0.0.103持续集成/持续交付的软件Gitlab(master02)10.0.0.104代......
  • 前后端分离项目案例
    docker部署ruoyi介绍:基于SpringBoot、SpringSecurity、Jwt、Vue的前后端分离的后台管理系统前端:Vue后端:JavaSpringBoot(jar包)项目代码地址:https://gitee.com/y_project/RuoYi-Vue部署项目:Ruo-Yi环境说明(需要提前安装docker)主机IP说明frontend0110.0.0.140前端......
  • 【AI绘画SD】ComfyUI-神级插件-一键高清放大,不改变原图,只做高清处理!
    哈喽大家好,我是设计师阿威以前介绍的一些AI绘画放大插件都是相当于等比例重绘,这就导致了有些细节部分可能会改变,今天给大家分享一个ComfyUI的插件—ComfyUI-SUPIR,可以不改变原图,只做高清处理。下图是作者的案例效果1、下载插件在Github下载插件:https://github.com/kijai......
  • stm32学习笔记---DMA直接存储器存取(代码部分)DMA数据转运/DMA+AD多通道
    目录第一个代码:DMA数据转运扩展知识DMA的配置步骤DMA的库函数DMA_DeInitDMA初始化和DMA结构体初始化函数DMA_CmdDMA_ITConfigDMA_SetCurrDataCounterDMA_GetCurrDataCounter四个获取标志位状态函数代码实现MyDMA.c第一步,开启时钟第二步,初始化DMA第三步,开关控制......