Tạo ứng dụng Đổ xúc xắc có thể tương tác

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

Trong lớp học lập trình này, bạn sẽ tạo ứng dụng Android Đổ xúc xắc cho phép người dùng nhấp vào một Button trong ứng dụng để đổ một viên xúc xắc. Kết quả đổ xúc xắc sẽ xuất hiện trong một TextView trên màn hình.

Bạn sẽ sử dụng Layout Editor (Trình chỉnh sửa bố cục) trong Android Studio để xây dựng bố cục ứng dụng, sau đó viết mã Kotlin về những gì xảy ra khi bạn nhấp vào Button.

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

  • Nắm được cách tạo và chạy ứng dụng "Hello, World!" trong Android Studio.
  • Quen thuộc với việc dùng TextViews trong ứng dụng.
  • Nắm được cách chỉnh sửa các thuộc tính của TextView trong Layout Editor.
  • Nắm được cách trích xuất văn bản thành tài nguyên chuỗi để dễ dàng dịch ứng dụng và sử dụng lại chuỗi.
  • Kiến thức cơ bản về lập trình Kotlin

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

  • Cách thêm Button vào ứng dụng Android.
  • Cách thêm hành vi khi nhấn vào một Button trong ứng dụng.
  • Cách mở và chỉnh sửa mã Activity của ứng dụng.
  • Cách hiện thông báo Toast.
  • Cách cập nhật nội dung của TextView khi ứng dụng đang chạy.

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

  • Ứng dụng Android Đổ xúc xắc có một Button để đổ xúc xắc và cập nhật kết quả đổ xúc xắc dưới dạng văn bản trên màn hình.

Bạn cần có

  • Một máy tính đã cài đặt Android Studio.

Sau đây là giao diện của ứng dụng khi bạn hoàn thành lớp học lập trình này.

2e8416293e597725.png

2. Thiết lập ứng dụng

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

  1. Nếu bạn đã có sẵn một dự án trong Android Studio, hãy chuyển tới File > New > New Project... (Tệp > Mới > Dự án mới…) để mở màn hình Create New Project (Tạo dự án mới).
  2. Trong Create New Project (Tạo dự án mới), hãy tạo dự án Kotlin mới sử dụng mẫu Empty Activity (Hoạt động trống).
  3. Đặt tên ứng dụng là "Dice Roller", với cấp độ API tối thiểu là 19 (KitKat).

cd369d7a6bb01f97.png

  1. Chạy ứng dụng mới và ứng dụng sẽ có dạng như sau.

d9a6470c99790ef5.png

3. Tạo bố cục cho ứng dụng

Mở Layout Editor

  1. Trong cửa sổ Project (Dự án), hãy nhấp đúp vào activity_main.xml (app > res > layout > activity_main.xml ) để mở Layout Editor. Bạn sẽ thấy Layout Editor, chỉ cho thấy TextView "Hello World" ("Xin chào thế giới") ở giữa ứng dụng. f737b63b4f821f32.png

Tiếp theo, bạn sẽ thêm một Button vào ứng dụng. Button là một thành phần giao diện người dùng trong Android, cho phép người dùng nhấn vào để thực hiện một hành động.

5efd52b1ba8dd391.png

Trong nhiệm vụ này, bạn sẽ thêm Button ở bên dưới TextView "Hello World" ("Xin chào thế giới"). TextViewButton sẽ nằm trong ConstraintLayout, là một loại ViewGroup.

Khi có Views trong ViewGroup, thì Views này được xem là con của ViewGroup mẹ. Trong ứng dụng của bạn, TextViewButton sẽ được xem là con của ConstraintLayout mẹ.

624aeb04dbe9909d.png ea4be68b34500570.png

Thêm Button làm thành phần con của ConstraintLayout hiện có trong ứng dụng của bạn.

Thêm Nút vào bố cục

  1. Kéo một Button từ Palette (Bảng khung hiển thị) vào chế độ xem Design (Thiết kế), định vị bảng đó bên dưới TextView "Hello World" ("Xin chào thế giới").

b57f8297ec57f005.png

  1. Dưới Palette (Bảng khung hiển thị) trong ngăn Component Tree (Cây thành phần), hãy chắc chắn ButtonTextView được liệt kê dưới ConstraintLayout (là con của ConstraintLayout).
  2. Hãy lưu ý rằng sẽ có thông báo lỗi về việc Button chưa được ràng buộc. Vì Button nằm trong ConstraintLayout, bạn phải thiết lập các điều kiện ràng buộc theo chiều dọc và chiều ngang để định vị nút này.

b875e0147bf9e3f5.png

Định vị Nút

Trong bước này, bạn sẽ thêm một điều kiện ràng buộc theo chiều dọc, từ đỉnh của Button đến đáy của TextView. Thao tác này sẽ định vị Button bên dưới TextView.

  1. Trong chế độ xem Design (Thiết kế), ở cạnh trên cùng của Button, hãy nhấn và giữ vòng tròn màu trắng có đường viền màu xanh dương. Khi bạn kéo con trỏ, một mũi tên sẽ xuất hiện theo sau con trỏ. Nhả chuột ra khi kéo đến cạnh dưới của TextView "Hello World" ("Xin chào thế giới"). Thao tác này sẽ thiết lập một điều kiện ràng buộc về bố cục và Button sẽ trượt lên ngay bên dưới TextView.

