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
相关产品推荐
相关产品推荐

