Supporting RTL Languages
1. Understanding TextDirection
| Property | Values | Description |
|---|---|---|
| TextDirection | ltr | rtl |
Defines the text direction for the widget tree. ltr is left-to-right, rtl is right-to-left. |
Example: Setting TextDirection in a Widget Tree
import 'package:flutter/material.dart';
void main() {
runApp(
MaterialApp(
home: Directionality(
textDirection: TextDirection.rtl,
child: Scaffold(
appBar: AppBar(title: Text("RTL Example")),
body: Center(child: Text("This text is RTL")),
),
),
),
);
}
Note: The
Directionality widget is used to set the text direction for its child widgets. It does not affect the layout direction, which is handled by LayoutDirection.
Key Points
TextDirection.ltris the default for most languages.TextDirection.rtlis used for Arabic, Hebrew, Persian, etc.- Use
Directionalityto control text direction in a subtree.
2. Using Directionality Widget
| Property | Values | Description |
|---|---|---|
| textDirection | TextDirection.ltr, TextDirection.rtl |
Sets the base text direction for the widget subtree. Required for RTL support. |
| child | Widget |
The widget subtree that will inherit the text direction. |
Example: Setting Directionality
import 'package:flutter/material.dart';
void main() {
runApp(
Directionality(
textDirection: TextDirection.rtl,
child: MyApp(),
),
);
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: Text("RTL Example")),
body: Center(
child: Text("مرحبا بالعالم"),
),
),
);
}
}
Note: The
Directionality widget affects how text is laid out and aligned within its subtree. It does not change the language or localization, but it controls the visual direction.
3. Detecting Locale Direction
| Property | Value | Description |
|---|---|---|
| TextDirection | TextDirection.ltr or TextDirection.rtl |
Determines the text direction for a widget or app |
Example: Detecting Direction in Flutter
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: Text("RTL Detection")),
body: Center(
child: Directionality(
textDirection: TextDirection.rtl,
child: Text("This is RTL text"),
),
),
),
);
}
}
Note: The
Directionality widget is used to set the text direction for its child widgets.
Key Points
TextDirection.ltris used for left-to-right text.TextDirection.rtlis used for right-to-left text.- The
Directionalitywidget affects layout and text alignment.
4. Configuring RTL Support
| Property | Values | Description |
|---|---|---|
| TextDirection | TextDirection.rtl |
Defines the text direction for the app or widget. |
| TextDirection.ltr | TextDirection.ltr |
Defines the text direction as left-to-right (default). |
Example: Setting TextDirection in MaterialApp
MaterialApp(
home: MyHomePage(),
textDirection: TextDirection.rtl,
)
Note: The
textDirection property must be set at the root of your app or widget tree to ensure consistent RTL behavior.
RTL Configuration Summary
- Root Level: Set
textDirectioninMaterialApporCupertinoApp. - Widget Level: Override
textDirectionfor specific widgets. - Localization: Use
Localizationsto handle RTL-aware layouts.
5. Testing RTL Layouts
Example: Testing RTL Layouts with Flutter Driver
import 'package:flutter_driver/flutter_driver.dart';
import 'package:test/test.dart';
void main() {
group('RTL Layout Test', () {
FlutterDriver driver;
setUp(() async {
driver = await FlutterDriver.connect();
});
tearDown(() async {
await driver?.close();
});
test('Verify RTL layout alignment', () async {
final element = await driver.waitFor(find.byType('Text'));
final textDirection = await driver.getText(element);
expect(textDirection, 'rtl');
});
});
}
| Test Type | Description | Notes |
|---|---|---|
| Text Direction | TextDirection.rtl |
Ensures text flows right-to-left |
| Widget Alignment | AlignmentDirectional |
Uses directional alignment for RTL support |
| Layout Direction | LayoutDirection.rtl |
Applies to entire widget tree |
Note: Use
TextDirection.rtl in conjunction with AlignmentDirectional to ensure proper RTL layout testing.
Warning: Ensure all UI elements are tested with
TextDirection.rtl to prevent layout shifts.
RTL Testing Best Practices
- Use
TextDirection.rtlto simulate right-to-left text flow. - Test alignment using
AlignmentDirectionalinstead ofAlignment. - Validate that all widgets adapt correctly to RTL layouts.
6. Using EdgeInsetsDirectional
In Flutter, EdgeInsetsDirectional is used to define padding and margins that adapt automatically to the text direction of the app (LTR or RTL). This is particularly useful for supporting right-to-left languages like Arabic, Hebrew, and Persian.
| Property | Description | Values |
|---|---|---|
| start | Start edge of the padding/margin, aligned with the text direction | double |
| end | End edge of the padding/margin, aligned with the text direction | double |
| top | Top edge of the padding/margin | double |
| bottom | Bottom edge of the padding/margin | double |
Example: Using EdgeInsetsDirectional in a Container
Container(
padding: EdgeInsetsDirectional.only(
start: 16.0,
top: 8.0,
end: 16.0,
bottom: 8.0,
),
child: Text('Hello, World!'),
)
Note: When using
EdgeInsetsDirectional, the start and end properties adapt to the current text direction. For example, in an RTL layout, start becomes the right edge and end becomes the left edge.
7. Using AlignmentDirectional
| Property | Values | Description |
|---|---|---|
| AlignmentDirectional | start, center, end |
Defines alignment relative to the text direction (RTL or LTR) |
Example: Using AlignmentDirectional in a Row
Row(
textDirection: TextDirection.rtl,
mainAxisAlignment: MainAxisAlignment.<span class="highlight">start</span>,
children: [
Text('Hello'),
Text('World'),
],
)
Note: In RTL layouts,
start aligns to the right side of the screen.
Warning: Ensure
textDirection is set correctly to avoid misalignment.
8. Using Positioned.directional() Constructor
The Positioned.directional() constructor is a key part of Flutter's directional layout system, designed to support right-to-left (RTL) layouts seamlessly. It allows positioning widgets relative to the direction of the text flow, making it easier to build apps that adapt to different writing systems.
| Property | Description | Values |
|---|---|---|
| key | Unique identifier for the widget | Key? |
| left | Distance from the start edge in the direction of text flow | double? |
| top | Distance from the top edge | double? |
| right | Distance from the end edge in the direction of text flow | double? |
| bottom | Distance from the bottom edge | double? |
| width | Width of the positioned widget | double? |
| height | Height of the positioned widget | double? |
| start | Distance from the start edge in the direction of text flow (RTL-aware) | double? |
| end | Distance from the end edge in the direction of text flow (RTL-aware) | double? |
Example: Using Positioned.directional() in an RTL layout
import 'package:flutter/material.dart';
class RTLPositionedExample extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Directionality(
textDirection: TextDirection.rtl,
child: Stack(
children: [
Positioned.directional(
start: 20,
top: 20,
width: 100,
height: 50,
child: Container(
color: Colors.blue,
child: Center(
child: Text("RTL Positioned"),
),
),
),
],
),
),
),
);
}
}
Note: When using
start and end, the widget will automatically adjust its position based on the TextDirection of the parent. In an RTL layout, start refers to the right edge, and end refers to the left edge.
9. Mirroring Icons for RTL
| Icon | Direction | Notes |
|---|---|---|
| Icons.arrow_forward | ltr |
Points right in LTR layout |
| Icons.arrow_forward | rtl |
Automatically mirrored to point left in RTL layout |
| Icons.arrow_back | ltr |
Points left in LTR layout |
| Icons.arrow_back | rtl |
Automatically mirrored to point right in RTL layout |
| Icons.expand_more | ltr |
Points down in LTR layout |
| Icons.expand_more | rtl |
Automatically mirrored to point down in RTL layout |
Example: Using RTL-aware Icons
import 'package:flutter/material.dart';
class RTLIconExample extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("RTL Icon Example"),
),
body: Center(
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(Icons.arrow_forward),
Text(" Next"),
],
),
),
);
}
}
Note: Flutter automatically handles mirroring of directional icons in RTL layouts. You don't need to manually switch icons.
10. Handling Mixed Text Directions
| Property | Description | Values |
|---|---|---|
| textDirection | Defines the base text direction for the widget tree | TextDirection.ltr, TextDirection.rtl |
| textAlign | Aligns text within a widget | TextAlign.left, TextAlign.right, TextAlign.center, TextAlign.justify |
Example: Using textDirection in a Text widget
<Text
textDirection: TextDirection.rtl,
textAlign: TextAlign.right,
data: "مرحبا"
/>
Example: Using Directionality widget for mixed content
Directionality(
textDirection: TextDirection.rtl,
child: Column(
children: [
Text("مرحبا"),
Text("Hello", textDirection: TextDirection.ltr),
],
),
)
Note: When mixing RTL and LTR content, use
Directionality to control the base direction for nested widgets.
Warning: Misconfiguring
textDirection can lead to incorrect text rendering and layout issues.