My AppLocalizations in Flutter return null value

261 views Asked by At

I am using flutter localization for my app. This is the code where I implemented it:

class Dashboard extends StatefulWidget {
  const Dashboard({Key? key}) : super(key: key);

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

class _DashboardState extends State<Dashboard> with WidgetsBindingObserver {

  AppLifecycleState? _appLifecycleState;

  @override
  void initState() {
    super.initState();
    WidgetsBinding.instance.addObserver(this);
  }


  @override
  void didChangeAppLifecycleState(AppLifecycleState state) {
    super.didChangeAppLifecycleState(state);
    if (state == AppLifecycleState.paused ||
        state == AppLifecycleState.inactive) {
      Provider.of<DataProvider>(context).disconnect();
    }
  }

  @override
  void dispose() {
    WidgetsBinding.instance?.removeObserver(this);
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Consumer<DataProvider>(builder: (context, dataProvider, child) {
      AppLocalizations? appLocalizations = AppLocalizations.of(context);

      final DataProvider dataProvider = Provider.of<DataProvider>(context);


      Widget actions = bike != null
          ? Container(
              alignment: Alignment.center,
              margin: const EdgeInsets.fromLTRB(0, 20, 0, 50),
              child: Column(
                children: [
                  Container(
                      margin: const EdgeInsets.only(bottom: 20),
                      alignment: Alignment.centerLeft,
                      child: Text(
                        appLocalizations!.actionsTitle,
                        style: const TextStyle(
                            fontSize: 24, fontWeight: FontWeight.bold),
                      )),
                  Row(
                    children: [
                      Expanded(
                        flex: 1,
                        child: Column(
                          children: [
                            ElevatedButton(
                                onPressed: () {
                                  if (bike.theftProtection) {
                                    setState(() {
                                      bikeProvider
                                          .untheft(bike.frameId.toString());
                                    });
                                  } else {
                                    setState(() {
                                      bikeProvider
                                          .theft(bike.frameId.toString());
                                    });
                                  }
                                },
                                child: Container(
                                  child: const Icon(
                                          CustomIcons.theft_protection_on,
                                          size: 25.0,
                                          color: Colors.white,
                                        ),
                                )),
                            Container(
                              margin: const EdgeInsets.only(top: 10),
                              child: Text(
                                bike.theftProtection
                                    ? appLocalizations!.theftProtectionOn
                                    : appLocalizations!.theftProtectionOff,
                                style: const TextStyle(fontSize: 14),
                              ),
                            ),
                          ],
                        ),
                      ),
                      const SizedBox(width: 10),
                      Expanded(
                        flex: 1,
                        child: Column(
                          children: [
                            ElevatedButton(
                                onPressed: () {
                                  if (bike.isLocked) {
                                    setState(() {
                                      bikeProvider
                                          .unlock(bike.frameId.toString());
                                    });
                                  } else {
                                    setState(() {
                                      bikeProvider
                                          .lock(bike.frameId.toString());
                                    });
                                  }
                                },
                                child: Container(
                                  child: const Icon(
                                          CustomIcons.lock_closed,
                                          size: 25.0,
                                          color: Colors.white,
                                        )
                                )),
                            Container(
                              margin: const EdgeInsets.only(top: 10),
                              child: Text(
                                bike.isLocked
                                    ? appLocalizations!.unlockLabel
                                    : appLocalizations!.lockLabel,
                                style: const TextStyle(fontSize: 14),
                              ),
                            ),
                          ],
                        ),
                      ),
                    ],
                  )
                ],
              ))
          : Container();

      return MaterialApp(
        title: 'Dashboard Page',
        theme: ThemeData(fontFamily: 'GalanoGrotesque'),
        debugShowCheckedModeBanner: false,
        home: Scaffold(
          appBar: null,
          body: ListView(
            padding: const EdgeInsets.fromLTRB(20, 30, 0, 100),
            children: [
              header,
              Container(
                margin: const EdgeInsets.only(right: 20),
                child: Column(
                  children: [
                    actions,
                  ],
                ),
              )
            ],
          ),
        ),
        localizationsDelegates: const [
          AppLocalizations.delegate,
          GlobalMaterialLocalizations.delegate,
          GlobalWidgetsLocalizations.delegate,
          GlobalCupertinoLocalizations.delegate,
        ],
        supportedLocales: const [
          Locale('de'),
          Locale('en'),
        ],
      );
    });
  }
}

But when starting the app, I get following error:

Null check operator used on a null value

It is on the line with actionsTitle. I use the localization in other files so I know it generally works. Does anybody know if I made some mistake while initializing the AppLocalizations?

Thank you

3

There are 3 answers

0
Ilian Gion Häsler On

Answer:

I managed to get the answer I needed. I removed the MaterialApp from my _DashboardState and returned only the Scaffold instead:

class Dashboard extends StatefulWidget {
  const Dashboard({Key? key}) : super(key: key);

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

class _DashboardState extends State<Dashboard> with WidgetsBindingObserver {

