How can i use Easy Localization with parameter widgets?

130 Views Asked by At

When I embed localized text into the widget I designed, it works without hot reload. But,

When I design a custom widget and send it with the parameter headlineText: (LocaleKeys.landing_welcome_headline).tr(), the data does not change until hot reload. Yes, they are not in the same tree and their contexts are different.

here is my localization class

import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:rezyonapp/core/constants/enums/locales.dart';

@immutable
final class ProductLocalization extends EasyLocalization {
  ProductLocalization({super.key, required super.child})
      : super(
          supportedLocales: _supportedItems,
          path: _translationPath,
          useOnlyLangCode: true,
        );

  static final List<Locale> _supportedItems = [
    Locales.tr.locale,
    Locales.en.locale,
  ];

  static const String _translationPath = "asset/translations";

  /// change project language by using locales
  static Future<void> updateLanguage({
    required BuildContext context,
    required Locales value,
  }) =>
      context.setLocale(value.locale);
}

this code below doesn't change my screen until I hot reload

 CarouselWidget(
                              headlineText: (LocaleKeys.landing_welcome_headline).tr(),
                              bodyText: (LocaleKeys.landing_welcome_body).tr(),
                              languageWidget: Consumer<DropdownService>(
                                builder: (context, value, child) => Container(
                                  child: DropdownButtonFormField<String>(
                                    decoration: InputDecoration(
                                      focusedBorder: UnderlineInputBorder(
                                          borderSide: BorderSide(color: ProjectColors.mainProjectColorMetallicSeaweed)),
                                      prefixIcon: const Icon(Icons.language),
                                    ),
                                    isExpanded: true,
                                    value: value.selectedCountry,
                                    icon: const Icon(Icons.arrow_downward),
                                    elevation: 30,
                                    style: TextStyle(color: ProjectColors.mainProjectColorMetallicSeaweed),
                                    onChanged: (String? v) {
                                      value.setCountryValue(v);
                                      if (v == "Türkçe") {
                                        ProductLocalization.updateLanguage(context: context, value: Locales.tr);
                                      } else {
                                        ProductLocalization.updateLanguage(context: context, value: Locales.en);
                                      }
                                    },
                                    items: value.countryDropwnList.map<DropdownMenuItem<String>>((String value) {
                                      return DropdownMenuItem<String>(
                                        value: value,
                                        child: Text(value),
                                      );
                                    }).toList(),
                                  ),
                                ),
                              ),
                            ),

this code below change on my screen immediately

class LandingViewGoButtonWidget extends StatelessWidget {
  const LandingViewGoButtonWidget({super.key});

  @override
  Widget build(BuildContext context) {
    return RawMaterialButton(
      shape: RoundedRectangleBorder(
          borderRadius: BorderRadius.circular(20.0),
          side: BorderSide(
            color: ProjectColors.mainProjectColorMetallicSeaweed,
          )),
      onPressed: () async {},
      child: Text(
        ((LocaleKeys.landing_button_save).tr()),
        style: Theme.of(context)
            .textTheme
            .bodyMedium
            ?.copyWith(color: ProjectColors.mainProjectColorMetallicSeaweed, fontWeight: FontWeight.w600),
      ),
    );
  }
}

What is the solution to this?

2

There are 2 best solutions below

0
Sayid On

I will share with the answer that helped me.

In your build method, call the rebuildAllChildren function and pass it the context:

@override
Widget build(BuildContext context) { 
  rebuildAllChildren(context);
  return ...
}

void rebuildAllChildren(BuildContext context) {
  void rebuild(Element el) {
    el.markNeedsBuild();
    el.visitChildren(rebuild);
  }
  (context as Element).visitChildren(rebuild);
}

This will visit all children and mark them as needing to rebuild. If you put this code in the topmost widget in your widgets tree, it will rebuild everything.

You can see more details and other answers here

0
Abdallah Alsaifi On

If what I think, You can trick it with couple solutions while researching, however state management is the best solution.

check Bloc, Provider, RiverPod