Giới thiệu
Kích thước của ImageView (width/height) chỉ có giá trị khác 0 sau khi layout đã hoàn tất (sau onLayout). Nếu gọi getWidth()/getHeight() trong onCreate() sẽ trả về 0. Bài viết hướng dẫn các cách đúng để lấy kích thước thực tế.
Các bước thực hiện
Bước 1: Tạo dự án mới
Android Studio → File → New Project → Empty View Activity.
Bước 2: Thiết kế giao diện (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"
tools:context=".MainActivity">
<ImageView
android:id="@+id/imageView"
android:layout_width="match_parent"
android:layout_height="200dp"
android:src="@drawable/ic_launcher_foreground"
android:scaleType="centerCrop"
android:contentDescription="Ảnh mẫu" />
<Button
android:id="@+id/btnCheckSize"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:layout_gravity="center"
android:text="Kiểm tra kích thước ImageView" />
<TextView
android:id="@+id/tvResult"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:layout_gravity="center"
android:textSize="16sp"
android:textStyle="bold" />
</LinearLayout>
Bước 3: Code xử lý (MainActivity.java / MainActivity.kt)
Java - Sử dụng ViewTreeObserver.OnGlobalLayoutListener:
package com.example.imagesize;
import android.os.Bundle;
import android.view.View;
import android.view.ViewTreeObserver;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;
public class MainActivity extends AppCompatActivity {
private ImageView imageView;
private TextView tvResult;
private Button btnCheck;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
imageView = findViewById(R.id.imageView);
tvResult = findViewById(R.id.tvResult);
btnCheck = findViewById(R.id.btnCheckSize);
btnCheck.setOnClickListener(v -> showImageViewSize());
// Cách 1: Lấy size ngay khi layout xong (tự động)
imageView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
// Quan trọng: remove listener để không gọi nhiều lần
imageView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
showImageViewSize();
}
});
}
private void showImageViewSize() {
int width = imageView.getWidth();
int height = imageView.getHeight();
tvResult.setText(String.format("Kích thước ImageView:\nWidth: %d px\nHeight: %d px", width, height));
}
}
Kotlin - Sử dụng doOnLayout (extension function):
package com.example.imagesize
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import com.example.imagesize.databinding.ActivityMainBinding
import kotlinx.coroutines.delay
class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
// Cách 1: doOnLayout - chạy khi layout hoàn tất
binding.imageView.doOnLayout {
updateSizeText()
}
// Cách 2: Nếu cần lấy size ngay lập tức (đã layout rồi)
binding.btnCheckSize.setOnClickListener {
updateSizeText()
}
}
private fun updateSizeText() {
val width = binding.imageView.width
val height = binding.imageView.height
binding.tvResult.text = "Kích thước ImageView:\nWidth: $width px\nHeight: $height px"
}
}
Các phương pháp lấy kích thước View
| Phương pháp | Khi nào dùng | Ưu/nhược điểm |
|---|---|---|
ViewTreeObserver.OnGlobalLayoutListener | Cần size ngay khi activity/fragment tạo | Được gọi nhiều lần, phải remove listener |
View.doOnLayout { } (Kotlin) | Code Kotlin hiện đại | Tự động remove, code gọn nhẹ |
View.post { } | Đơn giản, chạy sau khi UI vẽ xong | Dễ dùng nhưng không đảm bảo layout xong 100% |
onWindowFocusChanged | Cần size khi window có focus | Gọi nhiều lần khi focus thay đổi |
Override onSizeChanged (Custom View) | Tạo custom View | Clean nhất cho custom view |
Lưu ý quan trọng
- Luôn kiểm tra
width > 0 && height > 0trước khi dùng. - Nếu ImageView dùng
wrap_contentvà ảnh load async (Glide/Coil), size sẽ thay đổi sau khi ảnh load xong → dùngaddOnLayoutChangeListenerhoặc callback của thư viện ảnh. - Trên Jetpack Compose: dùng
onGloballyPositionedhoặcModifier.onSizeChanged { }.