Giới thiệu
Ví dụ minh họa cách lấy kích thước (chiều cao) của thanh điều hướng (Navigation Bar) hệ thống theo chương trình bằng Kotlin. Lưu ý: Trên Android hiện đại, Navigation Bar có thể ẩn/hiện động, kích thước thay đổi.
Các bước thực hiện
Bước 1: Tạo dự án mới
Android Studio > File > New Project.
Bước 2: Layout (activity_main.xml)
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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"
tools:context=".MainActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_marginTop="70dp"
android:background="#008080"
android:padding="5dp"
android:text="TutorialsPoint"
android:textColor="#fff"
android:textSize="24sp"
android:textStyle="bold" />
<TextView
android:id="@+id/text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="Chiều cao Navigation Bar"
android:textColor="@android:color/holo_purple"
android:textSize="16sp"
android:textStyle="bold" />
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/text"
android:layout_centerInParent="true"
android:layout_marginTop="10dp"
android:textColor="@android:color/background_dark"
android:textSize="24sp"
android:textStyle="bold" />
</RelativeLayout>
Bước 3: MainActivity.kt (Cách cũ - Resource ID)
import android.content.res.Resources
import android.os.Bundle
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
title = "KotlinApp"
val textView: TextView = findViewById(R.id.textView)
val resources: Resources = resources
val resourceId: Int = resources.getIdentifier("navigation_bar_height", "dimen", "android")
if (resourceId > 0) {
val heightPx = resources.getDimensionPixelSize(resourceId)
textView.text = "Navigation Bar Height: $heightPx px"
} else {
textView.text = "Không tìm thấy resource navigation_bar_height"
}
}
}
Bước 4: AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="https://schemas.android.com/apk/res/android"
package="com.example.navbarsize">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
Chạy ứng dụng
Chạy app, TextView sẽ hiển thị chiều cao Navigation Bar tính bằng pixel (ví dụ: 144px trên nhiều thiết bị).
Cách hiện đại & Chính xác hơn (WindowInsets - API 20+)
Cách dùng resource ID navigation_bar_height không đáng tin cậy khi Navigation Bar ẩn (gesture navigation) hoặc kích thước thay đổi. Nên dùng WindowInsets:
1. Sử dụng View.OnApplyWindowInsetsListener (API 20+)
view.setOnApplyWindowInsetsListener { v, insets ->
val navBarHeight = insets.getInsets(WindowInsets.Type.navigationBars()).bottom
val statusBarHeight = insets.getInsets(WindowInsets.Type.statusBars()).top
// Cập nhật UI, padding, margin ở đây
textView.text = "NavBar: $navBarHeight px, StatusBar: $statusBarHeight px"
insets // Trả về insets để tiếp tục lan truyền
}
2. Sử dụng WindowInsetsCompat (AndroidX - Khuyến nghị)
// Trong Activity/Fragment
ViewCompat.setOnApplyWindowInsetsListener(rootView) { v, insets ->
val navBarInsets = insets.getInsets(WindowInsetsCompat.Type.navigationBars())
val navHeight = navBarInsets.bottom
// Xử lý...
insets
}
3. Lấy kích thước một lần (không listen)
val navBarHeight = resources.getDimensionPixelSize(
resources.getIdentifier("navigation_bar_height", "dimen", "android")
)
// Hoặc từ WindowManager (API 30+)
val metrics = WindowMetricsCalculator.getOrCreate().computeCurrentWindowMetrics(this)
val windowInsets = metrics.getWindowInsets()
val navBarHeight = windowInsets.getInsets(WindowInsets.Type.navigationBars()).bottom
Bảng so sánh
| Cách | Độ tin cậy | Hỗ trợ Gesture Nav | API min |
|---|---|---|---|
| Resource ID (navigation_bar_height) | Thấp (cố định, không cập nhật) | Không | 1 |
| View.OnApplyWindowInsetsListener | Cao (real-time) | Có | 20 |
| WindowInsetsCompat (AndroidX) | Cao nhất (backport) | Có | 14+ (AndroidX) |
Lưu ý
- Navigation Bar width thường = màn hình width (trừ landscape có side bar).
- Trên Android 10+ với điều hướng bằng cử chỉ (gesture navigation), Navigation Bar có thể height = 0 hoặc rất nhỏ (handle bar).
- Luôn xử lý trường hợp insets = 0.