我有一个项目,我与提供者一起管理状态。在这个项目中,我希望弹出窗口中选择的容器的颜色发生变化,但变化不是瞬时的。
main.dart代码:
import 'package:easy_localization/easy_localization.dart';
import 'package:want_to_do/services/service.locator.dart';
import 'export.dart';
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
await EasyLocalization.ensureInitialized();
SystemChrome.setSystemUIOverlayStyle(
const SystemUiOverlayStyle(
statusBarColor: Colors.transparent,
),
);
await setupLocator();
runApp(
EasyLocalization(
supportedLocales: [
AppLocaleConstant.TR_LOCALE,
AppLocaleConstant.EN_LOCALE,
],
path: AppLocaleConstant.LANG_PATH,
fallbackLocale: AppLocaleConstant.EN_LOCALE,
child: MultiProvider(
providers: [
ChangeNotifierProvider(
create: (_) => SettingsViewModel(),
),
],
child: const MyApp(),
),
),
);
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Flutter Demo',
localizationsDelegates: context.localizationDelegates,
supportedLocales: context.supportedLocales,
locale: context.locale,
navigatorKey: locator<AppRoutes>().baseNavigatorKey,
onGenerateRoute: Routes.generateRoute,
initialRoute: Routes.MainTab,
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
useMaterial3: true,
),
builder: (context, widget) {
return widget!;
},
);
}
}
自定义任务优先级代码:
import 'package:want_to_do/export.dart';
import 'package:want_to_do/generated/locale_keys.g.dart';
class CustomTaskPriority extends StatelessWidget {
final VoidCallback onClickCancel;
final VoidCallback onClickSave;
final int selectedPriority;
final ValueChanged<int> onPrioritySelected;
const CustomTaskPriority({
super.key,
required this.onClickCancel,
required this.onClickSave,
required this.selectedPriority,
required this.onPrioritySelected,
});
@override
Widget build(BuildContext context) {
final List<int> priority = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 8),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Padding(
padding: const EdgeInsets.symmetric(vertical: 10),
child: Text(
LocaleKeys.home_taskPriority.locale,
style: TextStyle(
color: AppColors.white.withOpacity(0.87),
fontSize: 16,
fontWeight: FontWeight.w700,
),
),
),
Padding(
padding: const EdgeInsets.only(bottom: 20),
child: CustomDivider(),
),
Wrap(
spacing: 16,
runSpacing: 16,
children: [
...priority.map((priority) {
return _buildPriorityItem(
onTap: () => onPrioritySelected(priority),
isClick: selectedPriority == priority,
priority: priority,
);
}).toList(),
],
),
Padding(
padding: const EdgeInsets.symmetric(vertical: 20),
child: Row(
children: [
Expanded(
child: CustomButton(
backgroundColor: AppColors.darkGrey,
title: LocaleKeys.cancel.locale,
titleColor: AppColors.lavenderBlue,
onClick: () => onClickCancel.call(),
),
),
SizedBox(width: 10),
Expanded(
child: CustomButton(
title: LocaleKeys.save.locale,
onClick: () => onClickSave.call(),
),
),
],
),
),
],
),
);
}
Widget _buildPriorityItem({
required int priority,
required bool isClick,
required VoidCallback onTap,
}) {
return GestureDetector(
onTap: () => onTap.call(),
child: Container(
padding: EdgeInsets.symmetric(horizontal: 24, vertical: 8),
decoration: BoxDecoration(
color: isClick ? AppColors.lavenderBlue : AppColors.balticSea,
borderRadius: BorderRadius.circular(6),
),
child: Column(
children: [
Image.asset(
AppAssets.icFlagPath,
width: 24,
height: 24,
),
SizedBox(height: 6),
Text(
'${priority.toString()}',
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.w400,
color: AppColors.white.withOpacity(0.87),
),
),
],
),
),
);
}
}
我使用组件的区域 主选项卡代码:
import 'package:want_to_do/export.dart';
import 'package:want_to_do/generated/locale_keys.g.dart';
import 'package:want_to_do/ui/widgets/custom_task_priority.dart';
class MainTabPage extends StatefulWidget {
const MainTabPage({super.key});
@override
State<MainTabPage> createState() => _MainTabPageState();
}
class _MainTabPageState extends BaseStatefulState<MainTabPage> {
@override
Widget build(BuildContext context) {
final _vm = Provider.of<MainTabViewModel>(context);
return Scaffold(
backgroundColor: AppColors.backgroundColor,
extendBody: true,
floatingActionButton: FloatingActionButton(
onPressed: () {
showCustomBottomSheet(
context: context,
child: AddTaskBottomSheet(
taskTitleController: _vm.taskTitleController,
taskDescriptionController: _vm.taskDescriptionController,
onclickTaskPriority: () {
_vm.checkTaskParameters()
? showPopupDialog(
context: context,
child: CustomTaskPriority(
onClickCancel: appRoutes.popIfBackStackNotEmpty,
onClickSave: appRoutes.popIfBackStackNotEmpty,
selectedPriority: _vm.selectedPriority,
onPrioritySelected: (int value) {
_vm.selectedPriority = value;
},
),
)
: showToastMessage(
LocaleKeys.errorMessages_emptyOrNotSame.locale,
);
},
),
);
},
shape: CircleBorder(eccentricity: 1),
child: _buildFloatingActionButton(),
),
floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
bottomNavigationBar: BottomAppBar(
padding: EdgeInsets.zero,
color: AppColors.darkGrey,
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 10),
child: _buildNavigationBar(_vm),
),
),
body: _buildBody(_vm),
);
}
Widget _buildBody(MainTabViewModel vm) {
switch (vm.currentIndex) {
case 0:
return HomeProvider();
case 1:
return CalendarProvider();
case 2:
return HomeProvider();
case 3:
return ProfileProvider();
default:
return HomeProvider();
}
}
Widget _buildFloatingActionButton() {
return Container(
padding: EdgeInsets.all(16),
decoration: BoxDecoration(
color: AppColors.lavenderBlue,
shape: BoxShape.circle,
),
child: Image.asset(AppAssets.icPlusAddPath),
);
}
Widget _buildNavigationBar(MainTabViewModel vm) {
return Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
BottomAppBarItem(
iconAddress: vm.currentIndex == 0
? AppAssets.icActiveHomePath
: AppAssets.icInactiveHomePath,
pageName: LocaleKeys.home_home.locale,
onTap: () {
vm.currentIndex = 0;
},
),
BottomAppBarItem(
iconAddress: vm.currentIndex == 1
? AppAssets.icActiveCalendarPath
: AppAssets.icInactiveCalendarPath,
pageName: LocaleKeys.calendar.locale,
onTap: () {
vm.currentIndex = 1;
},
),
SizedBox(),
BottomAppBarItem(
iconAddress: vm.currentIndex == 2
? AppAssets.icActiveFocusPath
: AppAssets.icInactiveFocusPath,
pageName: LocaleKeys.focus.locale,
onTap: () {
vm.currentIndex = 2;
},
),
BottomAppBarItem(
iconAddress: vm.currentIndex == 3
? AppAssets.icActiveProfilePath
: AppAssets.icInactiveProfilePath,
pageName: LocaleKeys.profileTitle.locale,
onTap: () {
vm.currentIndex = 3;
},
),
],
);
}
}
MainTabViewModel 代码:
import 'package:want_to_do/base/base_view_model.dart';
import 'package:want_to_do/export.dart';
class MainTabViewModel extends BaseViewModel {
TextEditingController taskTitleController = TextEditingController();
TextEditingController taskDescriptionController = TextEditingController();
int _currentIndex = 0;
int get currentIndex => _currentIndex;
set currentIndex(int value) {
_currentIndex = value;
notifyListeners();
}
int _selectedPriority = 1;
int get selectedPriority => _selectedPriority;
set selectedPriority(int value) {
_selectedPriority = value;
print("Priority changed: $value");
notifyListeners();
}
String _taskTitleText = '';
String _taskDescriptionText = '';
set taskTitleText(String text) {
_taskTitleText = text;
notifyListeners();
}
String get taskTitleText => _taskTitleText;
set taskDescriptionText(String text) {
_taskDescriptionText = text;
notifyListeners();
}
String get taskDescriptionText => _taskDescriptionText;
bool checkTaskParameters() {
_taskTitleText = taskTitleController.text;
_taskDescriptionText = taskDescriptionController.text;
if (_taskTitleText.isNotEmpty && _taskDescriptionText.isNotEmpty)
return true;
return false;
}
}
MainTabProvider 代码:
import 'package:want_to_do/export.dart';
class MainTabProvider extends StatelessWidget {
const MainTabProvider({super.key});
@override
Widget build(BuildContext context) {
return ChangeNotifierProvider(
create: (context) => MainTabViewModel(),
child: const MainTabPage(),
);
}
}
BaseStatfulState 代码:
import 'package:want_to_do/export.dart';
import 'package:want_to_do/services/service.locator.dart';
import 'package:want_to_do/utils/utility.dart';
abstract class BaseStatefulState<T extends StatefulWidget> extends State<T> {
final AppRoutes appRoutes = locator<AppRoutes>();
LocalStorageService localStorage = LocalStorageService();
late FToast fToast;
@override
void initState() {
super.initState();
fToast = FToast();
fToast.init(context);
}
void showToastMessage(String content) {
fToast.showToast(
child: Utility().buildToast(content),
gravity: ToastGravity.TOP,
positionedToastBuilder: (context, child) {
return Positioned(
child: child,
top: 50,
left: 20,
right: 20,
);
},
);
}
void showCustomBottomSheet({
required BuildContext context,
required Widget child,
}) {
showModalBottomSheet<void>(
context: context,
isScrollControlled: true,
builder: (context) {
return Padding(
padding: EdgeInsets.only(
bottom: MediaQuery.of(context).viewInsets.bottom,
),
child: child,
);
},
);
}
void showPopupDialog({
required BuildContext context,
required Widget child,
}) {
showDialog<void>(
barrierColor: AppColors.black.withOpacity(0.74),
barrierDismissible: false,
context: context,
builder: (context) {
return Dialog(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(6),
),
insetPadding: EdgeInsets.symmetric(horizontal: 24),
elevation: 0,
backgroundColor: AppColors.darkGrey,
child: child,
);
},
);
}
}
BaseViewModel 代码:
import 'package:flutter/cupertino.dart';
class BaseViewModel extends ChangeNotifier {
}
单击加号按钮时出现的第一个屏幕: 在此输入图片描述
当我单击此屏幕上的某人时,我希望更改单击的容器的颜色。 这是我单击标志按钮时出现的屏幕: 在此输入图片描述
单击其中任何一个时的控制台输出: 在此输入图片描述
坦白说,我不想在组件中使用StatefulWidget。我不知道如何解决这种情况。我缺少什么?我在等待你的想法。提前致谢。我用消费者包装它,但仍然没有任何改变。
首先,弹出窗口或显示对话框或底部工作表应该是一个单独的状态(statefullWidget 或 statefulbuilder 都为您提供 SetState() 函数)
其次,每当你想要更新此状态 UI 时,你应该将此 SetState() 函数作为参数传递并从外部调用它。