Được chỉnh sửa ngày 28/10/2019.
Chào mừng các bạn đã đến với bài học Android số 26, bài học về cách xây dựng Activity trong Android. Đây là bài học trong chuỗi bài viết về lập trình ứng dụng Android bằng Java của Yellow Code Books.
Còn nhớ, đã rất lâu rồi, từ bài học số 5, chúng ta đã nói sơ qua cấu tạo cơ bản của một ứng dụng Android, trong đó các bạn đã biết đến một chút khái niệm và vai trò của Activity rồi.
Nhưng trước đó, ở bài học số 3, khi bạn còn chưa biết đến Android cần có những gì, bạn đã phải tạo cho chính bạn một Activity đầu tiên, có tên là MainActivity, và chúng ta đã cùng xây dựng các dòng code trên Activity đó đến tận bây giờ.
Vậy tính ra bạn đã hiểu Activity là gì rồi đúng không. Vậy bài học hôm nay mình sẽ viết gì. Tất nhiên còn một số kiến thức thú vị khác xoay quanh Activity. Như làm sao để tạo thêm nhiều Activity khác. Làm sao để truyền dữ liệu qua các Activity. Cách quản lý các Activity hiệu quả,… sẽ lần lượt được mình trình bày từ bài học hôm nay.
Vâng, câu trả lời cho câu hỏi này bạn đã biết rồi. Nếu bạn muốn nhớ lại, thì mình cũng đã có nói về Activity ở bài học số 5. Cơ bản là vì yêu cầu về chức năng của các ứng dụng trên thiết bị thông minh rất phức tạp. Như bạn cũng biết thông qua ứng dụng TourNote rồi đó. Nhưng việc nhồi nhét tất cả các yêu cầu và chức năng của một ứng dụng nào đó vào một màn hình nhỏ bé của thiết bị là điều không thể (điều này khác với các ứng dụng trên desktop, đôi khi chỉ cần một cửa sổ là đủ để quản lý). Do đó rất cần thiết khi chúng ta buộc phải tách các thành phần khác nhau của ứng dụng vào từng Activity, mỗi Activity như vậy được xem như một chức năng cơ bản của ứng dụng.
Việc tổ chức ứng dụng thành các Activity như thế nào là ở bạn. Thông thường ở giai đoạn sơ khởi, khi ứng dụng còn là bản thiết kế ở trên giấy, cũng đã rất dễ để chúng ta hình dung ra cấu trúc của các Activity trong ứng dụng. Và như mình có nói, mỗi Activity là một thành phần chức năng cơ bản của ứng dụng. Và cũng vì Activity cũng dính dáng nhiều đến UI của ứng dụng, nên dường như mỗi Activity sẽ chứa tập hợp các UI có chức năng như nhau.
Để dễ hiểu hơn. Bạn hãy xem mình dự định sẽ tổ chức bao nhiêu đây Activity cho TourNote.
Vậy TourNote của chúng ta sẽ có các Activity MainActivity, DetailActivity, ContactActivity và EditNoteActivity.
- MainActivity – Đảm nhiệm vai trò hiển thị danh sách các ghi chú mà người dùng đã tạo trước đó theo chủ đề (mỗi chủ đề là một tab). Mỗi ghi chú này chỉ được hiển thị vắn tắt thông tin. Ngoài ra MainActivity còn chứa đựng Navigation Drawer (chính là left menu) mà bạn đã tạo ra từ bài học trước.
- DetailActivity – Đảm nhiệm vai trò hiển thị đầy đủ thông tin của một ghi chú, khi mà người dùng click chọn vào một phần tử trên danh sách các ghi chú ở MainActivity.
- EditActivity – Giao diện này sẽ được dùng chung cho cà trường hợp tạo mới lẫn sửa chữa một ghi chú.
- ContactActivity – Giao diện giới thiệu ứng dụng và liên hệ tác giả. Giao diện này sẽ được chúng ta xây dựng từ bài học hôm nay.
Tổ chức các Activity trên đây là đối với TourNote, còn bạn, nếu bạn có xây dựng riêng bạn một ứng dụng nào đó, thì hãy tự tổ chức các Activity xem sao nhé.
Không quá khó để bạn tạo mới một Activity. Tuy nhiên bạn nên nhớ là khi tạo Activity, về lý thuyết thì bạn phải trải qua các bước sau đây, sót một bước là có lỗi xảy ra đấy nhé.
Tạo Mới XyzActivity.java Và activity_xyz.xml
Bộ đôi “quyền lực” này thường đi chung với nhau. Bạn có thể kiểm chứng bằng việc thực hành trên Activity mặc định từ trước đến giờ, chúng là MainActivity.java và activity_main.xml. Sở dĩ chúng đi một cặp với nhau, là vì một file sẽ chịu trách nhiệm chính trong việc hiển thị UI của màn hình (file xml), và một file chịu trách nhiệm xử lý logic cho màn hình đó (file java).
Tương tự như “kế hoạch” xây dựng các Activity cho TourNote của chúng ta trên kia, sau này chúng ta sẽ có các bộ đôi Activity như sau: DetailActivity.java và activity_detail.xml, ContactActivity.java và activity_contact.xml, EditNoteActivity.java và activity_edit_note.xml.
Thật đáng mừng rằng Android Studio đã hỗ trợ chúng ta công cụ để tạo mới một bộ các Activity một cách dễ dàng. Lát nữa đến phần thực hành tạo Activity cho TourNote bạn sẽ hiểu rõ hơn.
Khai Báo Activity Mới Với Manifest
Như mình có nói qua, mỗi Activity khi tạo mới đều phải được khai báo thành một thẻ activity trong file Manifest.
Do đó dĩ nhiên là DetailActivity, ContactActivity, và EditNoteActivity của TourNote sẽ không ngoại lệ. Đều phải nằm trong các thẻ activity này.
Nhưng cũng có thêm một tin đáng mừng rằng là nếu bạn sử dụng công cụ để tạo bộ java và xml cho Activity như mình có nói trên kia, thì mặc định bạn sẽ được hệ thống khai báo luôn vào Manifest. Một lát nữa ở bài thực hành mình sẽ nói cụ thể luôn nhé.
Sử Dụng Intent Để Kích Hoạt Activity
Intent ư? Intent là gì? Ở bài học hôm nay bạn sẽ chưa thực sự đi sâu vào Intent đâu. Bạn chỉ cần biết cách thức dùng Intent để kích hoạt, hay khởi động một Activity mới toanh mà bạn mới tạo. Cách kích hoạt này người ta gọi là kích hoạt kiểu tường minh của Intent. Khi đến bài thực hành bên dưới chúng ta sẽ xem cách kích hoạt tường minh của Intent là như thế nào.
Tuy nhiên nếu bạn quan tâm, Intent đã được mình nhắc đến một chút ở mục này, bạn có thể đọc qua tí để nhớ lại. Các kiến thức đầy đủ liên quan đến Intent sẽ được mình nói rõ hơn ở bài học sau nhé.
Trên kia là các lý thuyết. Nhưng khá quan trọng. Bạn hãy ghi nhớ cho việc thực hành này đây. Các bước của bài thực hành không đi xa hơn những lý thuyết trên kia đã nói đến.
Tạo Mới ContactActivity.java Và activity_contact.xml
Đấy, bạn thấy có khác lý thuyết đâu nào. Để tạo bộ đôi giao diện này, như mình có nói chúng ta sẽ nhờ Android Studio tạo cho. Người ta gọi cách tạo này chính là tạo theo wizard (hiểu nôm na theo nghĩa tiếng Việt là có công cụ hỗ trợ chúng ta tạo theo từng bước).
Để bắt đầu, ở cửa sổ Project, bạn hãy để vệt sáng ở package sẽ chứa file Activity java mà bạn muốn tạo. Rồi chọn theo menu File > New > Activity > Empty Activity. Hoặc nhấn chuột phải và chọn New > Activity > Empty Activity như hình dưới đây.
Lưu ý là tuy bạn nhìn thấy nhiều thể loại Activity khi đi vào menu này, nhưng việc chọn Empty Activity theo mình là tốt nhất. Nó giúp chúng ta có được một Activity và một giao diện vừa đủ để dùng. Các chọn lựa với các Activity còn lại sẽ tự động nhét thêm nhiều đoạn code, để tạo thành các template như khi bạn tạo mới project vậy. Việc tự phát sinh thêm nhiều code như vậy sẽ chỉ khiến bạn khó quản lý hơn thôi.
Sau khi bạn chọn lựa ở bước trên. Thì một dialog xuất hiện, dialog này cũng quen thuộc với bạn rồi.
- Tại đây bạn nhập tên Activity vào ô Activity Name. Activity mới của chúng ta có tên ContactActivity.
- Đảm bảo checkbox Generate Layout File được check, vì chúng ta muốn wizard khi này sẽ tự tạo tên file xml cho chúng ta. Cơ bản thì tên file xml này được tự động tạo ra dựa vào những gì bạn gõ vào Activity Name trên kia nên khá chuẩn, do đó bạn không cần chỉnh sửa gì cả.
- Bạn đảm bảo Launcher Activity không check, vì đây không phải là Activity mặc định được mở khi ứng dụng thực thi, một ứng dụng chỉ có một Activity được gọi là Launcher thôi và đó chính là MainActivity của chúng ta rồi.
- Package name thì chúng ta giữ như mặc định.
- Cuối cùng, hãy đảm bảo Java là ngôn ngữ được chọn trong mục Source Language, vì bài học Android này chúng ta vẫn viết bằng ngôn ngữ Java.
Dễ dàng đúng không nào. Sau khi bạn nhấn Finish, bạn sẽ thấy xuất hiện bộ đôi 2 file mà chúng ta mong muốn. Mình nói sơ qua bộ đôi này một chút.
- Với ContactActivity.java. Activity này có sẵn phương thức onCreate(). Trong đó, giao diện xml của nó được chỉ định luôn ở hàm setContentView().
- Với activity_contact.xml. Giao diện này được tạo mới mặc định thẻ gốc là ConstraintLayout.
Khai Báo Activity Mới Với Manifest
Như mình có trình bày ở mục trên. Rằng nếu bạn chọn cách thức tạo mới Activity bằng wizard, bạn sẽ không cần bất cứ khai báo thủ công nào cho Manifest. Tuy nhiên chúng ta cứ mở AndroidManifest.xml ra kiểm tra lại nào.
Bạn thấy đó, Activity mới được khai báo với vỏn vẹn một dòng trong Manifest. Thẻ cần khai báo chính là thẻ activity. Trong thẻ này có một thuộc tính duy nhất là android:name với nội dung .ContactActivity. Bạn có thể khai báo đầy đủ đường dẫn đến thuộc tính android:name này như sau com.yellowcode.tournote.ContactActivity. Nhưng vì com.yellowcode.tournote đã được định nghĩa trong thuộc tính package rồi, nên tóm lại chỉ cần khai báo vắn tắt .ContactActivity là được.
Nếu nhìn vào thẻ kế bên, cũng thẻ activity, bạn sẽ thấy thẻ này ngoài thuộc tính android:name ra nó còn có thẻ con intent-filter nữa. Thẻ intent-filter sẽ được mình trình bày đầy đủ ở bài học về Intent. Nhưng bạn có thể biết trước rằng Activity nào có thẻ con intent-filter như này sẽ được hệ thống khởi chạy đầu tiên khi ứng dụng thực thi. Bạn có thể thử chuyển thẻ intent-filter từ .MainActivity sang .ContactActivity rồi thực thi chương trình trên máy thật hoặc máy ảo để tự kiểm chứng nhé. Nhưng nhớ phải chuyển ngược lại sau đó.
Nếu như giờ đây bạn thực thi chương trình, thì cũng chẳng có gì xảy ra cả, vì Activity mới tuy được tạo ra và khai báo đúng đắn, nhưng chưa được kích hoạt bởi bất cứ dòng lệnh nào. Chúng ta cùng qua bước kế tiếp.
Sử Dụng Intent Để Kích Hoạt ContactActivity
Lại một lần nữa chúng ta cứ sử dụng Intent đi rồi sang bài học kế tiếp sẽ cùng thảo luận về em nó.
Như kịch bản thì ContactActivity này sẽ chứa đựng hai nội dung, đó là Về ứng dụng và Giúp đỡ. Việc phân biệt nội dung nào cần hiển thị và hiển thị như thế nào là ở bài học kế tiếp. Việc hôm nay chúng ta cần làm là xây dựng tiếp ở menu ActionBar để khi touch vào bất cứ item menu nào cũng sẽ kích hoạt ContactActvitity này.
Vậy thì chúng ta phải mở MainActivity.java lên. Đến phương thức onOptionsItemSelected(). Xóa bỏ các câu lệnh Toast.makeText() ở hai item R.id.about và R.id.help và thay bằng các câu lệnh kích hoạt ContactActivity. Code như sau.
Dòng code kích hoạt trên có các chú ý sau.
- Chúng ta khởi tạo một Intent để chứa đựng thông tin về kích hoạt Activity mới. Intent này được khởi tạo với hai tham số truyền vào, như đã nói, các bạn nên nhớ rằng đây được gọi là Intent tường minh. Tham số đầu tiên this chính là Context mà chúng ta sẽ tìm hiểu ở bài khác, vì Activity là một Context nên bạn truyền vào từ khóa this như vậy là được. Tham số thứ hai chính là Activity mà bạn muốn kích hoạt, chúng ta truyền vào ContactActivity.class.
- Phương thức startActivity(Intent) chính thức kích hoạt Activity với các thông tin mà Intent vừa cung cấp.
Giờ thì bạn có thể thực thi chương trình để kiểm chứng rồi. Bạn hãy thử nhấn vào từng item trên menu ActionBar để xem kết quả nhé. Màn hình bên phải dưới đây chính là ContactActivity đấy. Mỗi khi đến ContactActivity, bạn phải nhấn nút back của thiết bị để quay về MainActivity. Để chuyên nghiệp hơn, chúng ta sẽ xây dựng nút back trên ActionBar ở bước tiếp theo dưới đây.
Xây Dựng Chức Năng Back Trên ActionBar Của ContactActivity
Bởi vì nhấn nút back của thiết bị ở màn hình ContactActivity để quay về MainActivity thật là phiền phức và thiếu chuyên nghiệp. Nên chúng ta sẽ phải làm thêm một bước nhỏ nữa thôi.
Giống như bài học trước. Chúng ta đảm bảo icon back xuất hiện bằng hai dòng code sau.
Rồi đón lấy sự kiện onOptionsItemSelected(), lần này bạn check với item có id là android.R.id.home, đây là id sẵn có của hệ thống đối với item back này. Khi item này được click, chúng ta chỉ đơn giản là gọi phương thức finish() để kết thúc một Activity. Bài học sau chúng ta sẽ xem việc kết thúc một Activity thực sự là như thế nào.
Nào giờ thì bạn hãy chạy lại chương trình để kiểm chứng nhé.
Bạn có thể download source code mẫu của bài này ở đây.
Chúng ta vừa cùng nhau xây dựng thêm một màn hình nữa cho TourNote, thông qua việc tạo thêm một Activity mới. Tuy nhiên kiến thức về Activity còn rất nhiều điều thâm sâu đang chờ đợi bạn. Chúng ta sẽ còn nói tiếp về Activity ở các bài học sắp tới. Các bạn chờ xem nhé.
Bài Kế Tiếp
Chúng ta sẽ đi sâu vào tìm hiểu xem hệ thống Android quản lý các Activity như thế nào. Vòng đời của một Activity là gì. Và xem khi một Activity được hiển thị ra cho người dùng thấy, trong khi các Activity còn lại sẽ vào lại “hậu trường” là như thế nào.