在这里插入图片描述

前言

商品详情页面是电商应用中最重要的转化页面。它需要展示商品图片、价格、规格、描述、评价等信息,并提供加入购物车和立即购买的入口。本文将详细介绍如何在Flutter和OpenHarmony平台上实现一个功能完善的商品详情页面。

商品详情页面的设计直接影响用户的购买决策,需要在信息展示和购买引导之间取得平衡。

Flutter商品详情页面实现

页面结构设计

商品详情页面接收商品名称参数。

class ProductDetailPage extends StatefulWidget {
  final String productName;

  const ProductDetailPage({super.key, required this.productName});

  
  State<ProductDetailPage> createState() => _ProductDetailPageState();
}

class _ProductDetailPageState extends State<ProductDetailPage> {
  int _quantity = 1;
  bool _isFavorite = false;

使用StatefulWidget管理数量和收藏状态。

商品图片区域

使用PageView实现商品图片轮播。

  
  Widget build(BuildContext context) {
    return Scaffold(
      body: CustomScrollView(
        slivers: [
          SliverAppBar(
            expandedHeight: 350,
            pinned: true,
            backgroundColor: const Color(0xFF8B4513),
            leading: IconButton(
              icon: const Icon(Icons.arrow_back, color: Colors.white),
              onPressed: () => Navigator.pop(context),
            ),
            actions: [
              IconButton(
                icon: Icon(_isFavorite ? Icons.favorite : Icons.favorite_border, color: _isFavorite ? Colors.red : Colors.white),
                onPressed: () => setState(() => _isFavorite = !_isFavorite),
              ),
              IconButton(icon: const Icon(Icons.share, color: Colors.white), onPressed: () {}),
            ],
            flexibleSpace: FlexibleSpaceBar(
              background: Container(
                color: Colors.grey[200],
                child: const Center(child: Icon(Icons.shopping_bag, size: 100, color: Colors.grey)),
              ),
            ),
          ),

SliverAppBar实现可折叠的图片头部。收藏按钮根据状态显示不同图标和颜色。

商品信息区域

展示价格、名称和销量信息。

          SliverToBoxAdapter(
            child: Container(
              padding: const EdgeInsets.all(16),
              color: Colors.white,
              child: Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                children: [
                  Row(
                    crossAxisAlignment: CrossAxisAlignment.end,
                    children: [
                      const Text('¥', style: TextStyle(fontSize: 16, color: Color(0xFFE53935), fontWeight: FontWeight.bold)),
                      const Text('299', style: TextStyle(fontSize: 28, color: Color(0xFFE53935), fontWeight: FontWeight.bold)),
                      const SizedBox(width: 8),
                      Text('¥399', style: TextStyle(fontSize: 14, color: Colors.grey[500], decoration: TextDecoration.lineThrough)),
                    ],
                  ),
                  const SizedBox(height: 8),
                  Text(widget.productName, style: const TextStyle(fontSize: 18, fontWeight: FontWeight.bold)),
                  const SizedBox(height: 8),
                  Row(
                    children: [
                      Container(
                        padding: const EdgeInsets.symmetric(horizontal: 6, vertical: 2),
                        decoration: BoxDecoration(color: const Color(0xFFE53935).withOpacity(0.1), borderRadius: BorderRadius.circular(4)),
                        child: const Text('限时特惠', style: TextStyle(fontSize: 10, color: Color(0xFFE53935))),
                      ),
                      const SizedBox(width: 8),
                      Text('已售 1.2K', style: TextStyle(fontSize: 12, color: Colors.grey[600])),
                      const Spacer(),
                      Row(
                        children: [
                          const Icon(Icons.star, size: 14, color: Colors.amber),
                          const SizedBox(width: 2),
                          Text('4.9', style: TextStyle(fontSize: 12, color: Colors.grey[600])),
                        ],
                      ),
                    ],
                  ),
                ],
              ),
            ),
          ),

价格使用红色突出显示,原价使用删除线。促销标签和销量信息增强购买信心。

数量选择与购买按钮

底部固定的购买操作栏。

        ],
      ),
      bottomNavigationBar: Container(
        padding: const EdgeInsets.all(16),
        decoration: BoxDecoration(
          color: Colors.white,
          boxShadow: [BoxShadow(color: Colors.black.withOpacity(0.1), blurRadius: 10, offset: const Offset(0, -5))],
        ),
        child: Row(
          children: [
            Column(
              mainAxisSize: MainAxisSize.min,
              children: [
                const Icon(Icons.store_outlined, color: Colors.grey),
                Text('店铺', style: TextStyle(fontSize: 10, color: Colors.grey[600])),
              ],
            ),
            const SizedBox(width: 16),
            Column(
              mainAxisSize: MainAxisSize.min,
              children: [
                const Icon(Icons.chat_bubble_outline, color: Colors.grey),
                Text('客服', style: TextStyle(fontSize: 10, color: Colors.grey[600])),
              ],
            ),
            const SizedBox(width: 16),
            Expanded(
              child: Row(
                children: [
                  Expanded(
                    child: ElevatedButton(
                      onPressed: () {},
                      style: ElevatedButton.styleFrom(
                        backgroundColor: const Color(0xFFFF9800),
                        padding: const EdgeInsets.symmetric(vertical: 12),
                        shape: const RoundedRectangleBorder(
                          borderRadius: BorderRadius.horizontal(left: Radius.circular(25)),
                        ),
                      ),
                      child: const Text('加入购物车', style: TextStyle(color: Colors.white)),
                    ),
                  ),
                  Expanded(
                    child: ElevatedButton(
                      onPressed: () {},
                      style: ElevatedButton.styleFrom(
                        backgroundColor: const Color(0xFFE53935),
                        padding: const EdgeInsets.symmetric(vertical: 12),
                        shape: const RoundedRectangleBorder(
                          borderRadius: BorderRadius.horizontal(right: Radius.circular(25)),
                        ),
                      ),
                      child: const Text('立即购买', style: TextStyle(color: Colors.white)),
                    ),
                  ),
                ],
              ),
            ),
          ],
        ),
      ),
    );
  }
}

