Giới thiệu
ActionBar (hoặc Toolbar trong AppCompat) cho phép set custom view để hiển thị layout tùy chỉnh (logo, title tùy biến, button, search...). Bài viết hướng dẫn dùng Toolbar (khuyến nghị) và ActionBar.setCustomView() (cũ).
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 (theme NoActionBar).
Bước 2: Theme NoActionBar (res/values/themes.xml)
<resources>
<style name="Theme.CustomActionBar" parent="Theme.Material3.DayNight.NoActionBar">
<!-- Customize your theme here -->
</style>
</resources>
Trong AndroidManifest.xml: android:theme="@style/Theme.CustomActionBar"
Bước 3: Thêm Toolbar vào layout chính (res/layout/activity_main.xml)
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout
xmlns:android="https://schemas.android.com/apk/res/android"
xmlns:app="https://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:titleTextColor="@android:color/white"
app:subtitleTextColor="@android:color/white" />
</com.google.android.material.appbar.AppBarLayout>
<FrameLayout
android:id="@+id/contentFrame"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>
Bước 4: Tạo custom view layout (res/layout/custom_toolbar.xml)
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="https://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
android:gravity="center_vertical"
android:padding="8dp">
<ImageView
android:id="@+id/ivLogo"
android:layout_width="32dp"
android:layout_height="32dp"
android:src="@mipmap/ic_launcher"
android:contentDescription="Logo" />
<TextView
android:id="@+id/tvTitle"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_marginStart="12dp"
android:text="Instagram"
android:textSize="20sp"
android:textColor="@android:color/white"
android:textStyle="bold" />
<ImageButton
android:id="@+id/ibSearch"
android:layout_width="40dp"
android:layout_height="40dp"
android:src="@android:drawable/ic_menu_search"
android:background="?attr/selectableItemBackgroundBorderless"
android:contentDescription="Tìm kiếm" />
<ImageButton
android:id="@+id/ibMenu"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_marginStart="8dp"
android:src="@android:drawable/ic_menu_more"
android:background="?attr/selectableItemBackgroundBorderless"
android:contentDescription="Menu" />
</LinearLayout>
Bước 5: Code Activity (MainActivity.kt)
package com.example.customactionbar
import android.os.Bundle
import android.view.View
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.widget.Toolbar
import com.example.customactionbar.databinding.ActivityMainBinding
import com.example.customactionbar.databinding.CustomToolbarBinding
class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
private var customToolbarBinding: CustomToolbarBinding? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
// 1. Setup Toolbar làm ActionBar
setSupportActionBar(binding.toolbar)
supportActionBar?.setDisplayShowTitleEnabled(false) // Tắt title mặc định
// 2. Inflate custom view
customToolbarBinding = CustomToolbarBinding.inflate(layoutInflater)
binding.toolbar.addView(customToolbarBinding!!.root)
// 3. Xử lý click trên custom view
customToolbarBinding!!.tvTitle.setOnClickListener {
Toast.makeText(this, "Đã click vào title", Toast.LENGTH_SHORT).show()
}
customToolbarBinding!!.ibSearch.setOnClickListener {
Toast.makeText(this, "Mở tìm kiếm", Toast.LENGTH_SHORT).show()
}
customToolbarBinding!!.ibMenu.setOnClickListener {
Toast.makeText(this, "Mở menu", Toast.LENGTH_SHORT).show()
}
}
}
Cách cũ: ActionBar.setCustomView() (Deprecated)
Chỉ dùng nếu bắt buộc dùng ActionBar hệ thống (theme có ActionBar):
// Java
ActionBar actionBar = getSupportActionBar();
actionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM);
actionBar.setCustomView(R.layout.custom_action_bar);
actionBar.setDisplayShowCustomEnabled(true);
// Lấy view để set listener
View customView = actionBar.getCustomView();
TextView tvTitle = customView.findViewById(R.id.name);
tvTitle.setOnClickListener(v -> Toast.makeText(this, "Clicked title", Toast.LENGTH_SHORT).show());
So sánh: Toolbar vs ActionBar.setCustomView()
| Đặc điểm | Toolbar (Khuyến nghị) | ActionBar.setCustomView() |
|---|---|---|
| Linh hoạt | Cao (là View bình thường) | Thấp (giới hạn bởi ActionBar) |
| Hỗ trợ Material 3 | Có | Không |
| Animation, collapse | Có (CollapsingToolbarLayout) | Không |
| Menu inflation | toolbar.inflateMenu() | onCreateOptionsMenu |
| Back button | setNavigationIcon() + listener | Tự động qua setDisplayHomeAsUpEnabled |
Lưu ý quan trọng
- Luôn dùng Theme.NoActionBar và tự add Toolbar.
- Custom view trong Toolbar có thể là bất kỳ ViewGroup nào (ConstraintLayout, LinearLayout...).
- Để set title động:
binding.toolbar.title = "New Title"hoặc dùng TextView trong custom view. - Menu:
toolbar.inflateMenu(R.menu.menu_main)+toolbar.setOnMenuItemClickListener { }. - Back navigation:
toolbar.setNavigationIcon(R.drawable.ic_arrow_back)+setNavigationOnClickListener { onBackPressed() }.