
Chào các "developer tương lai", hay nói đúng hơn là những "kiến trúc sư số" đang nung nấu tạo ra những công trình UI/UX vĩ đại! Anh Creyt biết các em đang lướt Flutter ầm ầm, dựng UI nhanh như chớp. Nhưng có bao giờ các em nghĩ, nếu app của mình được một người bạn ở Ả Rập hay Israel dùng thì sao không? Mấy bạn đó đọc từ phải sang trái (RTL) đó nha. Lúc đó, cái padding 'trái' của em bỗng thành 'phải', nhìn nó cứ sai sai, như mặc áo trái vậy!
Đấy, lúc này, "PaddingDirectional" chính là vị cứu tinh, là "bodyguard" thông minh cho UI của các em. Thay vì nói 'padding trái là 16px', 'phải là 8px' cứng nhắc, thì PaddingDirectional cho phép em nói: 'padding ở đầu hướng đọc là 16px', 'ở cuối hướng đọc là 8px'. Nghe ngầu hơn hẳn đúng không?
Nó không quan tâm hướng vật lý là trái hay phải nữa, mà nó quan tâm đến cái hướng mà văn bản đang được đọc. Nếu là tiếng Việt (Left-to-Right - LTR), thì 'start' là trái, 'end' là phải. Còn nếu là tiếng Ả Rập (Right-to-Left - RTL), thì 'start' lại là phải, 'end' lại là trái. Tự động điều chỉnh, thông minh như một con AI vậy đó!
Code Ví Dụ Minh Hoạ: "Công Trình" Tự Điều Chỉnh
Để các em dễ hình dung, anh Creyt sẽ phác thảo một 'công trình' nhỏ xíu để thấy rõ sức mạnh của nó:
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'PaddingDirectional Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
// Quan trọng: Thử nghiệm với Directionality
// locale: const Locale('ar'), // Bỏ comment để thử với ngôn ngữ RTL (Arabic)
// supportedLocales: const [
// Locale('en', ''),
// Locale('ar', ''),
// ],
// localizationsDelegates: const [
// DefaultMaterialLocalizations.delegate,
// DefaultWidgetsLocalizations.delegate,
// ],
home: const MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key});
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
bool _isRTL = false; // Trạng thái để chuyển đổi LTR/RTL
@override
Widget build(BuildContext context) {
return Directionality( // Widget này giúp chúng ta "giả lập" hướng đọc
textDirection: _isRTL ? TextDirection.rtl : TextDirection.ltr,
child: Scaffold(
appBar: AppBar(
title: const Text('PaddingDirectional Magic'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
color: Colors.red.shade100,
padding: const EdgeInsetsDirectional.only(start: 20.0, end: 10.0, top: 15.0, bottom: 5.0),
child: const Text(
'Đây là văn bản ví dụ.\nNó sẽ tự điều chỉnh padding theo hướng đọc.',
style: TextStyle(fontSize: 18),
),
),
const SizedBox(height: 30),
// So sánh với EdgeInsets.only thông thường
Container(
color: Colors.green.shade100,
padding: const EdgeInsets.only(left: 20.0, right: 10.0, top: 15.0, bottom: 5.0),
child: const Text(
'Đây là văn bản ví dụ (EdgeInsets).\nPadding này sẽ cố định, không đổi.',
style: TextStyle(fontSize: 18),
),
),
const SizedBox(height: 50),
ElevatedButton(
onPressed: () {
setState(() {
_isRTL = !_isRTL; // Đảo ngược hướng đọc
});
},
child: Text(_isRTL ? 'Chuyển sang LTR' : 'Chuyển sang RTL'),
),
const SizedBox(height: 10),
Text('Hướng hiện tại: ${_isRTL ? 'RTL (Right-to-Left)' : 'LTR (Left-to-Right)'}'),
],
),
),
),
);
}
}
Ở ví dụ trên, anh dùng Directionality để giả lập việc thay đổi hướng đọc của ứng dụng (thực tế nó sẽ thay đổi khi em đổi ngôn ngữ hệ thống sang tiếng Ả Rập chẳng hạn).
- Khi
_isRTLlàfalse(hướng LTR),startsẽ làleft,endlàright. - Khi
_isRTLlàtrue(hướng RTL),startsẽ làright,endlàleft.
Em sẽ thấy cái Container màu đỏ (dùng EdgeInsetsDirectional) tự động "lật" padding ngang khi em bấm nút, còn cái Container màu xanh (dùng EdgeInsets.only) thì vẫn "cứng đầu" giữ nguyên.

