Tạo bố cục XML cho Android

1. Trước khi bắt đầu

Trong lớp học lập trình này, bạn sẽ xây dựng bố cục cho ứng dụng tính tiền boa cơ bản. Kết thúc lớp học này, bạn sẽ có một giao diện người dùng đang hoạt động, nhưng chức năng tính tiền boa vẫn chưa hoạt động. Làm cho ứng dụng bắt đầu hoạt động và trông chuyên nghiệp hơn sẽ là nội dung được đề cập trong các lớp học lập trình sau.

Điều kiện tiên quyết

  • Có khả năng tạo và chạy một ứng dụng Android dựa trên mẫu trong Android Studio

Kiến thức bạn sẽ học được

  • Biết cách đọc và ghi bố cục XML trong Android
  • Biết cách tạo bố cục cho một biểu mẫu đơn giản để người dùng nhập văn bản và đưa ra các lựa chọn

Sản phẩm bạn sẽ tạo ra

  • Giao diện người dùng cho ứng dụng tính toán tiền boa trên Android

Bạn cần có

2. Bắt đầu dự án

Hãy tham khảo máy tính tiền boa trên Google: https://www.google.com/search?q=tip+computer

18da3c120daa0759.png

Trong lộ trình này, bạn sẽ xây dựng một ứng dụng Android mô phỏng phiên bản đơn giản của máy tính tiền boa.

Các nhà phát triển thường đi theo cách tiếp cận này – trước hết sẽ xây dựng một phiên bản ứng dụng đơn giản và hoạt động một phần (thậm chí ứng dụng nhìn vẫn chưa đẹp lắm), sau đó sẽ hoàn chỉnh dần các chức năng và hình ảnh của ứng dụng.

Kết thúc lớp học lập trình này, ứng dụng tính tiền boa sẽ có dạng như sau:

bcc5260318477c14.png

Bạn sẽ sử dụng các thành phần sau đây trên giao diện người dùng do Android cung cấp:

  • EditText - để nhập và chỉnh sửa văn bản
  • TextView – để hiển thị văn bản như câu hỏi về chất lượng phục vụ và số tiền boa
  • RadioButton - nút chọn cho phép chọn các tuỳ chọn tiền boa
  • RadioGroup – để nhóm các tuỳ chọn nút chọn
  • Switch – nút chuyển bật/tắt để xác định có làm tròn tiền boa hay không

Tạo dự án Hoạt động trống

  1. Để bắt đầu, hãy tạo một dự án Kotlin mới trong Android Studio bằng mẫu Empty Activity (Hoạt động trống).
  2. Đặt tên ứng dụng là "Tính tiền boa", với cấp độ API tối thiểu là 19 (KitKat). Tên gói là com.example.tiptime.

4f7619e9faff20e9.png

  1. Nhấp vào Finish (Hoàn tất) để tạo ứng dụng.

3. Đọc và hiểu XML

Thay vì sử dụng Layout Editor (Trình chỉnh sửa bố cục) quen thuộc, bạn sẽ xây dựng bố cục ứng dụng bằng cách chỉnh sửa tệp XML mô tả giao diện người dùng. Học cách hiểu rõ và chỉnh sửa bố cục giao diện người dùng bằng XML rất quan trọng đối với một nhà phát triển Android như bạn.

Bạn sẽ xem xét và chỉnh sửa tệp XML dùng để định nghĩa bố cục giao diện người dùng của ứng dụng này. XML là viết tắt của eXtensible Markup Language(Ngôn ngữ đánh dấu mở rộng), là một cách mô tả dữ liệu sử dụng tài liệu dựa trên văn bản. XML có thể mở rộng và rất linh hoạt nên được sử dụng cho nhiều mục đích khác nhau, bao gồm định nghĩa bố cục giao diện người dùng cho các ứng dụng Android. Bạn có thể nhớ lại các lớp học lập trình trước đây, các tài nguyên ứng dụng khác như chuỗi cũng được định nghĩa trong tệp XML có tên là strings.xml.

Giao diện người dùng trên ứng dụng Android được xây dựng dưới dạng phân cấp vùng chứa của các thành phần (tiện ích) và bố cục trên màn hình của các thành phần đó. Lưu ý rằng các bố cục đó là chính các thành phần giao diện người dùng.

Bạn mô tả hệ phân cấp thành phần hiển thị (view hierarchy) của các thành phần giao diện người dùng trên màn hình. Ví dụ: một ConstraintLayout (mẹ) có thể chứa Buttons, TextViews, ImageViews hoặc các thành phần hiển thị (view) khác (con). Hãy nhớ rằng ConstraintLayout là một lớp con của ViewGroup. Hệ phân cấp này cho phép bạn định vị hoặc định kích thước khung nhìn con một cách linh hoạt.

74c7c563d18fffd4.png

Hệ phân cấp vùng chứa của một ứng dụng Android

32df120272b2331d.png

Mỗi thành phần giao diện người dùng được biểu thị bằng một phần tử XML trong tệp XML. Mỗi phần tử bắt đầu và kết thúc bằng một thẻ, trong đó mỗi thẻ bắt đầu bằng một < và kết thúc bằng >. Tương tự như cách bạn thiết lập thuộc tính trên các thành phần giao diện người dùng bằng Layout Editor (design) (Trình chỉnh sửa bố cục (thiết kế)), các phần tử XML cũng có thuộc tính của mình. Một cách đơn giản, mã XML cho các thành phần trên giao diện người dùng nêu trên có thể có dạng như sau:

<ConstraintLayout>
    <TextView
        text="Hello World!">
    </TextView>