a1973a29e117dd8f.gif

  1. Xem ngăn Attributes (Thuộc tính) ở bên phải Layout Editor.
  2. Trong Tiện ích điều kiện ràng buộc, hãy để ý một điều kiện ràng buộc mới về bố cục được đặt ở đáy của TextView, Đỉnh → Đáy của textView (0dp). (0dp) nghĩa là khoảng cách lề (margin) bằng 0. Bạn cũng gặp một lỗi thông báo về việc thiếu điều kiện ràng buộc theo chiều ngang.

88b750fbe0504d93.png

  1. Thêm một điều kiện ràng buộc theo chiều ngang từ phần bên trái của Button đến phần bên trái của ConstraintLayout mẹ.
  2. Làm tương tự cho phần bên phải, nối cạnh phải của Button với cạnh phải của ConstraintLayout. Kết quả sẽ có dạng như sau:

49de1c166b355ee1.png

  1. Khi Button vẫn đang được chọn, Constraint Widget (Tiện ích điều kiện ràng buộc) sẽ có dạng như sau. Hãy lưu ý rằng có hai điều kiện ràng buộc khác được thêm vào: Điểm đầu → Điểm đầu của mẹ (0dp)Điểm cuối → Điểm cuối của mẹ (0dp). Tức là Button được căn giữa theo chiều ngang trong thành phần mẹ ConstraintLayout.

dd1bac8adb275f79.png

  1. Chạy ứng dụng. Ứng dụng sẽ có dạng như ảnh chụp màn hình dưới đây. Bạn có thể nhấp vào Button, nhưng hiện chưa có gì xảy ra. Hãy cùng tiếp tục!

fbe13b0b8bf60aff.png

Thay đổi văn bản cho Nút

Bạn sẽ dùng Layout Editor để thực hiện một vài thay đổi nữa cho giao diện người dùng.

Thay vì sử dụng nhãn cho Button là "Button" ("Nút"), hãy đổi thành tên nhãn gợi nhớ thao tác mà nút này sẽ thực hiện: "Roll" ("Đổ xúc xắc").

  1. Trong Layout Editor, khi đã chọn Button, hãy chuyển đến ngăn Attributes (Thuộc tính), thay đổi trường text (văn bản) thành Roll (Đổ xúc xắc) rồi nhấn phím Enter (Return trên máy Mac).

9adeab9db109913e.png

  1. Trong ngăn Component Tree (Cây thành phần), một tam giác cảnh báo màu cam sẽ xuất hiện bên cạnh Button. Nếu bạn di con trỏ trên hình tam giác, một thông báo sẽ xuất hiện. Android Studio đã phát hiện một chuỗi bị cố định giá trị trong mã ("Roll") trong mã ứng dụng và đề xuất sử dụng tài nguyên chuỗi để thay thế.

Chuỗi bị cố định giá trị trong mã sẽ gây khó khăn cho việc dịch ứng dụng sang ngôn ngữ khác cũng như việc sử dụng lại chuỗi cho nhiều phần trong ứng dụng. Rất may là Android Studio có cơ chế giúp bạn tự động khắc phục vấn đề này.

6e9a5a173a49fc8b.png

  1. Trong ngăn Component Tree (Cây thành phần), hãy nhấp vào hình tam giác màu cam.

e4f601421031a5f3.png

Toàn bộ thông tin cảnh báo sẽ mở ra.

7206a03c9ba0d68d.png

  1. Ở cuối thông báo, hãy nhấp vào nút Fix (Khắc phục) bên dưới mục Suggested Fix (Cách khắc phục đề xuất). (Có thể bạn phải cuộn xuống.)
  2. Hộp thoại Extract Resource (Trích xuất tài nguyên) sẽ mở ra. Trích xuất một chuỗi có nghĩa là lấy phần văn bản "Roll" và tạo một tài nguyên chuỗi có tên là roll trong strings.xml (app > res > values > string.xml). Các giá trị mặc định đã đúng nên hãy nhấp vào OK.

78dc6e6f7abc1152.png

  1. Vui lòng lưu ý trong ngăn Attributes (Thuộc tính), thuộc tính văn bản của Button bây giờ thể hiện là @string/roll, đề cập đến tài nguyên bạn vừa tạo.

4fa3d5e4bce95d2.png

Trong chế độ xem Design (Thiết kế), phần văn bản của Button vẫn phải thể hiện là Roll.

5bdd2399b9664fca.png

Tạo kiểu cho TextView

