Một màn hình hiển thị tên người dùng và tên nhóm. Cách nối các mảnh text trong Kotlin có thể chạy với tiếng Việt nhưng làm người dịch khó đổi thứ tự từ. Giữ nguyên câu trong resource và đánh số placeholder giúp tách cấu trúc ngôn ngữ khỏi thứ tự truyền dữ liệu.
Bài đối chiếu Android String resources, Context.getString và hướng dẫn localization ngày 02/11/2026. Overload getString(int, Object...) có từ API 1. XML đã được parse cục bộ; Kotlin được rà thủ công, chưa build bằng Android SDK, chạy emulator hay instrumentation test. Các câu dịch là ví dụ biên tập, chưa qua người dịch bản địa.
Định nghĩa hợp đồng của hai arguments
Quy ước argument 1 là tên người dùng, argument 2 là tên nhóm. Cả hai là chuỗi text hiển thị. Chúng ta không dùng số lượng nên không xử lý quy tắc số ít, số nhiều trong ví dụ này.
Đặt nội dung mặc định của app demo vào app/src/main/res/values/strings.xml. Nếu file đã tồn tại, thêm các string bên trong phần tử resources hiện tại, không tạo hai root:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="member_summary">%1$s thuộc nhóm %2$s</string>
<string name="demo_user_name" translatable="false">An</string>
<string name="demo_team_name" translatable="false">Mobile</string>
</resources>
Tên demo được đánh dấu không dịch để người dịch tập trung vào khuôn câu. Trong ứng dụng thật, chúng thường đến từ dữ liệu nghiệp vụ. Đừng dùng tên resource của demo làm quy tắc lưu toàn bộ tên người dùng trong file XML.
Cho bản dịch đổi vị trí placeholder
Tạo app/src/main/res/values-en/strings.xml cho ví dụ tiếng Anh:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="member_summary">Team %2$s includes %1$s</string>
</resources>
Bản dịch đưa nhóm lên trước nhưng vẫn dùng %2$s cho tên nhóm. Code Kotlin không cần đảo arguments theo từng locale. Giữ một hợp đồng truyền dữ liệu ổn định sẽ dễ review hơn nhiều nhánh nối chuỗi theo ngôn ngữ.
Ví dụ cố ý đổi cả cấu trúc câu để thấy vị trí dữ liệu, không khẳng định đây là bản dịch duy nhất hay phù hợp mọi màn hình. Khi tích hợp sản phẩm, hãy gửi cho người dịch ý nghĩa từng placeholder và ảnh ngữ cảnh.
Lấy câu đã format bằng Context
Hàm dưới nhận Context và TextView của màn hình đã tạo, không cần giả định một ID layout cụ thể:
import android.content.Context
import android.widget.TextView
fun bindMemberSummary(context: Context, target: TextView) {
val userName = context.getString(R.string.demo_user_name)
val teamName = context.getString(R.string.demo_team_name)
target.text = context.getString(
R.string.member_summary,
userName,
teamName,
)
}
Đặt hàm trong package module app để R là lớp resource do chính app sinh ra; không import android.R. Gọi hàm từ màn hình sau khi có TextView hợp lệ. Context cần phản ánh cấu hình ngôn ngữ đang dùng ở màn hình đó; ví dụ không tự thay đổi locale hay thiết lập ngôn ngữ riêng cho app.
Với dữ liệu demo, câu mong muốn khi dùng resource mặc định là “An thuộc nhóm Mobile”; resource tiếng Anh tạo “Team Mobile includes An”. Đây là kết quả suy ra từ hợp đồng format để kiểm tra trên app, chưa phải output đã quan sát từ thiết bị trong bài.
Kiểm tra trước khi giao bản dịch
Giữ đủ resource mặc định trong values, kể cả khi bạn đã thêm values-en. Android cần bộ mặc định để fallback khi một bản dịch không có key. Hai file có cùng tên member_summary phải giữ đúng ý nghĩa và loại của arguments.
Thử tên rỗng, tên dài, chữ có dấu và ký tự % trong dữ liệu. Dữ liệu được truyền làm argument, không dùng chính chuỗi do người dùng nhập làm format template. Nếu XML chứa ký tự & hoặc < trong text, cần escape theo XML; việc format placeholder không thay cho bước viết XML hợp lệ.
Trên project thật, chạy build và Android lint, đổi ngôn ngữ mặc định/tiếng Anh, rồi quan sát đúng thứ tự và khả năng xuống dòng của TextView. Parse XML cục bộ chỉ xác nhận cấu trúc XML, không kiểm chứng AAPT, resource merging hay cách UI hiển thị.
Những lỗi dễ gặp
%s không đánh số khiến hợp đồng vị trí khó thấy hơn khi câu có nhiều dữ liệu. Đổi loại placeholder trong một bản dịch có thể tạo lỗi format ở runtime. Ghép các mảnh câu riêng lẻ trong code cũng khiến người dịch không thể chủ động đặt dấu câu và đổi thứ tự.
Giữ nguyên câu làm đơn vị dịch, mô tả rõ arguments và kiểm tra cả fallback là ba việc nhỏ giúp phần text dễ duy trì. Nếu chuyển sang nội dung có số lượng, hãy thiết kế plurals riêng thay vì nhân rộng khuôn câu hiện tại.