  AppLifecycleState? _appLifecycleState;

  @override
  void initState() {
    super.initState();
    WidgetsBinding.instance.addObserver(this);
  }


  @override
  void didChangeAppLifecycleState(AppLifecycleState state) {
    super.didChangeAppLifecycleState(state);
    if (state == AppLifecycleState.paused ||
        state == AppLifecycleState.inactive) {
      Provider.of<DataProvider>(context).disconnect();
    }
  }

  @override
  void dispose() {
    WidgetsBinding.instance?.removeObserver(this);
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Consumer<DataProvider>(builder: (context, dataProvider, child) {
      AppLocalizations? appLocalizations = AppLocalizations.of(context);

      final DataProvider dataProvider = Provider.of<DataProvider>(context);


      Widget actions = bike != null
          ? Container(
              alignment: Alignment.center,
              margin: const EdgeInsets.fromLTRB(0, 20, 0, 50),
              child: Column(
                children: [
                  Container(
                      margin: const EdgeInsets.only(bottom: 20),
                      alignment: Alignment.centerLeft,
                      child: Text(
                        appLocalizations!.actionsTitle,
                        style: const TextStyle(
                            fontSize: 24, fontWeight: FontWeight.bold),
                      )),
                  Row(
                    children: [
                      Expanded(
                        flex: 1,
                        child: Column(
                          children: [
                            ElevatedButton(
                                onPressed: () {
                                  if (bike.theftProtection) {
                                    setState(() {
                                      bikeProvider
                                          .untheft(bike.frameId.toString());
                                    });
                                  } else {
                                    setState(() {
                                      bikeProvider
                                          .theft(bike.frameId.toString());
                                    });
                                  }
                                },
                                child: Container(
                                  child: const Icon(
                                          CustomIcons.theft_protection_on,
                                          size: 25.0,
                                          color: Colors.white,
                                        ),
                                )),
                            Container(
                              margin: const EdgeInsets.only(top: 10),
                              child: Text(
                                bike.theftProtection
                                    ? appLocalizations!.theftProtectionOn
                                    : appLocalizations!.theftProtectionOff,
                                style: const TextStyle(fontSize: 14),
                              ),
                            ),
                          ],
                        ),
                      ),
                      const SizedBox(width: 10),
                      Expanded(
                        flex: 1,
                        child: Column(
                          children: [
                            ElevatedButton(
                                onPressed: () {
                                  if (bike.isLocked) {
                                    setState(() {
                                      bikeProvider
                                          .unlock(bike.frameId.toString());
                                    });
                                  } else {
                                    setState(() {
                                      bikeProvider
                                          .lock(bike.frameId.toString());
                                    });
                                  }
                                },
                                child: Container(
                                  child: const Icon(
                                          CustomIcons.lock_closed,
                                          size: 25.0,
                                          color: Colors.white,
                                        )
                                )),
                            Container(
                              margin: const EdgeInsets.only(top: 10),
                              child: Text(
                                bike.isLocked
                                    ? appLocalizations!.unlockLabel
                                    : appLocalizations!.lockLabel,
                                style: const TextStyle(fontSize: 14),
                              ),
                            ),
                          ],
                        ),
                      ),
                    ],
                  )
                ],
              ))
          : Container();

      return Scaffold(
          appBar: null,
          body: ListView(
            padding: const EdgeInsets.fromLTRB(20, 30, 0, 100),
            children: [
              header,
              Container(
                margin: const EdgeInsets.only(right: 20),
                child: Column(
                  children: [
                    actions,
                  ],
                ),
              )
            ],
          ),
        );
    });
  }
}

Them I created a new StatelessWidget in which I make the MaterialApp with Dashboard as Home:

class DashboardPage extends StatelessWidget {
  const DashboardPage({Key? key}) : super(key: key);
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Dashboard Page',
      theme: ThemeData(fontFamily: 'GalanoGrotesque'),
      debugShowCheckedModeBanner: false,
      localizationsDelegates: const [
        AppLocalizations.delegate,
        GlobalMaterialLocalizations.delegate,
        GlobalWidgetsLocalizations.delegate,
        GlobalCupertinoLocalizations.delegate,
      ],
      supportedLocales: const [
        Locale('de'),
        Locale('en'),
      ],
      home: Dashboard(),
    );
  }
}

With that solution the context was correct and I didn't receive any errors anymore. Thanks to Just a Person, he gave a good answer and I could figure out my answer based on his.

0
Canilho On

When you have errors like this, you should try to validate if any of your variables is not defined, or is returning Null when they are being accessed.

One way to validate if a variable is Null, is to do a validation like this

assert(bike != null, 'Bike is null!');
assert(appLocalizations != null, 'appLocalizations is null!');

Make sure your Dart code is Null safe. Take the hints of your Stacktrace errors, to find issues like these.

2
Just a Person On

