Được chỉnh sửa ngày 23/10/2019.
Chào mừng các bạn đã đến với bài học Android số 24, bài học về ActionBar. Đây là bài học trong chuỗi bài về lập trình ứng dụng Android bằng Java của Yellow Code Books.
Với việc kết thúc bài học số 23, thì bạn cũng đã biết cách sử dụng một số dạng resource thông dụng trong Android rồi. Nhưng sang bài hôm nay, chúng ta tạm ngưng nói đến việc sử dụng các resource tiếp theo nữa, bởi vì nếu nói hoài một chủ đề sẽ rất chán. Vậy chúng ta chen vào một kiến thức khác thú vị hơn, kiến thức về ActionBar, rồi sau đó sẽ quay lại các bài học về resource hay ho khác ở các bài học kế tiếp.
ActionBar Là Gì?
Bạn hãy mở một ứng dụng nào đó bất kỳ trên thiết bị Android của bạn, thì bạn sẽ thấy, ActionBar là một thanh đẹp đẹp ở trên cùng của các màn hình ứng dụng. Ngoài việc hiển thị nhãn (hay gọi với cái tên tiếng anh là title) của màn hình hiện tại ra, ActionBar còn giúp đặt một số Button lên đó. Và thế là ActionBar bỗng trở thành một “xương sống” cho ứng dụng, nó giúp kết nối các màn hình ứng dụng với nhau, giúp người dùng hiểu rõ sự liền mạch của ứng dụng, cũng như giúp họ hiểu nhanh các chức năng của ứng dụng mà họ đang sử dụng.
Hình minh họa sau cho bạn thấy rõ hơn các thành phần bên trong một màn hình ứng dụng Android.
Diện Mạo Của ActionBar Qua Các Đời Android
Qua tiêu đề của mục này, bạn cũng biết được rằng ActionBar không hề giống nhau ở các phiên bản của hệ điều hành Android. Vậy thì biết được sự khác nhau này để làm gì? Mời bạn đọc tiếp bài học hôm nay, còn nhiều thứ hay ho lắm.
Android 1.x & 2.x – Phiên Bản Android Với Title Bar
Với “đời” Android này, như bạn cũng đã biết qua khi đọc bài viết của mình về Theme, ActionBar ở giai đoạn này chưa ra đời, phía trên màn hình ứng dụng lúc bấy giờ chỉ có một thanh mỏng hiển thị title nên người ta còn gọi là TitleBar.
Android 3.0 – Phiên Bản Android Cho Tablet
Đến giai đoạn này của hệ điều hành, với nhu cầu muốn tập trung vào giao diện trên tablet, thế là ngoài các tinh chỉnh khác của hệ thống liên quan đến SystemBar mà mình không nói đến, thì ActionBar cũng được ra đời. Ý tưởng của ActionBar lúc này tuy được hướng đến cho tablet thôi, nhưng nó được giữ tới bây giờ, đó là ý tưởng về một ActionBar có thể chứa đựng nhiều thông tin, ngoài title ra còn phải có icon app, rồi các menu mở rộng được gom lại vào cùng một nhóm và nằm bên góc phải của ActionBar.
Bạn có thể xem thêm để thấy mối tương quan giữa giai đoạn ActionBar này với giai đoạn Theme.Holo nhé.
Android 4.0 Đến Android 4.4 – Phiên Bản Android Cho Cả Phone Và Tablet
Giai đoạn này không chứng kiến nhiều sự thay đổi cho ActionBar, mà chỉ chú trọng vào sự tương thích tốt giữa các thiết bị phone và tablet.
Android 5.x Đến Nay
Từ khi xuất hiện Theme.Material ở Android 5.x thì ActionBar cũng được nâng cấp đáng kể. Khi này ứng dụng được cung cấp thêm khả năng bố trí các Button lên ActionBar, bên cạnh đó menu mở rộng bên góc phải vẫn xuất hiện.
Mặc dù ngày nay các thiết bị Android chạy hệ điều hành trước Android 4.0 đã gần như tuyệt chủng. Nhưng qua bài học này, mình muốn các bạn cũng phải nắm được tổng thể các khác nhau của ActionBar ở các thế hệ Android, để hiểu rõ giao diện của ứng dụng của bạn trên các thiết bị.
Nhưng có một tin khá vui, sẽ khiến bạn đỡ đau đầu hơn sau khi đọc qua các mục trên đây của mình. Đó là hiện nay, chúng ta đang được Android hỗ trợ cho một thư viện tương thích ngược có tên là appcompat-v7 (về sau còn có một thư viện mới hơn mang tên androidx). Thư viện tương thích ngược này được khai báo sẵn khi bạn tạo project có hỗ trợ các thiết bị dưới Android 5.0. Bạn có thể xem lại bài 11 để thấy được khai báo của thư viện này. Thư viện này sẽ giúp mang giao diện Material, cùng với ActionBar về cho các hệ điều hành cũ, làm cho giao diện của các ứng dụng ngày nay trở nên nhất quán trên các phiên bản hệ điều hành. Và như vậy thì coi như chúng ta không cần quan tâm đến sự khác biệt ở các hệ điều hành ở các mục trên đây của mình nữa, các mục trên chỉ còn mang tính tham khảo mà thôi.
Xây Dựng ActionBar
Đến đây chúng ta bắt đầu tìm hiểu xem làm thế nào để xây dựng một ActionBar.
Định Nghĩa Button Trên Action Bar
Với việc bạn tạo một project như TourNote, thì ActionBar mặc định cũng được tạo sẵn, và title của ứng dụng cũng được đặt sẵn lên ActionBar, nên chúng ta không quan tâm đến title ở bài hôm nay. Chúng ta hãy tập trung vào việc đặt các Button lên ActionBar như thế nào. Để đặt các Button vào ActionBar, Android buộc bạn phải làm theo cách này, bạn cần định nghĩa các Button vào một file XML và để nó vào thư mục res/menu/. Việc định nghĩa các Button được thực hiện giống như đoạn XML mẫu như sau.
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/add"
android:icon="@drawable/ic_action_new"
app:showAsAction="always"
android:title="@string/add"/>
<item
android:id="@+id/reset"
android:icon="@drawable/ic_action_refresh"
app:showAsAction="always|withText"
android:title="@string/reset"/>
<item
android:id="@+id/about"
android:icon="@drawable/ic_action_about"
app:showAsAction="never"
android:title="@string/about">
</item>
</menu>
Bạn đừng nên code vội, hãy cùng mình tìm hiểu các thành phần và ý nghĩa của định nghĩa này, chúng ta sẽ có cơ hội được code khi xây dựng ActionBar cho TourNote ở bài thực hành bên dưới bài học này.
- Đầu tiên, bạn sẽ thấy thẻ gốc của file định nghĩa này là thẻ menu. Tại sao lại là menu mà không phải action_bar hay gì gì đó? Thực ra thẻ này được tái sử dụng lại qua các đời hệ điều hành Android. Sơ khởi ban đầu chức năng của nó đúng với tên thẻ, khi mà ActionBar chỉ mới là TitleBar. Lúc đó người ta gọi các Button mà bạn chuẩn bị tạo cho ActionBar như bài học hôm nay bằng cái tên Option Menu. Thôi không cần nhớ nhiều lằng nhằng, bạn chỉ cần chú ý trong thẻ menu này có khai báo thêm một namespace có tên là app.
- Bên trong menu sẽ chứa đựng các item, mỗi item này là một Button trên ActionBar của chúng ta.
- Thuộc tính id của item thì bạn đã biết rồi, thuộc tính này định nghĩa ra ID cho Button để chúng ta sử dụng chúng bên trong Java code.
- Thuộc tính title của item sẽ định nghĩa ra nhãn cho Button. Mặc định nhãn này sẽ không được hiển thị khi mà Button đó được “nhìn thấy” trên ActionBar (lát nữa bạn sẽ biết), nhãn chỉ hiển thị khi Button nằm ở menu mở rộng của ActionBar này. Nhưng dù cho nhãn đó không được hiển thị, thì bạn vẫn có thể nhấn giữ vào một Button của ActionBar để giúp nó hiển thị ra, lát nữa bạn cứ thử xem.
- Thuộc tính icon của item đơn giản là hiển thị icon cho Button mà thôi.
- Thuộc tính showAsAction của item giúp xác định độ ưu tiên hiển thị Button lên ActionBar. Độ ưu tiên này là gì? Bạn cũng nên biết rằng ActionBar trên điện thoại có không gian khiêm tốn đúng không nào, và chúng chỉ dàn hàng ngang các Button trên thanh Action đó. Bạn cũng thấy chúng ta đâu có tùy chọn chỉ định kích cỡ cho các Button đó đâu. Vì vậy mà một ActionBar sẽ chỉ hiển thị được vài Button (số lượng nhiều hay ít sẽ tùy loại thiết bị). Do đó độ ưu tiên sẽ giúp ứng dụng xác định Button nào quan trọng hơn sẽ được hiển thị ra ngoài màn hình, Button kém quan trọng hơn sẽ bị đẩy vào menu mở rộng ở góc bên phải. Các cấp độ ưu tiên này từ cao đến thấp bao gồm always, ifRoom và never. Trong khi hai cấp độ đầu sẽ tranh giành không gian trên ActionBar, thì never lại luôn mang Button vào trong menu mở rộng. Bạn có thể chỉ định thêm “|withText” kèm theo “always” hay “ifRoom” để có thể hiển thị text song song với Button (chỉ định này không phải lúc nào cũng hữu dụng).
Thao Tác Với Các Button Của Action Bar
Với bước trên đây, nếu thực thi chương trình, bạn vẫn chưa thể trông thấy các Button trên ActionBar được. Bạn phải làm thêm một chút với Java code, bạn cần chỉ định menu là file đã định nghĩa trên đây, và chỉ định các sự kiện click cho từng Button nữa.
Do trong thư mục res/menu/ của chúng ta có thể sẽ chứa nhiều file menu, mỗi file như vậy định nghĩa ra một ActionBar cho một màn hình nào đó. Nên để chỉ định file menu nào cho ActionBar nào, bạn chỉ cần override phương thức onCreateOptionsMenu() trong màn hình đó. Rồi chỉ định như code sau.
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.actions, menu);
return super.onCreateOptionsMenu(menu);
}
Như đã nói, bạn hãy chú ý vào dòng getMenuInflater().inflate(R.menu.actions, menu) của code trên, nó giúp bạn lấy menu đã định nghĩa ở bước trên kia R.menu.actions và gắn nó vào menu của màn hình hiện tại.
Sau khi khai báo menu, bạn phải định nghĩa tiếp sự kiện click cho các Button. Chắc bạn đang nghĩ đến sự kiện onClick? Không đâu, với các Button của ActionBar, chúng ta lại sẽ phải override một phương thức khác, chính là onOptionsItemSelected(). Với phương thức này thì bạn chỉ cần lấy id của từng item mà chúng ta đã định nghĩa ra rồi xây dựng logic click cho nó.
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.add:
// Làm gì đó
return true;
case R.id.reset:
// Làm cái gì đó
return true;
case R.id.about:
// Làm bất cứ cái gì đó
return true;
}
return super.onOptionsItemSelected(item);
}
ActionBar Và ToolBar
Từ phiên bản Android 5.0, Google có định nghĩa thêm một khái niệm ToolBar. Thực chất thì ToolBar cũng là một ActionBar nhưng có sự linh động hơn. ToolBar cũng được hỗ trợ tương thích ngược cho các hệ điều hành cũ hơn thông qua thư viện appcompat-v7. Tuy nhiên ở bài học hôm nay mình chỉ nói đến ActionBar để các bạn làm quen, chúng ta sẽ nâng cấp TourNote lên ToolBar ở một bài học khác nhé.
Thực Hành Xây Dựng ActionBar Cho TourNote
Bây giờ chúng ta sẽ vận dụng tất cả lý thuyết của bài hôm nay để thực hành xây dựng một ActionBar cho TourNote.
Để dễ hình dung công việc mà chúng ta cần làm, mình mời các bạn xem lại màn hình chính của TourNote. Như mình có nói, mỗi màn hình có thể có một ActionBar riêng, nên buổi hôm nay chúng ta chỉ xây dựng ActionBar cho màn hình chính thôi nhé.
Chúng ta cũng sẽ không quan tâm đến các tab “Ăn Uống”, “Tham Quan”,… các tab này tuy cũng gắn với ActionBar đấy, nhưng sẽ được xây dựng sau và được thêm vào ActionBar một cách động bởi người dùng. ActionBar của TourNote mà chúng ta cần xây dựng sẽ có một Button tìm kiếm luôn nằm ngoài màn hình chính, và hai Button“Về Ứng Dụng” và “Giúp Đỡ” được thu gọn vào trong menu mở rộng.
Download Resource
Trước khi tạo ActionBar, chúng ta phải chuẩn bị đầy đủ resource cho ứng dụng. Trong trường hợp này chúng ta chỉ cần icon hình cái kính lúp.
Nếu bạn còn nhớ công cụ Android Asset Studio thì quá tốt. Bạn có thể vào công cụ đó, tìm Clipart là hình kính lúp, rồi chọn Theme là Dark để icon có màu trắng. Rồi down về. Xong.
Hoặc bạn lười thì có thể vào link này để down file zip. Các ảnh trong file này có tên ic_action_search.png. Các ảnh này được mình down sẵn về từ Android Asset Studio cho bạn rồi. Bạn hãy tự giải nén rồi để các ảnh vừa down vào các alternative resource tương ứng nhé.
Sẵn tiện mình cũng thêm một dòng vào resource string, dòng này sẽ làm nhãn cho Button tìm kiếm của chúng ta. Bạn có thể tự thêm vào hoặc tham khảo trên Github ở link mình để bên dưới bài học hôm nay.
Định Nghĩa Các Button Cho ActionBar
Bước này, bởi vì thư mục menu/ chưa có trong res/ của chúng ta, nên bạn phải tạo thư mục này ngay. Cách tạo một thư mục resource đã được thực hành khi bạn tạo res/values-vi/ rồi nhé.
Sau khi tạo xong res/menu/, bạn hãy tạo trong đó một Menu resource file có tên main_actions.xml.
Khi file main_actions.xml vừa được tạo ra, bạn có thể nhìn thấy editor của Android Studio hiển thị resource này dưới dạng menu cho bạn chỉnh sửa. Bạn có thể tự học việc sử dụng giao diện để tạo và chỉnh sửa các menu item sau. Còn bây giờ mình khuyên bạn nên chọn tab Text từ editor này để đi qua màn hình code bằng XML nhé.
Bạn hãy khai báo các item cho menu của ActionBar như sau.
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/search"
android:icon="@drawable/ic_action_search"
android:title="@string/menu_item_search"
app:showAsAction="always" />
<item
android:id="@+id/about"
android:title="@string/menu_item_about_app"
app:showAsAction="never" />
<item
android:id="@+id/help"
android:title="@string/menu_item_help"
app:showAsAction="never" />
</menu>
Thao Tác Với Các Button Của ActionBar
Tiếp tục, chúng ta cũng làm như bài học, code dưới đây sẽ khai báo việc sử dụng main_actions.xml làm menu chính thức cho ActionBar của màn hình chính. Bạn hãy vào lớp MainActivity.java và thêm vào phương thức onCreateOptionMenu() như sau.
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main_actions, menu);
return super.onCreateOptionsMenu(menu);
}
}
Sau cùng là các đoạn code hiện thực kết quả khi nhấn vào các Button của ActionBar thông qua phương thức onOptionsItemSelected(). Hiện tại chúng ta chưa làm gì cho các sự kiện click này, mà chỉ tạm show ra câu thông báo bằng Toast mà thôi.
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main_actions, menu);
return super.onCreateOptionsMenu(menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.search:
Toast.makeText(this, "Search button selected", Toast.LENGTH_SHORT).show();
return true;
case R.id.about:
Toast.makeText(this, "About button selected", Toast.LENGTH_SHORT).show();
return true;
case R.id.help:
Toast.makeText(this, "Help button selected", Toast.LENGTH_SHORT).show();
return true;
}
return super.onOptionsItemSelected(item);
}
}
Và đây là thành quả khi khởi chạy TourNote.
Thật ấn tượng đúng không nào. Tuy nhiên ActionBar hiện tại của TourNote chưa làm được gì cả, bạn có thể thử nhấn, hay thử nhấn giữ vào các Button của ActionBar để kiểm chứng. Chúng ta sẽ hoàn thiện ActionBar của TourNote ở từng bài học liên quan sau này.
Download Source Code Mẫu
Bạn có thể download source code mẫu của bài này ở đây.
Chúng ta vừa xem qua các kiến thức liên quan đến việc xây dựng một ActionBar. Có lẽ bạn đã hiểu được tính tiện dụng của ActionBar khi cung cấp các tùy chọn đến các chức năng khác của ứng dụng, mà không làm ứng dụng của chúng ta trở nên rối hơn. Ngoài ActionBar ra thì cũng còn nhiều thành phần giao diện khác làm được điều này, đáng kể đến chính là Left Menu, mà mình nghĩ chúng ta hoàn toàn có thể bắt đầu làm quen ở bài học sau được rồi đó.
Cảm ơn bạn đã đọc các bài viết của Yellow Code Books. Bạn hãy ủng hộ blog bằng cách:
– Đánh giá 5 sao ở mỗi bài nếu thấy thích.
– Comment bên dưới mỗi bài nếu có thắc mắc.
– Để lại địa chỉ email của bạn ở thanh bên phải để nhận được thông báo sớm nhất khi có bài viết mới.
– Chia sẻ các bài viết của Yellow Code Books đến nhiều người khác.
Bài Kế Tiếp
Như đã nói, chúng ta sẽ tiến hành xây dựng Left Menu cho ứng dụng TourNote.
//làm gì đó ở đây là làm gì hả bạn
À vì đây là các kết quả của hiệu ứng click lên item menu, cho nên ý mình là để cho các bạn xây dựng các logic riêng. Bạn có thể mở ra màn hình mới, hiển thị popup, hay câu thông báo nào đó với từng hoàn cảnh của bạn thôi. Như ở bài thực hành bên dưới bài học mình đã hiện thực cho các bạn thấy bằng việc hiển thị thông báo dạng Toast, rồi bài học sau đó mình sẽ hiển thị các màn hình tương ứng từ từ.
Cảm ơn bài viết ạ!
Em dùng android studio 3.3, code như trên thì gặp lỗi với method onCreateOptionsMenu() với lời nhắc là “onCreateOptionsMenu(Menu) is never used.” Nếu có thay đổi do version android studio thì làm sao để mình tra cứu được ạ?
Action bar được thay thế bằng tool bar rồi phải không ad?