Localize a widget in Flutter
Asked Answered
S

2

1

I'm currently test driving and I have already built a localized "Hello world" following the tutorial. However, when I tried to move my widget to a different file, I got a red screen of death with the error:

The following NoSuchMethodError was thrown building ToDoItem(dirty):
The method 'helloWorld' was called on null.
Receiver: null
Tried calling: helloWorld()

My To Do item class looks like this

todo_item.dart

import 'package:flutter/material.dart';
import 'package:to_do_app/localization.dart';

class ToDoItem extends StatelessWidget {

  @override
  Widget build(BuildContext context) {
    return new Text(ToDoLocalizations.of(context).helloWorld());
  }
}

Of course the problem is that my Localization class has not been initialized, however I don't know how to initialize it since the Text widget does not have a LocalizationDelegates parameter.

I'm aware that this could be fixed by injecting the String directly into my widget's constructor, but for the sake of it I want to know how to localize widgets.

EDIT: Here is my localization class

import 'dart:async';
import 'dart:developer';
import 'package:flutter/widgets.dart';
import 'package:intl/intl.dart';
import 'package:to_do_app/l10n/messages_all.dart';

class ToDoLocalizations {
  ToDoLocalizations(Locale locale) : _localeName = locale.toString();

  final String _localeName;

  static Future<ToDoLocalizations> load(Locale locale) {
    return initializeMessages(locale.toString()).then((Object _) {
      return new ToDoLocalizations(locale);
    });
  }

  static ToDoLocalizations of(BuildContext context) {
    return Localizations.of<ToDoLocalizations>(context, ToDoLocalizations);
  }

  String helloWorld() {
    return Intl.message(
        'Hello, World!',
        name: 'helloWorld',
        desc: 'A friendly salutation',
        locale: _localeName
    );
  }
}

class ToDoLocalizationsDelegate
    extends LocalizationsDelegate<ToDoLocalizations> {


  @override
  bool isSupported(Locale locale) {
    return ['en', 'nb'].contains(locale.languageCode);
  }

  @override
  bool shouldReload(LocalizationsDelegate<ToDoLocalizations> old) {
    return false;
  }

  @override
  Future<ToDoLocalizations> load(Locale locale) {
    return ToDoLocalizations.load(locale);
  }
}
Stearn answered 9/3, 2018 at 13:12 Comment(1)
See #62992063 maybe it is relevantElsaelsbeth
S
0

After closely following the aforementioned tutorial and the code outlined on this example repository without success, this answer pointed me in the right direction. All of my code was sound and the only missing part was to write import statements using relative paths instead of absolute paths and then the error disappeared.

Stearn answered 12/3, 2018 at 9:44 Comment(3)
The relative path solution does not work for me, do you have a complete sample code solution ?Carapace
I used this repo as a guideline for my implementation.Deportment
For sample code, refer to this blog: blog.geekyants.com/flutter-in-app-localization-438289682f0cShawm
P
0

I had added the MaterialApp widget in main.dart, further again in some of files i added MaterialApp by accident. So, adding the second MaterialApp widget overrode what I had previously defined.

Palpate answered 12/10, 2020 at 3:56 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.