Đoạn văn bản "Xin chào thế giới!" khá nhỏ và thông điệp này không phù hợp với ứng dụng của bạn. Trong bước này, bạn sẽ thay thế thông điệp "Xin chào thế giới!" bằng chữ số để cho thấy kết quả đổ xúc xắc, đồng thời tăng cỡ chữ để dễ nhìn hơn.

  1. Trong Design Editor (Trình chỉnh sửa thiết kế), hãy chọn TextView để các thuộc tính trong cửa sổ Attributes (Thuộc tính) hiện ra.
  2. Hãy thay đổi textSize của TextView thành 36sp để thể hiện văn bản lớn hơn và dễ đọc hơn. Có thể bạn phải cuộn xuống để tìm textSize.

ca5dbfd4f37a49e7.png

  1. Xoá thuộc tính text của TextView. Bạn không cần hiển thị gì trong TextView cho đến khi người dùng đổ xúc xắc.

da4031d0ef02f3c5.png

Tuy nhiên, việc hiện văn bản trong TextView sẽ giúp ích cho bạn khi chỉnh sửa bố cục và mã cho ứng dụng. Đối với mục đích này, bạn có thể thêm văn bản vào TextView và chỉ hiện văn bản này khi xem trước bố cục nhưng không hiện khi ứng dụng đang chạy.

  1. Chọn TextView trong cửa sổ Component Tree (Cây thành phần).
  2. Dưới phần Các thuộc tính phổ biến, hãy tìm thuộc tính văn bản và bên dưới thuộc tính đó là một thuộc tính văn bản khác đi kèm biểu tượng công cụ. Thuộc tính văn bản là giá trị mà người dùng sẽ nhìn thấy khi ứng dụng đang chạy. Thuộc tính text (văn bản) có biểu tượng công cụ là thuộc tính "văn bản công cụ" dành riêng cho nhà phát triển.
  3. Nhập "1" vào văn bản công cụ này trong TextView (để giả sử kết quả đổ xúc xắc của bạn là 1). Giá trị "1" sẽ chỉ xuất hiện trong Design Editor (Trình chỉnh sửa thiết kế) trong Android Studio, nhưng sẽ không xuất hiện khi bạn chạy ứng dụng trên một thiết bị hoặc trình mô phỏng thực tế.

eaf488ba04947f7f.png

Hãy lưu ý rằng chỉ có nhà phát triển ứng dụng mới xem được văn bản này nên bạn không cần tạo tài nguyên chuỗi tương ứng.

  1. Xem ứng dụng trong bản xem trước. Màn hình đang hiện "1".

bbfbfec435beb0cd.png

  1. Chạy ứng dụng. Đây là giao diện của ứng dụng khi chạy trên trình mô phỏng. "1" không xuất hiện. Đây là hành vi chính xác.

577368e5c11a4d6e.png

Thật tuyệt, bạn đã hoàn thành phần thay đổi bố cục!

Bạn đang có một ứng dụng cho thấy một nút, nhưng khi nhấn vào nút đó thì chưa có gì xảy ra. Để thay đổi tình trạng này, bạn cần phải viết một vài mã Kotlin để đổ xúc xắc và cập nhật màn hình khi nhấn vào nút này.

Để thực hiện thay đổi này, bạn cần tìm hiểu thêm một chút về cấu trúc của ứng dụng Android.

4. Giới thiệu về Hoạt động

Activity cung cấp cho bạn một cửa sổ để bạn vẽ giao diện người dùng trên đó. Thường thì Activity chiếm toàn bộ màn hình ứng dụng đang chạy. Mỗi ứng dụng lại có một hoặc nhiều hoạt động (activity). Hoạt động ở cấp cao nhất hay hoạt động đầu tiên thường được gọi là MainActivity và được cung cấp theo mẫu dự án. Ví dụ: khi người dùng cuộn qua danh sách ứng dụng trên thiết bị rồi nhấn vào biểu tượng ứng dụng "Dice Roller" (Đổ xúc xắc), hệ thống Android sẽ khởi động MainActivity của ứng dụng.

Trong mã MainActivity, bạn cần cung cấp thông tin chi tiết về bố cục của Activity cũng như cách thức người dùng sẽ tương tác với bố cục đó.

  • Ứng dụng Birthday Card (Thiệp sinh nhật) có một Activity dùng để thể hiện hình ảnh và lời chúc sinh nhật.
  • Ứng dụng Dice Roller (Đổ xúc xắc) có một Activity dùng để thể hiện bố cục TextViewButton bạn vừa tạo.

Với những ứng dụng phức tạp hơn, có thể sẽ có nhiều màn hình và nhiều hơn một Activity. Mỗi Activity có một mục đích cụ thể.

Ví dụ: trong ứng dụng thư viện ảnh, bạn có thể có một Activity dùng để thể hiện một lưới ảnh, Activity thứ hai dùng để xem từng ảnh riêng lẻ và Activity thứ ba dùng để chỉnh sửa từng ảnh.

97946b75b52c94b4.png

Mở tệp MainActivity.kt

Bạn sẽ thêm mã để phản hồi cho mỗi lần nhấn nút trong MainActivity. Để thực hiện chính xác, bạn cần hiểu rõ hơn về mã MainActivity đã có trong ứng dụng của mình.

  1. Chuyển đến vị trí sau rồi mở tệp MainActivity.kt (app > java > com.example.diceroller > MainActivity.kt). Bạn sẽ thấy nội dung như dưới đây. Nếu bạn nhìn thấy import..., hãy nhấp vào ... để mở rộng lệnh nhập.
