Flutter页面选中数据回传:替换容器箭头为选中车型
Flutter 多选车型后返回更新原页面UI实现
核心需求
点击搜索页的「Vehicle Type」容器跳转至车型选择页,多选车型后点击「Set」返回,将原容器右侧箭头替换为选中的车型名称。
修改后的代码实现
1. search_screen.dart
class SearchScreen extends StatefulWidget { const SearchScreen({super.key}); @override State<SearchScreen> createState() => _SearchScreenState(); } class _SearchScreenState extends State<SearchScreen> { // 存储选中的车型 List<String> selectedVehicleTypes = []; @override Widget build(BuildContext context) { return Scaffold( body: Column( crossAxisAlignment: CrossAxisAlignment.center, children: [ Padding( padding: const EdgeInsets.only(top: 24), child: Row( children: [ const Padding( padding: EdgeInsets.only(left: 173), child: Text( 'Home', style: TextStyle( color: Color(0xFF010D38), fontSize: 20, fontWeight: FontWeight.w500), ), ), const Gap(85), // ignore: deprecated_member_use IconButton( onPressed: () {}, icon: const Icon(FontAwesomeIcons.trash), iconSize: 20, color: Color(0xFF010D38), ) ], ), ), const Gap(50), Column( children: [ GestureDetector( onTap: () async { // 跳转并等待返回选中的车型数据 final result = await GoRouter.of(context).push<List<String>>('/search/vechicleType'); if (result != null) { setState(() { selectedVehicleTypes = result; }); } }, child: Container( width: 316, height: 50, decoration: BoxDecoration( borderRadius: BorderRadius.circular(12), color: const Color(0xFF010D38), ), child: Row( children: [ const Padding( padding: EdgeInsets.only(left: 18), child: Text( 'Vechicle Type', style: TextStyle( fontSize: 16, fontWeight: FontWeight.normal, color: Color(0xFFA6A6A6), ), ), ), const Spacer(), Padding( padding: const EdgeInsets.only(right: 24), child: selectedVehicleTypes.isEmpty ? const Icon( Icons.keyboard_arrow_right_rounded, color: Colors.white, size: 30, ) : Text( selectedVehicleTypes.join(', '), style: const TextStyle( color: Colors.white, fontSize: 14, ), overflow: TextOverflow.ellipsis, ), ) ], ), ), ), const Gap(20), Container( width: 316, height: 50, decoration: BoxDecoration( borderRadius: BorderRadius.circular(12), color: const Color(0xFF010D38), ), child: const Row( children: [ Padding( padding: EdgeInsets.only(left: 18), child: Text( 'Condition', style: TextStyle( fontSize: 16, fontWeight: FontWeight.normal, color: Color(0xFFA6A6A6), ), ), ), Spacer(), Padding( padding: EdgeInsets.only(right: 24), child: Icon( Icons.keyboard_arrow_right_rounded, color: Colors.white, size: 30, ), ) ], ), ), const Gap(20), Container( width: 316, height: 50, decoration: BoxDecoration( borderRadius: BorderRadius.circular(12), color: const Color(0xFF010D38), ), child: const Row( children: [ Padding( padding: EdgeInsets.only(left: 18), child: Text( 'Make and Model', style: TextStyle( fontSize: 16, fontWeight: FontWeight.normal, color: Color(0xFFA6A6A6), ), ), ), Spacer(), Padding( padding: EdgeInsets.only(right: 24), child: Icon( Icons.keyboard_arrow_right_rounded, color: Colors.white, size: 30, ), ) ], ), ), const Gap(20), Container( width: 316, height: 50, decoration: BoxDecoration( borderRadius: BorderRadius.circular(12), color: const Color(0xFF010D38), ), child: const Row( children: [ Padding( padding: EdgeInsets.only(left: 18), child: Text( 'Price', style: TextStyle( fontSize: 16, fontWeight: FontWeight.normal, color: Color(0xFFA6A6A6), ), ), ), Spacer(), Padding( padding: EdgeInsets.only(right: 24), child: Icon( Icons.keyboard_arrow_right_rounded, color: Colors.white, size: 30, ), ) ], ), ), const Gap(20), Container( width: 316, height: 50, decoration: BoxDecoration( borderRadius: BorderRadius.circular(12), color: const Color(0xFF010D38), ), child: const Row( children: [ Padding( padding: EdgeInsets.only(left: 18), child: Text( 'Mileage', style: TextStyle( fontSize: 16, fontWeight: FontWeight.normal, color: Color(0xFFA6A6A6), ), ), ), Spacer(), Padding( padding: EdgeInsets.only(right: 24), child: Icon( Icons.keyboard_arrow_right_rounded, color: Colors.white, size: 30, ), ) ], ), ), ], ), const Gap(15), const Padding( padding: EdgeInsets.only(right: 230), child: Text( 'More criteria', style: TextStyle( shadows: [ Shadow( color: Colors.black, offset: Offset(0, -1), ) ], fontSize: 14, fontWeight: FontWeight.w500, color: Colors.transparent, decoration: TextDecoration.underline, decorationColor: Colors.black, decorationThickness: 1), ), ), const Gap(20), Container( width: 241, height: 45, decoration: BoxDecoration( color: const Color(0xFF223167), borderRadius: BorderRadius.circular(8), ), child: const Center( child: Text( 'Search', style: TextStyle( fontSize: 22, fontWeight: FontWeight.normal, letterSpacing: 2.2, color: Colors.white, ), ), ), ) ], ), ); } }
2. vehicle_type.dart
class VehicleType extends StatefulWidget { const VehicleType({super.key}); @override State<VehicleType> createState() => _VehicleTypeState(); } class _VehicleTypeState extends State<VehicleType> { List<String> vehicleType = [ 'Saloon', 'Coupe', 'Cabriolet', 'SUV', 'Minibus', ]; List<String> tempArray = []; @override Widget build(BuildContext context) { return Scaffold( body: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Padding( padding: const EdgeInsets.only(top: 6), child: Row( mainAxisAlignment: MainAxisAlignment.center, children: [ IconButton( onPressed: () => Navigator.pop(context), icon: const Icon(Icons.keyboard_arrow_left_outlined, size: 37), ), GestureDetector( onTap: () => Navigator.pop(context), child: const Text( 'Back', style: TextStyle( fontSize: 15, fontWeight: FontWeight.w500, color: Color(0xFF010D38), ), ), ), const Spacer(), const Text( 'vehicle Type', style: TextStyle( fontSize: 23, fontWeight: FontWeight.w500, color: Color(0xFF010D38), ), ), const Spacer(), GestureDetector( // 点击Set返回选中的车型数据 onTap: () => Navigator.pop(context, tempArray), child: const Padding( padding: EdgeInsets.only(right: 25), child: Text( 'Set', style: TextStyle( fontSize: 18, fontWeight: FontWeight.w500, color: Color(0xFF010D38), ), ), ), ) ], ), ), const Gap(48), Expanded( child: ListView.builder( itemCount: vehicleType.length, itemBuilder: (context, index) { return InkWell( onTap: () { setState(() { if (tempArray.contains( vehicleType[index].toString(), )) { tempArray.remove(vehicleType[index].toString()); } else { tempArray.add(vehicleType[index].toString()); } }); }, child: Card( shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(12)), color: const Color(0xFF010D38), margin: const EdgeInsets.symmetric(horizontal: 40, vertical: 5), child: ListTile( leading: const Padding( padding: EdgeInsets.only(left: 40), child: Icon(Icons.car_rental, size: 35), ), iconColor: Colors.white, title: Padding( padding: const EdgeInsets.only(left: 70), child: Text( vehicleType[index].toString(), style: const TextStyle(color: Colors.white, fontSize: 20), ), ), trailing: Icon(tempArray.contains( vehicleType[index].toString(), ) ? Icons.check : null), ), ), ); }, ), ), ], ), ); } }
关键实现点
- 状态存储:在
SearchScreen中添加selectedVehicleTypes列表,用于保存选中的车型数据 - 异步跳转接收数据:使用
await GoRouter.of(context).push()等待车型选择页返回的数据,拿到后通过setState更新UI - 动态UI展示:根据
selectedVehicleTypes是否为空,决定显示箭头还是选中的车型名称(用join(', ')拼接多个车型,添加overflow: TextOverflow.ellipsis防止文字溢出) - 返回数据逻辑:给
VehicleType页面的「Set」按钮添加点击事件,通过Navigator.pop(context, tempArray)将选中的车型列表返回给上一页
内容的提问来源于stack exchange,提问作者WhoDoYou
相关产品推荐
相关产品推荐

