Android Bài 7: Tạo Giao Diện Người Dùng

Posted by

baner7.png

Được chỉnh sửa ngày 14/7/2017.

Chào mừng các bạn quay trở lại với bài học thứ 7 trong chuỗi bài học về lập trình ứng dụng Android của Yellow Code Books.

Bài hôm nay chúng ta sẽ nói về Giao Diện Người Dùng  (Graphical User Interface – GUI), một thành phần quan trọng trong ứng dụng của các bạn. Nhắc lại một chút rằng, ở bài 5 chúng ta có nói qua các Thành Phần Của Ứng Dụng (Application Component), nhưng có bạn nào thắc mắc rằng giao diện sẽ được xây dựng như thế nào dựa trên các Thành Phần này không? Nếu bạn để ý kỹ bài học, thì mình có nói rằng trong 4 Thành Phần đó (Activities, Services, Content Providers và Broadcast Receiver) thì chỉ có duy nhất Activities là hiển thị giao diện cho người dùng. Vậy bài này các bạn sẽ được biết cách thức xây dựng giao diện cho một Activity. Activity là gì thì chúng ta sẽ tìm hiểu sau, điều các bạn cần quan tâm bây giờ là chúng ta sẽ thử sức xây dựng giao diện cho TourNote thông qua Activity có tên MainActivity.java.

Trước khi chính thức đi vào thực hành xây dựng giao diện, chúng ta nói qua một số khái niệm sau, chúng là những viên gạch cơ bản đầu tiên để xây dựng nên một “công trình” giao diện hoàn chỉnh, chúng hoành tráng hay nghèo nàn, kiên cố hay xiêu vẹo là ở những viên gạch cơ bản này đấy.

Khái Niệm Widget

Bạn ít khi nghe nói đến Widget trong giao tiếp thông thường, nhất là khi trao đổi tiếng Việt giữa các lập trình viên với nhau. Nhưng trong ngôn ngữ lập trình, Widget có khái niệm rõ ràng và được sử dụng trong các tài liệu tiếng Anh đấy nhé.

Vậy thì, Widget là một thành phần của Giao Diện Người Dùng, Widget giúp hiển thị các thông tin được sắp xếp, và có thể chỉnh sửa được tới người dùng. Mỗi Widget sẽ mang một kiểu thông tin nhất định, tập hợp chúng lại với nhau chúng ta tạo nên một Giao Diện Người Dùng. @@

Đọc các dòng trên có thể khiến bạn bị lùng bùng lỗ tai, nhưng thực ra Widget rất dễ hiểu, nó chính là cái Textbox, cái Label, cái Button,… trên ứng dụng của bạn mà thôi. Để dễ hiểu hơn bạn hãy nhìn vào hình ảnh rất đẹp của một ứng dụng sau. ^^

New - Edit Note.png

Bạn có thể thấy:

– Một số text, như Thêm Ghi Chú, Chủ Đề
– Một số chỗ để người dùng nhập text của họ vào, như Tiêu Đề, Miêu Tả, Ghi Chú
– Một số check box, như Ăn Uống, Tham Quan, Mua Sắm
– Một số nút, như nút +, nút x
– Một số nơi để hiển thị hình ảnh
– …

Tất cả những thành phần được liệt kê ở trên đều là các Widget cả đấy, chúng được sắp đặt ở các vị trí cụ thể trên màn hình, mỗi Widget đảm nhận các vai trò khác nhau đến với sự tương tác với người dùng. Bạn thấy có dễ hiểu hơn không nào. Chúng ta sẽ làm quen với từng Widget ở bài học sau nhé, còn bây giờ hãy qua khái niệm kế tiếp.

Khái Niệm View

Bạn đã hiểu Widget là gì rồi, giờ ta sẽ tìm hiểu về khái niệm View. View thực chất là nguồn gốc để tạo nên các Widget được nói đến ở trên.

View được hiểu như là các cấu tạo giống nhau, hay nói cách khác nó là các khuôn mẫu cơ bản để làm nền tảng tạo nên Widget. Nó tương tự như khái niệm về kế thừa trong OOP ấy, trong đó View là cha còn các Widget là con kế thừa từ View đó. Do đó trong khi ở View chỉ có các thuộc tính chung nhất, thì Widget là các thể hiện khác nhau của View. Mỗi Widget chứa đựng các thuộc tính đặc thù của nó mà View hoặc các Widget khác không có. Chẳng hạn Button sẽ có các thuộc tính khác với Label, Checkbox sẽ khác Radio Button,...

