Hôm nay chúng ta sẽ tìm hiểu về Android ActionBar. Đây là một phần quan trọng trong bất kỳ ứng dụng nào, dù là ứng dụng web hay ứng dụng di động. Chúng ta sẽ học cách triển khai Action Bar trong ứng dụng Android bằng cách sử dụng thành phần ActionBar
.
Android ActionBar
Android ActionBar là một thanh menu chạy dọc theo phía trên của màn hình activity trong Android. ActionBar có thể chứa các mục menu, và các mục này sẽ hiển thị khi người dùng nhấn vào nút “menu”. Nhìn chung, một ActionBar
bao gồm bốn thành phần chính sau:
- Biểu tượng ứng dụng (App Icon): Logo hoặc biểu tượng đại diện cho thương hiệu ứng dụng sẽ hiển thị ở đây
- Điều khiển hiển thị (View Control): Khu vực dành riêng để hiển thị tiêu đề ứng dụng. Ngoài ra, nó còn cho phép chuyển đổi giữa các chế độ hiển thị bằng cách thêm spinner hoặc điều hướng dạng tab
- Nút hành động (Action Buttons): Một số hành động quan trọng của ứng dụng có thể được đặt ở đây
- Menu mở rộng (Action Overflow): Các hành động kém quan trọng hơn sẽ được hiển thị dưới dạng menu
Thiết lập Android ActionBar
Tất cả các activity sử dụng theme Theme.Holo hoặc các theme được dẫn xuất từ Theme.Holo sẽ tự động có một ActionBar.
Menu ActionBar trong Android
Cách đơn giản nhất để thêm các biểu tượng trên thanh công cụ (toolbar) và các mục trong menu mở rộng của ActionBar là tạo file XML menu nằm trong thư mục res/menu. Chúng ta có thể thêm các mục menu trong file XML như sau: menu_main.xml
<menu xmlns:android="<https://schemas.android.com/apk/res/android>"
xmlns:app="<https://schemas.android.com/apk/res-auto>"
xmlns:tools="<https://schemas.android.com/tools>" tools:context=".MainActivity">
<item
android:id="@+id/add" android:icon="@android:drawable/ic_menu_add" app:showAsAction="always" android:title="@string/add"/>
<item
android:id="@+id/reset" android:icon="@android:drawable/ic_menu_revert" app:showAsAction="always|withText" android:title="@string/reset"/>
<item
android:id="@+id/about" android:icon="@android:drawable/ic_dialog_info" app:showAsAction="never" android:title="@string/about">
</item>
<item
android:id="@+id/exit" app:showAsAction="never" android:title="@string/exit">
</item>
</menu>
Có bốn thuộc tính cần được cấu hình cho mỗi mục trong menu:
- android:id: Thuộc tính này xác định ID cho menu item. Nó hoạt động tương tự như ID trong các phần khác của ứng dụng Android. Một giá trị android:id bắt đầu với @+id/ sẽ tạo một hằng số trong tập hằng R.menu.
- android:title: Giá trị của thuộc tính này là tiêu đề của menu item, hiển thị trên thanh công cụ hoặc trong menu.
- android:icon: Tham chiếu đến một biểu tượng trong thư mục drawable, dùng làm biểu tượng hiển thị cho mục menu.
- android:showAsAction: Thuộc tính này cho biết cách hiển thị mục menu trong ActionBar. Các tùy chọn bao gồm:
- always: luôn hiển thị trên ActionBar
- ifRoom: chỉ hiển thị nếu còn không gian trống
- never: không bao giờ hiển thị trên ActionBar, chỉ xuất hiện trong menu khi nhấn nút “menu”
- withText: thêm vào always hoặc ifRoom để yêu cầu hiển thị cả biểu tượng và tiêu đề (không chỉ biểu tượng)
Lưu ý: always không đảm bảo mục menu sẽ luôn hiển thị trên thanh công cụ – nếu bạn đặt quá nhiều mục menu với thuộc tính always (ví dụ như 100 mục), thì sẽ không đủ chỗ để hiển thị tất cả. Tuy nhiên, các mục có always
sẽ được ưu tiên chiếm chỗ trên Action Bar cao hơn so với các mục có ifRoom
.
Nạp Menu vào Android ActionBar (Inflating Menu)
Để các mục menu được định nghĩa trong file XML hiển thị lên ActionBar, ta cần nạp (inflate) file menu trong phương thức onCreateOptionsMenu()
của activity mong muốn. Dưới đây là đoạn mã mẫu:
@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;
}
Tham số R.menu.menu_main là hằng số tham chiếu đến tệp XML menu. Tham số menu là đối tượng menu mà chúng ta muốn nạp (inflate) các mục từ tệp XML vào.
Xử lý sự kiện trên Action Bar trong Android
Để phát hiện khi người dùng nhấn vào một mục nào đó trên Action Bar, chúng ta cần ghi đè (override) phương thức onOptionsItemSelected()
trong MainActivity, như ví dụ dưới đây:
@Override
public boolean onOptionsItemSelected(MenuItem item) { switch(item.getItemId()) {
case R.id.add:
//add the function to perform here
return(true);
case R.id.reset:
//add the function to perform here
return(true);
case R.id.about:
//add the function to perform here
return(true);
case R.id.exit:
//add the function to perform here
return(true);
}
return(super.onOptionsItemSelected(item));
}
Bây giờ, chúng ta sẽ gán một số chức năng cơ bản cho từng mục menu trong dự án.
Cấu trúc dự án
Ví dụ mã nguồn ActionBar trong Android
Chúng ta đã triển khai bốn mục menu trong MainActivity, như được thể hiện trong đoạn mã dưới đây:
package com.journaldev.actionbar;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
TextView count;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
@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;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) { switch(item.getItemId()) {
case R.id.add:
count=(TextView)findViewById(R.id.textView);
count.setText("Add is clicked");
return(true);
case R.id.reset:
count=(TextView)findViewById(R.id.textView);
count.setText("Nothing is selected");
return(true);
case R.id.about:
Toast.makeText(this, R.string.about_toast, Toast.LENGTH_LONG).show();
return(true);
case R.id.exit:
finish();
return(true);
}
return(super.onOptionsItemSelected(item));
}
}
Các mục được gán các chức năng tương ứng. Mục được chọn được xác định dựa trên id đã được khai báo trong file menu_main.xml
. Ở đây, chúng tôi chỉ thay đổi nội dung của TextView
ở hai mục đầu tiên, hiển thị một thông báo toast ở mục thứ ba và thoát ứng dụng ở mục thứ tư.
Lưu ý: AppCompatActivity là một sự thay thế cho phiên bản ActionBarActivity đã bị ngừng hỗ trợ. File styles.xml
được định nghĩa như sau:
<resources>
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Customize your theme here. -->
</style>
</resources>
Như bạn có thể thấy, chủ đề cha (parent theme) sử dụng một biến thể của Theme.AppCompat, chủ đề này mặc định đã bao gồm ActionBar (trừ khi bạn sử dụng lớp Theme.AppCompat.Light.NoActionBar). Do đó, không cần phải khai báo rõ ràng ActionBar trong phần này.
Android Action Bar hỗ trợ phiên bản cũ (Backporting)
- Vì ActionBar được giới thiệu từ Android Honeycomb 3.0, để triển khai ActionBar khi minSdkVersion là 11 hoặc thấp hơn, chúng ta cần thêm thư viện app-compat-v7 vào Gradle như đã làm trong ví dụ này để hỗ trợ tương thích ngược.
- Một cách khác là nhập và mở rộng MainActivity với ActionBarSherlock, hoạt động độc lập với bản backport của ActionBar, vì lớp này được giới thiệu sau Android 3.0.
Hình ảnh bên dưới cho thấy kết quả đầu ra của dự án. Bạn có thể thấy ActionBar bao gồm các biểu tượng được định nghĩa sẵn. TextView được cập nhật nội dung khi biểu tượng thêm (add) được nhấn. TextView quay về nội dung ban đầu khi nhấn nút đặt lại (reset). Khi nhấn vào “about”, thông báo toast sẽ xuất hiện như hình dưới.