Flutter:如何根据筛选类型点击展示对应网络图书封面
问题:Flutter图书详情页无法根据筛选类型展示对应封面
问题描述
实现了“最新”“特惠”“全部”三种图书筛选,列表展示正常,但点击筛选后的网格项打开详情页时,无法展示对应类别的图书封面——不管点击哪个筛选分类的图书,详情页都只会显示bookList(全部图书)里对应索引的封面,甚至错误固定调用了onSaleList的封面。已为特惠图书做单独处理,但始终未生效。
问题分析
从提供的代码中可以定位到几个核心问题:
- 详情页虽然接收了
type参数,但完全未根据该参数选择对应数据源,全程硬编码使用bookList,导致筛选后的列表索引与全部图书列表索引不匹配 - AppBar背景图错误固定调用
onSaleList[widget.index],未区分当前筛选类型 - 所有图书信息(封面、价格、标题等)均直接从
bookList取值,未根据type切换到对应筛选列表(如特惠的onSaleList、最新的newestList)
解决方案
根据传入的type参数动态获取对应图书数据源,替换所有硬编码的列表调用:
修改后的代码
import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:blur/blur.dart'; import 'package:matab/constants/constants.dart'; import 'package:matab/ui/general_widgets/custom_gradient_button.dart'; import 'package:matab/ui/pages/checkout/payment.dart'; import 'package:matab/ui/pages/styles.dart'; import '../../../controllers/book_controller.dart'; import '../../../controllers/cart_book_controller.dart'; import '../../../controllers/cart_magazine_controller.dart'; import '../../../controllers/magazine_controller.dart'; import '../../../controllers/order_controller.dart'; import 'book_attributes.dart'; import 'book_description.dart'; class BookDetailsPage extends StatefulWidget { final int index; final String type; final String cartButtonText; const BookDetailsPage( {Key? key, required this.index, required this.type, required this.cartButtonText}) : super(key: key); @override State<BookDetailsPage> createState() => _BookDetailsPageState(); } class _BookDetailsPageState extends State<BookDetailsPage> { final BookController bookController = Get.find(tag: 'bookController'); final CartBookController cartBookController = Get.find(tag: 'cartBookController'); final OrderController orderController = Get.find(tag: 'orderController'); bool alreadyExistFlag = false; // 根据type获取对应数据源 List<Book> getCurrentBookList() { switch(widget.type) { case "特惠": return bookController.onSaleList; case "最新": return bookController.newestList; // 假设你有最新图书列表,命名不符请自行修改 case "全部": default: return bookController.bookList; } } @override Widget build(BuildContext context) { final currentBookList = getCurrentBookList(); final currentBook = currentBookList[widget.index]; var cartButtonText = cartBookController.assignTitle(widget.index).obs; return Scaffold( backgroundColor: Colors.white, bottomNavigationBar: SizedBox( height: 200, child: Column( crossAxisAlignment: CrossAxisAlignment.center, mainAxisSize: MainAxisSize.max, mainAxisAlignment: MainAxisAlignment.end, children: [ Padding( padding: const EdgeInsets.fromLTRB(18.0, 20, 18, 10), child: CustomGradientButton( buttonText: "Buy this Book ", buttonFunction: () => { orderController.order.bookIDsList = [], orderController.order.bookCounts = [], orderController.order.bookCounts.add(1), orderController.order.totalPrice = currentBook.price, orderController.order.bookIDsList.add(currentBook.bookID), Get.to(const Payment( type: Constants.bookConst, total: 300)) }), ), Obx(() => Align( alignment: Alignment.bottomCenter, child: Padding( padding: const EdgeInsets.only(bottom: 18.0), child: TextButton( onPressed: () => { cartBookController.addBookToCart(widget.index), cartButtonText.value = cartBookController.assignTitle(widget.index), }, child: Text( cartButtonText.value, style: TextStyle( fontSize: 20.0, color: mainColor, fontWeight: FontWeight.bold), ), ), ), )), ]), ), appBar: AppBar( backgroundColor: Colors.transparent, bottomOpacity: 0.0, elevation: 0.0, automaticallyImplyLeading: false, toolbarHeight: 240, flexibleSpace: Stack( children: [ Container( height: 250, decoration: BoxDecoration( image: DecorationImage( image: NetworkImage(currentBook.coverImage), fit: BoxFit.cover, ), ), ), Padding( padding: const EdgeInsets.fromLTRB(30, 140, 0, 0), child: Container( height: 100, width: 80, decoration: BoxDecoration( borderRadius: const BorderRadius.all(Radius.circular(12.0)), border: Border.all(color: Colors.white, width: 4)), child: Image( image: NetworkImage(currentBook.coverImage), fit: BoxFit.cover, )), ), Padding( padding: const EdgeInsets.fromLTRB(10, 65, 0, 0), child: Container( height: 40, width: 40, decoration: const BoxDecoration( borderRadius: BorderRadius.all(Radius.circular(12.0)), ), child: Blur( blur: 1.8, blurColor: Colors.white, child: Container( decoration: const BoxDecoration( borderRadius: BorderRadius.all(Radius.circular(12.0))), ), ), ), ), Padding( padding: const EdgeInsets.fromLTRB(4, 62, 0, 0), child: IconButton( onPressed: () => {Get.back()}, icon: const ImageIcon( AssetImage( "assets/back.png", ), size: 40, ))), Padding( padding: const EdgeInsets.fromLTRB(330, 65, 0, 0), child: Container( height: 40, width: 40, decoration: const BoxDecoration( borderRadius: BorderRadius.all(Radius.circular(12.0)), ), child: Blur( blur: 1.8, blurColor: Colors.white, child: Container( decoration: const BoxDecoration( borderRadius: BorderRadius.all(Radius.circular(12.0))), ), ), ), ), Padding( padding: const EdgeInsets.fromLTRB(326, 62, 0, 0), child: IconButton( onPressed: () => {}, icon: const ImageIcon( AssetImage( "assets/heart.png", ), size: 40, ))) ], ), ), body: SingleChildScrollView( child: Column( children: [ BookAtrributes( price: currentBook.price, bookName: currentBook.title, author: currentBook.author, ratings: 3.4, ), SizedBox( height: 200, child: BookDescription( description: currentBook.description)), ], ), )); } }
额外注意事项
- 确保
BookController中存在newestList(最新图书列表),如果命名不同请自行修改getCurrentBookList中的对应字段 CartBookController的addBookToCart和assignTitle方法如果是基于bookList的索引实现,可能会出现索引不匹配问题——建议修改为接收Book对象作为参数,而非索引,从根源避免筛选后索引对应错误的问题
内容的提问来源于stack exchange,提问作者Passionate Programmer
相关产品推荐
相关产品推荐

