好的,我可以帮你添加这个功能。首先,你需要创建一个新页面来展示商品详情。在lib文件夹下创建一个新的文件夹,命名为“pages”,然后在该文件夹下创建一个新的文件,命名为“product_detail_page.dart”。在该文件中,你需要导入一些必要的组件和模型,代码如下:

import 'package:flutter/material.dart';
import 'package:cached_network_image/cached_network_image.dart';
import '../models/product.dart';
import '../services/api_service.dart';

class ProductDetailPage extends StatefulWidget {
  final int productId;

  ProductDetailPage({required this.productId});

  @override
  _ProductDetailPageState createState() => _ProductDetailPageState();
}

class _ProductDetailPageState extends State<ProductDetailPage> {
  late Future<Product> _productFuture;

  @override
  void initState() {
    super.initState();
    _productFuture = ApiService.getProductDetail(widget.productId);
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('商品详情'),
      ),
      body: FutureBuilder<Product>(
        future: _productFuture,
        builder: (context, snapshot) {
          if (snapshot.hasData) {
            final product = snapshot.data!;
            return SingleChildScrollView(
              child: Column(
                crossAxisAlignment: CrossAxisAlignment.stretch,
                children: <Widget>[
                  CachedNetworkImage(
                    imageUrl: product.imageUrl,
                    fit: BoxFit.cover,
                    height: 300,
                    errorWidget: (context, url, error) => Icon(Icons.error),
                  ),
                  Container(
                    padding: EdgeInsets.all(16),
                    child: Column(
                      crossAxisAlignment: CrossAxisAlignment.start,
                      children: <Widget>[
                        Text(
                          product.name,
                          style: TextStyle(
                            fontSize: 20,
                            fontWeight: FontWeight.bold,
                          ),
                        ),
                        SizedBox(height: 8),
                        Text(
                          '价格: ¥${product.price.toStringAsFixed(2)}',
                          style: TextStyle(fontSize: 16),
                        ),
                        SizedBox(height: 8),
                        Text(
                          '品牌: ${product.brand}',
                          style: TextStyle(fontSize: 16),
                        ),
                        SizedBox(height: 8),
                        Text(
                          '描述:',
                          style: TextStyle(
                            fontSize: 16,
                            fontWeight: FontWeight.bold,
                          ),
                        ),
                        SizedBox(height: 8),
                        Text(
                          product.description,
                          style: TextStyle(fontSize: 16),
                        ),
                        SizedBox(height: 16),
                        ElevatedButton(
                          onPressed: () {
                            // todo: 添加到购物车
                          },
                          child: Text('添加到购物车'),
                        ),
                      ],
                    ),
                  ),
                ],
              ),
            );
          } else if (snapshot.hasError) {
            return Center(
              child: Text('${snapshot.error}'),
            );
          } else {
            return Center(
              child: CircularProgressIndicator(),
            );
          }
        },
      ),
    );
  }
}

在该文件中,我们创建了一个ProductDetailPage类,它是一个有状态组件,需要传入一个productId,用于获取对应的商品详情。在initState方法中,我们通过ApiService来获取商品详情的数据,并将数据保存在_productFuture中。在build方法中,我们使用FutureBuilder来展示数据。如果数据已经获取到,我们就展示商品的图片、名称、价格、品牌、描述等信息,并提供一个“添加到购物车”的按钮。如果数据还没有获取到,我们就展示一个加载动画。

接下来,在HomePage中,我们需要将商品卡片包装在InkWell中,并给它添加一个onTap事件,用于跳转到ProductDetailPage页面。同时,我们需要在Product模型中添加一个fromJson方法和一个toMap方法,用于将JSON数据转换为模型对象和将模型对象转换为Map。修改后的代码如下:

import 'package:flutter/material.dart';
import 'package:pull_to_refresh/pull_to_refresh.dart';
import 'package:cached_network_image/cached_network_image.dart';
import '../models/product.dart';
import '../services/api_service.dart';
import 'product_detail_page.dart';

class HomePage extends StatefulWidget {
  @override
  _HomePageState createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  List<Product> _products = [];
  int _page = 1;
  final int _limit = 20;
  RefreshController _refreshController =
      RefreshController(initialRefresh: false);

  void _onLoading() async {
    _page++;
    List<Product> newProducts =
        await ApiService.getProductList(page: _page, limit: _limit);
    setState(() {
      _products.addAll(newProducts);
    });
    _refreshController.loadComplete();
  }

  @override
  void initState() {
    super.initState();
    _loadProducts();
  }

