Почему Navigator pushNamedAndRemoveUntil не работает должным образом? - PullRequest
1 голос
/ 09 мая 2020

Источник
В моем приложении у меня есть основная c панель приложений с чернильницами для обработки жестов (касаний).

Я использую провайдера для изменения своей темы, но когда я использую свой ящик приложения для go для любого именованного маршрута, он удаляет исходный маршрут, даже если я использую pushNamedAndRemoveUntil.

Однако это работает, когда я меняю свою тему . Например, когда я go на settings_screen.dart и использую переключатель, чтобы изменить свою тему со светлого на темный, появляется кнопка «Назад», то есть мой начальный маршрут. В чем причина такого странного поведения?
main.dart

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';

//Providers
import './providers/themes.dart';

//screens
import './screens/home_screen.dart';
import './screens/about_screen.dart';
import './screens/news_screen.dart';
import './screens/department_screen.dart';
import './screens/admission_screen.dart';
import './screens/placements_screen.dart';
import './screens/contact_us_screen.dart';
import './screens/settings_screen.dart';

void main() => runApp(SfitApp());

class SfitApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return ChangeNotifierProvider<Themes>(
      create: (_) => Themes(),
      child: MaterialAppWithTheme(),
    );
  }
}

class MaterialAppWithTheme extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final theme = Provider.of<Themes>(context);
    return MaterialApp(
      title: "SFIT App",
      //routes
      initialRoute: '/',
      routes: {
        '/': (context) => HomeScreen(),
        AboutScreen.routeName: (context) => AboutScreen(),
        NewsScreen.routeName: (context) => NewsScreen(),
        AdmissionScreen.routeName: (context) => AdmissionScreen(),
        DepartmentScreen.routeName: (context) => DepartmentScreen(),
        PlacementsScreen.routeName: (context) => PlacementsScreen(),
        ContactUsScreen.routeName: (context) => ContactUsScreen(),
        SettingsScreen.routeName: (context) => SettingsScreen(),
      },
      //theme
      theme: theme.getTheme(),
    );
  }
}

ящик приложения

import 'package:flutter/material.dart';

//constants
import '../constants.dart';

//screens
import '../screens/home_screen.dart';
import '../screens/settings_screen.dart';

class AppDrawer extends StatelessWidget {
  final String title;

  AppDrawer({@required this.title});

  @override
  Widget build(BuildContext context) {
    return Drawer(
      child: ListView(
        children: <Widget>[
          DrawerHeader(
            child: Text(
              title,
              style: Theme.of(context).textTheme.title,
            ),
          ),

//          Home
          InkWell(
            splashColor: Colors.lightBlueAccent,
            borderRadius: BorderRadius.circular(6),
            onTap: () {
              Navigator.of(context).popUntil(
                ModalRoute.withName('/'),
              );
            },
            child: ListTile(
              leading: ClipRRect(
                borderRadius: BorderRadius.circular(5),
                child: Container(
                  padding: EdgeInsets.all(7),
                  color: Colors.lightBlueAccent,
                  child: Icon(Icons.home, color: Colors.white),
                ),
              ),
              title: Text(
                'Home',
                style: Theme.of(context).textTheme.bodyText2,
              ),
            ),
          ),
//          About
          NavigationDrawerItem(appSections[0]),
//          News
          NavigationDrawerItem(appSections[1]),
//          Admission
          NavigationDrawerItem(appSections[2]),
//          Department
          NavigationDrawerItem(appSections[3]),
//          Training and Placement
          NavigationDrawerItem(appSections[4]),
//          Contact Us
          NavigationDrawerItem(appSections[5]),

          Divider(
            color: Theme.of(context).brightness == Brightness.light
                ? Colors.grey
                : Colors.grey[600],
          ),

//        Preferences
          InkWell(
            borderRadius: BorderRadius.circular(6),
            onTap: () {
              Navigator.of(context).pushNamed(SettingsScreen.routeName);
            },
            child: ListTile(
              leading: ClipRRect(
                borderRadius: BorderRadius.circular(5),
                child: Container(
                  padding: EdgeInsets.all(7),
                  child: Icon(
                    Icons.settings,
                    color: Theme.of(context).brightness == Brightness.light
                        ? Colors.black
                        : Colors.white,
                  ),
                ),
              ),
              title: Text(
                'Settings',
                style: Theme.of(context).textTheme.bodyText2,
              ),
            ),
          ),
        ],
      ),
    );
  }
}