package com.example.diceroller

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle

class MainActivity : AppCompatActivity() {

   override fun onCreate(savedInstanceState: Bundle?) {
       super.onCreate(savedInstanceState)
       setContentView(R.layout.activity_main)
   }
}

Bạn không cần hiểu rõ mọi từ trong mã trên, nhưng bạn cần nắm được khái niệm chung về chức năng của đoạn mã này. Càng tiếp xúc nhiều với mã Android, bạn sẽ càng quen thuộc và hiểu rõ hơn về những mã đó.

  1. Hãy xem mã Kotlin cho lớp (class) MainActivity, được xác định theo từ khoá class, sau đó là tên lớp.
class MainActivity : AppCompatActivity() {
    ...
}
  1. Lưu ý rằng lớp MainActivity không có hàm main().

Trước đó, bạn đã biết rằng mỗi chương trình Kotlin phải có một hàm main(). Ứng dụng Android hoạt động theo cách khác. Thay vì gọi hàm main(), hệ thống Android sẽ gọi phương thức onCreate() của MainActivity trong lần đầu mở ứng dụng.

  1. Tìm phương thức onCreate(), bạn sẽ thấy mã như dưới đây.
   override fun onCreate(savedInstanceState: Bundle?) {
       super.onCreate(savedInstanceState)
       setContentView(R.layout.activity_main)
   }

Bạn sẽ tìm hiểu về override trong một lớp học lập trình sau này (vì vậy, đừng lo lắng về override tại thời điểm này). Phần còn lại của phương thức onCreate() sẽ xây dựng lớp MainActivity bằng cách sử dụng mã trong lệnh nhập và thiết lập bố cục ban đầu bằng setContentView().

  1. Lưu ý các dòng lệnh bắt đầu bằng import.

Android cung cấp một khung gồm nhiều lớp (class) nhằm giúp bạn viết ứng dụng Android dễ dàng hơn. Tuy nhiên, bạn phải chỉ ra chính xác những lớp mà mình cần đến. Bạn có thể chỉ định một lớp nào đó trong nền tảng này để sử dụng trong mã bằng câu lệnh import. Ví dụ: lớp Button được định nghĩa trong android.widget.Button.

Bật tính năng tự động nhập

Việc thêm các câu lệnh import sẽ mất thêm nhiều thời gian khi bạn dùng thêm nhiều lớp. Rất may là Android Studio sẽ giúp bạn chọn chính xác lệnh nhập khi bạn dùng các lớp do người khác cung cấp. Ở bước này, bạn sẽ định cấu hình Android Studio để tự động thêm lệnh nhập khi có thể, đồng thời tự động xoá khỏi mã các lệnh nhập không dùng đến.

Trên macOS, hãy mở phần cài đặt bằng cách chuyển đến Tệp > Cài đặt dự án mới > Tuỳ chọn ưu tiên cho dự án mới… Mở rộng Other Settings > Auto Import (Chế độ cài đặt khác > Tự động nhập). Trong các phần JavaKotlin, hãy đánh dấu các tuỳ chọn Thêm nhanh các lệnh nhập rõ ràngTối ưu hoá nhanh các lệnh nhập (đối với dự án hiện tại). Lưu ý rằng có hai hộp đánh dấu trong mỗi phần. Lưu thay đổi rồi nhấn OK để đóng phần cài đặt.

1bedf6b103fd48c3.png

Trong Windows, hãy mở phần cài đặt bằng cách chuyển đến File > Settings > Editor > General > Auto Import (Tệp > Cài đặt > Trình chỉnh sửa > Chung > Tự động nhập). Trong các phần JavaKotlin, hãy đánh dấu các tuỳ chọn Thêm nhanh các lệnh nhập rõ ràngTối ưu hoá nhanh các lệnh nhập (đối với dự án hiện tại). Lưu ý rằng có hai hộp đánh dấu trong mỗi phần. Lưu thay đổi rồi nhấn OK để đóng phần cài đặt.

f1e7ad59d220294e.png

Chế độ cài đặt unambiguous imports (lệnh nhập rõ ràng) cho phép Android Studio tự động thêm lệnh nhập nếu có thể xác định được. Chế độ cài đặt optimize imports (tối ưu hoá lệnh nhập) cho phép Android Studio xoá tất cả lệnh nhập không còn dùng đến trong mã.

5. Tạo Nút (Button) tương tác

Giờ đây khi đã biết thêm một số thông tin về MainActivity, bạn sẽ chỉnh sửa ứng dụng để khi nhấp vào Button, ứng dụng sẽ thực hiện một hành động nào đó trên màn hình.

Hiện thông báo khi nhấp vào Nút (Button)

Ở bước này, bạn sẽ chỉ định rằng khi người dùng nhấp vào nút này, một thông báo ngắn sẽ xuất hiện ở cuối màn hình.

