Всплывающий доступ к контексту родительского элемента нижней навигации

#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