flutter_locale_master 1.0.5 copy "flutter_locale_master: ^1.0.5" to clipboard
flutter_locale_master: ^1.0.5 copied to clipboard

Advanced Flutter localization with automatic RTL/LTR switching, reactive UI updates, asset-based translations, pluralization, and custom widgets.

example/lib/main.dart

import 'package:flutter/material.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:flutter_locale_master/flutter_locale_master.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();

  // Simplified initialization with initial locale!
  final localeMaster = await FlutterLocaleMaster.initialize(
    basePath: 'lang/',
    initialLocale: const Locale('ar'),
    fallbackLocale: const Locale('ar'),
    supportedLocales: const [Locale('en'), Locale('fr'), Locale('ar')],
  );

  runApp(MyApp(localeMaster: localeMaster));
}

class MyApp extends StatelessWidget {
  final FlutterLocaleMaster localeMaster;

  const MyApp({super.key, required this.localeMaster});

  @override
  Widget build(BuildContext context) {
    return localeMaster.wrapApp(
      (locale) => MaterialApp(
        title: 'Flutter Locale Master Example',
        theme: ThemeData(primarySwatch: Colors.blue, useMaterial3: true),
        localizationsDelegates: [
          localeMaster.delegate,
          GlobalMaterialLocalizations.delegate,
          GlobalWidgetsLocalizations.delegate,
          GlobalCupertinoLocalizations.delegate,
        ],
        supportedLocales: localeMaster.supportedLocales,
        locale: locale,
        home: HomePage(localeMaster: localeMaster),
      ),
    );
  }
}

class HomePage extends StatefulWidget {
  final FlutterLocaleMaster localeMaster;

  const HomePage({super.key, required this.localeMaster});

  @override
  State<HomePage> createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  int _appleCount = 0;
  String _userName = 'Alice';

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: TranslatedText('welcome'),
        actions: [
          PopupMenuButton<String>(
            onSelected: (locale) =>
                widget.localeMaster.setLocale(Locale(locale)),
            itemBuilder: (context) => [
              const PopupMenuItem(value: 'en', child: Text('English')),
              const PopupMenuItem(value: 'fr', child: Text('Français')),
              const PopupMenuItem(value: 'ar', child: Text('العربية')),
            ],
            child: Padding(
              padding: const EdgeInsets.symmetric(horizontal: 16),
              child: Text(
                widget.localeMaster.currentLocale?.languageCode.toUpperCase() ??
                    'EN',
              ),
            ),
          ),
        ],
      ),
      body: SingleChildScrollView(
        padding: const EdgeInsets.all(16),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            TranslationSection(
              title: 'Basic Translations',
              children: [
                TranslationExample(
                  label: 'Simple greeting',
                  content: TranslatedText(
                    'greeting',
                    parameters: {'name': _userName},
                  ),
                ),
                TranslationExample(
                  label: 'Welcome message',
                  content: TranslatedText('welcome'),
                ),
              ],
            ),

            const SizedBox(height: 24),

            TranslationSection(
              title: 'Pluralization',
              children: [
                TranslationExample(
                  label: 'Items (singular/plural)',
                  content: Text(context.plural('items', _appleCount)),
                ),
                TranslationExample(
                  label: 'Apples with count',
                  content: Text(context.plural('apples', _appleCount)),
                ),
                AppleCountSlider(
                  count: _appleCount,
                  onChanged: (value) {
                    setState(() {
                      _appleCount = value;
                    });
                  },
                ),
              ],
            ),

            const SizedBox(height: 24),

            TranslationSection(
              title: 'Parameter Replacement',
              children: [
                NameInputField(
                  userName: _userName,
                  onChanged: (value) {
                    setState(() {
                      _userName = value;
                    });
                  },
                ),
              ],
            ),

            const SizedBox(height: 24),

            TranslationSection(
              title: 'Using LocaleConsumer',
              children: [
                TranslationExample(
                  label: 'Consumer example',
                  content: Text(
                    FlutterLocaleMaster.instance.tr(
                      'greeting',
                      parameters: {'name': 'Bob'},
                    ),
                  ),
                ),
              ],
            ),

            const SizedBox(height: 24),

            TranslationSection(
              title: 'Context Extensions',
              children: [
                TranslationExample(
                  label: 'Current locale',
                  content: Text(
                    'Current: ${widget.localeMaster.currentLocale?.languageCode}',
                  ),
                ),
                TranslationExample(
                  label: 'Supported locales',
                  content: Text(
                    'Supported: ${context.supportedLocales.join(', ')}',
                  ),
                ),
                TranslationExample(
                  label: 'Has translation',
                  content: Text(
                    'Has "greeting": ${context.hasTranslation('greeting')}',
                  ),
                ),
                TranslationExample(
                  label: 'Text direction',
                  content: Text('Direction: ${context.isRTL ? 'RTL' : 'LTR'}'),
                ),
                TranslationExample(
                  label: 'Is RTL',
                  content: Text('Is RTL: ${context.isRTL}'),
                ),
              ],
            ),

            const SizedBox(height: 24),

            TranslationSection(
              title: 'String Extensions',
              children: [
                TranslationExample(
                  label: 'Simple translation',
                  content: Text('greeting'.tr(parameters: {'name': _userName})),
                ),
                TranslationExample(
                  label: 'Plural with extension',
                  content: Text('apples'.plural(_appleCount)),
                ),
                TranslationExample(
                  label: 'Field translation',
                  content: Text('email'.field()),
                ),
                TranslationExample(
                  label: 'Translation exists',
                  content: Text('greeting'.exists() ? 'Yes' : 'No'),
                ),
              ],
            ),

            const SizedBox(height: 24),

            TranslationSection(
              title: 'Field Translations',
              children: [
                TranslationExample(
                  label: 'Email field',
                  content: Text('email'.field()),
                ),
                TranslationExample(
                  label: 'Name field',
                  content: Text('name'.field()),
                ),
                TranslationExample(
                  label: 'Password field',
                  content: Text('password'.field()),
                ),
              ],
            ),

            const SizedBox(height: 24),

            TranslationSection(
              title: 'Validation Messages',
              children: [
                TranslationExample(
                  label: 'Required validation',
                  content: Text('required'.tr(namespace: 'validation')),
                ),
                TranslationExample(
                  label: 'Email invalid',
                  content: Text('email_invalid'.tr(namespace: 'validation')),
                ),
                TranslationExample(
                  label: 'Password too short',
                  content: Text(
                    'password_too_short'.tr(namespace: 'validation'),
                  ),
                ),
              ],
            ),

            const SizedBox(height: 24),
          ],
        ),
      ),
    );
  }
}