</ConstraintLayout>

8dea708333aebabe.png

Hãy xem một ví dụ thực tế.

  1. Mở activity_main.xml (res > layout > activity_main.xml).
  2. Bạn có thể thấy ứng dụng hiện một TextView với dòng chữ "Hello World!" (Xin chào mọi người) trong một ConstraintLayout, như đã thấy trong các dự án được tạo dựa trên mẫu này trước đây.

4fbdb64c02d62e73.png

  1. Tìm tuỳ chọn cho các khung hiển thị Code (Mã), Split (Phân tách) và Design (Thiết kế) ở phía trên bên phải của Layout Editor.
  2. Chọn chế độ xem Code (Mã).

6203bec920791bcc.png

Mã XML trong activity_main.xml sẽ hiển thị như sau:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

rất nhiều thứ khác diễn ra bên ngoài ví dụ đơn giản này, nhưng Android Studio sẽ thực hiện một số bước để giúp mã XML dễ đọc hơn, tương tự như đã thực hiện với mã Kotlin của bạn.

  1. Hãy chú ý phần thụt đầu dòng. Android Studio sẽ tự động thực hiện việc này để hiển thị hệ phân cấp các phần tử. TextView được thụt đầu dòng vì nằm trong ConstraintLayout. ConstraintLayout là phần tử mẹ và TextView là phần tử con. Các thuộc tính cho mỗi phần tử đều được thụt đầu dòng, cho biết những thuộc tính này thuộc về phần tử đó.
  2. Hãy lưu ý đến việc lập trình màu sắc—một số đối tượng có màu xanh dương, một số có màu xanh lục, v.v. Các phần tương tự của tệp sẽ được vẽ cùng một màu để giúp bạn kết hợp các phần đó với nhau. Đặc biệt, hãy lưu ý rằng Android Studio sẽ vẽ phần đầu và phần cuối của các thẻ phần tử có cùng màu. (Lưu ý: màu sắc sử dụng trong lớp học lập trình có thể không khớp với màu bạn thấy trong Android Studio).

Thẻ, phần tử và thuộc tính XML

Dưới đây là phiên bản đơn giản của phần tử TextView, bạn có thể xem một số phần quan trọng:

<TextView
    android:text="Hello World!"
/>

Dòng chứa <TextView là phần mở đầu thẻ, và dòng có /> là phần kết thúc thẻ. Dòng chứa android:text="Hello World!" là thuộc tính của thẻ. Thuộc tính này thể hiện rằng văn bản sẽ được hiển thị trên TextView. 3 dòng này là cách viết tắt thường dùng, được gọi là thẻ phần tử rỗng. Cách viết này cũng tương tự như khi bạn sử dụng một thẻ mở và một thẻ đóng riêng biệt, như sau:

<TextView
    android:text="Hello World!"
></TextView>

Thông thường, thẻ phần tử rỗng sẽ được viết với số dòng càng ít càng tốt và phần thẻ đóng thường được ghép liền vào cuối dòng trước đó. Vì vậy, bạn có thể thấy thẻ phần tử rỗng được viết trên hai dòng (hoặc thậm chí một dòng nếu thẻ không có thuộc tính nào):

<!-- with attributes, two lines -->
<TextView
    android:text="Hello World!" />

Phần tử ConstraintLayout được viết với thẻ mở và thẻ đóng riêng biệt, vì phần tử này có thể chứa các phần tử khác bên trong. Dưới đây là phiên bản đơn giản của phần tử ConstraintLayout có chứa phần tử TextView bên trong:

<androidx.constraintlayout.widget.ConstraintLayout>
    <TextView
        android:text="Hello World!" />
</androidx.constraintlayout.widget.ConstraintLayout>

Nếu bạn muốn thêm một View khác làm phần tử con của ConstraintLayout, chẳng hạn như thêm một Button bên dưới TextView, thì phần tử này sẽ nằm sau thẻ đóng /> của TextView và trước thẻ đóng của ConstraintLayout, thể hiện như dưới đây:

<androidx.constraintlayout.widget.ConstraintLayout>
    <TextView
        android:text="Hello World!" />
    <Button
        android:text="Calculate" />
</androidx.constraintlayout.widget.ConstraintLayout>

Tìm hiểu thêm về sử dụng XML cho bố cục

  1. Có thể thấy thẻ của ConstraintLayoutandroidx.constraintlayout.widget.ConstraintLayout thay vì ConstraintLayout như TextView. Điều này là do ConstraintLayout là một phần của Android Jetpack, chứa các thư viện mã nhằm cung cấp các chức năng bổ sung cho nền tảng Android cốt lõi. Jetpack cung cấp các chức năng hữu ích, cho phép bạn xây dựng ứng dụng dễ dàng hơn. Bạn sẽ nhận ra thành phần giao diện người dùng này là một phần của Jetpack vì thành phần này bắt đầu bằng "androidx".
  2. Bạn có thể đã thấy các dòng lệnh bắt đầu bằng xmlns:, theo sau là android, apptools.
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"

xmlns là viết tắt của không gian tên XML, và mỗi dòng định nghĩa một lược đồ, hoặc từ vựng dành cho các thuộc tính liên quan đến các từ đó. Ví dụ: không gian tên android: đánh dấu các thuộc tính do hệ thống Android định nghĩa. Tất cả thuộc tính trong XML bố cục đều bắt đầu bằng một trong các không gian tên đó.

  1. Khoảng trắng giữa các phần tử XML không mang nhiều ý nghĩa đối với một máy tính, nhưng có thể giúp XML trở nên dễ đọc hơn.

