You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter+Getx实现同页面跳转:商品详情页嵌套相似商品跳转

在Flutter的Getx框架中实现重复跳转商品详情页的方案

核心思路

直接通过Getx的路由Get.to()重复推送ProductDetails页面,每次跳转时传入目标商品的唯一标识(比如ID)或完整商品数据,页面接收参数后重新加载对应商品的详情信息即可。

具体实现步骤

1. 定义商品模型

先写一个简单的商品实体类,用来存储商品信息:

class Product {
  final String id;
  final String name;
  final String description;
  final double price;
  final List<String> similarProductIds; // 相似商品ID列表

  Product({
    required this.id,
    required this.name,
    required this.description,
    required this.price,
    required this.similarProductIds,
  });
}

2. 配置Getx路由

在项目的路由配置文件(比如routes.dart)里注册ProductDetails页面:

import 'package:get/get.dart';
import 'package:your_app/pages/home_page.dart';
import 'package:your_app/pages/product_details.dart';

class AppRoutes {
  static const String home = '/';
  static const String productDetails = '/product-details';

  static final routes = [
    GetPage(name: home, page: () => HomePage()),
    GetPage(name: productDetails, page: () => ProductDetails()),
  ];
}

然后在main.dart里初始化路由:

void main() {
  runApp(GetMaterialApp(
    initialRoute: AppRoutes.home,
    getPages: AppRoutes.routes,
  ));
}

3. 从HomePage跳转到ProductDetails

在HomePage里,点击商品卡片时调用Get.toNamed()并传入商品ID:

// 假设homePage里有商品列表,点击某商品时:
Get.toNamed(
  AppRoutes.productDetails,
  arguments: product.id, // 传递当前商品的ID
);

4. 实现ProductDetails页面的逻辑

页面需要接收传入的商品ID,加载对应商品数据,同时处理相似商品的点击跳转:

class ProductDetails extends StatelessWidget {
  // 模拟商品数据源,实际项目中可以从API或数据库获取
  final Map<String, Product> productData = {
    '1': Product(
      id: '1',
      name: '商品A',
      description: '这是商品A的详情',
      price: 99.9,
      similarProductIds: ['2', '3'],
    ),
    '2': Product(
      id: '2',
      name: '商品B',
      description: '这是商品B的详情',
      price: 129.9,
      similarProductIds: ['1', '3'],
    ),
    '3': Product(
      id: '3',
      name: '商品C',
      description: '这是商品C的详情',
      price: 89.9,
      similarProductIds: ['1', '2'],
    ),
  };

  @override
  Widget build(BuildContext context) {
    // 获取传入的商品ID
    final String productId = Get.arguments;
    // 根据ID获取当前商品
    final Product currentProduct = productData[productId]!;

    return Scaffold(
      appBar: AppBar(title: Text(currentProduct.name)),
      body: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          // 商品详情内容
          Padding(
            padding: EdgeInsets.all(16),
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                Text(currentProduct.name, style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold)),
                SizedBox(height: 8),
                Text(currentProduct.description),
                SizedBox(height: 8),
                Text('¥${currentProduct.price.toStringAsFixed(2)}'),
              ],
            ),
          ),
          // 相似商品列表
          Padding(
            padding: EdgeInsets.symmetric(horizontal: 16),
            child: Text('相似商品', style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold)),
          ),
          SizedBox(height: 8),
          SizedBox(
            height: 120,
            child: ListView.builder(
              scrollDirection: Axis.horizontal,
              itemCount: currentProduct.similarProductIds.length,
              itemBuilder: (context, index) {
                final String similarId = currentProduct.similarProductIds[index];
                final Product similarProduct = productData[similarId]!;
                return GestureDetector(
                  onTap: () {
                    // 点击相似商品,跳转到同一个ProductDetails页面,传入新的商品ID
                    Get.toNamed(
                      AppRoutes.productDetails,
                      arguments: similarId,
                    );
                  },
                  child: Container(
                    width: 100,
                    margin: EdgeInsets.symmetric(horizontal: 8),
                    padding: EdgeInsets.all(8),
                    decoration: BoxDecoration(border: Border.all(color: Colors.grey)),
                    child: Column(
                      mainAxisAlignment: MainAxisAlignment.center,
                      children: [
                        Text(similarProduct.name, textAlign: TextAlign.center),
                        SizedBox(height: 4),
                        Text('¥${similarProduct.price.toStringAsFixed(2)}'),
                      ],
                    ),
                  ),
                );
              },
            ),
          ),
        ],
      ),
    );
  }
}

5. 优化建议(可选)

  • 如果商品数据是从API获取,建议用Getx的Controller来管理数据请求和状态,避免页面重复请求:
    class ProductController extends GetxController {
      final Rx<Product?> currentProduct = Rx<Product?>(null);
      final Map<String, Product> productCache = {};
    
      Future<void> fetchProduct(String productId) async {
        if (productCache.containsKey(productId)) {
          currentProduct.value = productCache[productId];
          return;
        }
        // 模拟API请求
        await Future.delayed(Duration(milliseconds: 500));
        final Product product = productData[productId]!;
        productCache[productId] = product;
        currentProduct.value = product;
      }
    }
    
    然后在页面中使用:
    final ProductController productController = Get.put(ProductController());
    
    @override
    void onInit() {
      super.onInit();
      final String productId = Get.arguments;
      productController.fetchProduct(productId);
    }
    
    这样可以缓存已加载的商品,提升性能。
  • Getx默认的Get.toNamed()会保留路由栈,返回时会回到上一个详情页,完全符合HomePage->ProductDetails->ProductDetails的跳转需求。

内容的提问来源于stack exchange,提问作者Zubair DKD

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 18:50:31