Về mặt giao diện thì ở cấp độ View chỉ đơn giản là một hình chữ nhật, có kích thước rõ ràng, nằm ở đâu trên màn hình, và nhận các sự kiện tương tác với user mà thôi.

Khái Niệm ViewGroup

ViewGroup cũng gần như là View, nhưng đặc biệt hơn một chút, đó là, ViewGroup được tạo ra để chứa đựng các View hay các ViewGroup khác. Nếu như View là nguồn gốc để tạo ra các Widget, thì ViewGroup lại là nguồn gốc để tạo ra các Layout. Các layout mà chúng ta sẽ sớm làm quen, như LinearLayout, RelativeLayout, FrameLayout, GridLayout,… Mỗi layout như một Thùng Chứa (Container) để chứa đựng các View hay các ViewGroup khác bên trong mình, các thành phần bên trong này được sắp xếp theo một quy tắc nhất định tùy theo từng loại ViewGroup.

Kết Hợp View Và ViewGroup Để Tạo Nên Giao Diện

Với khái niệm ViewViewGroup ở trên, các bạn có thể thấy rằng mối quan hệ của hai thành phần này giúp tạo thành một giao diện người dùng có bản chất là một cây phân cấp. Cây phân cấp này bao gồm các View và ViewGroup, chúng được sắp xếp hay lồng vào nhau theo những quy tắc nhất định. Như hình minh họa dưới đây.

viewgroup.png

Chỉnh Sửa Giao Diện Cho TourNote

Woohooo!!! Lý thuyết ở trên nặng đầu quá, nếu bạn chưa hiểu gì cả thì cũng không sao. Giờ chúng ta nên làm quen với thực hành tạo giao diện. Có một điều chúng ta phải thống nhất với nhau trước khi đi vào chi tiết thực hành, đó là việc xây dựng giao diện cho ứng dụng Android sẽ làm hoàn toàn bằng code. Và các bạn phải code XML. Các bạn phải code để tạo thành sự kết hợp các ViewViewGroup như cây phân cấp ở trên. Bạn đừng vội nản nhé, có một ý nhỏ sau đây về việc code XML mà bạn sẽ thấy thích.

– Nhiều ngôn ngữ khác cũng dùng code XML để thiết kế giao diện, nhưng có lẽ trình biên dịch của ngôn ngữ đó “xịn” hơn nên lập trình viên có thể kéo-thả giao diện thông qua các công cụ thiết kế, các công cụ này sẽ tự sinh code XML. Rốt cuộc lại thì lập trình viên vẫn nhận được kết quả cuối cùng là các file XML.
– Việc thiết kế giao diện bằng cách tự code XML giúp bạn quản lý giao diện dễ dàng hơn, và do đó, giao diện của ứng dụng của bạn có đẹp hay xấu, thực thi nhanh hay chậm là hoàn toàn là ở bạn.
– Android Studio đang dần hoàn thiện các công cụ kéo-thả để giúp lập trình viên Android dễ thở hơn. Từ Android Studio 2.2 trở lên, bạn đã có thể tạo ra một layout có tên là ConstraintLayout, layout này cho bạn có cơ hội được thiết lập giao diện hoàn toàn bằng kéo thả và công cụ. Nhưng… bạn cũng nên biết công cụ này rốt cuộc đã tạo ra XML như thế nào, và như thế bạn lại phải biết XML.

Thực Hành Chỉnh Sửa Giao Diện Cho TourNote

Để đảm bảo chắc chắn code của bạn sẽ thực thi lên được (vì bài trước bạn đã code một dòng làm cho ứng dụng bị crash để trải nghiệm), thì bạn nên xóa các dòng đã code từ bài trước đó đi nhé, bảo đảm class MainActivity.java “sạch” giống như sau.

public class MainActivity extends AppCompatActivity {
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
}