b6f4b2fa7f7434a4.png

  1. Thêm mã sau vào phương thức onCreate() sau lệnh gọi setContentView(). Phương thức findViewById() sẽ tìm Button trong bố cục. R.id.button là mã tài nguyên của Button. Đây là giá trị nhận dạng riêng biệt của nút lệnh này.
val rollButton: Button = findViewById(R.id.button)

Mã này lưu lại tham chiếu đến đối tượng Button trong biến rollButton, chứ không phải đối tượng Button.

Bây giờ, phương thức onCreate() sẽ có dạng như dưới đây:

override fun onCreate(savedInstanceState: Bundle?) {
   super.onCreate(savedInstanceState)
   setContentView(R.layout.activity_main)

   val rollButton: Button = findViewById(R.id.button)
}
  1. Kiểm tra xem Android Studio đã tự động thêm câu lệnh import cho Button hay chưa. Lưu ý rằng hiện tại có 3 lệnh nhập.
import android.os.Bundle
import android.widget.Button
import androidx.appcompat.app.AppCompatActivity

Tiếp theo, bạn cần liên kết mã với Button để mã này có thể thực thi khi nhấn vào Button. Trình nghe lượt nhấp (click listener) sẽ chứa một đoạn mã cho phép bạn thực hiện thao tác nhấn hoặc nhấp. Bạn có thể xem đây là đoạn mã chỉ dùng để "lắng nghe" người dùng nhấp vào một đối tượng nào đó, trong trường hợp này đối tượng đó là Button.

  1. Sử dụng đối tượng rollButton và thiết lập trình nghe lượt nhấp trên đối tượng này bằng cách gọi phương thức setOnClickListener(). Thay vì đặt dấu ngoặc đơn sau tên phương thức, bạn sẽ sử dụng dấu ngoặc nhọn. Đây là cú pháp đặc biệt để khai báo Lambda. Bạn sẽ tìm hiểu thêm về phần này trong một lớp học lập trình sau này.

Hiện tại, bạn chỉ cần biết là trong dấu ngoặc nhọn, bạn sẽ đưa ra hướng dẫn về những gì sẽ xảy ra khi nhấn nút. Bạn sẽ thấy ứng dụng thể hiện một thông báo ngắn (toast) như hướng dẫn trong bước tiếp theo.

rollButton.setOnClickListener {
}

Khi bạn gõ lệnh, Android Studio có thể cho thấy nhiều đề xuất. Trong trường hợp này, hãy chọn tuỳ chọn setOnClickListener {...}.

a3d45c0348b109d2.png

Trong dấu ngoặc nhọn, bạn sẽ đưa ra hướng dẫn về những gì sẽ xảy ra khi nhấn nút này. Bây giờ, ứng dụng của bạn sẽ cho thấy Toast. Đây là một thông báo ngắn gọn mà người dùng nhìn thấy.

  1. Tạo Toast với văn bản "Dice Rolled!" bằng cách gọi Toast.makeText().
val toast = Toast.makeText(this, "Dice Rolled!", Toast.LENGTH_SHORT)
  1. Sau đó, hãy yêu cầu Toast cho thấy chính nó bằng cách gọi phương thức show().
toast.show()

Sau đây là lớp MainActivity sau khi cập nhật; câu lệnh packageimport vẫn ở phần đầu tệp:

class MainActivity : AppCompatActivity() {

   override fun onCreate(savedInstanceState: Bundle?) {
       super.onCreate(savedInstanceState)
       setContentView(R.layout.activity_main)

       val rollButton: Button = findViewById(R.id.button)
       rollButton.setOnClickListener {
           val toast = Toast.makeText(this, "Dice Rolled!", Toast.LENGTH_SHORT)
           toast.show()
       }
   }
}

Bạn có thể gộp hai dòng lệnh trong trình nghe lượt nhấp thành một mà không cần có biến. Đây là một mẫu lập trình phổ biến bạn có thể tìm thấy trong mã khác.

Toast.makeText(this, "Dice Rolled!", Toast.LENGTH_SHORT).show()
  1. Chạy ứng dụng rồi nhấp vào nút Roll (Đổ xúc xắc). Một thông báo ngắn sẽ xuất hiện ở cuối màn hình và sẽ biến mất sau một khoảng thời gian ngắn.

fe4a03053b25cb7a.png

Thật tuyệt vời! Khi bạn nhấp vào nút lệnh thì thông báo xuất hiện! Đây là lần đầu tiên bạn viết mã Kotlin cho Android!

Cập nhật TextView khi nhấp vào Nút (Button)

Thay vì hiện thông báo Toast tạm thời, bạn sẽ viết mã để cập nhật TextView trên màn hình khi nhấp vào nút Roll.

  1. Trở lại tệp activity_main.xml (app > res > layout >activity_main.xml).
  2. Nhấp vào TextView.
  3. Lưu ý rằng id (mã nhận dạng) là textView.

dee0d8e4ef8ccf66.png

  1. Mở MainActivity.kt (app > java > com.example.diceroller > MainActivity.kt)
  2. Xoá các dòng lệnh tạo rồi cho thấy Toast.
