Bekerja dengan Toolbar di Android
Bagus Aji Santoso 16 Oktober 2017
Pendahuluan
Toolbar
diperkenalkan saat Android Lollipop, API 21 dirilis dan merupakan penerus dari ActionBar. Toolbar
adalah sebuah ViewGroup
yang dapat diletakkan di mana saja di dalam layout XML kita. Tampilan dan kelakuannya dapat diatur dengan lebih mudah dibanding ActionBar
.
Toolbar
dapat bekerja dengan sangat baik untuk aplikasi yang menargetkan API 21 ke atas. Meskipun begitu, Android telah memperbarui pustaka AppCompat agar Toolbar
dapat dipakai di perangkat dengan sistem operasi Android yang lebih lama. Di AppCompat, Toolbar
diimplementasi di dalam kelas android.support.v7.widget.Toolbar
.
Ada dua cara untuk menggunakan Toolbar:
- Gunakan sebuah
Toolbar
sebagai Action Bar untuk mendapatkan fasilitas ActionBar yang sudah ada (seperti pembacaan dan pemilihan menu,ActionBarDrawerToggle
, dll.) namun ingin bisa mengatur bagaimana penampilannya. - Menggunakan
Toolbar
untuk situasi dimana Action Bar sudah tidak mampu lagi menanganinya, contoh saat ingin menampilkan beberapa toolbar di dalam layar, dll.
Memahami App Resource di Android
Toolbar vs ActionBar
Toolbar adalah generalisasi dari sistem ActionBar. Perbedaan yang membedakan antara Toolbar
dari ActionBar
adalah:
Toolbar
adalah sebuahView
yang memiliki sebuah komponen layout sepertiView
lainnya.- Karena sebuah
View
, posisi, animasi serta kontrol toolbar dapat diatur dengan lebih mudah. - Bisa membuat beberapa elemen
Toolbar
di satu activity.
Perlu diingin kita juga dapat mengatur Toolbar
manapun sebagai ActionBar-nya Activity, artinya kita mendapatkan options menu didalamnya.
Catat juga bahwa ActionBar masih bisa dipakai jika hanya membutuhkan sebuah bar statis di atas yang dapat memiliki ikon dan tombol back.
Menggunakan Toolbar sebagai ActionBar
Untuk menggunakan Toolbar
sebagai ActionBar
, pertama pastikan AppCompat-v7 support library ditambahkan ke build.gradle
(Module:app):
dependencies {
...
compile 'com.android.support:appcompat-v7:25.2.0'
}
Lalu, disable ActionBar yang ada di res/values/styles.xml
. Cara termudah ialah dengan meng-extend Theme.AppCompat.NoActionBar
(atau bariasi Light-nya):
<resources>
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
</style>
</resources>
Sekarang kita perlu menambah sebuah Toolbar
ke layout Activity. Kelebihan utamanya kita bisa memposisikannya dimanapun di dalam layout. Di bawah ini kita meletakkan toolbar di bagian paling atas sebuah LinearLayout seperti ActionBar pada umumnya:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
android:orientation="vertical">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:minHeight="?attr/actionBarSize"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:titleTextColor="@android:color/white"
android:background="?attr/colorPrimary">
</android.support.v7.widget.Toolbar>
<!-- Layout for content is here. This can be a RelativeLayout -->
</LinearLayout>
Catatan: Pembaca mungkin ingin menambahkan android:fitsSystemWindows="true"
(learn more) ke parent layout dari Toolbar untuk memastikan bahwa tinggi activity dihitung dengan benar.
Karena Toolbar hanyalah sebuah ViewGroup
ia dapat di berikan style dan diposisikan seperti view lain. Artinya, jika menggunakan RelativeLayout, kita harus memastikan semua view lain berada di bawah toolbar secara eksplisit.
Menggunakan ActionBar di Android
Selanjutnya, di dalam Activity atau Fragment, atur Toolbar agar bekerja seperti ActionBar dengan memanggil method setSupportActionBar(ToolBar)
:
Catatan: Saat menggunakan support library, pastikan bahwa pembaca mengimpor android.support.v7.widget.Toolbar
bukan android.widget.Toolbar
.
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
public class MyActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_my);
// Find the toolbar view inside the activity layout
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
// Sets the Toolbar to act as the ActionBar for this Activity window.
// Make sure the toolbar exists in the activity and is not null
setSupportActionBar(toolbar);
}
// Menu icons are inflated just as they were with actionbar
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
}
Kemudian, kita perlu memastikan bahwa sebuah resource file menu dibaca di dalam onCreateOptionsMenu
:
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/miCompose"
android:icon="@drawable/ic_compose"
app:showAsAction="ifRoom"
android:title="Compose">
</item>
<item
android:id="@+id/miProfile"
android:icon="@drawable/ic_profile"
app:showAsAction="ifRoom|withText"
android:title="Profile">
</item>
</menu>
Untuk melakukan click handling pada Toolbar, silahkan baca juga artikel tentang ActionBar.
Sampai di sini, semua item menu akan ditampilkan di Toolbar, lewat callback menu standar.
Penggunaan Ulang Toolbar
Kita dapat menggunakan elemen Toolbar
yang sama di beberapa layout menggunakan tag include
. Pertama, buat dulu Toolbar-nya di res/layout/toolbar_main.xml
:
<android.support.v7.widget.Toolbar
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/colorPrimary"/>
Lalu, kita dapat memanggilnya dengan tag <include />
di layout activity:
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
android:orientation="vertical">
<!-- Load the toolbar here -->
<include
layout="@layout/toolbar_main"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<!-- Rest of content for the activity -->
</LinearLayout>
Dengan demikian kita akan memiliki navigasi yang konsisten antar activity atau peruabhan konfigurasi.
Memberi Style Untuk Toolbar
Tampilan Toolbar diatur dengan berbagai cara diantaranya menggunakan android:theme
, app:titleTextAppearance
, dan app:popupTheme
. Contoh:
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="?attr/actionBarSize"
android:background="?attr/colorPrimary"
android:theme="@style/ToolbarTheme"
app:titleTextAppearance="@style/Toolbar.TitleText"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
/>
Kemudian, kita perlu membuat style baru di res/values/styles.xml
:
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
</style>
<style name="ToolbarTheme" parent="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
<!-- android:textColorPrimary adalah warna teks title yang ada di Toolbar -->
<item name="android:textColorPrimary">@android:color/holo_blue_light</item>
<!-- actionMenuTextColor adalah warna teks action (menu item) -->
<item name="actionMenuTextColor">@android:color/holo_green_light</item>
<!-- Memberi warna accent untuk input field seperti checkbox -->
<item name="colorAccent">@color/cursorAccent</item>
<!-- memberi warna view saat normal. -->
<item name="colorControlNormal">@color/controlNormal</item>
<!-- Memberi warna saat view aktif (sedang diberi tanda cek atau di switch) -->
<item name="colorControlActivated">@color/controlActivated</item>
<!-- Memberi warna kontrol untuk efek ripples atau pemilihan list -->
<item name="colorControlHighlight">@color/controlActivated</item>
<!-- Tambahkan jika ingin memberi efek ripple saat memilih salah satu ikon -->
<!--
<item name="selectableItemBackground">?android:selectableItemBackground</item>
<item name="selectableItemBackgroundBorderless">?android:selectableItemBackground</item>
-->
</style>
<!-- Mengatur style title yang ada di dalam Toolbar -->
<style name="Toolbar.TitleText" parent="TextAppearance.Widget.AppCompat.Toolbar.Title">
<item name="android:textSize">21sp</item>
<item name="android:textStyle">italic</item>
</style>
Hasilnya sebagai berikut:
Displaying an App Icon
Dalam beberapa kasus, kita mungkin ingin menampilkan sebuah ikon aplikasi di dalam Toolbar. Kita dapat melakukannya dengan menambahkan kode berikut ke dalam Activity
:
// Membaca view Toolbar yang ada di XML dan mengaturnya sebagai ActionBar
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
// Menampilkan ikon di Toolbar
getSupportActionBar().setDisplayShowHomeEnabled(true);
getSupportActionBar().setLogo(R.mipmap.ic_launcher);
getSupportActionBar().setDisplayUseLogoEnabled(true);
Selanjutnya, kita perlu menghapus left inset margin
yang membuat posisi ikon terlalu kiri dengan menambahkan app:contentInsetStart
:
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
app:contentInsetLeft="0dp"
app:contentInsetStart="0dp"
...
>
</android.support.v7.widget.Toolbar>
Dengan demikian ikon di atas seharusnya sudah dapat tampil di dalam Toolbar sesuai yang diinginkan.
Custom Title View
Sebuah Toolbar
hanyalah ViewGroup
yang sudah didekorasi dan hasilnya title yang ada di dalam Toolbar dapat diatur sesuka hati dengan menambahkan TextView
didalamnya:
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:minHeight="?attr/actionBarSize"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:titleTextColor="@android:color/white"
android:background="?attr/colorPrimary">
<TextView
android:id="@+id/toolbar_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Toolbar Title"
android:textColor="@android:color/white"
style="@style/TextAppearance.AppCompat.Widget.ActionBar.Title"
android:layout_gravity="center"
/>
</android.support.v7.widget.Toolbar>
Kita pun dapat mengakses TextView yang ada di dalam Toolbar di Activity
:
/* Di dalam Activity */
// Mengatur Toolbar untuk sebagai ActionBar
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
// Menghapus title default
getSupportActionBar().setDisplayShowTitleEnabled(false);
// Mengambil akses TextView yang ada di dalam Toolbar
TextView mTitle = (TextView) toolbar.findViewById(R.id.toolbar_title);
Hasilnya:
Status Bar Semi Transparan
Terkadang, status bar perlu terlihat semi transparan transparan seperti pada gambar di bawah:
Untuk mendapatkan hasil yang seperti ini, petama kita perlu mengatur properti berikut di dalam res/values/styles.xml
theme utama (AppTheme):
<item name="android:statusBarColor">@android:color/transparent</item>
<item name="android:navigationBarColor">@android:color/transparent</item>
<item name="android:windowTranslucentStatus">true</item>
<item name="android:windowTranslucentNavigation">true</item>
<item name="android:windowDrawsSystemBarBackgrounds">true</item>
Activity atau root layout yang ingin memiliki status bar yang transparan harus menambah properti fitsSystemWindows di XML:
<RelativeLayout
android:fitsSystemWindows="true"
...
>
Baca jawaban stackoverflow post untuk pembahasan lebih detail.
Status Bar Transparan
Jika ingin status bar benar-benar transparan KitKat dan versi setelahnya, cara termudah ialah dengan:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
Window w = getWindow(); // di dalam onCreate
w.setFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS, WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);
}
lalu kemudian tambahkan style berikut di res/values/styles.xml
theme utama:
<item name="android:windowDrawsSystemBarBackgrounds">true</item>
Baca jawaban stackoverflow post untuk jawaban lebih detail.
Bereaksi terhadap Scroll
Kita dapat mengatur Toolbar
agar bereaksi terhadap scroll:
Contoh di atas dapat dicapai dengan menggunakan CoordinatorLayout. Pertama, kita perlu menambahkan dependensi design support library ke file app/build.gradle
:
dependencies {
// ...
compile 'com.android.support:appcompat-v7:23.1.0'
compile 'com.android.support:recyclerview-v7:23.1.0'
compile 'com.android.support:design:23.1.0'
}
Lalu, di dalam layout XML activity misalnya res/layout/activity_main.xml
, kita perlu mengatur agar CoordinatorLayout
menjadi parent dariToolbar
dan scrolling container contohnya RecyclerView
:
<!-- CoordinatorLayout dipakai untuk membuat efek scrolling and "floating" di dalam sebuah layout -->
<!-- Pada umumnya ia akan menjadi root layout yang membungkus app bar dan konten -->
<android.support.design.widget.CoordinatorLayout
android:id="@+id/main_content"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- AppBarLayout merupakan pembungkus bagi Toolbar di dalam CoordinatorLayout agar efek scrolling bekerja. -->
<!-- Perlu dicatat bahwa AppBarLayout harus menjadi elemen pertama di dalam CoordinatorLayout -->
<android.support.design.widget.AppBarLayout
android:id="@+id/appBar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/ThemeOverlay.AppCompat.ActionBar">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:layout_scrollFlags="scroll|enterAlways" />
</android.support.design.widget.AppBarLayout>
<!-- Dapat juga dimasukkan dari layout lain dengan keyword include -->
<!-- misalnya dimasukkan dari `res/layout/content_main.xml` jika menggunakan template Basic Activity -->
<!-- `app:layout_behavior` untuk memberikan standard scrolling behavior yang telah disediakan -->
<android.support.v7.widget.RecyclerView
android:id="@+id/my_recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipToPadding="false"
app:layout_behavior="@string/appbar_scrolling_view_behavior" />
</android.support.design.widget.CoordinatorLayout>
Tentu saja, RecyclerView
dapat diganti dengan sebuah FrameLayout
yang kemudian dapat ditimpa dengan sebuah fragment:
<android.support.design.widget.CoordinatorLayout
android:id="@+id/main_content"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- Masukkan AppBarLayout dan Toolbar seperti contoh sebelumnya! -->
<!-- FrameLayout dapat dipakai untuk memasukkan fragment -->
<!-- `app:layout_behavior` harus ditambahkan agar dapat melakukan scrolling dengan sebagaimana mestinya -->
<FrameLayout
android:id="@+id/content"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
/>
</android.support.design.widget.CoordinatorLayout>
Contoh-contoh di atas menghasilkan aplikasi sebagai berikut:
Baca panduan CoordinatorLayout dan AppBarLayout untuk penjelasan lebih detail. Untuk troubleshooting baca troubleshooting guide.
Diterjemahkan dari Using the App ToolbarEdit PagePage History