Nội dung bài viết
Được chỉnh sửa ngày 24/10/2019.
Chào mừng các bạn đã đến với bài học Android số 25, bài học về cách xây dựng Navigation Drawer. Đâ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 bài học hôm trước, bạn đã “nâng cấp” một tí cho TourNote thông qua việc tạo cho ứng dụng này một ActionBar. Hôm nay chúng ta lại sẽ nâng cái cấp này lên một tí ti nữa, thông qua việc xây dựng thêm cho nó một Navigation Drawer.
Có lẽ cái tên Navigation Drawer, hay nhiều bạn vẫn gọi là Left Menu, hoặc Slide Menu, không có gì xa lạ với chúng ta cả. Ai cũng biết về nó, ai cũng sử dụng nó hằng ngày. Navigation Drawer được Google giới thiệu vào năm 2013, ngay sau khi ActionBar được trình làng khoảng 2 năm. Navigation Drawer này chỉ đơn giản là một thanh menu được ẩn đi về phía bên trái màn hình. Nó được hiển thị ra khi người dùng nhấn vào icon menu trên Action Bar. Giới thiết kế gọi cái icon menu này bằng một cái tên khá hay: “icon Hamburger”, bởi vì trông nó giống như một cái hamburger… bạn tưởng tượng đi nào.
Cũng giống như ActionBar, Navigation Drawer mong muốn đem lại cho user một trải nghiệm rõ ràng hơn trên các ứng dụng phức tạp. Khi đó các chức năng chính của ứng dụng dường như được để hết cả lên thanh này (và cả ở ActionBar nữa, nhưng thường thì ActionBar chỉ chứa các chức năng quan trọng và được truy xuất cực kỳ nhiều mà thôi). Và cũng không quá khi nói rằng Navigation Drawer này mới chính thức là “xương sống” rõ ràng nhất cho ứng dụng.
Ngoài các thông tin về Navigation Drawer của mình trên đây, bạn có thể vào link này của Google để đọc một số thông tin hữu ích về mặt thiết kế liên quan đến thành phần này nhé.
Nếu như bạn còn nhớ, mình đã dành một bài để nói nhiều nhất có thể các layout được dùng phổ biến trong Android, trong bài viết đó, FrameLayout, LinearLayout, RelativeLayout và TableLayout đã được nhắc đến. Và cuối bài viết, mình có nói rằng là sẽ còn nhiều layout khác liên quan đến các giao diện đặc trưng khác chứ không riêng gì các layout phổ biến này. Và đến bài học hôm nay bạn đã có dịp làm quen với một trong số các layout đặc trưng cho Navigation Drawer. Mình xin giới thiệu, một layout mới mang tên DrawerLayout.
DrawerLayout
Như đã nói, DrawerLayout là một layout đặc biệt, nó chuyên dùng để tạo Navigation Drawer. Layout này nằm trong gói support-v4 và support-v13 để hỗ trợ sự tương thích ngược đến với các hệ điều hành cũ hơn. Nếu bạn thắc mắc tại sao lại có nhiều gói support-vx này thì hãy yên tâm, mình dự định dành một bài viết riêng để nói rõ về các thư viện support này nhé.
Và bởi vì layout này đặc biệt là dùng kèm theo Navigation Drawer, nên nó hầu như chẳng có nhiều nguyên tắc lắm đâu. Việc của bạn chỉ cần khai báo một DrawerLayout ở gốc của một Activity nào đó, rồi khai báo bên trong layout đó hai thành phần con, đại loại như thế này, là được.
Mình xin nói rõ một chút về vai trò của hai thành phần con trong DrawerLayout.
- Thành phần con thứ nhất, chính là giao diện chính của ứng dụng. Một lát nữa khi thực hành xây dựng ứng dụng TourNote, bạn phải thay đổi một chút cấu trúc của màn hình chính TourNote, sao cho trở thành thành phần con thứ nhất này.
- Thành phần con thứ hai, chính là thành phần của left menu. Thành phần này như đã nói, bình thường sẽ bị ẩn đi, đến khi người dùng nhấn vào icon hamburger hoặc vuốt từ bên trái màn hình sang phải, sẽ được hiển thị. Sau đó nếu người dùng nhấn lại vào icon hamburger, hoặc nhấn vào vùng ngoài left menu, hoặc vuốt từ bên phải màn hình sang trái, thì lại ẩn đi.
Chúng ta sẽ hiểu rõ hơn về DrawerLayout và từng thành phần con của nó khi tiến hành xây dựng Navigation Drawer cho TourNote ở bên dưới đây.
Trước khi đi vào chi tiết cách xây dựng Navigation Drawer, mình xin được nói rõ rằng, sẽ có hai cách để bạn có thể xây dựng thành phần này cho ứng dụng.
Cách thứ nhất, chẳng tốn công sức gì cả, khi bạn tạo mới bất kỳ project Android nào, đến bước chọn một template (bạn có thể xem lại bài 3 để hiểu các khái niệm liên quan đến tạo mới một project Android), thì bạn cứ chọn Navigation Drawer Activity như hình dưới. Tùy chọn này giúp bạn tạo một ứng dụng có cả Navigation Drawer lẫn Floating Action Button. Thật là đơn giản.
Cách thứ hai, là cách bạn phải bỏ công sức ra xây dựng từng bước như dưới đây chúng ta sẽ làm với TourNote. Mình thích cách trên kia, nhưng với các bài học của mình thì mình muốn cùng các bạn đi theo hướng gian khổ ở cách này. Bởi vì sau khi xây dựng thủ công mọi thứ, chắc chắn các bạn sẽ hiểu rõ hơn về thành phần giao diện này, và các kiến thức liên quan. Sau đó, tự bạn có thể tùy chỉnh, thêm thắt vài thứ vào giao diện một cách dễ dàng hơn.
Đây là thiết kế ban đầu về Navigation Drawer của TourNote.
Như những gì bạn đã đọc qua trên đây, chắc bạn cũng đã hình dung ra các bước mà bài thực hành này sẽ xây dựng. Bao gồm, thay đổi activity_main.xml sao cho layout gốc chính là DrawerLayout nè, rồi xây dựng các thành phần bên trong DrawerLayout nè, và cuối cùng là xây dựng các Java code liên quan nè. Chúng ta cùng vào chi tiết.
Download Resource
Do có xuất hiện thêm một vài icon nữa, bao gồm icon hình dấu chấm than và chấm hỏi, nên bạn có thể vào Android Asset Studio để tự tìm hai icon này.
Hoặc bạn có thể vào link này để down file zip về rồi giải nén và để các ảnh vừa down vào các alternative resource tương ứng nhé.
Thêm Một Số Thông Số Vào dimens.xml
Chúng ta sẽ tuân thủ các yêu cầu về mặt thiết kế ở link này của Google. Nên bước này chúng ta nên định nghĩa thêm một số kích thước cho Navigation Drawer vào file dimens.xml, bạn chú ý các dòng được tô sáng.
Khai Báo Thêm Thư Viện Trong build.gradle
Chúng ta khoan hãy bắt tay vào xây dựng Navigation Drawer ngay, vì nếu bắt tay vào xây dựng, chắc chắn sẽ có báo lỗi xảy ra với project, là do các thành phần trong Navigation Drawer ở các bước sau đòi hỏi project phải có thư viện com.android.support:design bên trong nó.
Chắc hẳn bạn sẽ không hoang mang và hiểu rõ những gì mình nói trên đây nếu đã đọc qua bài 11 của mình. Nếu đã đọc và hiểu rồi, thì bạn hãy mở build.gradle ở cấp độ module lên, và thêm vào dòng được tô sáng sau vào khối dependencies của file này nhé.
Bạn nên sync lại project sau khi thêm vào dòng trên kia, rồi hẵn qua bước tiếp theo bên dưới.
Xây Dựng DrawerLayout
Nào chúng ta bắt đầu xây dựng Navigation Drawer, bằng cách xây dựng Drawer Layout.
Chúng ta cùng mở lại giao diện chính của TourNote ra, chính là file activity_main.xml. Tại đây, như các bài thực hành từ trước giờ, thẻ gốc của file này vẫn là ConstraintLayout.
Với thay đổi ở bước này, bạn chỉ chuyển toàn bộ giao diện gốc của TourNote này thành thành phần thứ nhất. Như vậy giao diện gốc xưa kia giờ đây nằm trong một thẻ có tên android.support.v4.widget.DrawerLayout. Bạn chú ý ghi đầy đủ đường dẫn đến gói support.v4.widget luôn nhé, vì đây là layout được lấy từ thư viện support như mình có nói đến trên kia mà.
Bạn khoan run ứng dụng lên vội, vì chưa có thay đổi gì đâu.
Xây Dựng Thành Phần Con Thứ Hai
Bạn đã biết thành phần con thứ nhất trong DrawerLayout chính là ConstraintLayout cũ được chúng ta nhét vào trong DrawerLayout rồi đúng không nào. Vậy nên bước này chúng ta chỉ cần xây dựng thành phần con thứ hai, chính là giao diện cho left menu. Dưới đây là một vài ý quan trọng cho thành phần này.
- Với layout ở thành phần con thứ hai này, bạn xây dựng chúng bằng bất cứ layout nào cũng được. Nhưng mình khuyên bạn nên dùng NavigationView. Đây cũng là một layout được chuyên dùng trong Navigation Drawer, nó giúp định nghĩa ra một menu layout chuẩn, với các màu sắc và kích cỡ mặc định, và khi sử dụng nó, bạn không cần phải lo lắng canh chỉnh chiều rộng của left menu này như thế nào.
- Bởi vì NavigationView là con cháu của FrameLayout nên nó không giỏi lắm trong việc sắp xếp các thành phần UI con vào trong nó. Tốt nhất bạn nên xây dựng thêm một layout linh động hơn vào con của NavigationView này. Như code dưới đây mình thêm LinearLayout.
- Dù bạn có dùng layout nào cho thành phần này, cũng đừng quên khai báo thuộc tính android:layout_gravity=”start”, nó giúp neo layout này vào bên trái của thành phần con thứ nhất trên kia.
Và đây là code của toàn bộ giao diện activity_main.xml. Code mới ở mục này được thêm vào như những dòng được tô sáng dưới đây.
Chú ý rằng bên trong NavigationView này mình đã lồng vào một LinearLayout với mục đích như đã nói đến trên đây. Bên trong LinearLayout này mình xây dựng một header để hiển thị thông tin người dùng. Phía dưới header là hai item của left menu, đó là item info và item help. Hai item này tốt nhất nên nằm trong một ListView, nhưng vì chúng ta chưa được học qua ListView, nên mình chỉ xây dựng tạm như thế này để nhìn cho đẹp mắt thôi chứ chưa có logic gì cho việc click lên ẻm đâu nhá.
Chỉnh Sửa MainActivity.java
Đến bước này, nếu bạn thực thi chương trình, cũng sẽ không có bất cứ giao diện cho left menu nào xuất hiện đâu nhé. Thực chất chúng đã nằm sẵn ở bên tay trái màn hình thiết bị nhờ vào việc sắp xếp của DrawerLayout. Việc tiếp theo của chúng ta là xây dựng một số hành động bên MainActivity.java nữa để menu này có cơ hội được xuất hiện.
Thứ nhất, bạn phải đảm bảo cho icon hamburger xuất hiện trên ActionBar bằng hai dòng lệnh sau.
Sau đó, dĩ nhiên rồi, bạn khai báo DrawerLayout trong Java code, để thiết lập vài logic cho nó.
Cuối cùng, chúng ta lại dùng đến một thành phần có tên là ActionBarDrawerToggle. Thành phần này được gắn vào ActionBar, làm nhiệm vụ điều khiển việc đóng mở DrawerLayout cho chúng ta. Sau đây là các đoạn code khai báo, gắn vào ActionBar, và đồng bộ thành phần ActionBarDrawerToggle này với Activity. Đoạn code khai báo sau cần sự định nghĩa thêm hai resource string, đó là navigation_drawer_open và navigation_drawer_close, bạn có thể xem thêm định nghĩa string này ở link project ở cuối bài học hôm nay.
Giờ thì bạn có thể thực thi ứng dụng lên xem được rồi nhé.
Bạn có thể download source code mẫu của bài này ở đây.
Vậy là chúng ta vừa xem xong cách thức xây dựng một Navigation Drawer cho TourNote. Bạn đừng nên học thuộc lòng các bước xây dựng giao diện trong bài hôm nay. Nội dung bài học được mình tham khảo ở link gốc này của Google, và nó cũng không hoàn toàn khớp với link gốc, nó dựa trên sự tham khảo và tổng hợp từ nhiều nguồn khác nhau. Quan trọng là bạn hiểu các thành phần và tìm cách kết hợp chúng với nhau là được rồi.
Bài Kế Tiếp
Trước giờ chúng ta đã làm quen nhiều cách thao tác ở MainActivity.java. Và bạn cũng đã biết một Activity như vậy chịu trách nhiệm hiển thị một giao diện lên màn hình thiết bị rồi đúng không nào. Vậy thì còn việc hiển thị nhiều màn hình trong một ứng dụng thì sao. Và còn bất kỳ thông tin nào khác liên quan đến khái niệm Activity hay không. Bài sau chúng ta cùng tìm hiểu qua nhé.