riez0306
riez0306

Reputation: 43

flutter_localizations error Null check operator used on a null value

I want to make MyApp with Navigation Drawer. When open drawer, I got the following exception that is occured by flutter_localization.

Exception caught by widgets library ======================================================= The following _CastError was thrown building NavigationDrawer(dirty, dependencies: [_LocalizationsScope-[GlobalKey#9fbb0]]): Null check operator used on a null value

import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import 'package:flutter_localizations/flutter_localizations.dart';

void main() {
  WidgetsFlutterBinding.ensureInitialized();
  runApp(const MaterialApp(
    localizationsDelegates: [
      AppLocalizations.delegate,
      GlobalMaterialLocalizations.delegate,
      GlobalWidgetsLocalizations.delegate,
      GlobalCupertinoLocalizations.delegate,
    ],
    supportedLocales: [
      Locale('en'),
      Locale('ja'),
    ],
    home: MyPage(),
  ));
}

/// A simple app that loads an adaptive banner ad.
class MyPage extends StatefulWidget {
  const MyPage({super.key});

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

class NavigationDrawer extends StatelessWidget {
  const NavigationDrawer({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) => Drawer(
    child: SingleChildScrollView(
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.stretch,
        children: [
          buildMenuItems(context),
        ],
      ),
    ),
  );

  Widget buildMenuItems(BuildContext context) => Container(
    padding: const EdgeInsets.all(24),
    child: Wrap(
      runSpacing: 16,
      children: [
        ListTile(
          leading: const Icon(Icons.person),
          title: Text(AppLocalizations.of(context).person),
          onTap: (){},
        ),
      ],
    ),
  );
}

class MyPageState extends State<MyPage> {
  final _key = GlobalKey<ScaffoldState>();

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: AppLocalizations.of(context).appname,
      theme: ThemeData.light(),
      darkTheme: ThemeData.dark(),
      themeMode: ThemeMode.system,
      home: Scaffold(
        key: _key,
        appBar: AppBar(
          title: Text(AppLocalizations.of(context).appname),
        ),
        drawer: SafeArea(
          bottom: false,
          child: const NavigationDrawer(),
        ),
        body: Stack(
        ),),
    );
  }
}

AppLocalizations.of(context).appname work well. But AppLocalizations.of(context).person does not work. So I guess the context in NavigationDrawer does not have locale info.

Upvotes: 2

Views: 1178

Answers (2)

riez0306
riez0306

Reputation: 43

class MyPageState extends State<MyPage> {
  final _key = GlobalKey<ScaffoldState>();

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: AppLocalizations.of(context).appname,
      theme: ThemeData.light(),
      darkTheme: ThemeData.dark(),
      themeMode: ThemeMode.system,
      localizationsDelegates: [
        AppLocalizations.delegate,
        GlobalMaterialLocalizations.delegate,
        GlobalWidgetsLocalizations.delegate,
        GlobalCupertinoLocalizations.delegate,
      ],
      supportedLocales: [
        Locale('en'),
        Locale('ja'),
      ],
      home: Scaffold(
        key: _key,
        appBar: AppBar(
          title: Text(AppLocalizations.of(context).appname),
        ),
        drawer: SafeArea(
          bottom: false,
          child: const NavigationDrawer(),
        ),
        body: Stack(
        ),),
    );
  }
}

Upvotes: 1

Rahul
Rahul

Reputation: 4331

That would be happening because .appname takes context of MaterialApp defined in main method but NavigationDrawer is trying to find localized string in MaterialApp defined in MyPageState.

Q. What it is happening?

A. MaterialApp has build method and it is based on WidgetsApp which also has build method. Inside WidgetsApp's build method, Localizations widget is used. AppLocalizations.of(context) tries to find AppLocalizations class object in nearest Localizations widget which in your case is default one. Hence it is throwing error.

S. You can either pass the localization delegate again in inner MaterialApp or You can create extension method to find AppLocalizations which is at root.

Upvotes: 2

Related Questions