Giới thiệu
ImageView là View cơ bản để hiển thị ảnh. Bài viết trình bày các cách set ảnh: từ resource (drawable), từ URI/file, và best practices với Glide/Coil.
Các cách set ảnh vào ImageView
1. Từ Drawable Resource (XML)
<ImageView
android:id="@+id/imageView"
android:layout_width="200dp"
android:layout_height="200dp"
android:src="@drawable/ic_launcher_foreground"
android:scaleType="centerCrop"
android:contentDescription="Mô tả ảnh" />
2. Từ Drawable Resource (Code)
Java:
ImageView imageView = findViewById(R.id.imageView);
imageView.setImageResource(R.drawable.ic_launcher_foreground);
// Hoặc dùng Drawable (API 21+)
imageView.setImageDrawable(ContextCompat.getDrawable(this, R.drawable.ic_launcher_foreground));
Kotlin:
binding.imageView.setImageResource(R.drawable.ic_launcher_foreground)
// Hoặc
binding.imageView.setImageDrawable(ContextCompat.getDrawable(this, R.drawable.ic_launcher_foreground))
3. Từ File/URI (Internal Storage, Content Provider)
Java:
// Từ file path
File imgFile = new File("/storage/emulated/0/Pictures/photo.jpg");
if (imgFile.exists()) {
Bitmap bitmap = BitmapFactory.decodeFile(imgFile.getAbsolutePath());
imageView.setImageBitmap(bitmap);
}
// Từ Uri (content://...)
Uri imageUri = Uri.parse("content://media/external/images/media/123");
imageView.setImageURI(imageUri);
Kotlin:
// Từ file
val file = File("/storage/emulated/0/Pictures/photo.jpg")
if (file.exists()) {
val bitmap = BitmapFactory.decodeFile(file.absolutePath)
binding.imageView.setImageBitmap(bitmap)
}
// Từ Uri
val uri = Uri.parse("content://media/external/images/media/123")
binding.imageView.setImageURI(uri)
4. Từ Assets (assets/images/photo.jpg)
// Java
try (InputStream is = getAssets().open("images/photo.jpg")) {
Drawable drawable = Drawable.createFromStream(is, null);
imageView.setImageDrawable(drawable);
} catch (IOException e) {
e.printStackTrace();
}
// Kotlin
try {
val drawable = Drawable.createFromStream(assets.open("images/photo.jpg"), null)
binding.imageView.setImageDrawable(drawable)
} catch (e: IOException) {
e.printStackTrace()
}
Ví dụ hoàn chỉnh: Đổi ảnh khi click Button
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">
<ImageView
android:id="@+id/imageView"
android:layout_width="200dp"
android:layout_height="200dp"
android:scaleType="centerCrop"
android:src="@drawable/ic_launcher_foreground"
android:contentDescription="Ảnh hiển thị" />
<Button
android:id="@+id/btnChangeImage"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="24dp"
android:text="Đổi ảnh" />
</LinearLayout>
Code (MainActivity.kt)
package com.example.loadimageview
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import com.example.loadimageview.databinding.ActivityMainBinding
class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
private var currentImage = 0
private val images = intArrayOf(
R.drawable.img1,
R.drawable.img2,
R.drawable.img3,
R.drawable.ic_launcher_foreground
)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
binding.btnChangeImage.setOnClickListener {
currentImage = (currentImage + 1) % images.size
binding.imageView.setImageResource(images[currentImage])
}
}
}
Best Practices: Dùng thư viện tải ảnh (Glide/Coil)
Đối với ảnh từ network, file lớn, hoặc danh sách (RecyclerView), không nên dùng setImageBitmap/setImageURI trực tiếp vì:
- OOM (OutOfMemoryError) khi decode bitmap lớn.
- Không có caching → tải lại nhiều lần.
- Block UI thread khi decode.
- Không handle placeholder/error state.
Với Glide:
Glide.with(this)
.load(imageUrl) // String URL, Uri, File, Resource ID
.placeholder(R.drawable.placeholder)
.error(R.drawable.error_image)
.centerCrop()
.into(imageView)
Với Coil (Kotlin):
imageView.load(imageUrl) {
crossfade(true)
placeholder(R.drawable.placeholder)
error(R.drawable.error_image)
transformations(CenterCropTransformation())
}
scaleType phổ biến
| scaleType | Mô tả |
|---|---|
centerCrop | Căn giữa, crop để lấp đầy (giữ tỷ lệ) - phổ biến nhất |
centerInside | Căn giữa, scale down để vừa khung (không crop) |
fitCenter | Scale để vừa khung, giữ tỷ lệ (có thể có khoảng trắng) |
fitXY | Kéo dãn đầy khung (bị méo nếu tỷ lệ khác) |
center | Căn giữa, không scale |
Lưu ý quan trọng
- Luôn set
android:contentDescriptioncho accessibility (TalkBack). - Dùng
android:adjustViewBounds="true"nếu muốn ImageView tự điều chỉnh bounds theo tỷ lệ ảnh. - Với bitmap lớn: dùng
BitmapFactory.Options.inSampleSizehoặc thư viện load ảnh. - RecyclerView + ImageView: bắt buộc dùng Glide/Coil để tránh lag và OOM.