Android Studio sẽ tự động thêm một số khoảng trắng và thụt đầu dòng để XML dễ đọc hơn. Bạn sẽ tìm hiểu sau về cách thức để yêu cầu Android Studio đảm bảo XML của bạn tuân theo các quy ước lập trình.

  1. Bạn có thể thêm chú thích vào XML, tương tự như cách bạn thực hiện với mã Kotlin. Bắt đầu với <!-- và kết thúc bằng -->.
<!-- this is a comment in XML -->

<!-- this is a
multi-line
Comment.
And another
Multi-line comment -->
  1. Lưu ý dòng đầu tiên của tệp:
<?xml version="1.0" encoding="utf-8"?>

Dòng này cho biết đây là một tệp XML, nhưng không phải tệp XML nào cũng chứa dòng này.

4. Xây dựng bố cục trong XML

  1. Vẫn trong tệp activity_main.xml, hãy chuyển sang chế độ xem màn hình Split (Phân tách) để xem mã XML bên cạnh Design Editor (Trình chỉnh sửa thiết kế). Design Editor (Trình chỉnh sửa thiết kế) cho phép bạn xem trước bố cục giao diện người dùng.

a03bcf5beacb4b45.png

  1. Bạn có thể chọn khung hiển thị theo sở thích cá nhân. Tuy nhiên, đối với lớp học lập trình này, hãy sử dụng khung hiển thị Split (Phân tách) để có thể thấy cả phần XML bạn chỉnh sửa và tác động của những chỉnh sửa đó trong Design Editor (Trình chỉnh sửa thiết kế).
  2. Hãy thử nhấp vào các dòng lệnh khác nhau, dòng bên dưới ConstraintLayout và tiếp đó là dòng bên dưới TextView. Bạn sẽ thấy rằng thành phần hiển thị tương ứng sẽ được chọn trong chế độ xem Design Editor (Trình chỉnh sửa thiết kế). Kết quả sẽ tương tự khi làm điều ngược lại, ví dụ: nếu bạn nhấp vào TextView trong Design Editor (Trình chỉnh sửa thiết kế), đoạn mã XML tương ứng được làm nổi bật.

1abc54a646c39f66.png

Xoá TextView

  1. Bây giờ bạn không cần đến TextView nữa nên có thể xoá thành phần hiển thị này. Hãy nhớ xoá toàn bộ nội dung từ thẻ mở <TextView đến hết thẻ đóng />.
<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Hello World!"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintLeft_toLeftOf="parent"
    app:layout_constraintRight_toRightOf="parent"
    app:layout_constraintTop_toTopOf="parent" />

Phần nội dung còn lại trong tệp là về ConstraintLayout:

<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

</androidx.constraintlayout.widget.ConstraintLayout>
  1. Thêm khoảng đệm 16 dp vào ConstraintLayout để giao diện người dùng không bị tràn vào cạnh màn hình.

Khoảng đệm cũng tương tự như lề trang nhưng sẽ bổ sung thêm khoảng trống vào bên trong ConstraintLayout, thay vì thêm khoảng trống ở bên ngoài.

<androidx.constraintlayout.widget.ConstraintLayout
    ...
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="16dp"
    tools:context=".MainActivity">

Thêm trường văn bản phí dịch vụ

Ở bước này, bạn sẽ thêm thành phần giao diện người dùng để cho phép người dùng nhập phí dịch vụ vào ứng dụng. Bạn sẽ sử dụng phần tử EditText để cho phép người dùng nhập hoặc chỉnh sửa văn bản trong ứng dụng.

7746dedb0d79923f.png

  1. Xem tài liệu về EditText rồi kiểm tra XML của mẫu.
  2. Tìm một khoảng trống giữa các thẻ mở và đóng của ConstraintLayout.
  3. Sao chép và dán XML trong tài liệu này vào khoảng trống đó trong bố cục của bạn trên Android Studio.

Tệp bố cục của bạn sẽ có dạng như sau:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="16dp"
    tools:context=".MainActivity">

    <EditText
        android:id="@+id/plain_text_input"
        android:layout_height="wrap_content"
        android:layout_width="match_parent"
        android:inputType="text"/>

</androidx.constraintlayout.widget.ConstraintLayout>

Có thể bạn chưa hiểu rõ toàn bộ nội dung này. Các bước sau sẽ giải thích chi tiết giúp bạn.

  1. Chú ý rằng EditText đang được gạch chân màu đỏ.
  2. Di chuột qua đó bạn sẽ thấy lỗi "thành phần hiển thị chưa được ràng buộc". Các lỗi này bạn đã quen thuộc trong các lớp học lập trình trước đó. Hãy nhớ, cần thiết lập các điều kiện ràng buộc lên thành phần con của ConstraintLayout để bố cục biết cách sắp xếp các thành phần này.

40c17058bd6786f.png

  1. Thêm các điều kiện ràng buộc sau đây vào EditText để neo thành phần hiển thị này vào góc trên cùng bên trái của thành phần cha.
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"

Nếu bạn đang viết bằng tiếng Anh hoặc một ngôn ngữ khác được viết từ trái sang phải (LTR), thì cạnh bắt đầu là phía bên trái. Nhưng một số ngôn ngữ như tiếng Ả Rập được viết từ phải sang trái (RTL). Vì thế, cạnh bắt đầu là phía bên phải. Đó là lý do tại sao điều kiện ràng buộc sử dụng từ "bắt đầu" để có thể phù hợp với các ngôn ngữ LTR hoặc RTL. Tương tự, các điều kiện ràng buộc sử dụng từ "kết thúc" thay vì bên phải.

