跟着鸿蒙小林博主,练习下项目~记录下首页的搭建,后续继续完善和整体项目完成会进行布局修改,先按照博主的跟做,后续在改
1.分为底部整体框架搭建
2.首页布局(顶部搜索、新人专享、金刚区(两个不同集合数据)、图片海报、三个分区、瀑布流列表)。组件单独写的
- MainPages
@Entry
@Component
/**
*首页
*/
struct MainPages {
@State isCheck_Index_One: boolean = true
@State currentIndex: number = 0
//底部ui
@Builder
tabBuilder(title: string, targetIndex: number, selectedImg: Resource, normalImg: Resource) {
Column() {
Image(this.currentIndex === targetIndex ? selectedImg : normalImg)
.width(this.isCheck_Index_One && targetIndex === 0 ? 50 : 25)
.height(this.isCheck_Index_One && targetIndex === 0 ? 50 : 25)
.borderRadius(this.isCheck_Index_One && targetIndex === 0 ? 25 : 0)
Text(title)
.margin({ top: 5 })
.fontSize(14)
.margin({ top: 5 })
.fontWeight(this.currentIndex === targetIndex ? FontWeight.Bold : FontWeight.Normal)
.fontColor('#6B6B6B')
}
.width('100%')
.height(50)
.justifyContent(FlexAlign.Center)
}
build() {
//底部导航栏
Column() {
Tabs({ barPosition: BarPosition.End }) {
TabContent() {
//首页布局
HomeUI()
}
.tabBar(this.tabBuilder("首页", 0, $r('app.media.me_image'), $r('app.media.index1_not_check')))
TabContent() {
Text('分类').fontSize(30)
}
.tabBar(this.tabBuilder("分类", 1, $r('app.media.index2_check'), $r('app.media.index2_not_check')))
TabContent() {
Text('购物车').fontSize(30)
}
.tabBar(this.tabBuilder("购物车", 2, $r('app.media.index3_check'), $r('app.media.index3_not_check')))
TabContent() {
Text('我的').fontSize(30)
}
.tabBar(this.tabBuilder("我的", 3, $r('app.media.index4_check'), $r('app.media.index4_not_check')))
}
.onChange((index: number) => {
this.currentIndex = index
if (index === 0) {
this.isCheck_Index_One = true
} else {
this.isCheck_Index_One = false
}
})
}
.linearGradient({
angle: 180,
colors: [[0xff0000, 0], [0xff6666, 0.2], [0xffffff, 1]]
})
.width('100%').height('100%')
}
}
- HomeUI
//首页布局
@Component
@Preview
export struct HomeUI {
@State locationName: string = ''
@State coupons: ESObject[] = [
{ amount: "¥10", desc: "新人专享" },
{ amount: "¥20", desc: "新人专享" },
{ amount: "¥10", desc: "新人专享" },
{ amount: "¥30", desc: "新人专享" }
]
/**
*新用户
*/
@Builder
CouponComponent() {
Column() {
Row() {
Text("新人专享卷")
.fontSize(24)
.fontColor('#FF0000')
Text("前三单免运费")
.fontSize(14)
.fontColor('#888888')
.margin({ left: 10 })
}
.width('100%')
.padding(16)
}
List({ space: 10 }) {
ForEach(this.coupons, (item: ESObject) => {
ListItem() {
Column() {
Text(item.amount)
.fontSize(22)
.fontColor('#FF4444')
.margin({ bottom: 8 })
Text(item.desc)
.fontSize(14)
.fontColor('#999999')
}
}
})
}
}
build() {
Scroll(){
Column() {
HomeTopBar({ locationName: this.locationName })
CommonSearBar({
onSearchClick: () => {
console.debug('测试点击')
}
});
CouponComponent()
.margin({ top: 15, left: 10, right: 10 })
//金刚区
SplitLayout()
//海报区
Image("https://img0.baidu.com/it/u=2721636467,4123351490&fm=253&fmt=auto&app=138&f=JPEG?w=1000&h=500")
.width("95%")
.height(100)
.margin({top:10})
.borderRadius(20)
.objectFit(ImageFit.Fill)
//三个海报
SpecialColumn()
.margin({ top: 15, left: 10, right: 10,bottom:10 })
//瀑布流列表
WaterFlowGoods()
.margin({ left: 10, right: 10})
}
}.width('100%').height('100%')
}
}
3.首页里面的搜索组件
/**
*搜索组件
*/
@Component
export struct CommonSearBar {
@State searchText: string = ''
private onSearchClick?: () => void
build() {
Row() {
Image($r('app.media.search'))
.width(24)
.height(24)
.margin({ left: 12 })
Text(this.searchText || "请输入搜索内容")
.width('70%')
.height(35)
.backgroundColor(Color.White)
.padding({ left: 5 })
.fontSize(16)
Text('搜索')
.width(90)
.layoutWeight(1)
.fontSize(16)
.fontColor(Color.White)
.backgroundColor('#FF0000')
.borderRadius(20)
.padding({ top: 5, bottom: 5 })
.textAlign(TextAlign.Center)
}
.height(40)
.width('90%')
.padding(1)
.backgroundColor('#F5F5F5')
.borderRadius(28)
.onClick(() => {
this.onSearchClick?.()
})
}
}
4.CouponComponent首页新用户领劵
/**
*首页新用户领劵
*/
@Component
export struct CouponComponent {
@State coupons: ESObject[] = [
{ amount: "¥10", desc: "新人专享" },
{ amount: "¥20", desc: "新人专享" },
{ amount: "¥10", desc: "新人专享" },
{ amount: "¥30", desc: "新人专享" }
]
build() {
Column() {
Row() {
Text("新人专享券")
.fontSize(24)
.fontColor('#FF0000')
Text("前三单免运费")
.fontSize(14)
.fontColor('#888888')
.margin({ left: 10 })
}
.width('100%')
.padding(10)
List({ space: 10 }) {
ForEach(this.coupons, (item: ESObject) => {
ListItem() {
Column() {
Text(item.amount)
.fontSize(22)
.fontColor('#FF4444')
.margin({ bottom: 8 })
Text(item.desc)
.fontSize(14)
.fontColor('#999999')
}
.width(80)
.padding(16)
.backgroundColor('#FFFFFF')
.borderRadius(8)
}
})
}
.width('100%')
.height(100)
.margin({left:20})
.listDirection(Axis.Horizontal)
Button('立即领取')
.width(200)
.height(40)
.backgroundColor('#FF0000')
.fontColor(Color.White)
.borderRadius(20)
.margin({ top:20,bottom: 16 })
}
.backgroundColor("#F5F5F5")
.width('100%')
.height('33%')
.borderRadius(10)
}
}
5.SplitLayout金刚区+海报
/**
*金刚区
*/
@Component
@Preview
export struct SplitLayout {
build() {
Column() {
Grid() {
ForEach(HomeData.topData, (row: ESObject) => {
ForEach(row, (item: ESObject) => {
GridItem() {
Column() {
Image(item.image)
.width(40)
.height(40)
.borderRadius(20)
.margin({ top: 5 })
Text(item.title)
.padding(1)
.fontSize(16)
.fontColor(Color.Black)
.textAlign(TextAlign.Center)
}
}
})
})
}
.columnsTemplate('1fr 1fr 1fr 1fr ')
.height(200)
List({ space: 25 }) {
ForEach(HomeData.bottomData, (item: ESObject) => {
ListItem(){
Column(){
Image(item.image)
.width(40)
.height(40)
.borderRadius(15)
Text(item.title)
.textAlign(TextAlign.Center)
.fontColor(Color.Black)
.fontSize(16)
.padding(5)
}
}
})
}
.scrollBar(BarState.Off)
.margin({left:10})
.height(70)
.listDirection(Axis.Horizontal)
}
.alignItems(HorizontalAlign.Start)
.height(310)
.width('95%')
.margin({ top: 20 })
.backgroundColor('#F5F5F5')
.padding(16)
.borderRadius(20)
}
}
6.三个海报SpecialColumn
@Component
@Preview
export struct SpecialColumn {
build() {
Row(){
Column() {
Row() {
Text('今日疯抢')
.fontSize(16)
.fontWeight(FontWeight.Bold)
.fontColor(Color.Black)
Blank()
Text('一元秒杀')
.fontSize(10)
.fontColor(Color.White)
.backgroundColor(Color.Red)
.borderRadius({ topLeft: 8, bottomRight: 8 })
.padding(2)
}
Text('立省两元')
.fontSize(10)
.fontColor('#999999')
.margin({ top: 4 })
List({ space: 10 }) {
ForEach(HomeData.priceInfo,(priceInfo:ESObject)=>{
ListItem() {
Column() {
Image(priceInfo.image)
.width(40)
.height(50)
.margin({ bottom: 8 })
.objectFit(ImageFit.Cover)
Row() {
Text(priceInfo.oldPrice)
.fontSize(12)
.fontColor('#999999')
.decoration({ type: TextDecorationType.LineThrough })
Blank()
Text(priceInfo.newPrice)
.fontSize(14)
.fontColor(Color.Red)
}
}
.margin({ top: 12 })
.padding(8)
.borderRadius(8)
}
})
}
.listDirection(Axis.Horizontal)
.width('100%')
.height(100)
}
.borderRadius(8)
.alignItems(HorizontalAlign.Start)
.linearGradient({
direction: GradientDirection.Bottom, // 渐变方向
colors: [["#F8D7D8", 0.0], ["#FEFFFF", 0.3]]
})
.width('45%')
.padding(10)
Column() {
Text('尝鲜盒子')
.fontSize(16)
.fontColor(Color.Black)
.fontWeight(FontWeight.Bold)
Text('一分钱试吃')
.fontSize(10)
.fontColor('#999999')
.margin({ top: 4 })
Column() {
Image(HomeData.priceInfo[0].image)
.width(40)
.height(50)
.margin({ bottom: 8 })
.objectFit(ImageFit.Cover)
Text(HomeData.priceInfo[0].newPrice)
.fontSize(14)
.fontColor(Color.Red)
}
.margin({ top: 12 })
.padding(10)
}
.borderRadius(8)
.linearGradient({
direction: GradientDirection.Bottom, // 渐变方向
colors: [["#FCECD0", 0.0], ["#FEFFFF", 0.3]]
})
.width('25%')
.padding(10)
Column() {
Text('健康生活')
.fontSize(16)
.fontColor(Color.Black)
.fontWeight(FontWeight.Bold)
Text('果蔬榨榨杯')
.fontSize(10)
.fontColor('#999999')
.margin({ top: 4 })
Column() {
Image(HomeData.priceInfo[1].image)
.width(40)
.height(50)
.margin({ bottom: 8 })
.objectFit(ImageFit.Cover)
Text(HomeData.priceInfo[1].newPrice)
.fontSize(14)
.fontColor(Color.Red)
}
.margin({ top: 12 })
.padding(10)
}
.linearGradient({
direction: GradientDirection.Bottom, // 渐变方向
colors: [["#BFE4CB", 0.0], ["#FEFFFF", 0.3]]
})
.borderRadius(8)
.width('25%')
.padding(10)
}
.width('100%')
.height(150)
.justifyContent(FlexAlign.SpaceBetween)
}
}
7.瀑布流 WaterFlowGoods()
/**
*首页瀑布流
*/
@Component
@Preview
export struct WaterFlowGoods {
@State goodsList: Array<GoodsItem> = [
{
image: "https://img1.baidu.com/it/u=499325528,1576211670&fm=253&fmt=auto&app=120&f=JPEG?w=500&h=667",
name: "红颜草莓",
spec: "早熟",
originalPrice: "¥39",
price: "¥19"
},
{
image: "https://img0.baidu.com/it/u=3907484858,1857304284&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=500",
name: "沙地红心西瓜",
spec: "脆甜",
originalPrice: "¥13",
price: "¥9.9"
}
,
{
image: "https://img0.baidu.com/it/u=3907484858,1857304284&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=500",
name: "芒果",
spec: "香甜",
originalPrice: "¥23",
price: "¥19.9"
} ,
{
image: "https://img0.baidu.com/it/u=3907484858,1857304284&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=500",
name: "海南菠萝",
spec: "脆酸甜",
originalPrice: "¥43",
price: "¥29.9"
}
]
@State columns: number = 2
build() {
//瀑布流
WaterFlow(){
ForEach(this.goodsList,(item:GoodsItem)=>{
FlowItem(){
//布局
Column(){
Image(item.image)
.width('100%')
.borderRadius({topLeft:10,topRight:10})
Column(){
Text(item.name)
.fontSize(16)
.fontColor('#333')
.margin({ bottom: 4 })
Text(item.spec)
.fontSize(12)
.fontColor('#666')
.margin({ bottom: 8 })
Row(){
Text(item.originalPrice)
.fontSize(12)
.fontColor('#999')
.decoration({ type: TextDecorationType.LineThrough })
Text(item.price)
.fontSize(16)
.fontColor(Color.Red)
.margin({left:10})
Blank()
Column(){
Image($r('app.media.cart'))
.width(20)
.height(20)
}
.justifyContent(FlexAlign.Center)
.width(36)
.height(36)
.backgroundColor("#ff2bd2fa")
.borderRadius(18)
}
.width('100%')
.justifyContent(FlexAlign.SpaceBetween)
}
.alignItems(HorizontalAlign.Start)
.padding(12)
}
.backgroundColor(Color.White)
.borderRadius(12)
}
.margin({ bottom: 12 })
})
}
.margin({top:30})
//设置列数
.columnsTemplate('1fr 1fr')
.columnsGap(12)
}
}
8.数据类HomeData
export class HomeData{
static topData: ESObject[][] = [
[
{ image: "https://tse2-mm.cn.bing.net/th/id/OIP-C.iqeBi3j390BfpXYkfwL7ZwHaIC?w=168&h=182&c=7&r=0&o=5&dpr=2&pid=1.7", title: "当季水果" },
{ image: "https://tse2-mm.cn.bing.net/th/id/OIP-C.45Yw7hjv6Pya3G4AkSXV7gHaE6?w=268&h=180&c=7&r=0&o=5&dpr=2&pid=1.7", title: "有机蔬菜" },
{ image: "https://tse4-mm.cn.bing.net/th/id/OIP-C.D4joDEE4liDJ24JkH8vT7wHaE8?w=274&h=183&c=7&r=0&o=5&dpr=2&pid=1.7", title: "进口水产" },
{ image: "https://tse2-mm.cn.bing.net/th/id/OIP-C.qlXw3xeqY17Pz4Zes2XO9wHaGn?w=221&h=197&c=7&r=0&o=5&dpr=2&pid=1.7", title: "散养家禽" },
{ image: "https://tse3-mm.cn.bing.net/th/id/OIP-C.iiVk_wx6cKy6Qz-GORTrBQHaE7?w=280&h=187&c=7&r=0&o=5&dpr=2&pid=1.7", title: "五谷杂粮" }
],
[
{ image: "https://tse2-mm.cn.bing.net/th/id/OIP-C.45Yw7hjv6Pya3G4AkSXV7gHaE6?w=268&h=180&c=7&r=0&o=5&dpr=2&pid=1.7", title: "有机蔬菜" },
{ image: "https://tse2-mm.cn.bing.net/th/id/OIP-C.qlXw3xeqY17Pz4Zes2XO9wHaGn?w=221&h=197&c=7&r=0&o=5&dpr=2&pid=1.7", title: "散养家禽" },
{ image: "https://tse4-mm.cn.bing.net/th/id/OIP-C.D4joDEE4liDJ24JkH8vT7wHaE8?w=274&h=183&c=7&r=0&o=5&dpr=2&pid=1.7", title: "进口水产" },
{ image: "https://tse3-mm.cn.bing.net/th/id/OIP-C.iiVk_wx6cKy6Qz-GORTrBQHaE7?w=280&h=187&c=7&r=0&o=5&dpr=2&pid=1.7", title: "五谷杂粮" },
{ image: "https://tse2-mm.cn.bing.net/th/id/OIP-C.iqeBi3j390BfpXYkfwL7ZwHaIC?w=168&h=182&c=7&r=0&o=5&dpr=2&pid=1.7", title: "当季水果" }
]
]
static bottomData: ESObject[] = [
{ image: "https://tse2-mm.cn.bing.net/th/id/OIP-C.iqeBi3j390BfpXYkfwL7ZwHaIC?w=168&h=182&c=7&r=0&o=5&dpr=2&pid=1.7", title: "尝夏鲜" },
{ image: "https://tse2-mm.cn.bing.net/th/id/OIP-C.45Yw7hjv6Pya3G4AkSXV7gHaE6?w=268&h=180&c=7&r=0&o=5&dpr=2&pid=1.7", title: "烧烤露营" },
{ image: "https://tse4-mm.cn.bing.net/th/id/OIP-C.D4joDEE4liDJ24JkH8vT7wHaE8?w=274&h=183&c=7&r=0&o=5&dpr=2&pid=1.7", title: "厨卫百货" },
{ image: "https://tse2-mm.cn.bing.net/th/id/OIP-C.qlXw3xeqY17Pz4Zes2XO9wHaGn?w=221&h=197&c=7&r=0&o=5&dpr=2&pid=1.7", title: "天天会员价" },
{ image: "https://tse3-mm.cn.bing.net/th/id/OIP-C.iiVk_wx6cKy6Qz-GORTrBQHaE7?w=280&h=187&c=7&r=0&o=5&dpr=2&pid=1.7", title: "盒马NB" },
{ image: "https://tse2-mm.cn.bing.net/th/id/OIP-C.iqeBi3j390BfpXYkfwL7ZwHaIC?w=168&h=182&c=7&r=0&o=5&dpr=2&pid=1.7", title: "自有产品" },
{ image: "https://tse2-mm.cn.bing.net/th/id/OIP-C.45Yw7hjv6Pya3G4AkSXV7gHaE6?w=268&h=180&c=7&r=0&o=5&dpr=2&pid=1.7", title: "每日秒杀" },
{ image: "https://tse4-mm.cn.bing.net/th/id/OIP-C.D4joDEE4liDJ24JkH8vT7wHaE8?w=274&h=183&c=7&r=0&o=5&dpr=2&pid=1.7", title: "好劵连连" },
{ image: "https://tse2-mm.cn.bing.net/th/id/OIP-C.qlXw3xeqY17Pz4Zes2XO9wHaGn?w=221&h=197&c=7&r=0&o=5&dpr=2&pid=1.7", title: "清洁纸品" },
{ image: "https://tse3-mm.cn.bing.net/th/id/OIP-C.iiVk_wx6cKy6Qz-GORTrBQHaE7?w=280&h=187&c=7&r=0&o=5&dpr=2&pid=1.7", title: "敬请期待" }
]
static priceInfo: ESObject = [
{
image: "https://tse3-mm.cn.bing.net/th/id/OIP-C.n_NQx-NMBlbYSU0fvKlMfwHaHa?w=213&h=213&c=7&r=0&o=5&dpr=2&pid=1.7",
oldPrice: "¥99",
newPrice: "¥79"
}, {
image: "https://tse2-mm.cn.bing.net/th/id/OIP-C.qHml5NfgkGlIvftvCc6krAHaE8?w=270&h=180&c=7&r=0&o=5&dpr=2&pid=1.7",
oldPrice: "¥99",
newPrice: "¥79"
}
]
}