class NavigationDrawerItem extends StatelessWidget {
  final appSectionItem;

  NavigationDrawerItem(this.appSectionItem);

  @override
  Widget build(BuildContext context) {
    return InkWell(
      splashColor: appSectionItem['color'],
      borderRadius: BorderRadius.circular(6),
      onTap: () {
        Navigator.of(context).pushNamedAndRemoveUntil(
          appSectionItem['onTap'],
          ModalRoute.withName('/'),
        );
      },
      child: ListTile(
        leading: ClipRRect(
          borderRadius: BorderRadius.circular(5),
          child: Container(
            padding: EdgeInsets.all(7),
            color: appSectionItem['color'],
            child: Icon(
              appSectionItem['icon'],
              color: Colors.white,
            ),
          ),
        ),
        title: Text(
          appSectionItem['title'],
          style: Theme.of(context).textTheme.bodyText2,
        ),
      ),
    );
  }
}

themes.dart

import 'package:flutter/material.dart';

class Themes with ChangeNotifier {
  ThemeData _theme = ThemeData(
    brightness: Brightness.light,
//    primaryColor: Colors.yellow,
//    accentColor: Colors.amber,
    fontFamily: 'OpenSans',
    textTheme: TextTheme(
      headline5: TextStyle(
        fontFamily: 'OpenSans',
        fontSize: 16,
      ),
      headline6: TextStyle(
        fontFamily: 'OpenSans',
        fontWeight: FontWeight.bold,
        fontSize: 25,
      ),
      bodyText1: TextStyle(
        fontFamily: 'OpenSans',
        fontSize: 14,
      ),
      bodyText2: TextStyle(
        fontFamily: 'OpenSans',
        fontSize: 12,
      ),
      headline4: TextStyle(
        fontFamily: 'PlayfairDisplay',
        fontSize: 25,
        color: Colors.yellow[900],
      ),
    ),
  );

  getTheme() => _theme;

  changeTheme(brightness) {
    _theme = ThemeData(brightness: brightness);
    notifyListeners();
  }

}

экран настроек

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';

//providers
import '../providers/themes.dart';

class SettingsScreen extends StatefulWidget {
  static const routeName = 'settings_screen';

  @override
  _SettingsScreenState createState() => _SettingsScreenState();
}

class _SettingsScreenState extends State<SettingsScreen> {
  bool isSwitched = false;

  @override
  Widget build(BuildContext context) {
    Themes themeChanger = Provider.of<Themes>(context);
    return Scaffold(
      appBar: AppBar(
        title: Text(
          'Settings',
          style: Theme.of(context).textTheme.headline6,
        ),
        brightness: Theme.of(context).brightness,
        elevation: 3,
      ),
      body: Container(
        width: double.infinity,
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.stretch,
          children: <Widget>[
            Padding(
              padding: EdgeInsets.fromLTRB(20, 10, 0, 10),
              child:
                  Text("Theme", style: Theme.of(context).textTheme.headline5),
            ),
            ListTile(
              title: Text(
                "Overall look and feel of the app",
                style: Theme.of(context).textTheme.bodyText1,
              ),
              subtitle: Text("Light/ Dark"),
              trailing: Switch(
                value: isSwitched,
                onChanged: (value) {
                  if (value) {
                    themeChanger.changeTheme(Brightness.dark);
                    setState(() {
                      isSwitched = value;
                    });
                    print(value);
                  } else {
                    themeChanger.changeTheme(Brightness.light);
                    setState(() {
                      isSwitched = value;
                    });
                    print(value);
                  }
                },
              ),
            ),
          ],
        ),
      ),
    );
  }
}

Остальные файлы не включены. Но когда я перехожу к любому из них, кнопка «Действие», которая должна появляться на панели приложения, не отображается.

...