rollButton.setOnClickListener {

}
  1. Tại đó, hãy tạo một biến mới có tên là resultTextView để lưu trữ TextView.
  2. Sử dụng findViewById() để tìm textView trong bố cục theo mã nhận dạng rồi lưu lại tham chiếu đến đối tượng này.
val resultTextView: TextView = findViewById(R.id.textView)
  1. Đặt văn bản trên resultTextView thành "6" trong dấu ngoặc kép.
resultTextView.text = "6"

Việc này tương tự như khi thiết lập thuộc tính văn bản () trong Thuộc tính, nhưng bây giờ bạn thực hiện trong mã, vì vậy phần văn bản cần phải nằm trong dấu ngoặc kép. Tạm thời, bạn đặt văn bản này với giá trị cố định, nghĩa là TextView sẽ luôn thể hiện là 6. Bạn sẽ bổ sung mã để đổ xúc xắc và cho thấy các giá trị khác trong nhiệm vụ tiếp theo.

Lớp MainActivity giờ đây có dạng như sau:

class MainActivity : AppCompatActivity() {

   override fun onCreate(savedInstanceState: Bundle?) {
       super.onCreate(savedInstanceState)
       setContentView(R.layout.activity_main)

       val rollButton: Button = findViewById(R.id.button)
       rollButton.setOnClickListener {
           val resultTextView: TextView = findViewById(R.id.textView)
           resultTextView.text = "6"
       }
   }
}
  1. Chạy ứng dụng. Nhấp vào nút. Thao tác này sẽ cập nhật TextView thành "6".

40a78aac9e1b5b20.png

6. Thêm logic đổ xúc xắc

Giờ đây, thứ duy nhất còn thiếu là phần đổ xúc xắc. Bạn có thể dùng lại lớp Dice trong lớp học lập trình trước để xử lý logic đổ xúc xắc.

Thêm lớp Dice

  1. Sau dấu ngoặc nhọn cuối cùng trong lớp (class) MainActivity, hãy tạo lớp Dice chứa phương thức roll().
class Dice(val numSides: Int) {

   fun roll(): Int {
       return (1..numSides).random()
   }
}
  1. Lưu ý rằng Android Studio có thể gạch chân numSides bằng một đường gợn sóng màu xám. (Có thể mất một lúc thì đường này mới xuất hiện.)
  2. Di con trỏ qua numSides và một cửa sổ sẽ bật lên với thông báo Property 'numSides' could be private ("numSides" có thể là thuộc tính riêng tư). 9516161d8578b240.png

Nếu chỉ định numSidesprivate thì bạn chỉ truy cập được thuộc tính này trong lớp Dice. Do chỉ có một đoạn mã duy nhất sử dụng thuộc tính numSides ở bên trong lớp Dice, nên bạn có thể chỉ định đối số này dưới dạng private cho lớp Dice. Bạn sẽ tìm hiểu thêm về biến privatepublic trong bài tiếp theo.

  1. Hãy tiếp tục và khắc phục theo đề xuất của Android Studio bằng cách nhấp vào Make 'numSides' 'private' (Chỉ định "numSides" là "riêng tư").

Tạo phương thức rollDice()

Giờ đây khi đã thêm lớp Dice vào ứng dụng, bạn sẽ cập nhật MainActivity để sử dụng lớp này. Để sắp xếp mã hợp lý hơn, hãy đặt toàn bộ phần logic đổ xúc xắc vào một hàm.

  1. Thay thế mã trong trình nghe lượt nhấp để thiết lập văn bản thành "6" bằng lệnh gọi đến phương thức rollDice().
rollButton.setOnClickListener {
   rollDice()
}
  1. rollDice() chưa được định nghĩa nên Android Studio sẽ gắn cờ thông báo lỗi và hiện rollDice() màu đỏ.
  2. Nếu bạn di con trỏ qua rollDice(), Android Studio sẽ hiển thị nội dung lỗi và một số giải pháp khả thi.

21ef4d7c6c33e154.png

  1. Nhấp vào More actions… (Hành động khác…) để mở ra một trình đơn. Android Studio hỗ trợ bạn trong nhiều việc!

16bb603205fc3d3.png

  1. Chọn Create function 'rollDice' (Tạo hàm "rollDice"). Android Studio sẽ tạo một định nghĩa trống (empty definition) cho hàm này bên trong MainActivity.
private fun rollDice() {
    TODO("Not yet implemented")
}

Tạo thực thể mới cho đối tượng Dice (Xúc xắc)

Ở bước này, bạn sẽ cập nhật mã để phương thức rollDice() tạo và đổ một viên xúc xắc, sau đó cho thấy kết quả trong TextView.

  1. Trong rollDice(), hãy xoá lệnh gọi TODO().
  2. Thêm mã để tạo một viên xúc xắc có 6 mặt.
val dice = Dice(6)
  1. Đổ viên xúc xắc này bằng cách gọi phương thức roll() rồi lưu kết quả vào một biến tên là diceRoll.