底部栏包含店铺、客服入口和购买按钮。加入购物车和立即购买使用不同颜色区分。

OpenHarmony鸿蒙实现

页面定义

鸿蒙平台使用路由参数接收商品信息。

@Entry
@Component
struct ProductDetailPage {
  @State productName: string = ''
  @State isFavorite: boolean = false
  @State quantity: number = 1

  aboutToAppear() {
    const params = router.getParams() as Record<string, string>
    this.productName = params?.name || '商品详情'
  }

页面布局实现

使用Scroll构建可滚动页面。

  build() {
    Column() {
      Scroll() {
        Column() {
          Stack() {
            Image($r('app.media.product_placeholder'))
              .width('100%')
              .height(350)
              .objectFit(ImageFit.Cover)
            
            Row() {
              Image($r('app.media.back'))
                .width(24)
                .height(24)
                .fillColor(Color.White)
                .onClick(() => router.back())
              Blank()
              Image(this.isFavorite ? $r('app.media.heart_filled') : $r('app.media.heart'))
                .width(24)
                .height(24)
                .fillColor(this.isFavorite ? '#F44336' : Color.White)
                .onClick(() => { this.isFavorite = !this.isFavorite })
              Image($r('app.media.share'))
                .width(24)
                .height(24)
                .fillColor(Color.White)
                .margin({ left: 16 })
            }
            .width('100%')
            .padding(16)
            .position({ y: 40 })
          }
          .width('100%')
          .height(350)
          .backgroundColor('#F0F0F0')
          
          Column() {
            Row() {
              Text('¥')
                .fontSize(16)
                .fontColor('#E53935')
                .fontWeight(FontWeight.Bold)
              Text('299')
                .fontSize(28)
                .fontColor('#E53935')
                .fontWeight(FontWeight.Bold)
              Text('¥399')
                .fontSize(14)
                .fontColor('#999999')
                .decoration({ type: TextDecorationType.LineThrough })
                .margin({ left: 8 })
            }
            .alignItems(VerticalAlign.Bottom)
            .width('100%')
            
            Text(this.productName)
              .fontSize(18)
              .fontWeight(FontWeight.Bold)
              .fontColor('#333333')
              .margin({ top: 8 })
              .width('100%')
            
            Row() {
              Text('限时特惠')
                .fontSize(10)
                .fontColor('#E53935')
                .backgroundColor('#E539351A')
                .borderRadius(4)
                .padding({ left: 6, right: 6, top: 2, bottom: 2 })
              Text('已售 1.2K')
                .fontSize(12)
                .fontColor('#666666')
                .margin({ left: 8 })
              Blank()
              Image($r('app.media.star'))
                .width(14)
                .height(14)
                .fillColor('#FFC107')
              Text('4.9')
                .fontSize(12)
                .fontColor('#666666')
                .margin({ left: 2 })
            }
            .width('100%')
            .margin({ top: 8 })
          }
          .width('100%')
          .padding(16)
          .backgroundColor(Color.White)
        }
      }
      .layoutWeight(1)
      
      Row() {
        Column() {
          Image($r('app.media.store'))
            .width(20)
            .height(20)
            .fillColor('#999999')
          Text('店铺')
            .fontSize(10)
            .fontColor('#666666')
        }
        Column() {
          Image($r('app.media.service'))
            .width(20)
            .height(20)
            .fillColor('#999999')
          Text('客服')
            .fontSize(10)
            .fontColor('#666666')
        }
        .margin({ left: 16 })
        
        Row() {
          Button('加入购物车')
            .fontSize(14)
            .fontColor(Color.White)
            .backgroundColor('#FF9800')
            .layoutWeight(1)
            .borderRadius({ topLeft: 25, bottomLeft: 25 })
          Button('立即购买')
            .fontSize(14)
            .fontColor(Color.White)
            .backgroundColor('#E53935')
            .layoutWeight(1)
            .borderRadius({ topRight: 25, bottomRight: 25 })
        }
        .layoutWeight(1)
        .margin({ left: 16 })
      }
      .width('100%')
      .height(60)
      .padding({ left: 16, right: 16 })
      .backgroundColor(Color.White)
    }
    .width('100%')
    .height('100%')
  }
}

底部购买栏固定显示。按钮使用不同颜色区分功能。

总结

本文介绍了Flutter和OpenHarmony平台上商品详情页面的实现方法。商品详情页面是电商应用的核心转化页面,其设计需要突出商品信息并提供便捷的购买入口。欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net

Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