Giới thiệu
Toast là thông báo nhẹ hiển thị ngắn gọn trên màn hình, tự động biến mất sau vài giây, không chặn tương tác người dùng. Dùng cho feedback đơn giản: "Đã lưu", "Lỗi kết nối", "Copied to clipboard"...
Cách dùng cơ bản
Toast.makeText() - Cú pháp chuẩn
// Java
Toast.makeText(context, "Nội dung thông báo", Toast.LENGTH_SHORT).show();
// Kotlin
Toast.makeText(context, "Nội dung thông báo", Toast.LENGTH_SHORT).show()
context:this(Activity),getApplicationContext(),view.context,requireContext()(Fragment).LENGTH_SHORT(~2 giây),LENGTH_LONG(~3.5 giây).- Phải gọi
.show()- quên gọi này là lỗi phổ biến.
Ví dụ hoàn chỉnh
Layout (res/layout/activity_main.xml)
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="https://schemas.android.com/apk/res/android"
xmlns:tools="https://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="24dp"
android:gravity="center"
tools:context=".MainActivity">
<Button
android:id="@+id/btnShortToast"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Toast SHORT (2s)" />
<Button
android:id="@+id/btnLongToast"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
android:text="Toast LONG (3.5s)" />
<Button
android:id="@+id/btnCustomToast"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
android:text="Custom Toast (Layout tùy chỉnh)" />
</LinearLayout>
Code (MainActivity.kt)
package com.example.toastdemo
import android.os.Bundle
import android.view.Gravity
import android.view.LayoutInflater
import android.view.View
import android.widget.Button
import android.widget.TextView
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import com.example.toastdemo.databinding.ActivityMainBinding
class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
binding.btnShortToast.setOnClickListener {
Toast.makeText(this, "Đây là Toast SHORT", Toast.LENGTH_SHORT).show()
}
binding.btnLongToast.setOnClickListener {
Toast.makeText(this, "Đây là Toast LONG - hiển thị lâu hơn", Toast.LENGTH_LONG).show()
}
binding.btnCustomToast.setOnClickListener {
showCustomToast()
}
}
private fun showCustomToast() {
val inflater = layoutInflater
val layout = inflater.inflate(R.layout.custom_toast, findViewById(R.id.custom_toast_container))
val text = layout.findViewById(R.id.tvToastMessage)
text.text = "Đây là Custom Toast với icon và màu sắc!"
val toast = Toast(applicationContext)
toast.duration = Toast.LENGTH_LONG
toast.gravity = Gravity.CENTER
toast.view = layout
toast.show()
}
}
Custom Toast Layout (res/layout/custom_toast.xml)
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="https://schemas.android.com/apk/res/android"
android:id="@+id/custom_toast_container"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:padding="16dp"
android:background="@drawable/toast_background"
android:gravity="center_vertical">
<ImageView
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_marginEnd="12dp"
android:src="@android:drawable/ic_dialog_info"
android:contentDescription="Icon" />
<TextView
android:id="@+id/tvToastMessage"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@android:color/white"
android:textSize="16sp" />
</LinearLayout>
Toast Background (res/drawable/toast_background.xml)
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="https://schemas.android.com/apk/res/android">
<solid android:color="#333333" />
<corners android:radius="12dp" />
</shape>
Snackbar - Thay thế hiện đại cho Toast
Snackbar (Material Design) tốt hơn Toast:
- Hiển thị ở bottom screen, có action button (Undo, Retry...).
- Tương tác được (swipe to dismiss).
- Animation mượt mà, Material Design 3.
Dependency: implementation("com.google.android.material:material:1.12.0")
// Snackbar cơ bản
Snackbar.make(binding.root, "Đã xóa mục", Snackbar.LENGTH_LONG).show()
// Snackbar với Action
Snackbar.make(binding.root, "Mục đã xóa", Snackbar.LENGTH_LONG)
.setAction("Hoàn tác") { viewModel.undoDelete() }
.setActionTextColor(Color.YELLOW)
.show()
Lưu ý quan trọng
- Toast chỉ hiển thị trên main thread. Nếu gọi từ background thread:
runOnUiThread { Toast.makeText(...).show() }. - Không hiển thị nhiều Toast cùng lúc - chúng xếp hàng (queue).
- Custom Toast: từ Android 12 (API 31), custom view toast bị hạn chế (chỉ text + icon). Khuyến nghị dùng Snackbar.
- Trong Fragment: dùng
requireContext()hoặcrequireActivity()làm context. - Test trên Android 13+: Toast custom layout có thể không hiển thị đúng.
So sánh Toast vs Snackbar
| Đặc điểm | Toast | Snackbar |
|---|---|---|
| Vị trí | Bottom (fixed) | Bottom (có animation) |
| Action button | Không | Có |
| Swipe dismiss | Không | Có |
| Custom layout | Hỗ trợ (bị hạn chế API 31+) | Hỗ trợ đầy đủ |
| Material Design | Không | Có (MD3) |