Khi thêm vào các điều kiện ràng buộc mới, phần tử EditText sẽ có dạng như sau:

<EditText
    android:id="@+id/plain_text_input"
    android:layout_height="wrap_content"
    android:layout_width="match_parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="parent"
    android:inputType="text"/>

Xem lại các thuộc tính EditText

Kiểm tra cẩn thận tất cả thuộc tính EditText bạn đã dán vào nhằm đảm bảo những thuộc tính này sẽ hoạt động đúng như dự kiến trong ứng dụng của bạn.

  1. Tìm thuộc tính id, đang được gán thành @+id/plain_text_input.
  2. Hãy thay đổi tên thuộc tính id thành tên phù hợp hơn, @+id/cost_of_service.
  1. Xem thuộc tính layout_height. Thuộc tính này được thiết lập thành wrap_content, nghĩa là chiều cao sẽ cao bằng phần nội dung bên trong. Điều này sẽ không có vấn đề gì vì chỉ có 1 dòng văn bản.
  2. Xem thuộc tính layout_width. Thuộc tính này được thiết lập thành match_parent, nhưng bạn không thể thiết lập match_parent trên thành phần con của ConstraintLayout. Hơn nữa, trường văn bản không cần hiển thị quá rộng. Hãy thiết lập chiều rộng cố định cho trường văn bản là 160dp, như thế sẽ có nhiều không gian cho người dùng nhập phí dịch vụ.

1f82a5e86ae94fd2.png

  1. Hãy lưu ý thuộc tính mới inputType. Giá trị của thuộc tính này là "text", nghĩa là người dùng có thể nhập bất kỳ ký tự văn bản nào vào trường đó trên màn hình (ký tự bảng chữ cái, ký hiệu, v.v.)
android:inputType="text"

Tuy nhiên, bạn chỉ muốn người dùng nhập ký tự số vào EditText vì trường này thể hiện giá trị tiền tệ.

  1. Xoá từ text nhưng để lại dấu ngoặc kép.
  2. Bắt đầu nhập number vào đúng vị trí của nó. Sau khi nhập "n", Android Studio sẽ hiển thị một danh sách các nội dung có thể điền vào, trong đó có chứa ký tự "n".

99b04cbd21e74693.gif

  1. Chọn numberDecimal để yêu cầu người dùng nhập vào chữ số thập phân.
android:inputType="numberDecimal"

Để xem các tuỳ chọn khác cho các kiểu dữ liệu nhập vào, hãy tham khảo Chỉ định kiểu phương thức nhập trong tài liệu dành cho nhà phát triển.

Sẽ rất hữu ích khi hiển thị cho người dùng một số gợi ý về nội dung cần nhập vào trường này. Bạn sẽ cần thay đổi thêm một chút như bên dưới.

  1. Thêm thuộc tính hint vào EditText để mô tả những nội dung người dùng nên nhập cho trường này.
android:hint="Cost of Service"

Bạn cũng sẽ thấy phần thay đổi được cập nhật trong chế độ xem Design Editor (Trình chỉnh sửa thiết kế).

824454d2a316efb1.png

  1. Chạy ứng dụng của bạn trong trình mô phỏng. Ứng dụng sẽ hiển thị như sau:

c9d413de53b0853d.png

Bạn làm tốt lắm! Mặc dù chưa làm gì nhiều nhưng bạn đã có một khởi đầu tốt đẹp và đã chỉnh sửa một số thành phần trong XML. Mã XML cho bố cục của bạn sẽ có dạng như sau.

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="16dp"
    tools:context=".MainActivity">

    <EditText
        android:id="@+id/cost_of_service"
        android:layout_width="160dp"
        android:layout_height="wrap_content"
        android:hint="Cost of Service"
        android:inputType="numberDecimal"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

Thêm câu hỏi về chất lượng dịch vụ

Ở bước này, bạn sẽ thêm một TextView cho phần câu hỏi "Bạn đánh giá thế nào về chất lượng dịch vụ?" Hãy thử nhập thành phần hiển thị này trong XML mà không cần sao chép/dán. Android Studio sẽ hiển thị các đề xuất giúp bạn.

  1. Sau khi đóng thẻ EditText, />, hãy thêm một dòng mới và bắt đầu nhập <TextView
  2. Chọn TextView trong số các đề xuất và Android Studio sẽ tự động thêm thuộc tính layout_widthlayout_height cho TextView này.
  3. Chọn wrap_content cho cả hai vì bạn chỉ cần TextView lớn bằng phần nội dung văn bản bên trong. fee18cc43df85294.png
  4. Thêm thuộc tính text bằng "How was the service?"
<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="How was the service?"
  1. Đóng thẻ bằng />.
  2. Lưu ý trong Design Editor (Trình chỉnh sửa thiết kế), TextView sẽ chồng chéo với EditText.

ac09d5cae6ae2455.png

Điều này có vẻ không ổn, vì vậy bạn sẽ thêm các điều kiện ràng buộc vào TextView trong bước tiếp theo. Hãy suy nghĩ về những ràng buộc bạn cần thực hiện. TextView nên được đặt theo chiều ngang và chiều dọc ở đâu? Bạn có thể kiểm tra ảnh chụp màn hình của ứng dụng để tham khảo.

bcc5260318477c14.png

