Flutter中的从右到左(RTL)

92

我使用Flutter已经有一个多星期的时间,并且希望创建一个阿拉伯语(从右到左)的应用程序。

我正在阅读Internationalizing Flutter Apps,但它没有提及如何设置布局方向。

那么,在Flutter中如何显示从右到左(RTL)布局?


2
如果您只需要设置文本方向,请将 textDirection 属性设置为 TextDirection.rtl,应用于您的 TextField 或 Text widget。 - Son of Stackoverflow
如何在语言环境改变时限制小部件更改其子元素的对齐方式? 您能否解决此问题:https://stackoverflow.com/questions/65180615/restrict-a-widget-to-change-its-childrens-alignment-when-locale-is-changed-flut - Febin K R
7个回答

201

你有两个选择:

1. 强制在所有设备上使用某个语言环境(和方向)

-- 方法 1: 使用本地化

flutter_localizations包添加到您的pubspec.yml中。

dependencies:
  flutter:
    sdk: flutter
  flutter_localizations:
    sdk: flutter

之后

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

MaterialApp(
  localizationsDelegates: [
    GlobalCupertinoLocalizations.delegate,
    GlobalMaterialLocalizations.delegate,
    GlobalWidgetsLocalizations.delegate,
  ],
  supportedLocales: [
    Locale("fa", "IR"), // OR Locale('ar', 'AE') OR Other RTL locales
  ],
  locale: Locale("fa", "IR") // OR Locale('ar', 'AE') OR Other RTL locales,
  .
  .
  .
);

-- 方法二: 不使用本地化

MaterialApp(
  .
  .
  .
  builder: (context, child) {
    return Directionality(
      textDirection: TextDirection.rtl,
      child: child,
    );
  },
  .
  .
  .
);

2. 根据设备语言设置布局方向(如果用户手机语言是RTL语言并且存在于supportedLocales中,则您的应用程序以RTL模式运行,否则您的应用程序是LTR)

flutter_localizations包添加到pubspec.yml文件中。

dependencies:
  flutter:
    sdk: flutter
  flutter_localizations:
    sdk: flutter

然后

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

MaterialApp(
  localizationsDelegates: [
    GlobalCupertinoLocalizations.delegate,
    GlobalMaterialLocalizations.delegate,
    GlobalWidgetsLocalizations.delegate,
  ],
  supportedLocales: [
    Locale("en", "US"),
    Locale("fa", "IR"), // OR Locale('ar', 'AE') OR Other RTL locales
  ],
  .
  .
  .
);

注意:Flutter 中的 RTL 语言有:

[
  'ar', // Arabic
  'fa', // Farsi
  'he', // Hebrew
  'ps', // Pashto
  'ur', // Urdu
];

_rtlLanguages 不使用。 - Elia Weiss
@mohammad 你好,请在 https://stackoverflow.com/questions/68528499 中回答我的问题。 - mm sh
@DJafari您好,请在https://stackoverflow.com/questions/68528499中回答我的问题。 - mm sh
@DJafari 有没有办法获取或更改当前的“textDirection”? - jksevend
@jksevend,请在另一个问题中提出您的问题,并在此处插入链接。 - DJafari
显示剩余3条评论

52

设置整个应用程序的 RTL配置 的最佳和最短途径。

void main() {
  runApp(
    MaterialApp(
      home: Directionality( // add this
        textDirection: TextDirection.rtl, // set this property 
        child: HomePage(),
      ),
    ),
  );
}

错误:参数类型'TextDirection(其中TextDirection在D:\ flutter \ .pub-cache \ hosted \ pub.dartlang.org \ intl-0.15.8 \ lib \ src \ intl \ bidi_utils.dart中定义)'无法赋值给参数类型'TextDirection(其中TextDirection在D:\ flutter \ bin \ cache \ pkg \ sky_engine \ lib \ ui \ text.dart中定义)'。(argument_type_not_assignable at [zapit] lib\main.dart:186) - Elia Weiss
@EliaWeiss 请确保您不导入任何其他冲突的包,这是您应该使用的导入语句 package:flutter/material.dart; - CopsOnRoad
如何在任何页面上的按钮单击时设置动态?如果用户想要将RTL更改为LTR,该怎么做? - Pradeep
这个答案是不正确的,因为它只会将主页设置为从右到左的方向,其他页面也必须使用“Directionality”进行包装,可以查看我的第二种选择方法。 - DJafari
1
@DJafari 这将使所有页面都变成从右到左的,而不仅仅是“主页”。如果您从“主页”导航到其他页面,您会看到这种效果。 - CopsOnRoad

44
你需要创建一个Builder,并使用TextDirection.rtl传递布局方向。
new MaterialApp(
          title: 'Flutter RTL',
          color: Colors.grey,
          builder: (BuildContext context, Widget child) {
              return new Directionality(
                textDirection: TextDirection.rtl,
                child: new Builder(
                  builder: (BuildContext context) {
                    return new MediaQuery(
                      data: MediaQuery.of(context).copyWith(
                            textScaleFactor: 1.0,
                          ),
                      child: child,
                    );
                  },
                ),
              );
            },
          .
          .
          .
        );

4
虽然它能工作,但我不喜欢这个答案。你没有解释它的工作原理,以及这样做如何影响其他布局计算等内容。 - aderchox
为什么需要覆盖文本比例因子? - Miguel Beltran

10
如果您需要以相反方向显示文本,只需将其textdirection 属性设置为TextDirection.rtl
TextField小部件的示例代码:
TextField(
  textDirection: TextDirection.rtl,
  decoration: InputDecoration(
    labelText: "Enter Pashto Name",
  ),
),
    Text(
      "This text is in the other direction!"
      textDirection: TextDirection.rtl,
    ),

1
你甚至可以将它用于文本小部件。 - Son of Stackoverflow
最佳答案,适用于我快捷方式 - Noor Hossain

1
只需将以下内容附加到您的Material App中:

 builder: (BuildContext context, Widget child) {
              return new Directionality(
                textDirection: TextDirection.rtl,
                child: new Builder(
                  builder: (BuildContext context) {
                    return new MediaQuery(
                      data: MediaQuery.of(context).copyWith(
                            textScaleFactor: 1.0,
                          ),
                      child: child,
                    );
                  },
                ),
              );
            },

1
如果您使用flutter_localizations: sdk:flutter 请添加以下行以更改应用程序方向。
 supportedLocales: [
    Locale("fa", "IR"), 
    Locale("en", 'US'),
  ],
  locale: Locale("fa", "IR")  // this is important line if not add this Apps will not change direction

1

GetMaterialApp(textDirection:TextDirection.rtl,home:SignUpScreen() // const HomeExpert());

这段代码是使用Flutter框架构建应用程序时的一部分。它创建了一个名为“GetMaterialApp”的新实例,并将文本方向设置为从右到左。主页被设置为“SignUpScreen()”,但也可以选择使用“HomeExpert()”。

2
虽然这段代码可能回答了问题,但提供有关它如何以及/或为什么解决问题的附加上下文将改善答案的长期价值。 - Vickel

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接