← Back to Blog

Flutter AboutDialog Localization: App Info Screens for Multilingual Apps

flutteraboutdialogaboutlicenselocalizationrtl

Flutter AboutDialog Localization: App Info Screens for Multilingual Apps

AboutDialog is a Flutter widget that displays an about box with the application name, version, icon, and license information. In multilingual applications, AboutDialog is essential for showing translated app descriptions and legal text, displaying localized version information and copyright notices, providing translated license page navigation, and building accessible about screens with announcements in the active language.

Understanding AboutDialog in Localization Context

AboutDialog renders a Material Design about dialog with app information and a button to view licenses. For multilingual apps, this enables:

  • Translated app name and description text
  • Localized version strings and copyright notices
  • Translated "View licenses" button text via MaterialLocalizations
  • RTL-aware dialog layout with proper text alignment

Why AboutDialog Matters for Multilingual Apps

AboutDialog provides:

  • App identity: Translated app name and description displayed in a standard dialog
  • Version info: Localized version strings formatted for the active language
  • License access: Automatic "View licenses" button with MaterialLocalizations translation
  • Standard layout: Consistent about dialog appearance across all languages

Basic AboutDialog Implementation

import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';

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

  @override
  Widget build(BuildContext context) {
    final l10n = AppLocalizations.of(context)!;

    return Scaffold(
      appBar: AppBar(title: Text(l10n.settingsTitle)),
      body: ListView(
        children: [
          ListTile(
            leading: const Icon(Icons.info_outline),
            title: Text(l10n.aboutAppLabel),
            onTap: () {
              showAboutDialog(
                context: context,
                applicationName: l10n.appName,
                applicationVersion: l10n.appVersion,
                applicationIcon: const FlutterLogo(size: 48),
                applicationLegalese: l10n.copyrightNotice,
                children: [
                  const SizedBox(height: 16),
                  Text(l10n.appDescription),
                ],
              );
            },
          ),
        ],
      ),
    );
  }
}

Advanced AboutDialog Patterns for Localization

Custom About Page with Translated Sections

A full about page with translated sections for team info, contact, and acknowledgments.

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

  @override
  Widget build(BuildContext context) {
    final l10n = AppLocalizations.of(context)!;

    return Scaffold(
      appBar: AppBar(title: Text(l10n.aboutTitle)),
      body: ListView(
        padding: const EdgeInsets.all(16),
        children: [
          Center(
            child: Column(
              children: [
                const FlutterLogo(size: 72),
                const SizedBox(height: 16),
                Text(
                  l10n.appName,
                  style: Theme.of(context).textTheme.headlineSmall,
                ),
                Text(
                  l10n.appVersion,
                  style: Theme.of(context).textTheme.bodyMedium?.copyWith(
                        color: Theme.of(context).colorScheme.onSurfaceVariant,
                      ),
                ),
              ],
            ),
          ),
          const SizedBox(height: 24),
          Card(
            child: Padding(
              padding: const EdgeInsets.all(16),
              child: Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                children: [
                  Text(
                    l10n.aboutSectionTitle,
                    style: Theme.of(context).textTheme.titleMedium,
                  ),
                  const SizedBox(height: 8),
                  Text(l10n.aboutSectionDescription),
                ],
              ),
            ),
          ),
          const SizedBox(height: 12),
          Card(
            child: Column(
              children: [
                ListTile(
                  leading: const Icon(Icons.email),
                  title: Text(l10n.contactUsLabel),
                  subtitle: Text(l10n.contactEmail),
                  onTap: () {},
                ),
                ListTile(
                  leading: const Icon(Icons.language),
                  title: Text(l10n.websiteLabel),
                  subtitle: Text(l10n.websiteUrl),
                  onTap: () {},
                ),
                ListTile(
                  leading: const Icon(Icons.privacy_tip),
                  title: Text(l10n.privacyPolicyLabel),
                  onTap: () {},
                ),
                ListTile(
                  leading: const Icon(Icons.description),
                  title: Text(l10n.termsOfServiceLabel),
                  onTap: () {},
                ),
              ],
            ),
          ),
          const SizedBox(height: 12),
          Card(
            child: Padding(
              padding: const EdgeInsets.all(16),
              child: Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                children: [
                  Text(
                    l10n.acknowledgmentsTitle,
                    style: Theme.of(context).textTheme.titleMedium,
                  ),
                  const SizedBox(height: 8),
                  Text(l10n.acknowledgmentsDescription),
                  const SizedBox(height: 12),
                  OutlinedButton(
                    onPressed: () {
                      showLicensePage(
                        context: context,
                        applicationName: l10n.appName,
                        applicationVersion: l10n.appVersion,
                        applicationLegalese: l10n.copyrightNotice,
                      );
                    },
                    child: Text(l10n.viewLicensesLabel),
                  ),
                ],
              ),
            ),
          ),
          const SizedBox(height: 16),
          Center(
            child: Text(
              l10n.copyrightNotice,
              style: Theme.of(context).textTheme.bodySmall?.copyWith(
                    color: Theme.of(context).colorScheme.onSurfaceVariant,
                  ),
            ),
          ),
        ],
      ),
    );
  }
}