Theo chiều dọc, bạn muốn TextView đặt bên dưới trường văn bản về chi phí dịch vụ. Theo chiều ngang, bạn muốn TextView được căn chỉnh theo cạnh bắt đầu của thành phần mẹ.

  1. Thêm một điều kiện ràng buộc theo chiều ngang vào TextView để ràng buộc cạnh bắt đầu của TextView này với cạnh bắt đầu của thành phần mẹ.
app:layout_constraintStart_toStartOf="parent"
  1. Thêm một điều kiện ràng theo chiều dọc vào TextView để ràng buộc cạnh trên của TextView với cạnh dưới cùng của thành phần hiển thị chi phí dịch vụ View.
app:layout_constraintTop_toBottomOf="@id/cost_of_service"

Lưu ý rằng không có dấu cộng trong @id/cost_of_service vì mã nhận dạng đã được định nghĩa.

3822136f7ed815f2.png

Tại thời điểm này, ứng dụng vẫn còn rất sơ khai nhưng bạn đừng lo lắng về điều đó. Chỉ cần đảm bảo tất cả thông tin cần thiết đều hiển thị trên màn hình và các chức năng đều hoạt động. Bạn sẽ khắc phục phần nhìn của ứng dụng trong các lớp học lập trình sau.

  1. Thêm mã nhận dạng tài nguyên vào TextView. Bạn sẽ cần tham chiếu đến thành phần hiển thị này về sau khi bổ sung các thành phần hiển thị khác cũng như các điều kiện ràng buộc trên các thành phần hiển thị này.
android:id="@+id/service_question"

Tại thời điểm này, tệp XML của bạn sẽ như bên dưới.

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="16dp"
    tools:context=".MainActivity">

    <EditText
        android:id="@+id/cost_of_service"
        android:hint="Cost of Service"
        android:layout_height="wrap_content"
        android:layout_width="160dp"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        android:inputType="numberDecimal"/>

    <TextView
        android:id="@+id/service_question"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="How was the service?"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@id/cost_of_service"/>

</androidx.constraintlayout.widget.ConstraintLayout>

5. Thêm các tuỳ chọn tính tiền boa

Tiếp theo, bạn sẽ thêm các nút chọn cho phép người dùng lựa chọn tỷ lệ tính tiền boa khác nhau.

Bạn cần có 3 tuỳ chọn:

  • Amazing (Tuyệt vời) (20%)
  • Good (Tốt) (18%)
  • Okay (Ổn) (15%)

Nếu không biết chắc phải thêm các nút chọn này như thế nào, bạn có thể tìm kiếm trên Google. Đây là một công cụ hỗ trợ tuyệt vời dành cho nhà phát triển nếu gặp bất kỳ khó khăn nào.

  1. Tìm kiếm chuỗi radio button android trên Google. Kết quả hiển thị hàng đầu là một hướng dẫn trong trang web dành cho nhà phát triển Android về cách sử dụng nút chọn — thật tuyệt vời!

f5f1c6778ae7a5d.png

  1. Đọc qua hướng dẫn về Nút chọn.

Trong nội dung mô tả, bạn có thể sử dụng thành phần giao diện người dùng RadioButton trong bố cục của mình cho mỗi nút chọn bạn cần. Ngoài ra, người dùng chỉ được phép chọn một tuỳ chọn cho mỗi lần thực hiện, bạn cần nhóm các nút chọn trong một RadioGroup.

Một số thành phần XML có thể giúp bạn đáp ứng nhu cầu này. Hãy đọc kỹ và xem cách thiết lập RadioGroup là thành phần hiển thị mẹ và chứa thành phần hiển thị con là RadioButtons.

  1. Quay lại với phần bố cục trong Android Studio để thêm RadioGroupRadioButton vào ứng dụng.
  2. Sau phần tử TextView nhưng vẫn ở trong ConstraintLayout, hãy bắt đầu nhập <RadioGroup. Android Studio sẽ cung cấp các đề xuất hữu ích, giúp bạn hoàn thành mã XML của mình.aee75ba409dc51aa.png
  3. Đặt layout_widthlayout_height của RadioGroup thành wrap_content.
  4. Thêm tập mã nhận dạng tài nguyên vào @+id/tip_options.
  5. Đóng thẻ mở bằng >.
  6. Android Studio sẽ thêm </RadioGroup>. Tương tự như ConstraintLayout, thành phần RadioGroup cũng chứa các thành phần khác bên trong. Vì vậy, bạn nên di chuyển thành phần này vào một dòng riêng. đặt layout_width và layout_height thành wrap_content
  7. Thiết lập ràng buộc để RadioGroup nằm bên dưới câu hỏi về chất lượng dịch vụ (theo chiều dọc) và đến cạnh bắt đầu của thành phần mẹ (theo chiều ngang).
  8. Đặt thuộc tính android:orientation thành vertical. Nếu muốn RadioButtons hiển thị trên một dòng, bạn nên thiết lập thuộc tính này thành horizontal.

XML cho RadioGroup sẽ có dạng như sau:

<RadioGroup
    android:id="@+id/tip_options"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toBottomOf="@id/service_question">

</RadioGroup>

Thêm nút chọn

  1. Sau thuộc tính cuối cùng của RadioGroup, nhưng trước thẻ đóng </RadioGroup>, hãy thêm một RadioButton.
<RadioGroup
    android:id="@+id/tip_options"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toBottomOf="@id/service_question">

    <!-- add RadioButtons here -->

</RadioGroup>
  1. Đặt layout_widthlayout_height thành wrap_content.
  2. Gán mã nhận dạng tài nguyên cho RadioButton@+id/option_twenty_percent.
  3. Đặt phần văn bản thành Amazing (20%).
  4. Đóng thẻ bằng />.