Giờ bạn hãy tìm đến file activity_main.xml và click đúp để mở file này lên, đây chính là giao diện của class ActivityMain.java. Nhắc lại là nếu không biết mở class này ở đâu, bạn hãy tìm trong cửa sổ Project ở bên trái màn hình. File activity_main.xml sẽ xuất hiện ở cửa sổ Project như một trong hai hình sau, tùy vào cách thức hiển thị là Android hay Project.

Group 2.png

Cửa sổ được mở lên sẽ rất khác với lúc bạn mở ActivityMain.java hôm trước. Vì mình cũng đã có nói đến ở Bài 3, rằng cửa sổ editor này rất đặc biệt, nó sẽ hiển thị nội dung theo đúng loại file đã mở, trong trường hợp này bạn đang mở file giao diện XML nên Android Studio sẽ hiển thị theo kiểu thiết kế giao diện như sau.

Screen Shot 2016-09-26 at 11.36.34.png

Giao diện ở cửa sổ này có thể khác với giao diện ở máy bạn một chút tùy vào version của Android Studio. Các bạn có thể chú ý ở phía dưới cửa sổ này có 2 tab: DesignText (như hình dưới). Mặc định cửa sổ này hiển thị chế độ Design, tức là các bạn có thể kéo-thả giao diện, hệ thống sẽ sinh ra code XML một cách tự động cho bạn. Nhưng như mình nói, chúng ta làm quen với việc code XML trước, các bạn có thể xem cách thức kéo-thả giao diện ở các tài liệu khác (hoặc mình sẽ dành thời gian viết về việc kéo-thả cho các bạn sau). Để chuyển sang chế độ code XML, bạn hãy click vào tab Text.

Screen Shot 2016-09-26 at 13.03.09.png

Sau khi chuyển sang chế độ Text, giao diện của cửa sổ này sẽ như sau.

Screen Shot 2016-09-26 at 13.14.11.png

Với cửa sổ này, bạn có thể code XML ở phần bên trái, mọi thay đổi sẽ được cập nhật tức thì ở phần bên phải, giúp bạn kiểm chứng xem mình code giao diện có đúng chưa để còn canh chỉnh lại. Chú ý là nếu cửa sổ bên phải không thấy xuất hiện, bạn có thể tìm trên thanh ở tận cùng bên phải có chữ Preview và nhấn vào đó, hoặc bạn có thể chọn ở menu View > Tool Windows > Preview để đóng/mở cửa sổ này.

Nhìn vào khung Preview chúng ta thấy có một text ở phần content của màn hình với nội dung “Hello World!”. Trước hết chúng ta bỏ dòng text đi bằng cách xóa bỏ code từ dòng đến dòng /> ở bên code XML bên trái. Với việc bỏ đi các dòng này thì bạn đã bỏ đi một Widget có tên là TextView khỏi màn nhình. Dòng code XML của bạn giờ như sau.

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.yellowcode.tournote.MainActivity">
  
</RelativeLayout>

Chú ý: Nếu code XML của bạn không hoàn toàn giống như mình trên đây, thì ắt hẳn là bạn đang dùng Android Studio version khá mới, công cụ mới này tự sinh ra ConstraintLayout thay vì RelativeLayout như mình đang hướng dẫn. Bạn yên tâm, bạn hoàn toàn có thể xóa các code XML khác biệt đó của bạn và code lại theo như bài học hôm nay để được làm quen với kỹ năng lập trình giao diện bằng XML trước nhé. Bạn có thể đọc trước bài 18 để biết và thêm vào XML một vài thuộc tính báo lỗi (nếu có), chúng liên quan đến dimen của bài học hôm nay.

Giờ thì khi bạn đã bỏ đi một Widget trong code XML, thì Widget “Hello World!” bên khung Preview cũng không còn, thật là tuyệt!

Giờ bạn hãy thay thế TextView vừa xóa lúc nãy bằng một TextView khác, với nội dung thông báo cho người dùng biết họ đang không có ghi chú nào hết, họ có thể thêm ghi chú của họ vô ngay bây giờ. Bạn hãy gõ vào chính xác nội dung như phần tô sáng bên dưới, chú ý khi gõ, hệ thống sẽ gợi ý cho bạn các từ để bạn điền vào nhanh, bạn thấy hợp lý thì nhấn Enter (máy Mac là Return) để chọn dòng gợi ý đó nhé, bạn hãy từ từ trải nghiệp editor thú vị này.

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.yellowcode.tournote.MainActivity">
  
    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:gravity="center"
        android:text="Bạn chưa có ghi chú nào cho mình, hãy tạo mới ghi chú cho mình từ hôm nay"
        android:textSize="15sp"/>
  