You are accessing AppLocalizations.of(context) in the build method before defining MaterialApp. In this case MaterialApp is the widget that introduces the AppLocalizations in the widget tree.

You can solve this issue by extracting the MaterialApp in a new widget and then use the Consumer widget in the child widget where you can use AppLocalizations.of(context). Inherited widgets in flutter use .of(context) syntax to look for a widget in the widget tree above the current widget and not the current widget. You are using the MaterialApp and AppLocalizations in the same widget which is causing the error.

Solution:

import 'package:flutter/material.dart';

class Dashboard extends StatefulWidget {
  const Dashboard({Key? key}) : super(key: key);

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

class _DashboardState extends State<Dashboard> with WidgetsBindingObserver {

  AppLifecycleState? _appLifecycleState;

  @override
  void initState() {
    super.initState();
    WidgetsBinding.instance.addObserver(this);
  }


  @override
  void didChangeAppLifecycleState(AppLifecycleState state) {
    super.didChangeAppLifecycleState(state);
    if (state == AppLifecycleState.paused ||
        state == AppLifecycleState.inactive) {
      Provider.of<DataProvider>(context).disconnect();
    }
  }

  @override
  void dispose() {
    WidgetsBinding.instance?.removeObserver(this);
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
      return MaterialApp(
        title: 'Dashboard Page',
        theme: ThemeData(fontFamily: 'GalanoGrotesque'),
        debugShowCheckedModeBanner: false,
        home: SecondWidget(),
        localizationsDelegates: const [
          AppLocalizations.delegate,
          GlobalMaterialLocalizations.delegate,
          GlobalWidgetsLocalizations.delegate,
          GlobalCupertinoLocalizations.delegate,
        ],
        supportedLocales: const [
          Locale('de'),
          Locale('en'),
        ],
      );
    });
  }
}

class SecondWidget extends StatelessWidget {
 
  Widget build(BuildContext context){
    return Consumer<DataProvider>(builder: (context, dataProvider, child) {
      AppLocalizations? appLocalizations = AppLocalizations.of(context);

      final DataProvider dataProvider = Provider.of<DataProvider>(context);


      Widget actions = bike != null
          ? Container(
              alignment: Alignment.center,
              margin: const EdgeInsets.fromLTRB(0, 20, 0, 50),
              child: Column(
                children: [
                  Container(
                      margin: const EdgeInsets.only(bottom: 20),
                      alignment: Alignment.centerLeft,
                      child: Text(
                        appLocalizations!.actionsTitle,
                        style: const TextStyle(
                            fontSize: 24, fontWeight: FontWeight.bold),
                      )),
                  Row(
                    children: [
                      Expanded(
                        flex: 1,
                        child: Column(
                          children: [
                            ElevatedButton(
                                onPressed: () {
                                  if (bike.theftProtection) {
                                    setState(() {
                                      bikeProvider
                                          .untheft(bike.frameId.toString());
                                    });
                                  } else {
                                    setState(() {
                                      bikeProvider
                                          .theft(bike.frameId.toString());
                                    });
                                  }
                                },
                                child: Container(
                                  child: const Icon(
                                          CustomIcons.theft_protection_on,
                                          size: 25.0,
                                          color: Colors.white,
                                        ),
                                )),
                            Container(
                              margin: const EdgeInsets.only(top: 10),
                              child: Text(
                                bike.theftProtection
                                    ? appLocalizations!.theftProtectionOn
                                    : appLocalizations!.theftProtectionOff,
                                style: const TextStyle(fontSize: 14),
                              ),
                            ),
                          ],
                        ),
                      ),
                      const SizedBox(width: 10),
                      Expanded(
                        flex: 1,
                        child: Column(
                          children: [
                            ElevatedButton(
                                onPressed: () {
                                  if (bike.isLocked) {
                                    setState(() {
                                      bikeProvider
                                          .unlock(bike.frameId.toString());
                                    });
                                  } else {
                                    setState(() {
                                      bikeProvider
                                          .lock(bike.frameId.toString());
                                    });
                                  }
                                },
                                child: Container(
                                  child: const Icon(
                                          CustomIcons.lock_closed,
                                          size: 25.0,
                                          color: Colors.white,
                                        )
                                )),
                            Container(
                              margin: const EdgeInsets.only(top: 10),
                              child: Text(
                                bike.isLocked
                                    ? appLocalizations!.unlockLabel
                                    : appLocalizations!.lockLabel,
                                style: const TextStyle(fontSize: 14),
                              ),
                            ),
                          ],
                        ),
                      ),
                    ],
                  )
                ],
              ))
          : Container();
      return Scaffold(
          appBar: null,
          body: ListView(
            padding: const EdgeInsets.fromLTRB(20, 30, 0, 100),
            children: [
              header,
              Container(
                margin: const EdgeInsets.only(right: 20),
                child: Column(
                  children: [
                    actions,
                  ],
                ),
              )
            ],
          ),
        );
    },
      );
  }
}