val diceRoll = dice.roll()
  1. Tìm TextView bằng cách gọi findViewById().
val resultTextView: TextView = findViewById(R.id.textView)

Biến diceRoll là một số, nhưng TextView lại sử dụng văn bản. Bạn có thể sử dụng phương thức toString() trên diceRoll để chuyển giá trị của biến diceRoll thành một chuỗi.

  1. Chuyển giá trị của diceRoll thành một chuỗi rồi sử dụng chuỗi này để cập nhật phần văn bản của resultTextView.
resultTextView.text = diceRoll.toString()

Phương thức rollDice() có dạng như sau:

private fun rollDice() {
    val dice = Dice(6)
    val diceRoll = dice.roll()
    val resultTextView: TextView = findViewById(R.id.textView)
    resultTextView.text = diceRoll.toString()
}
  1. Hãy chạy ứng dụng. Kết quả đổ xúc xắc sẽ thay đổi thành các giá trị khác ngoài 6! Vì kết quả đổ xúc xắc là một số ngẫu nhiên từ 1 đến 6 nên thỉnh thoảng giá trị 6 cũng có thể xuất hiện.

bbf0d6a6579100b9.png 276d8f65e4914c4c.png

Hoan hô! Bạn thật tuyệt vời!

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

Cũng dễ hiểu khi mã của bạn khá lộn xộn sau khi bạn chỉnh sửa rải rác vài nơi để ứng dụng có thể hoạt động được. Tuy nhiên, trước khi kết thúc, bạn nên thực hiện một số thao tác dọn dẹp đơn giản. Nhờ vậy, ứng dụng của bạn sẽ gọn gàng hơn và cũng dễ dàng hơn cho việc bảo trì sau này.

Đây là thói quen mà các nhà phát triển Android chuyên nghiệp vẫn hay làm khi viết mã.

Hướng dẫn về quy tắc lập trình Android

Khi làm việc theo nhóm, các thành viên trong nhóm nên viết mã theo cách tương tự nhau để đảm bảo tính nhất quán. Đó là lý do Android cho ra đời Hướng dẫn về quy tắc lập trình Android – bao gồm cả quy ước đặt tên, định dạng và các phương pháp hay khác. Hãy làm theo các nguyên tắc này khi viết mã Android: Hướng dẫn về quy tắc lập trình Kotlin cho nhà phát triển Android.

Dưới đây là một số cách giúp bạn tuân thủ các quy tắc lập trình này.

Dọn dẹp mã

Viết mã súc tích

Bạn có thể viết mã súc tích hơn bằng cách gộp mã thành những dòng lệnh ngắn hơn. Ví dụ: đây là mã thiết lập trình nghe lượt nhấp trên Button.

rollButton.setOnClickListener {
    rollDice()
}

Trong phần hướng dẫn cho trình nghe lượt nhấp chỉ có 1 dòng lệnh, bạn có thể gộp toàn bộ lệnh gọi phương thức rollDice() và dấu ngoặc nhọn vào một dòng. Đoạn mã này sẽ trở thành như sau. Chỉ còn một dòng thay vì ba dòng!

rollButton.setOnClickListener { rollDice() }

Định dạng lại mã

Bây giờ, bạn sẽ định dạng lại mã để đảm bảo tuân thủ quy ước định dạng mã được đề xuất cho Android.

  1. Trong lớp MainActivity.kt, hãy chọn tất cả văn bản trong tệp bằng phím tắt Control+A trên Windows (hoặc Command+A trên máy Mac). Hoặc bạn có thể chuyển đến trình đơn sau đây trong Android Studio Edit > Select All (Chỉnh sửa > Chọn tất cả).
  2. Sau khi chọn tất cả văn bản trong tệp, hãy chuyển đến trình đơn sau đây trong Android Studio Mã > Định dạng lại mã hoặc sử dụng phím tắt Ctrl+Alt+L (hoặc Command+Option+L trên máy Mac).

Thao tác này sẽ cập nhật định dạng mã của bạn, bao gồm cả khoảng trắng, căn lề, v.v. Có thể bạn sẽ không thấy gì thay đổi, như vậy thì thật tuyệt! Vậy tức là trước đó bạn đã định dạng đúng rồi!

Thêm chú thích cho mã

Bạn có thể thêm nhận xét vào mã để mô tả những gì đang xảy ra trong đoạn mã đó. Khi mã trở nên phức tạp hơn, bạn cần ghi chú lý do bạn viết mã theo cách đó. Sau này nếu quay lại chỉnh sửa, có thể bạn vẫn hiểu rõ tác động của mã nhưng lại không nhớ lý do khiến bạn lại viết như vậy.

Thường thì bạn nên thêm nhận xét cho từng lớp (ứng dụng của bạn chỉ có lớp MainActivityDice) và phương thức bạn viết trong ứng dụng. Sử dụng ký hiệu /***/ ở phần đầu và cuối của nhận xét để hệ thống nhận biết đây không phải là mã. Hệ thống sẽ bỏ qua các dòng này khi thực thi mã của bạn.