</RelativeLayout>

Khi bạn code xong thì cửa sổ Preview sẽ cho bạn xem trước giao diện như hình phía dưới đây. Nếu bạn không thấy được giao diện mà mình vừa code, thì xem lại code nhé, có sai sót chỗ nào rồi đấy, hoặc bạn có thể đọc thêm phần giải thích ở bên dưới để biết vì sao ta lại code như vậy, hay vì sao bị lỗi nhé.

Screen Shot 2016-09-26 at 13.45.29.png

Giải Thích Một Chút Giao Diện XML Bạn Vừa Code

Chúc mừng bạn vừa code xong giao diện đơn giản cho TourNote, nếu bạn đã thấy thành phẩm, hoặc đang lỗi gì đó thì dừng chân xem qua một chút giải thích sau đây trước khi run ứng dụng.

– Dòng đầu tiên . Chà đây không phải khái niệm của Android nên bạn không cần quan tâm cũng được. Đây là định nghĩa của XML mà thôi, nó thông báo rằng cấu trúc bạn đang dùng là XML version 1.0, và text được mã hóa theo định dạng utf-8.

– Kế tiếp bạn hãy chú ý đến dòng có chữ RelativeLayout. RelativeLayout như được trình bày trên đây đó là một ViewGroup, do đó bên trong nó có thể chứa các View hoặc ViewGroup khác. Trong trường hợp này nó đang chứa TextView. Bạn sẽ được làm quen về các ViewViewGroup một cách cụ thể hơn ở các bài khác.

– Dòng tiếp theo xmlns:android=”http://schemas.android.com/apk/res/android “ và xmlns:tools=”http://schemas.android.com/tools “. Đây là các dòng khai báo các namespace, namespace là nơi định nghĩa ra các từ khóa androidtools mà bạn thấy rất nhiều trong code XML của bạn. Nhờ các namsepace này mà bạn mới có thể dùng được các từ khóa androidtools nhiều lần trong một file XML mà không cần phải khai báo lại. Mỗi file XML bạn chỉ cần định nghĩ một lần cho một namespace thôi. Nếu thử xóa một trong các khai báo cho namespace này đi bạn sẽ thấy báo lỗi ở những nơi sử dụng android hay tools tương ứng đấy nhé.

– Các android:idandroid:layout_width, android:layout_height, android:paddingBottom, android:paddingLeft,… là các thuộc tính của View hay ViewGroup mà ta sẽ nói đến ở bài sau.

– Cuối cùng là View bạn mới xây dựng: TextView. TextView là một trong số các Widget được xây dựng từ View gốc, ở đây bạn vừa thấy các thuộc tính cơ bản của một View, vừa thấy các thuộc tính bổ sung thêm của TextView như android:text và android:textSize.

Run Ứng Dụng

Lúc này bạn hãy thử run ứng dụng TourNote để xem thành quả nhé.

Download Source Code Mẫu

Bạn có thể download source code mẫu ở đây.

Bạn vừa cùng mình thử thiết kế giao diện ở mức cơ bản cho ứng dụng TourNote, chúng ta sẽ đi sâu hơn về thiết kế giao diện ở các bài tiếp theo.

Cảm ơn bạn đã đọc các bài viết của Yellow Code Books. Bạn hãy đánh giá 5 sao nếu thấy thích bài viết, hãy comment bên dưới nếu có thắc mắc, hãy để lại địa chỉ email của bạn để nhận được thông báo mới nhất khi có bài viết mới, và nhớ chia sẻ các bài viết của Yellow Code Books đến nhiều người khác nữa nhé.

Bài Kế Tiếp

Bạn sẽ được học cách quản lý các resource của ứng dụng, từ đó bạn biết cách làm sao có thể xây dựng một ứng dụng chạy được trên tất cả các kích thước màn hình khác nhau, bao gồm cả việc hỗ trợ màn hình xoay ngang/dọc, và còn hỗ trợ nhiều ngôn ngữ nữa.

Advertisements
Rating: 5.0/5. From 13 votes.
Please wait...

4 comments

Gửi phản hồi