<RadioGroup
   android:id="@+id/tip_options"
   android:layout_width="wrap_content"
   android:layout_height="wrap_content"
   app:layout_constraintTop_toBottomOf="@id/service_question"
   app:layout_constraintStart_toStartOf="parent"
   android:orientation="vertical">

   <RadioButton
       android:id="@+id/option_twenty_percent"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:text="Amazing (20%)" />

</RadioGroup>

53cb416b368e9612.png

Bây giờ khi đã thêm một RadioButton, bạn có thể sửa đổi XML để thêm 2 nút chọn nữa cho các tuỳ chọn Good (18%)Okay (15%) không?

XML của RadioGroupRadioButtons sẽ hiển thị như sau:

<RadioGroup
   android:id="@+id/tip_options"
   android:layout_width="wrap_content"
   android:layout_height="wrap_content"
   app:layout_constraintTop_toBottomOf="@id/service_question"
   app:layout_constraintStart_toStartOf="parent"
   android:orientation="vertical">

   <RadioButton
       android:id="@+id/option_twenty_percent"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:text="Amazing (20%)" />

   <RadioButton
       android:id="@+id/option_eighteen_percent"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:text="Good (18%)" />

   <RadioButton
       android:id="@+id/option_fifteen_percent"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:text="Okay (15%)" />

</RadioGroup>

bab25b6a35d4ce52.png

Thêm lựa chọn mặc định

Hiện tại, chưa có tuỳ chọn tính tiền boa nào được chọn. Tốt nhất bạn nên thiết lập một trong các nút chọn làm lựa chọn mặc định.

RadioGroup có một thuộc tính cho phép bạn chỉ định nút chọn nào sẽ được đánh dấu khi khởi tạo. Đó là thuộc tính checkedButton và bạn sẽ thiết lập thuộc tính này thành mã nhận dạng tài nguyên cho nút chọn mặc định bạn muốn.

  1. Trên RadioGroup này, hãy đặt thuộc tính android:checkedButton thành @id/option_twenty_percent.
<RadioGroup
   android:id="@+id/tip_options"
   android:checkedButton="@id/option_twenty_percent"
   ...

Chú ý, phần bố cục trong Design Editor (Trình chỉnh sửa thiết kế) đã được cập nhật. Tuỳ chọn tính tiền boa 20% được thiết lập thành lựa chọn mặc định — thật tuyệt! Bây giờ, ứng dụng đã bắt đầu giống một máy tính tiền boa!

c412e7f16590cd33.png

Đây là giao diện của XML cho đến hiện tại:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="16dp"
    tools:context=".MainActivity">

    <EditText
        android:id="@+id/cost_of_service"
        android:hint="Cost of Service"
        android:layout_height="wrap_content"
        android:layout_width="160dp"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        android:inputType="numberDecimal"/>

    <TextView
        android:id="@+id/service_question"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="How was the service?"
        app:layout_constraintTop_toBottomOf="@id/cost_of_service"
        app:layout_constraintStart_toStartOf="parent" />

    <RadioGroup
        android:id="@+id/tip_options"
        android:checkedButton="@id/option_twenty_percent"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintTop_toBottomOf="@id/service_question"
        app:layout_constraintStart_toStartOf="parent"
        android:orientation="vertical">

        <RadioButton
            android:id="@+id/option_twenty_percent"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Amazing (20%)" />

        <RadioButton
            android:id="@+id/option_eighteen_percent"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Good (18%)" />

        <RadioButton
            android:id="@+id/option_fifteen_percent"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Okay (15%)" />
    </RadioGroup>
</androidx.constraintlayout.widget.ConstraintLayout>

6. Hoàn thành những phần còn lại của bố cục

Hiện tại, bạn đang hoàn thiện phần cuối cùng của bố cục. Bạn sẽ thêm Switch, ButtonTextView để hiển thị số tiền boa.

bcc5260318477c14.png

Thêm thành phần Switch để làm tròn số tiền boa

Tiếp theo, bạn sẽ dùng tiện ích Switch để cho phép người dùng chọn làm tròn hoặc không làm tròn số tiền boa.

Bạn muốn Switch này rộng bằng với thành phần mẹ. Bạn có thể cho rằng nên thiết lập chiều rộng này thành match_parent. Như đã lưu ý trước đó, bạn không thể thiết lập giá trị thuộc tính cho các thành phần giao diện người dùng trong ConstraintLayout thành match_parent. Thay vào đó, bạn cần ràng buộc cạnh bắt đầu và cạnh kết thúc của thành phần hiển thị này, đồng thời đặt chiều rộng thành 0dp. Khi đặt chiều rộng thành 0dp, hệ thống sẽ không tính chiều rộng này mà chỉ cần đáp ứng các điều kiện ràng buộc đang thiết lập trên thành phần hiển thị này.

  1. Thêm phần tử Switch sau phần XML cho RadioGroup.
  2. Như đã lưu ý ở trên, hãy đặt layout_width thành 0dp
  3. Đặt layout_height thành wrap_content. Điều này sẽ làm cho thành phần hiển thị Switch cao bằng phần nội dung bên trong.
  4. Đặt thuộc tính id thành @+id/round_up_switch.
  5. Đặt thuộc tính text thành Round up tip?. Giá trị này sẽ được dùng làm nhãn cho Switch.
  6. Cố định cạnh bắt đầu của Switch với cạnh bắt đầu của tip_options và cạnh kết thúc của nút chuyển này với cạnh kết thúc của thành phần mẹ.
  7. Cố định phần đỉnh của Switch với phần đáy của tip_options.
  8. Đóng thẻ bằng />.