Mẹo Vặt Từ Giảng Viên Creyt (Best Practices)
Rồi, giờ là vài 'mẹo vặt' mà anh Creyt tích góp được trong bao năm 'xây dựng' UI:
- Dùng đúng lúc, đúng chỗ: Luôn ưu tiên
EdgeInsetsDirectional(hay các widget có hậu tốDirectionalnhưAlignDirectional,StartvàEndtrongRow/Columnmain/crossAxisAlignment) khi em cần padding/alignment liên quan đến hướng đọc của văn bản. Nếu đó là một icon cố định ở bên trái màn hình không phụ thuộc ngôn ngữ, thìEdgeInsets.only(left: ...)vẫn là chân ái. - Tư duy quốc tế hóa (i18n) từ đầu: Đừng đợi đến lúc app ra lò rồi mới 'vá' cho RTL. Ngay từ khi thiết kế UI, hãy nghĩ xem 'cái này có cần lật không?'. Nếu có, dùng
Directionalngay. - Test kỹ với RTL: Luôn dành thời gian test app của mình với các ngôn ngữ RTL (như tiếng Ả Rập) trên thiết bị thật hoặc emulator. Đôi khi có những lỗi nhỏ mà chỉ khi 'lật' UI mới thấy được.
- Tránh nhầm lẫn:
startkhông phải lúc nào cũng làleft,endkhông phải lúc nào cũng làright. Nó là 'khởi đầu' và 'kết thúc' của dòng chữ. Nhớ kỹ điều này là em sẽ không bao giờ nhầm nữa!
Ứng Dụng Thực Tế: Ai Đang Dùng "Vị Thần" Này?
Em nghĩ xem, những ứng dụng nào đang làm mưa làm gió trên thị trường mà có hỗ trợ đa ngôn ngữ?
- Facebook, Instagram, Twitter: Mấy ông lớn này có người dùng khắp thế giới, nên việc UI phải 'tự động lật' là chuyện hiển nhiên. Thử chuyển ngôn ngữ Facebook sang tiếng Ả Rập mà xem, mọi thứ sẽ đảo chiều một cách mượt mà.
- Google Apps (Gmail, Maps, Chrome): Tương tự, Google là bá chủ về đa ngôn ngữ, các ứng dụng của họ đều được tối ưu cho RTL.
- WhatsApp, Telegram: Các ứng dụng nhắn tin cũng cần đảm bảo trải nghiệm nhất quán cho mọi người dùng, bất kể hướng đọc.
Tóm lại, bất kỳ ứng dụng nào muốn vươn tầm quốc tế, muốn 'cưng chiều' người dùng từ mọi nền văn hóa thì đều phải dùng đến những 'vị thần' như PaddingDirectional này!
Khi Nào Nên "Triệu Hồi" PaddingDirectional?
Vậy khi nào thì anh em mình nên 'triệu hồi' PaddingDirectional?
- Khi xây dựng layout chung cho toàn bộ ứng dụng: Nếu app của em có khả năng hỗ trợ nhiều ngôn ngữ, đặc biệt là có RTL, thì hãy mặc định dùng
EdgeInsetsDirectionalcho các padding ngang. Nó giúp em 'khỏe' về sau rất nhiều. - Các thành phần UI cần đối xứng theo hướng đọc: Ví dụ: một danh sách có icon ở đầu dòng, text ở giữa, và một mũi tên ở cuối dòng. Khi chuyển sang RTL, icon sẽ sang phải, mũi tên sang trái.
PaddingDirectionalsẽ giúp em cân bằng khoảng cách giữa các thành phần này. - Tránh dùng khi: Padding đó là cố định về mặt vật lý và không liên quan đến hướng đọc. Ví dụ, em có một logo luôn nằm ở góc trên bên trái màn hình, không bao giờ thay đổi vị trí dù ngôn ngữ là gì. Lúc đó,
EdgeInsets.only(top: ..., left: ...)là đủ rồi.
Thuộc Series: Flutter
Bài giảng này được tự động xuất bản ngẫu nhiên từ thư viện kiến thức. Đừng quên đón xem các Từ khoá Hướng Dẫn tiếp theo nhé!