TextInputLayout là một thành phần từ thư viện Material Components cho Android dùng để bọc EditText và thêm các khả năng nhập văn bản nâng cao. Chức năng chính của TextInputLayout là nhãn nổi (floating label), nhãn này nâng lên trên trường khi nhập văn bản, tiết kiệm không gian và cải thiện khả năng đọc. Ngoài ra, thành phần này hỗ trợ hiển thị thông báo lỗi, biểu tượng bên trong trường, bộ đếm ký tự và các tùy chọn kiểu dáng khác nhau. Theo Material Design Guidelines (2025), TextInputLayout là cách được khuyến nghị để tạo trường văn bản trong ứng dụng Android tuân thủ tiêu chuẩn Material Design 3.
Những điểm chính
TextInputLayout là một ViewGroup từ gói com.google.android.material.textfield mở rộng LinearLayout và chứa một EditText bên trong. Thành phần này là một phần của thư viện Material Components cho Android, bắt đầu từ phiên bản 1.0.0. Mục đích chính của TextInputLayout là cung cấp triển khai sẵn có của Trường văn bản Material Design với nỗ lực tối thiểu từ phía nhà phát triển.
Không giống như EditText tiêu chuẩn, TextInputLayout quản lý hoạt ảnh của nhãn nổi, được thiết lập qua thuộc tính android:hint của EditText bên trong. Khi trường trống, nhãn hiển thị bên trong trường như một gợi ý thông thường. Ngay khi người dùng bắt đầu nhập, nhãn di chuyển có hoạt ảnh lên phía trên của trường, thu nhỏ kích thước. Theo Material Design Guidelines (2025), hoạt ảnh này cải thiện nhận thức về biểu mẫu vì người dùng luôn thấy tên trường, ngay cả sau khi nhập dữ liệu.
Về mặt kiến trúc, TextInputLayout triển khai mẫu decorator: nó chặn các sự kiện EditText, quản lý hiển thị các phần tử bổ sung (nhãn, lỗi, biểu tượng, bộ đếm) và điều phối hoạt ảnh của chúng. EditText bên trong có thể truy cập qua phương thức getEditText() và có thể được cấu hình với các thuộc tính tiêu chuẩn, bao gồm inputType, maxLines và hint.
<!-- Basic TextInputLayout markup -->
@+id/tilEmail
android:layout_width="match_parent"
android:layout_height="wrap_content">
@+id/etEmail
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Email"
android:inputType="textEmailAddress" />
</com.google.android.material.textfield.TextInputLayout>
Nhãn nổi (floating label) là tính năng chính của TextInputLayout. Khi trường trống, văn bản từ android:hint hiển thị bên trong EditText như một trình giữ chỗ thông thường. Khi trường nhận tiêu điểm hoặc văn bản được nhập, nhãn nâng lên phía trên của TextInputLayout, giảm kích thước phông chữ và thay đổi màu sắc. Hành vi này giải quyết vấn đề gợi ý trở nên vô hình sau khi người dùng bắt đầu nhập.
Cấu hình nhãn nổi được thực hiện qua các thuộc tính TextInputLayout: app:hintEnabled xác định nhãn nổi có được bật hay không (mặc định true), app:hintAnimationEnabled bật hoặc tắt hoạt ảnh chuyển tiếp, app:expandedHintEnabled cho phép hiển thị nhãn ngay cả khi trường trống và không được tiêu điểm. Màu của nhãn ở các trạng thái khác nhau được quản lý qua các kiểu colorPrimary và colorControlHighlight.
Theo Google Material Components Team (2025), nhãn nổi đặc biệt hữu ích trong các biểu mẫu có nhiều trường, nơi người dùng có thể quên tên trường sau khi bắt đầu nhập. Không giống như android:hint đơn giản biến mất khi nhập, nhãn nổi luôn hiển thị, cung cấp ngữ cảnh cho mỗi trường.
| Thuộc tính | Mô tả | Mặc định |
|---|---|---|
| hintEnabled | Bật hoặc tắt nhãn nổi | true |
| hintAnimationEnabled | Bật hoạt ảnh nâng/hạ nhãn | true |
| expandedHintEnabled | Hiển thị nhãn ngay cả khi trường trống và không được tiêu điểm | false |
| hintTextAppearance | Kiểu văn bản của nhãn nổi | Chủ đề ứng dụng |
TextInputLayout cung cấp một hệ thống hiển thị lỗi tích hợp được kết hợp trực quan với trường nhập. Khi đặt lỗi qua phương thức setError, thành phần làm nổi bật trường (màu của đường kẻ hoặc đường viền chuyển sang đỏ) và hiển thị văn bản lỗi bên dưới trường. Điều này loại bỏ nhu cầu về một TextView riêng cho thông báo lỗi.
Quản lý hiển thị lỗi được thực hiện qua các phương thức setError(CharSequence) và setErrorEnabled(boolean). Khi gọi setError với văn bản, lỗi hiển thị ngay lập tức; khi gọi setError(null), lỗi bị ẩn. TextInputLayout cũng hỗ trợ biểu tượng lỗi tùy chỉnh qua thuộc tính app:errorIconDrawable và quản lý màu lỗi qua app:errorTextColor.
Theo Material Design Guidelines (2025), thông báo lỗi phải cụ thể và hữu ích: thay vì “Đầu vào không hợp lệ” hãy viết “Email phải chứa @”. Hiển thị lỗi nên xảy ra sau khi hoàn thành nhập (khi mất tiêu điểm hoặc sau khi gửi biểu mẫu), không phải theo thời gian thực — điều này giảm căng thẳng cho người dùng khi điền biểu mẫu.
// Thiết lập lỗi theo chương trình
textInputLayout.error = "Password min 8 chars"
// Ẩn lỗi
textInputLayout.error = null
// Kiểm tra và đặt lỗi xác thực
if (email.isNullOrBlank()) {
tilEmail.error = "Email is required"
} else {
tilEmail.error = null
}
TextInputLayout hỗ trợ hiển thị biểu tượng ở cả đầu trường (biểu tượng bắt đầu) và cuối trường (biểu tượng kết thúc). Biểu tượng có thể thực hiện các chức năng khác nhau: chuyển đổi hiển thị mật khẩu, xóa trường, hành động tùy chỉnh. Mỗi loại biểu tượng được điều khiển bởi một thuộc tính riêng và có thể được thay thế bằng biểu tượng tùy chỉnh qua thuộc tính app:startIconDrawable hoặc app:endIconDrawable.
Chế độ biểu tượng kết thúc được thiết lập qua thuộc tính app:endIconMode, có thể nhận các giá trị sau: password_toggle — chuyển đổi hiển thị mật khẩu, clear_text — xóa trường, dropdown_menu — mũi tên cho danh sách thả xuống, custom — biểu tượng tùy chỉnh. Đối với password_toggle, TextInputLayout tự động quản lý việc chuyển đổi inputType giữa textPassword và textVisiblePassword, đồng thời tạo hoạt ảnh cho biểu tượng con mắt.
<!-- TextInputLayout with password toggle icon -->
@+id/tilPassword
android:layout_width="match_parent"
app:endIconMode="password_toggle"
app:passwordToggleTint="@color/primary">
@+id/etPassword
android:inputType="textPassword" />
</com.google.android.material.textfield.TextInputLayout>
Material Components cho Android cung cấp hai kiểu chính cho TextInputLayout: FilledBox (được tô màu) và OutlinedBox (có đường viền). Kiểu FilledBox có nền được tô màu và một đường kẻ bên dưới trường thay đổi màu khi được tiêu điểm. Kiểu OutlinedBox có nền trong suốt và đường viền xung quanh toàn bộ trường, tạo ranh giới rõ ràng hơn và phù hợp hơn cho các biểu mẫu có nhiều trường.
Việc chọn kiểu phụ thuộc vào thiết kế ứng dụng: FilledBox được khuyến nghị cho các biểu mẫu sử dụng thường xuyên vì nó thu hút ít sự chú ý đến từng trường riêng lẻ. OutlinedBox được ưu tiên cho các biểu mẫu ngắn (đăng nhập, đăng ký) nơi mỗi trường cần được đánh dấu rõ ràng. Kiểu được thiết lập qua thuộc tính style trong XML hoặc qua chủ đề ứng dụng.
| Đặc điểm | FilledBox | OutlinedBox |
|---|---|---|
| Nền | Tô màu (thường là xám) | Trong suốt |
| Đường viền | Đường kẻ ở dưới | Đường viền quanh trường |
| Tiêu điểm | Đường kẻ dày lên và đổi màu | Đường viền đổi màu và dày lên |
| Khuyến nghị | Biểu mẫu nhập thường xuyên | Biểu mẫu ngắn, nhấn mạnh trường |
| Kiểu | Widget.MaterialComponents.TextInputLayout.FilledBox | Widget.MaterialComponents.TextInputLayout.OutlinedBox |
Material Design 3 (M3) đã giới thiệu các kiểu cập nhật cho TextInputLayout với kiểu chữ được cải thiện, mã thông báo màu mới và hỗ trợ màu động Material You. Trong M3, OutlinedBox đã trở thành kiểu được khuyến nghị mặc định và FilledBox đã điều chỉnh phần đệm và bán kính viền để phù hợp với đặc tả mới.
Một ví dụ hoàn chỉnh về triển khai biểu mẫu đăng ký với TextInputLayout, bao gồm xác thực email và mật khẩu, hiển thị lỗi và biểu tượng hiển thị mật khẩu. Khi nhấn nút đăng ký, tất cả các trường được kiểm tra và thông báo lỗi tương ứng được hiển thị.
@+id/tilName
app:boxBackgroundMode="outlined">
@+id/etName
android:hint="Name" />
</...TextInputLayout>
@+id/tilRegEmail
app:boxBackgroundMode="outlined">
@+id/etRegEmail
android:hint="Email"
android:inputType="textEmailAddress" />
</...TextInputLayout>
@+id/tilRegPassword
app:boxBackgroundMode="outlined"
app:endIconMode="password_toggle">
@+id/etRegPassword
android:hint="Password"
android:inputType="textPassword" />
</...TextInputLayout>
private fun validateForm(): Boolean {
var isValid = true
if (etName.text.isNullOrBlank()) {
tilName.error = "Enter your name"
isValid = false
} else {
tilName.error = null
}
val email = etRegEmail.text.toString()
if (!Patterns.EMAIL_ADDRESS.matcher(email).matches()) {
tilRegEmail.error = "Invalid email format"
isValid = false
} else {
tilRegEmail.error = null
}
val password = etRegPassword.text.toString()
if (password.length < 8) {
tilRegPassword.error = "Password min 8 chars"
isValid = false
} else {
tilRegPassword.error = null
}
return isValid
}
Các câu hỏi thường gặp
TextInputLayout có sẵn từ phiên bản 1.0.0 của thư viện com.google.android.material. Đối với các tính năng Material Design 3, hãy sử dụng phiên bản 1.6.0 trở lên. Bao gồm: implementation “com.google.android.material:material:1.12.0” trong build.gradle của mô-đun.
Màu của nhãn nổi ở trạng thái tiêu điểm được điều khiển bởi thuộc tính app:hintTextColor hoặc qua chủ đề bằng colorPrimary. Đối với các trạng thái khác nhau (tiêu điểm, lỗi, vô hiệu), hãy sử dụng bộ chọn trong res/color/ hoặc các thuộc tính boxStrokeColor, errorTextColor từ thư viện Material Components.
Đặt thuộc tính app:counterEnabled=“true” và chỉ định số ký tự tối đa qua app:counterMaxLength=“100”. TextInputLayout sẽ tự động hiển thị bộ đếm ở cuối trường (ví dụ: “25/100”). Màu bộ đếm có thể được cấu hình qua app:counterTextColor và app:counterOverflowTextColor cho trường hợp vượt quá giới hạn.
FilledBox — nền được tô màu, nhấn mạnh đường kẻ dưới. Chiếm ít không gian thị giác hơn. OutlinedBox — nền trong suốt với đường viền quanh trường, ranh giới rõ ràng hơn. FilledBox được khuyến nghị cho các trường nhập thường xuyên, OutlinedBox cho các biểu mẫu ngắn nơi sự rõ ràng của từng trường là quan trọng.
Có, đặt thuộc tính app:hintEnabled=“false” để tắt nhãn nổi. Trong trường hợp này, TextInputLayout sẽ hoạt động như một trình bọc thông thường cho EditText, giữ lại chức năng lỗi, biểu tượng và bộ đếm ký tự, nhưng không có hoạt ảnh nhãn. Hữu ích cho các trường không cần gợi ý hoặc sử dụng nhãn tùy chỉnh.
Tóm tắt
Chúng tôi sẽ phát triển ứng dụng di động chìa khóa trao tay
IT Sectr tạo các ứng dụng iOS và Android cho các công ty khởi nghiệp và doanh nghiệp từ năm 2017. Chúng tôi sẽ tư vấn và đề xuất giải pháp tốt nhất cho bạn.
Đọc thêm