Sẽ tốt hơn nếu nút chuyển này được bật theo mặc định. Bạn có thể sử dụng thuộc tính android:checked để làm việc này, trong đó các giá trị có thể sẽ là true (bật) hoặc false (tắt).

  1. Đặt thuộc tính android:checked thành true.

Kết hợp tất cả lại với nhau, mã XML cho phần tử Switch sẽ có dạng như sau:

<Switch
    android:id="@+id/round_up_switch"
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    android:checked="true"
    android:text="Round up tip?"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="@id/tip_options"
    app:layout_constraintTop_toBottomOf="@id/tip_options" />

d374fab984650296.png

Thêm nút Tính tiền

Tiếp theo, bạn sẽ thêm một Button để người dùng có thể yêu cầu tính tiền boa. Bạn muốn nút này rộng bằng kích thước thành phần mẹ. Vì vậy, các điều kiện ràng buộc theo chiều ngang và chiều rộng sẽ giống như nút chuyển Switch.

  1. Thêm một Button sau Switch.
  2. Đặt chiều rộng thành 0dp, như bạn đã làm cho Switch.
  3. Đặt chiều cao thành wrap_content.
  4. Gán mã nhận dạng tài nguyên @+id/calculate_button cho nút này và thiết lập phần văn bản thành "Calculate".
  5. Cố định cạnh trên của Button với cạnh dưới cùng của nút chuyển Round up tip? (Làm tròn tiền boa?) Switch.
  6. Cố định cạnh bắt đầu với cạnh bắt đầu của thành phần mẹ và cạnh kết thúc với cạnh kết thúc của thành phần mẹ.
  7. Đóng thẻ bằng />.

Dưới đây là toàn bộ mã XML cho tính năng Button Calculate (Tính tiền):

<Button
   android:id="@+id/calculate_button"
   android:layout_width="0dp"
   android:layout_height="wrap_content"
   android:text="Calculate"
   app:layout_constraintTop_toBottomOf="@id/round_up_switch"
   app:layout_constraintStart_toStartOf="parent"
   app:layout_constraintEnd_toEndOf="parent" />

5338cf87c61d15c9.png

Thêm kết quả tính tiền boa

Bạn sắp hoàn thành phần bố cục ứng dụng! Trong bước này, bạn sẽ thêm một TextView để hiển thị kết quả tính tiền boa. Đặt thành phần hiển thị này bên dưới nút Calculate (Tính tiền) và căn chỉnh dựa trên điểm kết thúc hay vì điểm bắt đầu như các thành phần giao diện người dùng khác.

  1. Thêm một TextView kèm theo mã nhận dạng tài nguyên có tên tip_result và phần văn bản tương ứng là Tip Amount.
  2. Cố định cạnh kết thúc của TextView với cạnh kết thúc của thành phần mẹ.
  3. Cố định cạnh trên cùng với cạnh đáy của nút Calculate (Tính tiền).
<TextView
    android:id="@+id/tip_result"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintTop_toBottomOf="@id/calculate_button"
    android:text="Tip Amount" />

9644bcdabbd8d7d1.png

  1. Chạy ứng dụng. Ứng dụng này sẽ trông giống như ảnh chụp màn hình sau đây.

e4ed552fa9fbe4ce.png

Thật tuyệt vời! Một trải nghiệm đặc biệt nếu đây là lần đầu tiên bạn làm việc với XML!

Lưu ý rằng ứng dụng có thể không giống hoàn toàn như ảnh chụp màn hình vì các mẫu thiết kế có thể đã thay đổi trong phiên bản Android Studio sau này. Nút Calculate (Tính tiền) hiện vẫn chưa có tác dụng gì. Tuy nhiên, bạn có thể nhập chi phí, chọn tỷ lệ phần trăm tiền boa và bật/tắt tuỳ chọn làm tròn tiền boa. Bạn sẽ bổ sung chức năng hoạt động cho nút Calculate (Tính tiền) trong lớp học lập trình tiếp theo. Chúng ta sẽ quay lại với nút này sau!

7. Áp dụng các phương pháp lập trình hay

Trích xuất các chuỗi

Bạn có thể nhìn thấy các cảnh báo về các chuỗi được mã hoá cứng. Hãy nhớ lại các lớp học lập trình trước đây khi bạn trích xuất các chuỗi sang một tệp tài nguyên. Việc này sẽ giúp bạn dễ dàng dịch ứng dụng sang các ngôn ngữ khác cũng như sử dụng lại chuỗi đó trong ứng dụng. Kiểm tra lại activity_main.xml và trích xuất tất cả tài nguyên chuỗi.

  1. Nhấp vào một chuỗi; di chuột qua biểu tượng bóng đèn màu vàng xuất hiện, sau đó nhấp vào hình tam giác bên cạnh biểu tượng đó; chọn Extract String Resource (Trích xuất tài nguyên chuỗi). Có thể sử dụng tên mặc định cho các tài nguyên chuỗi. Nếu muốn, bạn có thể sử dụng các tên gợi tả hơn như amazing_service, good_serviceok_servicecho các tuỳ chọn tiền boa.

Bây giờ, hãy kiểm tra các tài nguyên chuỗi bạn vừa thêm.

  1. Nếu cửa sổ Project (Dự án) không hiển thị, hãy nhấp vào thẻ Project (Dự án) ở phía bên trái cửa sổ.
  2. Mở app > res > values > strings.xml để xem tất cả tài nguyên chuỗi của giao diện người dùng.