  Future<void> _loadProducts() async {
    List<Product> products =
        await ApiService.getProductList(page: _page, limit: _limit);
    setState(() {
      _products = products;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('商城主页')),
      body: SmartRefresher(
        enablePullDown: false,
        enablePullUp: true,
        controller: _refreshController,
        onLoading: _onLoading,
        child: GridView.builder(
          itemCount: _products.length,
          gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
            crossAxisCount: 2,
            childAspectRatio: 0.75,
          ),
          itemBuilder: (BuildContext context, int index) {
            final product = _products[index];
            return InkWell(
              onTap: () {
                Navigator.push(
                  context,
                  MaterialPageRoute(
                    builder: (context) =>
                        ProductDetailPage(productId: product.id),
                  ),
                );
              },
              child: Card(
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: <Widget>[
                    Expanded(
                      child: CachedNetworkImage(
                        imageUrl: product.imageUrl,
                        fit: BoxFit.cover,
                        errorWidget: (context, url, error) =>
                            Icon(Icons.error),
                      ),
                    ),
                    Padding(
                      padding: EdgeInsets.all(8),
                      child: Column(
                        crossAxisAlignment: CrossAxisAlignment.start,
                        children: <Widget>[
                          Text(product.name,
                              style:
                                  TextStyle(fontWeight: FontWeight.bold)),
                          SizedBox(height: 4),
                          Text(
                              '价格: ¥${product.price.toStringAsFixed(2)}'),
                          SizedBox(height: 4),
                          Text('品牌: ${product.brand}'),
                        ],
                      ),
                    ),
                  ],
                ),
              ),
            );
          },
        ),
      ),
    );
  }
}

HomePage中,我们将商品卡片包装在InkWell中,并给它添加一个onTap事件,用于跳转到ProductDetailPage页面。我们使用Navigator.push来跳转页面,并传递product.id作为productId。在Product模型中,我们添加了一个fromJson方法和一个toMap方法,用于将JSON数据转换为模型对象和将模型对象转换为Map。修改后的Product模型代码如下:

class Product {
  int id;
  String name;
  String imageUrl;
  double price;
  String brand;
  String description;
  int categoryId;
  String supplier;
  String origin;
  int stock;
  int isActive;
  int isDeleted;
  int isFeatured;
  int weight;
  int createdAt;
  int updatedAt;

  Product({
    required this.id,
    required this.name,
    required this.imageUrl,
    required this.price,
    required this.brand,
    required this.description,
    required this.categoryId,
    required this.supplier,
    required this.origin,
    required this.stock,
    required this.isActive,
    required this.isDeleted,
    required this.isFeatured,
    required this.weight,
    required this.createdAt,
    required this.updatedAt,
  });

  factory Product.fromJson(Map<String, dynamic> json) {
    return Product(
      id: json['id'],
      name: json['name'],
      imageUrl: json['imageUrl'],
      price: json['price'].toDouble(),
      brand: json['brand'],
      description: json['description'],
      categoryId: json['categoryId'],
      supplier: json['supplier'],
      origin: json['origin'],
      stock: json['stock'],
      isActive: json['isActive'],
      isDeleted: json['isDeleted'],
      isFeatured: json['isFeatured'],
      weight: json['weight'],
      createdAt: json['createdAt'],
      updatedAt: json['updatedAt'],
    );
  }

  Map<String, dynamic> toMap() {
    return {
      'id': id,
      'name': name,
      'imageUrl': imageUrl,
      'price': price,
      'brand': brand,
      'description': description,
      'categoryId': categoryId,
      'supplier': supplier,
      'origin': origin,
      'stock': stock,
      'isActive': isActive,
      'isDeleted': isDeleted,
      'isFeatured': isFeatured,
      'weight': weight,
      'createdAt': createdAt,
      'updatedAt': updatedAt,
    };
  }
}

最后,我们需要在ApiService中添加一个新的方法,用于获取商品详情的数据。代码如下:

static Future<Product> getProductDetail(int productId) async {
  try {
    Response response = await _dio.get(
      '$baseUrl/getproductdetail',
      queryParameters: {'productId': productId},
    );
    Map<String, dynamic> jsonData = jsonDecode(response.data);
    Product product = Product.fromJson(jsonData);
    return product;
  } catch (e) {
    throw e;
  }
}

现在,你可以运行你的应用程序,查看商品是否能够正常显示,并且能否点击打开商品详情页面。如果一切正常,你可以开始添加“添加到购物车”功能

我现在用flutter写了一个商城现在只有主页我想让你给我添加一个点击商品跳转到对应的商品详情页面我的商品详情调用在http127001getproductdetailproductId=-1896935422返回的是json格式的数据brand东北石油大学出版社categoryId24createdAt1682227708000description生容易活容易生活不容易。是的好好生活从来都不是

原文地址: https://www.cveoy.top/t/topic/fuEU 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录