Flutter技术问询:如何根据选中索引、页面状态及Model修改AppBar背景色
解决方案
要实现点击子分类卡片时动态更新AppBar背景色,需要通过状态管理跟踪选中的子分类模型,并调用AppBar配置方法更新颜色,具体步骤如下:
1. 添加状态变量跟踪选中的子分类
在SubCategoryScreenState类中添加变量,保存当前选中的SubCategoryDetail模型:
SubCategoryDetail? _selectedSubCategory;
2. 初始化默认选中状态
修改initState方法,初始化时默认选中第一个子分类(或保持初始颜色),并设置对应的AppBar背景色:
@override void initState() { super.initState(); // 默认选中第一个子分类(如果列表不为空) _selectedSubCategory = model.subCategoryDetailList.isNotEmpty ? model.subCategoryDetailList.first : null; setAppBarVisibility(true, backgroundColor: _selectedSubCategory?.backgroundColor ?? AppColors.primaryColor, appBarTitleCenter: true, appBarTitle: model.title, backButtonVisibility: true); }
注意:确保
SubCategoryDetail模型中存在backgroundColor属性(类型为Color),如果是十六进制颜色字符串,需要先转换为Color类型,例如:// 在SubCategoryDetail模型中添加转换方法 Color get backgroundColor => Color(int.parse(this.colorHex.replaceFirst('#', '0xFF')));
3. 点击卡片时更新选中状态与AppBar颜色
修改onSelectCategory方法,更新选中的模型后,重新调用setAppBarVisibility更新背景色:
void onSelectCategory(SubCategoryDetail selectedModel) { setState(() { _selectedSubCategory = selectedModel; }); // 动态更新AppBar背景色 setAppBarVisibility(true, backgroundColor: selectedModel.backgroundColor, appBarTitleCenter: true, appBarTitle: model.title, backButtonVisibility: true); }
4. 可选:添加选中卡片的视觉反馈
为了让用户直观看到选中的子分类,可以在卡片的装饰中添加选中标识:
// 在ListView.builder的itemBuilder中修改Container的decoration decoration: BoxDecoration( borderRadius: BorderRadius.circular(Dimensions.size_30), // 选中时添加边框高亮 border: _selectedSubCategory == detailModel ? Border.all(color: AppColors.accentColor, width: 2) : null, ),
修改后的完整代码
import 'package:flutter/material.dart'; import 'package:neeraj_flutter_app/base/baseClass.dart'; import 'package:neeraj_flutter_app/constants/assets.dart'; import 'package:neeraj_flutter_app/constants/classes.dart'; import 'package:neeraj_flutter_app/constants/colors.dart'; import 'package:neeraj_flutter_app/constants/dimensions.dart'; import 'package:neeraj_flutter_app/models/category_data.dart'; import 'package:neeraj_flutter_app/models/main_category_model.dart'; import 'package:neeraj_flutter_app/utils/device_utils.dart'; import 'package:neeraj_flutter_app/widgets/sub_category_card_widget.dart'; import 'package:neeraj_flutter_app/widgets/vertical_gap.dart'; import 'package:permission_handler/permission_handler.dart'; class SubCategoryScreen extends StatefulWidget { late MainCategoryDetail model; SubCategoryScreen(this.model); @override State<StatefulWidget> createState() { return SubCategoryScreenState(model); } } class SubCategoryScreenState extends BaseClass { late MainCategoryDetail model; SubCategoryDetail? _selectedSubCategory; // 新增:跟踪选中的子分类 SubCategoryScreenState(this.model); @override void initState() { super.initState(); // 默认选中第一个子分类(如果列表不为空) _selectedSubCategory = model.subCategoryDetailList.isNotEmpty ? model.subCategoryDetailList.first : null; setAppBarVisibility(true, backgroundColor: _selectedSubCategory?.backgroundColor ?? AppColors.primaryColor, appBarTitleCenter: true, appBarTitle: model.title, backButtonVisibility: true); } @override Widget? setBody() { return Container( width: DeviceUtils.getScreenWidtht(context), decoration: const BoxDecoration(image: DecorationImage(image: AssetImage(Assets.BACKGROUND_SECPAGE), fit: BoxFit.fill)), child: Column( mainAxisSize: MainAxisSize.max, crossAxisAlignment: CrossAxisAlignment.center, children: [ Expanded( child: ListView.builder( padding: EdgeInsets.zero, itemBuilder: (context, index) { SubCategoryDetail detailModel = model.subCategoryDetailList.elementAt(index); return Container( width: DeviceUtils.getScreenWidtht(context) * 0.40, height: DeviceUtils.getScreenHeight(context) * 0.50, margin: const EdgeInsets.all(Dimensions.size_20), decoration: BoxDecoration( borderRadius: BorderRadius.circular(Dimensions.size_30), // 可选:选中卡片添加边框高亮 border: _selectedSubCategory == detailModel ? Border.all(color: AppColors.accentColor, width: 2) : null, ), child: InkWell( onTap: () => onSelectCategory(detailModel), borderRadius: BorderRadius.circular(Dimensions.size_12), splashColor: AppColors.primaryColor, hoverColor: AppColors.primaryColor, focusColor: AppColors.primaryColor, child: SubCategoryCardWidget(detailModel, onPlayButtonClick)), ); }, itemCount: model.subCategoryDetailList.length, scrollDirection: Axis.horizontal, )) ], ), ); } void onSubCatPress() async { print("play game clicked"); Map<Permission, PermissionStatus> statuses = await [Permission.bluetoothConnect, Permission.bluetoothScan].request(); if (statuses[Permission.bluetoothConnect] == PermissionStatus.granted) { print(statuses[Permission.bluetoothConnect]); //showBottomDialog(context); Navigator.of(context).pushNamed(Classes.bluetoothBle); } } void onSelectCategory(SubCategoryDetail selectedModel) { setState(() { _selectedSubCategory = selectedModel; }); // 动态更新AppBar背景色 setAppBarVisibility(true, backgroundColor: selectedModel.backgroundColor, appBarTitleCenter: true, appBarTitle: model.title, backButtonVisibility: true); print("sub category >>> ${selectedModel.title}"); } void onPlayButtonClick(SubCategoryDetail model) { print("play game clicked ${model.title}"); Navigator.of(context).pushNamed(Classes.freeRunScreen, arguments: model); } }
内容的提问来源于stack exchange,提问作者Ankit Kumawat
相关产品推荐
相关产品推荐

