build method

  1. @override
Widget build(
  1. BuildContext context,
  2. WidgetRef ref,
  3. Locale state,
  4. LanguageSwitcherNotifier notifier,
  5. List<LocaleInfo> supportedLocales,
)
override

Build method that concrete implementations must override.

This method receives all necessary data for building language switcher UI:

  • context: The build context for accessing theme and navigation
  • ref: WidgetRef for accessing Riverpod providers
  • state: Current locale state from the language switcher provider
  • notifier: LanguageSwitcherNotifier for changing locales
  • supportedLocales: List of all supported locales from app configuration

Example implementation:

@override
Widget build(
  BuildContext context,
  WidgetRef ref,
  Locale state,
  LanguageSwitcherNotifier notifier,
  List<LocaleInfo> supportedLocales,
) {
  return Column(
    children: supportedLocales.map((localeInfo) {
      return RadioListTile<Locale>(
        value: localeInfo.locale,
        groupValue: state,
        title: Text(localeInfo.displayName),
        onChanged: (locale) {
          if (locale != null) notifier.changeLocale(locale);
        },
      );
    }).toList(),
  );
}

Implementation

@override
Widget build(
  BuildContext context,
  WidgetRef ref,
  Locale state,
  LanguageSwitcherNotifier notifier,
  List<LocaleInfo> supportedLocales,
) {
  final currentLocale = state;

  return Container(
    decoration: const BoxDecoration(
      borderRadius: BorderRadius.vertical(top: Radius.circular(20)),
    ),
    child: Column(
      mainAxisSize: MainAxisSize.min,
      children: [
        Container(
          margin: const EdgeInsets.only(top: 12),
          width: 40,
          height: 4,
          decoration: BoxDecoration(
            color: Theme.of(context).dividerColor,
            borderRadius: BorderRadius.circular(2),
          ),
        ),

        // Header
        Padding(
          padding: const EdgeInsets.all(20),
          child: Row(
            children: [
              Icon(
                Icons.language,
                color: Theme.of(context).colorScheme.primary,
              ),
              const SizedBox(width: 12),
              Text(
                context.jetI10n.changeLanguage,
                style: Theme.of(context).textTheme.titleLarge?.copyWith(
                  fontWeight: FontWeight.w600,
                ),
              ),
              const Spacer(),
              IconButton(
                onPressed: () {
                  HapticFeedback.lightImpact();
                  Navigator.of(context).pop();
                },
                icon: const Icon(Icons.close),
                style: IconButton.styleFrom(
                  backgroundColor: Theme.of(
                    context,
                  ).colorScheme.surfaceContainerHighest,
                ),
              ),
            ],
          ),
        ),

        // Locale options
        ListView.builder(
          shrinkWrap: true,
          physics: const NeverScrollableScrollPhysics(),
          itemCount: supportedLocales.length,
          itemBuilder: (context, index) {
            final localeInfo = supportedLocales[index];
            final isSelected =
                currentLocale.languageCode == localeInfo.locale.languageCode;

            return ListTile(
              contentPadding: const EdgeInsets.symmetric(
                horizontal: 20,
                vertical: 4,
              ),
              leading: Container(
                width: 40,
                height: 40,
                decoration: BoxDecoration(
                  shape: BoxShape.circle,
                  color: isSelected
                      ? Theme.of(context).colorScheme.primary
                      : Theme.of(context).colorScheme.surfaceContainerHighest,
                ),
                child: Center(
                  child: Text(
                    localeInfo.locale.languageCode.toUpperCase(),
                    style: TextStyle(
                      color: isSelected
                          ? Theme.of(context).colorScheme.onPrimary
                          : Theme.of(context).colorScheme.onSurfaceVariant,
                      fontWeight: FontWeight.bold,
                      fontSize: 12,
                    ),
                  ),
                ),
              ),
              title: Text(
                localeInfo.displayName,
                style: Theme.of(context).textTheme.bodyLarge?.copyWith(
                  fontWeight: isSelected
                      ? FontWeight.w600
                      : FontWeight.normal,
                ),
              ),

              trailing: isSelected
                  ? Icon(
                      Icons.check_circle,
                      color: Theme.of(context).colorScheme.primary,
                    )
                  : null,
              onTap: () async {
                if (!isSelected) {
                  HapticFeedback.lightImpact();
                  await notifier.changeLocale(localeInfo.locale);
                }
                if (context.mounted) {
                  Navigator.of(context).pop();
                }
              },
            );
          },
        ),

        // Bottom padding
        const SizedBox(height: 20),
      ],
    ),
  );
}