<resources>
    <string name="app_name">Tip Time</string>
    <string name="cost_of_service">Cost of Service</string>
    <string name="how_was_the_service">How was the service?</string>
    <string name="amazing_service">Amazing (20%)</string>
    <string name="good_service">Good (18%)</string>
    <string name="ok_service">Okay (15%)</string>
    <string name="round_up_tip">Round up tip?</string>
    <string name="calculate">Calculate</string>
    <string name="tip_amount">Tip Amount</string>
</resources>

Định dạng lại XML

Android Studio cung cấp nhiều công cụ giúp bạn dọn dẹp mã và đảm bảo mã của bạn tuân theo các quy ước lập trình được đề xuất.

  1. Trong activity_main.xml, chọn Edit > Select All (Chỉnh sửa > Chọn tất cả).
  2. Chọn Code > Reformat Code (Mã > Định dạng lại mã).

Thao tác này sẽ đảm bảo căn lề nhất quán và có thể sắp xếp lại mã XML của các thành phần giao diện người dùng để gom nhóm mọi thứ với nhau. Chẳng hạn như đặt tất cả thuộc tính android: của một phần tử lại với nhau.

8. Mã giải pháp

bcc5260318477c14.png

res/layout/activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="16dp"
    tools:context=".MainActivity">

    <EditText
        android:id="@+id/cost_of_service"
        android:layout_width="160dp"
        android:layout_height="wrap_content"
        android:hint="@string/cost_of_service"
        android:inputType="numberDecimal"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <TextView
        android:id="@+id/service_question"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/how_was_the_service"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@id/cost_of_service" />

    <RadioGroup
        android:id="@+id/tip_options"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:checkedButton="@id/option_twenty_percent"
        android:orientation="vertical"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@id/service_question">

        <RadioButton
            android:id="@+id/option_twenty_percent"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/amazing_service" />

        <RadioButton
            android:id="@+id/option_eighteen_percent"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/good_service" />

        <RadioButton
            android:id="@+id/option_fifteen_percent"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/ok_service" />
    </RadioGroup>

    <Switch
        android:id="@+id/round_up_switch"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:checked="true"
        android:text="@string/round_up_tip"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="@id/tip_options"
        app:layout_constraintTop_toBottomOf="@id/tip_options" />

    <Button
        android:id="@+id/calculate_button"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:text="@string/calculate"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@id/round_up_switch" />

    <TextView
        android:id="@+id/tip_result"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/tip_amount"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toBottomOf="@id/calculate_button" />
</androidx.constraintlayout.widget.ConstraintLayout>

res/values/strings.xml

<resources>
   <string name="app_name">Tip Time</string>
   <string name="cost_of_service">Cost of Service</string>
   <string name="how_was_the_service">How was the service?</string>
   <string name="amazing_service">Amazing (20%)</string>
   <string name="good_service">Good (18%)</string>
   <string name="ok_service">Okay (15%)</string>
   <string name="round_up_tip">Round up tip?</string>
   <string name="calculate">Calculate</string>
   <string name="tip_amount">Tip Amount</string>
</resources>

9. Tóm tắt

  • XML (Ngôn ngữ đánh dấu mở rộng) là cách sử dụng thẻ, phần tử và thuộc tính để sắp xếp văn bản trong một tệp.
  • XML được dùng để định nghĩa bố cục cho ứng dụng Android.
  • EditText cho phép người dùng nhập hoặc chỉnh sửa văn bản.
  • EditText dùng để gợi ý người dùng về thông tin có thể nhập cho trường đó.
  • Chỉ định thuộc tính android:inputType để giới hạn loại văn bản người dùng có thể nhập vào trường EditText.
  • Tạo một danh sách các tuỳ chọn loại trừ với RadioButtons, gom nhóm với RadioGroup.
  • RadioGroup có thể bố trí theo chiều dọc hoặc chiều ngang và bạn có thể chỉ định RadioButton nào làm tuỳ chọn mặc định.
  • Sử dụng Switch để cho phép người dùng chuyển đổi giữa hai tuỳ chọn.
  • Bạn có thể thêm nhãn vào Switch mà không cần sử dụng TextView riêng.
  • Mỗi thành phần con của ConstraintLayout cần định nghĩa các điều kiện ràng buộc theo chiều dọc và chiều ngang.
  • Sử dụng các điều kiện ràng buộc "bắt đầu" và "kết thúc" để xử lý cả ngôn ngữ Trái sang Phải (LTR) và Phải sang Trái (RTL).
  • Tên của các thuộc tính ràng buộc tuân theo mẫu định dạng layout_constraint<Source>_to<Target>Of.
  • Để tạo một View rộng bằng thành phần mẹ ConstraintLayout, hãy thiết lập điều kiện ràng buộc điểm bắt đầu và kết thúc với điểm bắt đầu và kết thúc của thành phần mẹ, sau đó đặt chiều rộng thành 0dp.

10. Tìm hiểu thêm

Dưới đây là đường liên kết đến các tài liệu tham khảo thêm về những chủ đề đã đề cập. Bạn có thể tìm thấy tất cả tài liệu về Phát triển Android trên trang developer.android.com. Đừng quên rằng bạn có thể tìm kiếm thêm thông tin trên Google nếu gặp bất cứ sự cố gì.

11. Tự thực hành

Thực hiện những việc sau:

  • Tạo một ứng dụng tính toán khác, chẳng hạn như chương trình chuyển đổi đơn vị nấu ăn, để chuyển đổi mililit sang ounce chất lỏng, gam sang cốc và ngược lại, v.v. Bạn sẽ cần những trường thông tin nào?