class TranslationSection extends StatelessWidget {
  final String title;
  final List<Widget> children;

  const TranslationSection({
    super.key,
    required this.title,
    required this.children,
  });

  @override
  Widget build(BuildContext context) {
    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        Text(
          title,
          style: Theme.of(
            context,
          ).textTheme.headlineSmall?.copyWith(fontWeight: FontWeight.bold),
        ),
        const SizedBox(height: 12),
        ...children,
        const SizedBox(height: 16),
      ],
    );
  }
}

class TranslationExample extends StatelessWidget {
  final String label;
  final Widget content;

  const TranslationExample({
    super.key,
    required this.label,
    required this.content,
  });

  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.symmetric(vertical: 8),
      child: Row(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          SizedBox(
            width: 150,
            child: Text(
              '$label:',
              style: Theme.of(
                context,
              ).textTheme.bodyMedium?.copyWith(fontWeight: FontWeight.w500),
            ),
          ),
          const SizedBox(width: 16),
          Expanded(child: content),
        ],
      ),
    );
  }
}

class AppleCountSlider extends StatelessWidget {
  final int count;
  final ValueChanged<int> onChanged;

  const AppleCountSlider({
    super.key,
    required this.count,
    required this.onChanged,
  });

  @override
  Widget build(BuildContext context) {
    return TranslationExample(
      label: 'Apple count slider',
      content: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Text('Count: $count'),
          Slider(
            value: count.toDouble(),
            min: 0,
            max: 10,
            divisions: 10,
            onChanged: (value) => onChanged(value.toInt()),
          ),
          Text(context.plural('apples', count)),
        ],
      ),
    );
  }
}

class NameInputField extends StatefulWidget {
  final String userName;
  final ValueChanged<String> onChanged;

  const NameInputField({
    super.key,
    required this.userName,
    required this.onChanged,
  });

  @override
  State<NameInputField> createState() => _NameInputFieldState();
}

class _NameInputFieldState extends State<NameInputField> {
  late TextEditingController _controller;

  @override
  void initState() {
    super.initState();
    _controller = TextEditingController(text: widget.userName);
  }

  @override
  void didUpdateWidget(NameInputField oldWidget) {
    super.didUpdateWidget(oldWidget);
    if (oldWidget.userName != widget.userName) {
      _controller.text = widget.userName;
    }
  }

  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return TranslationExample(
      label: 'Name input',
      content: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          TextField(
            controller: _controller,
            decoration: const InputDecoration(
              hintText: 'Enter your name',
              border: OutlineInputBorder(),
            ),
            onChanged: (value) {
              widget.onChanged(value.isEmpty ? 'Alice' : value);
            },
          ),
          const SizedBox(height: 8),
          TranslatedText('greeting', parameters: {'name': widget.userName}),
        ],
      ),
    );
  }
}
2
likes
160
points
226
downloads

Publisher

unverified uploader

Weekly Downloads

Advanced Flutter localization with automatic RTL/LTR switching, reactive UI updates, asset-based translations, pluralization, and custom widgets.

Repository (GitHub)
View/report issues

Topics

#localization #i18n #rtl #flutter

Documentation

Documentation
API reference

License

MIT (license)

Dependencies

flutter, flutter_localizations

More

Packages that depend on flutter_locale_master