Flutter:ChangeNotifierProvider不侦听更改

z6psavjg  于 2023-06-30  发布在  Flutter
关注(0)|答案(1)|浏览(154)

我是个新手。我已经添加了本地化到我的应用程序,我做了一个语言切换器。我正在尝试提供语言切换器的更改。它适用于所有字符串,除了底部导航栏。它在改变语言后有一个奇怪的行为。有时它会立即更改导航栏中字符串的语言,有时只在我第二次点击下拉菜单中所选的语言后才会更改。它只会在我点击导航栏项目后更改导航栏项目的语言。
下面是我的代码:
导航栏箭头

class NavBarScreen extends StatefulWidget {
  static of(BuildContext context, {bool root = false}) => root
      ? context.findRootAncestorStateOfType<_NavBarState>()
      : context.findAncestorStateOfType<_NavBarState>();
  @override
  State<NavBarScreen> createState() => _NavBarState();
}

class _NavBarState extends State<NavBarScreen> {
  int _selectedTab = 0;

  final List _pages = [
    Dashboard(),
    CodeScreen(),
    ImageGeneration(),
    TranslateScreen(),
    IAP(),
    LocalizationAppPage(),
  ];

  _changeTab(int index) {
    setState(() {
      ChangeNotifierProvider<LocaleProvider>;
      _selectedTab = index;
    });
  }

  @override
  Widget build(BuildContext context) {
    return ChangeNotifierProvider<LocaleProvider>(
        create: (context) => LocaleProvider(),
        builder: (context, child) {
          final provider = Provider.of<LocaleProvider>(context);

          return MaterialApp (
              debugShowCheckedModeBanner: false,
              title: 'home',
              theme: ThemeData(
              fontFamily: 'Raleway',
              scaffoldBackgroundColor: Colors.deepPurple.shade100,
              primaryColor: Colors.deepPurpleAccent,
          ),
              locale: provider.locale,
              supportedLocales: L10n.all,
              localizationsDelegates:  [
              S.delegate,
              AppLocalizations.delegate,
              GlobalMaterialLocalizations.delegate,
              GlobalCupertinoLocalizations.delegate,
              GlobalWidgetsLocalizations.delegate,
          ],
              home: Scaffold(
                backgroundColor: Colors.black,
              body: _pages[_selectedTab],
              bottomNavigationBar:
              Localizations.override(
              context: context,
              locale: provider.locale,
                child: Theme(
                data: ThemeData(
                canvasColor: Colors.black,
                ),
              child:
              BottomNavigationBar(
                backgroundColor: Colors.black,
              currentIndex: _selectedTab,
              onTap: (index) => _changeTab(index),
              selectedItemColor: const Color(0xFFbfeb91),
              unselectedItemColor: Colors.grey,
              showUnselectedLabels: true,
              items:  [
                BottomNavigationBarItem(
                    icon: Icon(Icons.message),
                    label: 'Chat'
                ),
                BottomNavigationBarItem(
                    icon: Icon(Icons.code),
                    label: 'Code'
                ),
                BottomNavigationBarItem(
                    icon: Icon(Icons.image),
                    label: S.of(context).image
                ),
                BottomNavigationBarItem(
                    icon: Icon(Icons.language),
                    label: S.of(context).translate
                ),
                BottomNavigationBarItem(
                    icon: Icon(Icons.shopping_cart),
                    label: 'Shop'
                ),
                BottomNavigationBarItem(
                    icon: Icon(Icons.settings),
                    label: "Language"
                ),
              ],
            ),
          ),
          ),
          ),
          );
        }
    );
  }
}

locale_provider.dart

class LocaleProvider extends ChangeNotifier {
  Locale? _locale;

  Locale? get locale => _locale;

  void setLocale(Locale locale) {
    if (!L10n.all.contains(locale)) return;

    _locale = locale;
    notifyListeners();
  }

  void clearLocale() {
    _locale = null;
    notifyListeners();
  }
}

language_switcher_widget.dart

class LanguageWidget extends StatefulWidget {
   LanguageWidget({super.key});

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

class _LanguageWidgetState extends State<LanguageWidget> {

@override
  void initState() {
    super.initState();
    ChangeNotifierProvider<LocaleProvider>;
  }

  @override
  Widget build(BuildContext context) {
    var locale = Localizations.localeOf(context);

    return Center(
      child:Column(
        mainAxisAlignment: MainAxisAlignment.center,
        crossAxisAlignment: CrossAxisAlignment.center,
      children: [
        DropdownButtonHideUnderline(
        child: DropdownButton(
          dropdownColor: Colors.black,
          value: locale,
          icon: Container(color: Colors.black, width: 44),
          items: L10n.all.map(
                (locale) {
              final flag = L10n.getFlag(locale.languageCode);
              final circleFlag = L10n.getCountryCode(locale.languageCode);

              return DropdownMenuItem(
                value: locale,
                onTap: () async {
                  var provider =
                  Provider.of<LocaleProvider>(context, listen: false);
                  provider.setLocale(locale);
                },
                child: Row(
                  mainAxisAlignment: MainAxisAlignment.start,
                    crossAxisAlignment: CrossAxisAlignment.end,
                    children: [
                      CircleFlag(circleFlag, size: 60),
                      const SizedBox(width: 12,),
                      Text(flag, style: const TextStyle(fontFamily: 'Raleway', fontSize: 32, color: Color(0xFFbfeb91))),
                    ]
                ),
              );
            },
          ).toList(),
          onChanged: (_) {},
        ),
      ),]
    ),
    );
  }
}
oprakyz7

oprakyz71#

你必须用Consumer Widget Package MaterialApp,然后使用providers值的更改,并且区域设置应该更改。
这样做的原因是,您注册提供程序的上下文与您希望获取提供程序的上下文相同。奇怪的是,你没有得到一个ProviderNotFoundException
更多详情:Consumer Widget

相关问题