首页 > 解决方案 > Flutter 对话框 RTL

问题描述

我做了以下

import 'dart:async';

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

Future<void> main() async {
  runApp(
    MaterialApp(
      locale: Locale('he'),
      localizationsDelegates: [
        // ... app-specific localization delegate[s] here
        GlobalMaterialLocalizations.delegate,
        GlobalWidgetsLocalizations.delegate,
        GlobalCupertinoLocalizations.delegate,
      ],
      supportedLocales: [
        const Locale('he', ''), // Heberew
        const Locale('en', ''), // English
      ],
      theme: ThemeData.light(),
      home: new Main(
          // Pass the appropriate camera to the TakePictureScreen widget.
          ),
    ),
  );
}

class Main extends StatefulWidget {
  @override
  _MainState createState() => _MainState();
}

class _MainState extends State<Main> {
  Widget _buildDialog(BuildContext context) {
    print("_buildDialog");
    return MaterialApp(
      // locale: Locale('he'),
      // localizationsDelegates: [
      //   // ... app-specific localization delegate[s] here
      //   GlobalMaterialLocalizations.delegate,
      //   GlobalWidgetsLocalizations.delegate,
      //   GlobalCupertinoLocalizations.delegate,
      // ],
      // supportedLocales: [
      //   const Locale('he', ''), // Heberew
      //   const Locale('en', ''), // English
      // ],
      title: "Test",
      home: Scaffold(
        body: AlertDialog(
          content: Row(children: <Widget>[
            Text('1'),
            Text('2'),
          ]),
          actions: <Widget>[
            FlatButton(
              child: const Text('CLOSE'),
              onPressed: () {
                Navigator.pop(context, false);
              },
            ),
            FlatButton(
              child: const Text('SHOW'),
              onPressed: () {
                Navigator.pop(context, true);
              },
            ),
          ],
        ),
      ),
    );
  }

  void _showPushDialog() {
    print("DIALOG");
    showDialog<bool>(
      context: context,
      builder: (_) => _buildDialog(context),
    ).then((bool shouldNavigate) {
      if (shouldNavigate == true) {
        _navigateToPushDetail();
      }
    });
  }

  void _navigateToPushDetail() {
    print("TODO: Goto...");
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      locale: Locale('he'),
      localizationsDelegates: [
        // ... app-specific localization delegate[s] here
        GlobalMaterialLocalizations.delegate,
        GlobalWidgetsLocalizations.delegate,
        GlobalCupertinoLocalizations.delegate,
      ],
      supportedLocales: [
        const Locale('he', ''), // Heberew
        const Locale('en', ''), // English
      ],
      title: 'Welcome to Flutter',
      home: Scaffold(
        appBar: AppBar(
          title: Text('Welcome to Flutter'),
        ),
        body: new Material(
          child: Row(children: <Widget>[
            Text('1'),
            Text('2'),
            RaisedButton(
              onPressed: () {
                print("pushed?");
                _showPushDialog();
              },
              child: Text("press me"),
            )
          ]),
        ),
      ),
    );
  }
}

运行应用程序时,它按预期在 RTL 中显示 21。但是当点击按钮时它显示 12(而不是像父页面中的 21)

如果我取消注释 _buildDialog (37-47) 中的行,对话框将显示在 RTL 中,所以这将解决我的问题。

我的问题是:

1.有没有更好的方法来做到这一点?

2.注意我还需要用MaterialApp和Scaffold包围AlertDialog,不清楚为什么需要?

3. 为什么我们需要一个新的背景?

4. 为什么我们需要新的本地化定义?

5. 我错过了什么吗?

标签: flutter

解决方案


MaterialApp小部件提供了Navigator, Theme,Directionality等功能。它主要用作根小部件。您不必在每个页面中都使用它。

Scaffold小部件对于创建新页面很有用。它提供了AppBar, Drawer,BottomNavigationBar等功能。由于它试图填满设备屏幕,所以不要环绕它AlertDialog

我做了一些改变。

import 'dart:async';

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

Future<void> main() async {
  runApp(
    MaterialApp(
      locale: Locale('he'),
      localizationsDelegates: [
        // ... app-specific localization delegate[s] here
        GlobalMaterialLocalizations.delegate,
        GlobalWidgetsLocalizations.delegate,
        GlobalCupertinoLocalizations.delegate,
      ],
      supportedLocales: [
        const Locale('he', ''), // Heberew
        const Locale('en', ''), // English
      ],
      theme: ThemeData.light(),
      home: new Main(
        // Pass the appropriate camera to the TakePictureScreen widget.
      ),
    ),
  );
}

class Main extends StatefulWidget {
  @override
  _MainState createState() => _MainState();
}

class _MainState extends State<Main> {
  Widget _buildDialog(BuildContext context) {
    return AlertDialog(
      content: Row(children: <Widget>[
        Text('1'),
        Text('2'),
      ]),
      actions: <Widget>[
        FlatButton(
          child: const Text('CLOSE'),
          onPressed: () {
            Navigator.pop(context, false);
          },
        ),
        FlatButton(
          child: const Text('SHOW'),
          onPressed: () {
            Navigator.pop(context, true);
          },
        ),
      ],
    );
  }

  void _showPushDialog() {
    print("DIALOG");
    showDialog<bool>(
      context: context,
      builder: (_) => _buildDialog(context),
    ).then((bool shouldNavigate) {
      if (shouldNavigate == true) {
        _navigateToPushDetail();
      }
    });
  }

  void _navigateToPushDetail() {
    print("TODO: Goto...");
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Welcome to Flutter'),
      ),
      body: new Material(
        child: Row(children: <Widget>[
          Text('1'),
          Text('2'),
          RaisedButton(
            onPressed: () {
              print("pushed?");
              _showPushDialog();
            },
            child: Text("press me"),
          )
        ]),
      ),
    );
  }
}

推荐阅读