Ví dụ về chú thích trên một lớp:

/**
* This activity allows the user to roll a dice and view the result
* on the screen.
*/
class MainActivity : AppCompatActivity() {

Ví dụ về chú thích trên một phương thức:

/**
* Roll the dice and update the screen with the result.
*/
private fun rollDice() {

Trong một phương thức, bạn có thể thoải mái thêm chú thích nếu việc đó giúp ích cho người đọc mã. Hãy nhớ rằng bạn có thể dùng ký hiệu // ở phần đầu mỗi nhận xét. Những gì được viết trên cùng một dòng và sau ký hiệu // này đều được xem là một chú thích.

Ví dụ về 2 chú thích bên trong một phương thức:

private fun rollDice() {
   // Create new Dice object with 6 sides and roll it
   val dice = Dice(6)
   val diceRoll = dice.roll()

   // Update the screen with the dice roll
   val resultTextView: TextView = findViewById(R.id.textView)
   resultTextView.text = diceRoll.toString()
}
  1. Hãy tiếp tục và dành chút thời gian để thêm chú thích vào mã của bạn.
  2. Sau khi cập nhật toàn bộ những thay đổi về định dạng và chú thích ở trên, bạn nên chạy lại ứng dụng để đảm bảo ứng dụng vẫn hoạt động như dự kiến.

Bạn có thể xem mã giải pháp để tham khảo một cách nhận xét về mã.

8. Mã giải pháp

Mã giải pháp cho lớp học lập trình này nằm trong dự án và mô-đun dưới đây.

Để lấy mã cho lớp học lập trình này và mở trong Android Studio, hãy thực hiện các bước sau.

Lấy mã

  1. Nhấp vào URL được cung cấp. Thao tác này sẽ mở trang GitHub của dự án trong một trình duyệt.
  2. Kiểm tra để đảm bảo tên nhánh khớp với tên nhánh được chỉ định trong lớp học lập trình. Ví dụ: trong ảnh chụp màn hình sau đây, tên nhánh là main (chính).

8cf29fa81a862adb.png

  1. Trên trang GitHub cho dự án này, hãy nhấp vào nút Code (Mã), một cửa sổ bật lên sẽ hiện ra.

1debcf330fd04c7b.png

  1. Trong cửa sổ bật lên, nhấp vào nút Download ZIP (Tải tệp ZIP xuống) để lưu dự án vào máy tính. Chờ quá trình tải xuống hoàn tất.
  2. Xác định vị trí của tệp trên máy tính (thường nằm trong thư mục Downloads (Tệp đã tải xuống)).
  3. Nhấp đúp vào tệp ZIP để giải nén. Thao tác này sẽ tạo một thư mục mới chứa các tệp dự án.

Mở dự án trong Android Studio

  1. Khởi động Android Studio.
  2. Trong cửa sổ Welcome to Android Studio (Chào mừng bạn đến với Android Studio), hãy nhấp vào Open (Mở).

d8e9dbdeafe9038a.png

Lưu ý: Nếu Android Studio đã mở thì chuyển sang chọn tuỳ chọn File (Tệp) > Open (Mở) trong trình đơn.

8d1fda7396afe8e5.png

  1. Trong trình duyệt tệp, hãy chuyển đến vị trí của thư mục dự án chưa giải nén (thường nằm trong thư mục Downloads (Tệp đã tải xuống)).
  2. Nhấp đúp vào thư mục dự án đó.
  3. Chờ Android Studio mở dự án.
  4. Nhấp vào nút Run (Chạy) 8de56cba7583251f.png để tạo bản dựng và chạy ứng dụng. Đảm bảo ứng dụng được xây dựng như mong đợi.

9. Tóm tắt

  • Thêm một Button vào ứng dụng Android sử dụng Layout Editor.
  • Chỉnh sửa lớp MainActivity.kt để thêm hành vi tương tác cho ứng dụng.
  • Bật cửa sổ thông báo lên Toast như một giải pháp tạm thời để xác minh bạn đang đi đúng hướng.
  • Thiết lập trình nghe lượt nhấp cho Button sử dụng phương thức setOnClickListener() để thêm hành vi khi người dùng nhấp vào Button.
  • Khi ứng dụng đang chạy, bạn có thể cập nhật màn hình bằng cách gọi các phương thức trên TextView, Button hoặc thành phần giao diện người dùng khác trong bố cục.
  • Chú thích mã để giúp những người khác hiểu được phương pháp tiếp cận của bạn khi đọc mã.
  • Định dạng lại và dọn dẹp mã.

10. Tìm hiểu thêm

11. Tự thực hành

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

  1. Thêm một viên xúc xắc khác vào ứng dụng. Nhấp vào nút Roll (Đổ xúc xắc) để tung 2 viên xúc xắc. Kết quả sẽ hiện ra ở 2 TextViews riêng biệt trên màn hình.

Kiểm tra thành phẩm của bạn:

Sau khi hoàn thiện, ứng dụng của bạn phải không gặp lỗi nào khi chạy và cho thấy hai viên xúc xắc trong ứng dụng.