#flutter #themes #bottomnavigationview #flutter-provider #flutter-bottomnavigation
#трепетание #темы #bottomnavigationview #flutter-provider #flutter-bottomnavigation
Вопрос:
Проблема всякий раз, когда я нажимаю флажок внутри ThemeSwitcher, происходит что-то сумасшедшее, подобное этому: введите описание изображения здесь
Я пытаюсь получить контекст MainPage.dart и передать его виджету с именем ThemeSwitcher в SettingsPage.dart
Я использую этот плагин: https://pub.dev/packages/animated_theme_switcher
1- Существует класс main.dart, который содержит ThemeProvider всего приложения
2- Класс MainPage.dart, который содержит переходы между 4 страницами
3- Страница настроек.dart, которая содержит виджет области переключения тем и виджет темы
Пожалуйста, проверьте важные блоки кода, связанные с этим плагином в моем проекте:
main.dart
import 'package:flutter/material.dart';
import 'InitPage.dart';
import 'package:animated_theme_switcher/animated_theme_switcher.dart';
void main() => runApp(MyApp());
class MyApp extends StatefulWidget {
@override
MyAppState createState() => MyAppState();
}
class MyAppState extends State<MyApp> {
@override
void initState() {
super.initState();
}
@override
Widget build(BuildContext context) {
final isPlatformDark =
WidgetsBinding.instance.window.platformBrightness == Brightness.dark;
final initTheme = isPlatformDark ? darkTheme : lightTheme;
return ThemeProvider(
initTheme: initTheme,
child: Builder(builder: (context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeProvider.of(context),
home: InitPage(),
);
}),
);
}
}
final lightTheme = ThemeData(
brightness: Brightness.light,
primaryColor: Colors.white,
accentColor: Colors.greenAccent,
bottomAppBarColor: Colors.greenAccent,
hintColor: Colors.yellowAccent,
textTheme: TextTheme(
title: TextStyle(
color: Colors.white,
),
),
);
final darkTheme = ThemeData(
brightness: Brightness.dark,
primaryColor: Colors.black,
accentColor: Colors.blueAccent,
hintColor: Colors.deepOrangeAccent,
bottomAppBarColor: Colors.grey,
textTheme: TextTheme(
title: TextStyle(
color: Colors.white,
),
),
);
MainPage.dart
import 'package:Fekra/constants.dart';
import 'package:move_to_background/move_to_background.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'HomePage.dart';
import 'ProfilePage.dart';
import 'NotificationsPage.dart';
import 'SettingsPage.dart';
class MainPage extends StatefulWidget {
@override
MainPageState createState() => new MainPageState();
}
class MainPageState extends State<MainPage>
with SingleTickerProviderStateMixin {
int current_index = 0;
int notCount = 6;
SvgPicture home1 = new SvgPicture.asset('assets/home1_icon.svg', color:grey, width: 27, height: 27);
SvgPicture home2 = new SvgPicture.asset('assets/home2_icon.svg', color: green, width: 27, height: 27);
SvgPicture profile1 = new SvgPicture.asset('assets/profile1_icon.svg', color: grey, width: 27, height: 27);
SvgPicture profile2 = new SvgPicture.asset('assets/profile2_icon.svg', color: green, width: 27, height: 27);
SvgPicture notifications1 = new SvgPicture.asset('assets/notifications1_icon.svg', color: grey, width: 27, height: 27);
SvgPicture notifications2 = new SvgPicture.asset('assets/notifications2_icon.svg', color: green, width: 27, height: 27);
SvgPicture settings1 = new SvgPicture.asset('assets/settings1_icon.svg', color:grey, width: 27, height: 27);
SvgPicture settings2 = new SvgPicture.asset('assets/settings2_icon.svg', color: green, width: 27, height: 27);
final List<Widget> children = [
HomePage(),
ProfilePage(),
NotificationsPage(),
SettingsPage(),
];
TabController tabController;
@override
void initState() {
super.initState();
tabController = TabController(vsync: this, length: children.length);
}
void dispose() {
tabController.dispose();
super.dispose();
}
Future<bool> onBack() {
bool value = false;
setState(() {
if (current_index != 0) {
current_index = 0;
value = false;
} else {
MoveToBackground.moveTaskToBack();
}
});
return Future<bool>.value(value);
}
onTapped(int index) {
setState(() {
current_index = index;
if(current_index == 2) {
notCount = 0;
}
});
}
@override
Widget build(BuildContext context) {
return WillPopScope(
onWillPop: onBack,
child: new Scaffold(
body: Column(children: <Widget>[
Expanded(child:
IndexedStack(
index: current_index,
children: children,
)),Divider(
thickness: 0.3,
color: grey,
indent: 0,
endIndent: 0,
height: 0),
]),
bottomNavigationBar: BottomNavigationBar(
onTap: onTapped,
backgroundColor: Colors.white,
elevation: 0,
currentIndex: current_index,
type: BottomNavigationBarType.fixed,
items: [
BottomNavigationBarItem(
icon: current_index == 0 ?
Container(
alignment: AlignmentDirectional.bottomCenter,
width: 35,
height: 35,
child: home2,)
: Container(
alignment: AlignmentDirectional.bottomCenter,
width: 35,
height: 35,
child: home1,),
title: Container(),
),
BottomNavigationBarItem(
icon: current_index == 1 ?
Container(
alignment: AlignmentDirectional.bottomCenter,
width: 35,
height: 35,
child: profile2,)
: Container(
alignment: AlignmentDirectional.bottomCenter,
width: 35,
height: 35,
child: profile1,),
title: Container(),
),
BottomNavigationBarItem(
icon: current_index == 2 ?
Container(
alignment: AlignmentDirectional.bottomCenter,
width: 35,
height: 35,
child: notifications2,)
:
Stack(
alignment: AlignmentDirectional.bottomCenter,
children: [
notifications1,
Container(
width: 35,
height: 35,
alignment: Alignment.topRight,
child: notCount == 0 ? null : Container(
width: 18,
height: 18,
alignment: AlignmentDirectional.center,
decoration: BoxDecoration(
color: Colors.transparent,
shape: BoxShape.circle,
border: Border.all(color: Colors.white, width: 2),
),
child: Container(alignment:AlignmentDirectional.center
,width: 18,
height: 18,
decoration: BoxDecoration(
color: Colors.red,
shape: BoxShape.circle,
),
child:Text(
notCount.toString(),
textAlign: TextAlign.center,
style: TextStyle(fontSize: 10, color: Colors.white),
),
)
),
),
],
),
title: Container(),
),
BottomNavigationBarItem(
icon: current_index == 3 ?
Container(
alignment: AlignmentDirectional.bottomCenter,
width: 35,
height: 35,
child: settings2,):
Container(
alignment: AlignmentDirectional.bottomCenter,
width: 35,
height: 35,
child: settings1,),
title: Container(),
),
],
),
));
}
}
SettingsPage.dart
@override
Widget build(BuildContext context) {
return ThemeSwitchingArea(
child: WillPopScope(
onWillPop: () async {
return true;
},
child: Scaffold(
body: SafeArea(
child: Column(
children: <Widget>[
Container(
margin: EdgeInsets.fromLTRB(0, 0, 0, 10),
height: 70,
decoration: BoxDecoration(
color: Colors.white,
border: Border.all(
color: grey,
width: 0.2,
),
borderRadius: BorderRadius.only(
bottomRight: Radius.circular(30),
bottomLeft: Radius.circular(30)),
),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Text(
"Settings",
style: TextStyle(
color: Colors.black, fontSize: 30.0),
textAlign: TextAlign.center,
),
ThemeSwitcher(
builder: (context) {
return Checkbox(
value: ThemeProvider.of(context) == darkTheme,
onChanged: (needDark) {
ThemeSwitcher.of(context).changeTheme(
theme: needDark ? darkTheme : lightTheme,
);
},
);
},
),
],
),
),
Expanded(
child: SingleChildScrollView(
scrollDirection: Axis.vertical,
child: Container(
width: MediaQuery
.of(context)
.size
.width,
margin: EdgeInsets.fromLTRB(0, 0, 0, 15),
decoration: BoxDecoration(
color: Colors.white,
border: Border.all(
color: grey,
width: 0.2,
),
borderRadius: BorderRadius.circular(30.0),
),
child: Column(children: <Widget>[
Container(
width: MediaQuery
.of(context)
.size
.width,
height: 65,
margin: EdgeInsets.fromLTRB(
0, 0, 0, 0),
child: FlatButton(
onPressed: myAccountPressed,
textColor: green,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.only(
topRight: Radius.circular(
30),
topLeft: Radius.circular(
30)),
),
child: Row(
mainAxisAlignment:
MainAxisAlignment.start,
children: <Widget>[
Container(
margin: EdgeInsets
.fromLTRB(
12, 0, 20, 0),
child: SvgPicture.asset(
'assets/account_icon.svg',
width: 25),
),
Container(
margin: EdgeInsets
.fromLTRB(
0, 0, 10, 0),
child: Text("My Account",
style: TextStyle(
fontSize: 20.0,
color: Colors
.black)),
),
]))),
Divider(
thickness: 0.5,
color: grey,
indent: 75,
endIndent: 25,
height: 0),
Container(
width: MediaQuery
.of(context)
.size
.width,
height: 65,
margin: EdgeInsets.fromLTRB(
0, 00, 0, 00),
child: FlatButton(
onPressed: notificationPressed,
textColor: green,
child: Row(
mainAxisAlignment:
MainAxisAlignment.start,
children: <Widget>[
Container(
margin: EdgeInsets
.fromLTRB(
12, 0, 20, 0),
child: SvgPicture.asset(
'assets/notifications3_icon.svg',
width: 25),
),
Container(
margin: EdgeInsets
.fromLTRB(
0, 0, 10, 0),
child: Text(
"Notifications",
style: TextStyle(
fontSize: 20.0,
color: Colors
.black)),
),
]))),
Divider(
thickness: 0.5,
color: grey,
indent: 75,
endIndent: 25,
height: 0),
Container(
width: MediaQuery
.of(context)
.size
.width,
height: 65,
margin: EdgeInsets.fromLTRB(
0, 00, 0, 00),
child: FlatButton(
onPressed: followMajorsPressed,
textColor: green,
child: Row(
mainAxisAlignment:
MainAxisAlignment.start,
children: <Widget>[
Container(
margin: EdgeInsets
.fromLTRB(
12, 0, 20, 0),
child: SvgPicture.asset(
'assets/majors_icon.svg',
width: 25),
),
Container(
margin: EdgeInsets
.fromLTRB(
0, 0, 10, 0),
child: Text(
"Follow Majors",
style: TextStyle(
fontSize: 20.0,
color: Colors
.black)),
),
]))),
Divider(
thickness: 0.5,
color: grey,
indent: 75,
endIndent: 25,
height: 0),
Container(
width: MediaQuery
.of(context)
.size
.width,
height: 65,
margin: EdgeInsets.fromLTRB(
0, 00, 0, 00),
child: FlatButton(
onPressed: share,
textColor: green,
child: Row(
mainAxisAlignment:
MainAxisAlignment.start,
children: <Widget>[
Container(
margin: EdgeInsets
.fromLTRB(
12, 0, 20, 0),
child: SvgPicture.asset(
'assets/share_icon.svg',
width: 25),
),
Container(
margin: EdgeInsets
.fromLTRB(
0, 0, 10, 0),
child: Text(
"Invite Friends",
style: TextStyle(
fontSize: 20.0,
color: Colors
.black)),
),
]))),
Divider(
thickness: 0.5,
color: grey,
indent: 75,
endIndent: 25,
height: 0),
Container(
width: MediaQuery
.of(context)
.size
.width,
height: 65,
margin: EdgeInsets.fromLTRB(
0, 00, 0, 00),
child: FlatButton(
onPressed: aboutPressed,
textColor: green,
child: Row(
mainAxisAlignment:
MainAxisAlignment.start,
children: <Widget>[
Container(
margin: EdgeInsets
.fromLTRB(
12, 0, 20, 0),
child: SvgPicture.asset(
'assets/about_icon.svg',
width: 25),
),
Container(
margin: EdgeInsets
.fromLTRB(
0, 0, 10, 0),
child: Text("About",
style: TextStyle(
fontSize: 20.0,
color: Colors
.black)),
),
]))),
Divider(
thickness: 0.5,
color: grey,
indent: 75,
endIndent: 25,
height: 0),
Container(
width: MediaQuery
.of(context)
.size
.width,
height: 65,
margin: EdgeInsets.fromLTRB(
0, 00, 0, 00),
child: FlatButton(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.only(
bottomLeft: Radius.circular(
30),
bottomRight: Radius
.circular(30)),
),
onPressed: logoutPressed,
textColor: green,
child: Row(
mainAxisAlignment:
MainAxisAlignment.start,
children: <Widget>[
Container(
margin: EdgeInsets
.fromLTRB(
12, 0, 20, 0),
child: SvgPicture.asset(
'assets/logout_icon.svg',
width: 25),
),
Container(
margin: EdgeInsets
.fromLTRB(
0, 0, 10, 0),
child: Text("Log Out",
style: TextStyle(
fontSize: 20.0,
color: Colors
.black)),
),
]))),
]),
))),
],
))))
);
}
Ответ №1:
Решение:
Мне удалось решить мою проблему на следующий день, поместив виджет ThemeSwitchingArea в MainPage.dart и оставив виджет ThemeSwitcher в SettingsPage.dart