About Dialog in Settings Menu

An AboutListTile integrated into a settings list with translated labels.

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

  @override
  Widget build(BuildContext context) {
    final l10n = AppLocalizations.of(context)!;

    return Scaffold(
      appBar: AppBar(title: Text(l10n.settingsTitle)),
      body: ListView(
        children: [
          ListTile(
            leading: const Icon(Icons.language),
            title: Text(l10n.languageLabel),
            subtitle: Text(l10n.currentLanguageName),
            onTap: () {},
          ),
          ListTile(
            leading: const Icon(Icons.palette),
            title: Text(l10n.themeLabel),
            onTap: () {},
          ),
          ListTile(
            leading: const Icon(Icons.notifications),
            title: Text(l10n.notificationsLabel),
            onTap: () {},
          ),
          const Divider(),
          ListTile(
            leading: const Icon(Icons.help_outline),
            title: Text(l10n.helpLabel),
            onTap: () {},
          ),
          ListTile(
            leading: const Icon(Icons.feedback),
            title: Text(l10n.feedbackLabel),
            onTap: () {},
          ),
          AboutListTile(
            icon: const Icon(Icons.info_outline),
            applicationName: l10n.appName,
            applicationVersion: l10n.appVersion,
            applicationIcon: const FlutterLogo(size: 48),
            applicationLegalese: l10n.copyrightNotice,
            aboutBoxChildren: [
              const SizedBox(height: 16),
              Text(l10n.appDescription),
            ],
            child: Text(l10n.aboutAppLabel),
          ),
        ],
      ),
    );
  }
}

RTL Support and Bidirectional Layouts

AboutDialog respects RTL text direction. All content aligns from right to left, and the dialog buttons position correctly.

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

  @override
  Widget build(BuildContext context) {
    final l10n = AppLocalizations.of(context)!;

    return Scaffold(
      appBar: AppBar(title: Text(l10n.appName)),
      body: Center(
        child: FilledButton(
          onPressed: () {
            showAboutDialog(
              context: context,
              applicationName: l10n.appName,
              applicationVersion: l10n.appVersion,
              applicationIcon: const FlutterLogo(size: 48),
              applicationLegalese: l10n.copyrightNotice,
              children: [
                const SizedBox(height: 16),
                Text(l10n.appDescription),
                const SizedBox(height: 8),
                Text(
                  l10n.developedByLabel,
                  style: Theme.of(context).textTheme.bodySmall,
                ),
              ],
            );
          },
          child: Text(l10n.aboutAppLabel),
        ),
      ),
    );
  }
}

Testing AboutDialog Localization

import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';

void main() {
  Widget buildTestWidget({Locale locale = const Locale('en')}) {
    return MaterialApp(
      locale: locale,
      localizationsDelegates: AppLocalizations.localizationsDelegates,
      supportedLocales: AppLocalizations.supportedLocales,
      home: const LocalizedAboutDialogExample(),
    );
  }

  testWidgets('AboutDialog shows localized content', (tester) async {
    await tester.pumpWidget(buildTestWidget());
    await tester.pumpAndSettle();
    await tester.tap(find.byType(ListTile));
    await tester.pumpAndSettle();
    expect(find.byType(AboutDialog), findsOneWidget);
  });

  testWidgets('AboutDialog works in RTL', (tester) async {
    await tester.pumpWidget(buildTestWidget(locale: const Locale('ar')));
    await tester.pumpAndSettle();
    expect(tester.takeException(), isNull);
  });
}

Best Practices

  1. Translate applicationName and applicationLegalese using AppLocalizations so the about dialog displays in the active language.

  2. Use AboutListTile for easy integration into settings lists with automatic translated "About" dialog triggering.

  3. Call showLicensePage with translated applicationName and applicationLegalese for a consistent localized license viewing experience.

  4. Add custom children to showAboutDialog for translated descriptions, team info, and contact details beyond the standard fields.

  5. Provide translated applicationVersion formatted for the active locale if version strings include locale-specific formatting.

  6. Test the "View licenses" button works correctly in all supported locales since it relies on MaterialLocalizations.

Conclusion

AboutDialog provides a standard app information dialog for Flutter apps. For multilingual apps, it handles translated app names, descriptions, and legal text, integrates with MaterialLocalizations for automatic button translation, and supports RTL dialog layouts. By combining AboutDialog with custom about pages, settings integration, and license page navigation, you can build app information screens that display correctly in every supported language.

Further Reading