Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> Android

Cách hiển thị custom view trên ActionBar/Toolbar Android

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ểmToolbar (Khuyến nghị)ActionBar.setCustomView()
Linh hoạtCao (là View bình thường)Thấp (giới hạn bởi ActionBar)
Hỗ trợ Material 3CóKhông
Animation, collapseCó (CollapsingToolbarLayout)Không
Menu inflationtoolbar.inflateMenu()onCreateOptionsMenu
Back buttonsetNavigationIcon() + listenerTự độ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() }.