Tạo ứng dụng đơn giản với thành phần kết hợp văn bản

Sử dụng bộ sưu tập để sắp xếp ngăn nắp các trang Lưu và phân loại nội dung dựa trên lựa chọn ưu tiên của bạn.

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

Trong lớp học lập trình này, bạn sẽ sử dụng Jetpack Compose để tạo một ứng dụng Android đơn giản nhằm hiển thị lời chúc mừng sinh nhật trên màn hình.

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

  • Biết cách tạo ứng dụng trong Android Studio.
  • Biết cách chạy ứng dụng trên trình mô phỏng hoặc thiết bị Android.

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

  • Cách viết các hàm có khả năng kết hợp, chẳng hạn như các hàm Text, ColumnRow.
  • Cách hiển thị văn bản trong ứng dụng.
  • Cách định dạng văn bản, chẳng hạn như thay đổi kích thước văn bản và cỡ chữ.

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

  • Ứng dụng Android hiển thị lời chào sinh nhật ở định dạng văn bản. Bên dưới là ảnh chụp màn hình ứng dụng sau khi hoàn tất:

1969df37dc980e41.png

Bạn cần có

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

2. Xem video tập lập trình (Không bắt buộc)

Nếu bạn muốn xem một trong những người hướng dẫn của khoá học hoàn thành lớp học lập trình, hãy phát video bên dưới.

Bạn nên mở rộng video ra toàn màn hình (bằng biểu tượng Biểu tượng này hiển thị 4 góc trên một hình vuông được làm nổi bật để biểu thị chế độ toàn màn hình. ở góc dưới bên phải của video). Nhờ đó, bạn có thể thấy rõ các đoạn mã và Android Studio hơn.

Bước này là bước không bắt buộc. Bạn cũng có thể bỏ qua video này và bắt đầu tham gia lớp học lập trình ngay.

3. Thiết lập ứng dụng Happy Birthday (Chúc mừng sinh nhật)

Trong nhiệm vụ này, bạn sẽ thiết lập một dự án trong Android Studio thông qua mẫu Empty Compose Activity (Hoạt động Compose trống) và thay đổi thông điệp văn bản thành lời chào sinh nhật được cá nhân hóa.

Tạo dự án Empty Compose Activity

  1. Trong hộp thoại Welcome to Android Studio (Chào mừng bạn đến với Android Studio), hãy chọn New Project (Dự án mới).
  2. Trong hộp thoại New Project (Dự án mới), hãy chọn Empty Compose Activity (Hoạt động Compose trống) rồi nhấp vào Next (Tiếp theo).
  3. Nhập Happy Birthday trong trường Name (Tên), sau đó chọn mức API tối thiểu là 21 (Lollipop) trong trường Minimum SDK (SDK tối thiểu) và nhấp vào Finish (Hoàn tất).

86730c24681dd2fe.png

  1. Chờ Android Studio tạo các tệp dự án và xây dựng dự án.
  2. Nhấp vào fd26b2e3c2870c3.png Run ‘app' (Chạy "ứng dụng").

Ứng dụng sẽ có dạng như ảnh chụp màn hình sau:

282f9427f60fcc5f.png

Khi tạo ứng dụng Happy Birthday này bằng mẫu Empty Compose Activity, Android Studio sẽ thiết lập tài nguyên cho ứng dụng Android cơ bản, bao gồm thông báo Hello Android! (Xin chào Android!) trên màn hình. Trong lớp học lập trình này, bạn tìm hiểu cách hiển thị thông báo này, cách thay đổi văn bản thành lời chào sinh nhật, cũng như cách thêm và định dạng các thông báo bổ sung.

Giao diện người dùng (UI) là gì?

Giao diện người dùng (UI) của một ứng dụng là những gì bạn nhìn thấy trên màn hình: văn bản, hình ảnh, nút lệnh cũng như nhiều thành phần khác và bố cục hiển thị của các thành phần này. Đó là cách ứng dụng hiển thị nội dung cho người dùng và cách người dùng tương tác với ứng dụng.

Hình ảnh này chứa nút có khả năng nhấp (clickable button), thông điệp văn bản và trường nhập dữ liệu văn bản để người dùng có thể nhập dữ liệu.

e5abb8ad9f9ae2a7.png

Nút có khả năng nhấp

fded30871a8e0eca.png

Thông điệp văn bản

aafb9c476f72d558.png

Trường nhập dữ liệu văn bản

Mỗi phần tử trong số này được gọi là một thành phần giao diện người dùng. Hầu hết những gì bạn thấy trên màn hình của ứng dụng đều là thành phần trên giao diện người dùng (còn được gọi là thành phần giao diện người dùng). Đây là những thành phần có khả năng tương tác, như nút lệnh có khả năng nhấp hoặc trường nhập thông tin có thể chỉnh sửa, hoặc có thể là hình ảnh dùng để trang trí.

Trong lớp học lập trình này, bạn sẽ làm việc với một thành phần giao diện người dùng để hiển thị văn bản có tên là "thành phần Text".

4. Jetpack Compose là gì?

Jetpack Compose là một bộ công cụ hiện đại giúp xây dựng giao diện người dùng cho Android. Compose giúp đơn giản hóa và tăng tốc quá trình phát triển giao diện người dùng trên Android nhờ dùng ít mã hơn, các công cụ mạnh mẽ và khả năng triển khai trực quan. Với Compose, bạn có thể xây dựng giao diện người dùng bằng cách định nghĩa tập hợp các hàm, gọi là hàm có khả năng kết hợp (composable functions), cho phép lấy dữ liệu và chuyển phát (emit) các thành phần giao diện người dùng.

Hàm có khả năng kết hợp

Các hàm có khả năng kết hợp là thành phần xây dựng giao diện người dùng cơ bản trong Compose. Hàm có khả năng kết hợp:

  • Mô tả một số thành phần trên giao diện người dùng.
  • Không trả về giá trị.
  • Lấy giá trị đầu vào và tạo nội dung hiển thị trên màn hình.
  • Có thể chuyển phát một số thành phần giao diện người dùng.

Chú thích (Annotations)

Chú thích là phương tiện để thêm thông tin bổ sung vào mã. Thông tin này giúp các công cụ như trình biên dịch Jetpack Compose và các nhà phát triển khác hiểu được mã của ứng dụng.

Bạn có thể áp dụng chú thích bằng cách thêm tiền tố chú thích chứa ký tự @ ở đầu phần khai báo. Bạn có thể chú thích các thành phần mã khác nhau, bao gồm thuộc tính, hàm và lớp. Trong phần sau của khoá học, bạn sẽ tìm hiểu thêm về lớp.

Biểu đồ dưới đây là một ví dụ về hàm có chú giải:

ký tự tiền tố là @, chú giải là thành phần kết hợp, theo sau là phần khai báo hàm

Đoạn mã sau đây cung cấp các ví dụ về thuộc tính có chú giải. Bạn sẽ dùng tính năng này trong các lớp học lập trình sắp tới.

// Example code, do not copy it over

@Json
val imgSrcUrl: String

@Volatile
private var INSTANCE: AppDatabase? = null

Chú thích chứa tham số

Chú thích có thể chứa các tham số. Các tham số sẽ cung cấp thêm thông tin cho các công cụ trong quá trình xử lý. Sau đây là một số ví dụ về chú thích @Preview chứa và không chứa tham số.

15169d39d744c179.png

Chú thích không chứa tham số

992de02d7b5dbfda.png

Chú thích xem trước phần nền

fbc159107d248a84.png

Chú thích chứa tiêu đề xem trước

Bạn có thể truyền nhiều tham số vào chú thích, như được hiển thị dưới đây.

510f8443a174f972.png

Chú thích chứa tiêu đề xem trước và giao diện người dùng hệ thống (màn hình điện thoại)

Jetpack Compose sử dụng nhiều chú thích được tích hợp sẵn. Đến thời điểm này, bạn đã xem qua các chú thích @Composable@Preview trong khoá học này. Bạn sẽ tìm hiểu thêm về chú thích và cách sử dụng trong phần sau của khoá học.

Ví dụ về hàm có khả năng kết hợp

Bạn có thể chú thích cho hàm có khả năng kết hợp bằng cách sử dụng chú thích @Composable. Tất cả hàm có khả năng kết hợp phải dùng chú thích này. Chú thích này sẽ thông báo cho trình biên dịch Compose biết rằng hàm này sẽ giúp chuyển đổi dữ liệu thành giao diện người dùng. Lưu ý rằng trình biên dịch là một chương trình đặc biệt có chức năng lấy mã bạn viết, duyệt mã theo từng dòng rồi dịch mã này dưới dạng thông tin mà máy tính có thể hiểu được (ngôn ngữ máy).

Đoạn mã này là một ví dụ về một hàm có khả năng kết hợp đơn giản dùng để truyền dữ liệu (là tham số name) và sử dụng đoạn mã này để hiển thị thành phần văn bản trên màn hình.

@Composable
fun Greeting(name: String) {
   Text(text = "Hello $name!")
}

Một số lưu ý về hàm có khả năng kết hợp:

  • Các hàm có khả năng kết hợp có thể chấp nhận các tham số, cho phép triển khai logic ứng dụng để mô tả hoặc chỉnh sửa giao diện người dùng. Trong trường hợp này, thành phần giao diện người dùng sẽ chấp nhận một String để có thể kèm tên người dùng trong lời chào.
  • Hàm này không trả về bất kỳ giá trị nào. Hàm có khả năng kết hợp sẽ chuyển phát giao diện người dùng và không trả về bất kỳ giá trị nào vì hàm này được dùng để mô tả trạng thái màn hình mong muốn thay vì xây dựng các thành phần giao diện người dùng. Nói cách khác, hàm có khả năng kết hợp chỉ mô tả giao diện người dùng chứ không tạo hoặc xây dựng giao diện người dùng. Do đó hàm này sẽ không trả về bất cứ giá trị nào.

Lưu ý về hàm có khả năng kết hợp trong mã

  1. Trong Android Studio, mở tệp MainActivity.kt.
  2. Cuộn đến DefaultPreview() và xóa hàm này đi. Thêm một hàm có khả năng kết hợp mới có tên là BirthdayCardPreview() để xem trước hàm Greeting(), như thể hiện bên dưới. Bạn có thể áp dụng một phương pháp hay khi đặt tên hoặc đổi tên hàm là luôn dùng tên hàm mang tính gợi tả về chức năng hoạt động của hàm đó.
@Preview(showBackground = true)
@Composable
fun BirthdayCardPreview() {
   HappyBirthdayTheme {
       Greeting("Android")
   }
}

Hàm có khả năng kết hợp có thể gọi đến các hàm có khả năng kết hợp khác. Trong đoạn mã này, hàm xem trước đang gọi đến hàm có khả năng kết hợp Greeting().

Lưu ý rằng hàm trước đó cũng có một chú thích khác, chú thích @Preview, có chứa một tham số đặt trước chú thích @Composable. Bạn có thể tìm hiểu thêm về các đối số được truyền đến chú thích @Preview trong phần sau của khóa học này.

Tên hàm có khả năng kết hợp

Hàm có khả năng kết hợp không trả về giá trị nào và PHẢI đặt tên chú thích @Composable theo kiểu viết hoa pascal. Kiểu viết hoa pascal là một quy ước đặt tên, trong đó chữ cái đầu của mỗi từ trong từ ghép phải được viết hoa. Sự khác biệt giữa kiểu viết hoa pascal và kiểu viết hoa camel là tất cả từ trong kiểu pascal đều phải viết hoa chữ cái đầu tiên. Với kiểu viết hoa camel, từ đầu tiên không được viết hoa.

Hàm có khả năng kết hợp:

  • PHẢI là danh từ: DoneButton()
  • KHÔNG phải động từ hoặc cụm động từ: DrawTextField()
  • KHÔNG phải là giới từ theo sau danh từ: TextFieldWithLink()
  • KHÔNG phải là tính từ: Bright()
  • KHÔNG phải là trạng từ: Outside()
  • Danh từ CÓ THỂ đứng trước tính từ mô tả: RoundIcon()

Nguyên tắc này được áp dụng dù hàm có chuyển phát thành phần giao diện người dùng hay không. Để tìm hiểu thêm, hãy xem Đặt tên hàm có khả năng kết hợp.

Mã ví dụ Đừng sao chép

// Do: This function is a descriptive PascalCased noun as a visual UI element
@Composable
fun FancyButton(text: String) {

// Do: This function is a descriptive PascalCased noun as a non-visual element
// with presence in the composition
@Composable
fun BackButtonHandler() {

// Don't: This function is a noun but is not PascalCased!
@Composable
fun fancyButton(text: String) {

// Don't: This function is PascalCased but is not a noun!
@Composable
fun RenderFancyButton(text: String) {

// Don't: This function is neither PascalCased nor a noun!
@Composable
fun drawProfileImage(image: ImageAsset) {

5. Ngăn Design (Thiết kế) trên Android Studio

Android Studio cho phép bạn xem trước các hàm có khả năng kết hợp trong IDE thay vì cài đặt ứng dụng trên một thiết bị Android hoặc trình mô phỏng. Như đã tìm hiểu trong lộ trình trước đó, bạn có thể xem trước giao diện của ứng dụng trong ngăn Design (Thiết kế) trên Android Studio.

c284448a820d577c.png

Hàm có khả năng kết hợp phải cung cấp giá trị mặc định của tất cả tham số để có thể xem trước hàm đó. Vì lý do này, bạn không thể trực tiếp xem trước hàm Greeting(). Thay vào đó, trong trường hợp này, bạn cần thêm một hàm BirthdayCardPreview() khác. Hàm này sẽ gọi hàm Greeting() với một tham số phù hợp.

@Preview(showBackground = true)
@Composable
fun BirthdayCardPreview() {
   HappyBirthdayTheme {
       Greeting("Android")
   }
}

Bạn sẽ tìm hiểu về tham số showBackground trong chú thích @Preview ở các lớp học lập trình sau này.

Cách xem bản xem trước:

  1. Tạo mã của bạn.

Bản xem trước sẽ tự động cập nhật.

Một cách khác để cập nhật hoặc làm mới bản xem trước là nhấp vào fdd133641cfac2b3.png Build & Refresh (Tạo và làm mới) trong ngăn Design (Thiết kế).

5cec5263ba04ea1.png

  1. Trong hàm BirthdayCardPreview(), thay đổi đối số ""Android" trong hàm Greeting() thành tên của bạn.
fun BirthdayCardPreview() {
   HappyBirthdayTheme {
       Greeting("James")
   }
}
  1. Nhấp vào fdd133641cfac2b3.png Build & Refresh (Tạo và làm mới) trong ngăn Design (Thiết kế).

Bạn sẽ thấy bản xem trước được cập nhật.

4c1634ec586ca3ba.png

6. Thêm một thành phần văn bản mới

Trong nhiệm vụ này, bạn xóa lời chào Hello Android! và thêm lời chúc mừng sinh nhật.

Thêm hàm có khả năng kết hợp mới

  1. Trong tệp MainActivity.kt, hãy xóa phần định nghĩa hàm Greeting(). Bạn sẽ thêm hàm của riêng mình để hiển thị lời chúc trong lớp học lập trình sau này.
@Composable
fun Greeting(name: String) {
   Text(text = "Hello $name!")
}
  1. Lưu ý rằng Android Studio sẽ làm nổi bật lệnh gọi hàm Greeting() và sau đó di chuột qua lệnh gọi hàm này để nhận diện lỗi.

Hàm Greetings được làm nổi bật và có một cửa sổ hiển thị lỗi chưa giải quyết bật lên

  1. Xóa lệnh gọi hàm Greeting() cùng các đối số của hàm này từ các hàm onCreate()BirthdayCardPreview(). Tệp MainActivity.kt của bạn sẽ giống như sau:
class MainActivity : ComponentActivity() {
   override fun onCreate(savedInstanceState: Bundle?) {
       super.onCreate(savedInstanceState)
       setContent {
           HappyBirthdayTheme {
               // A surface container using the 'background' color from the theme
               Surface(color = MaterialTheme.colors.background) {
               }
           }
       }
   }
}

@Preview(showBackground = true)
@Composable
fun BirthdayCardPreview(){
   HappyBirthdayTheme {
   }
}
  1. Trước hàm BirthdayCardPreview(), thêm một hàm mới tên là BirthdayGreetingWithText(). Đừng quên thêm chú thích @Composable trước hàm này vì đây là một hàm có khả năng kết hợp dùng để chuyển phát một thành phần kết hợp Text.
@Composable
fun BirthdayGreetingWithText() {
}
  1. Thêm tham số message có kiểu String vào hàm có khả năng kết hợp BirthdayGreetingWithText().
@Composable
fun BirthdayGreetingWithText(message: String) {
}
  1. Trong hàm BirthdayGreetingWithText(), thêm một thành phần kết hợp Text(), truyền vào một thông điệp văn bản dưới dạng đối số được đặt tên.
@Composable
fun BirthdayGreetingWithText(message: String) {
    Text(
       text = message
    )
}

Hàm BirthdayGreetingWithText() này sẽ hiển thị văn bản trên giao diện người dùng. Để thực hiện điều đó, hàm này sẽ gọi đến hàm có khả năng kết hợp Text().

Xem trước hàm

Trong nhiệm vụ này, bạn sẽ xem trước hàm BirthdayGreetingWithText() trong ngăn Design (Thiết kế).

  1. Gọi hàm BirthdayGreetingWithText() bên trong hàm BirthdayCardPreview().
  2. Truyền một đối số String đến hàm BirthdayGreetingWithText(). Đây là một lời chào sinh nhật gửi đến bạn bè của bạn. Bạn có thể chỉnh lại lời chào theo tên bạn bè của bạn nếu muốn, chẳng hạn như "Happy Birthday Sam!".
@Preview(showBackground = false)
@Composable
fun BirthdayCardPreview() {
   HappyBirthdayTheme {
       BirthdayGreetingWithText( "Happy Birthday Sam!")
   }
}
  1. Trong ngăn Design (Thiết kế), hãy nhấp vào ea3433426a37f49b.png Build & Refresh (Tạo và làm mới) rồi chờ quá trình tạo hoàn tất để xem trước hàm này.

83a0e12c201f5b89.png

7. Thay đổi cỡ chữ

Bạn đã thêm văn bản vào giao diện người dùng, nhưng văn bản này có vẻ chưa giống hoàn toàn với ứng dụng cuối cùng. Trong nhiệm vụ này, bạn tìm hiểu cách thay đổi kích thước, màu sắc văn bản và các thuộc tính khác ảnh hưởng đến hình thức hiển thị của thành phần văn bản. Bạn có thể thử nghiệm các màu sắc và kích thước phông chữ khác nhau.

Pixel có khả năng mở rộng

Các pixel có khả năng mở rộng (SP) là một đơn vị đo kích thước phông chữ. Các thành phần trên giao diện người dùng trong ứng dụng Android sử dụng hai đơn vị đo lường khác nhau: pixel không phụ thuộc vào mật độ (DP), bạn sẽ dùng sau này cho phần bố cục, và pixel có khả năng mở rộng (SP). Theo mặc định, đơn vị SP có cùng kích thước với đơn vị DP, nhưng đơn vị này đổi kích thước dựa trên kích thước văn bản yêu thích của người dùng trong phần cài đặt của điện thoại.

  1. Trong tệp MainActivity.kt, di chuyển đến thành phần kết hợp Text() trong hàm BirthdayGreetingWithText().
  2. Truyền vào hàm Text() một đối số fontSize làm đối số được đặt tên thứ hai và thiết lập giá trị cho đối số đó thành 36.sp .
Text(
   text = message,
   fontSize = 36.sp
)

Android Studio sẽ làm nổi bật mã .sp vì bạn cần nhập một số lớp hoặc thuộc tính để biên dịch ứng dụng.

6b6e60b13e085a13.png

  1. Nhấp vào mã .sp được Android Studio làm nổi bật ở trên.
  2. Nhấp vào Import (Nhập) trong cửa sổ bật lên để nhập androidx.compose.ui.unit.sp để có thể sử dụng thuộc tính tiện ích .sp.

mã sp có cửa sổ bật lên, cho biết thao tác nhập tham chiếu chưa được xử lý.

  1. Di chuyển lên đầu tệp và chú ý các câu lệnh import, trong đó bạn sẽ thấy câu lệnh import androidx.compose.ui.unit.sp. Điều này có nghĩa là Android Studio đã thêm gói này vào tệp.

1631e626a2c9e1b8.png

  1. Nhấp vào Build & Refresh (Tạo và làm mới) trong ngăn Design (Thiết kế) để xem bản xem trước được cập nhật. Lưu ý phần thay đổi kích thước phông chữ trong bản xem trước của lời chúc mừng sinh nhật.

Hiển thị tuỳ chọn Build and refresh (Tạo và làm mới)

Bây giờ, bạn có thể thử nghiệm với các kích thước phông chữ khác nhau.

8. Thêm một thành phần văn bản khác

Trong các nhiệm vụ trước, bạn đã thêm thông điệp chúc mừng sinh nhật cho bạn bè của mình. Trong nhiệm vụ này, bạn sẽ ký tên mình vào thiệp sinh nhật.

  1. Trong tệp MainActivity.kt, di chuyển đến hàm BirthdayGreetingWithText().
  2. Truyền vào hàm này tham số from có kiểu String cho phần chữ ký của bạn.
fun BirthdayGreetingWithText(message: String, from: String)
  1. Sau thành phần kết hợp Text dành cho thông điệp sinh nhật, thêm một thành phần kết hợp Text khác chấp nhận đối số text và sau đó thiết lập giá trị đối số này thành from.
Text(
   text = from
)
  1. Thêm đối số có tên fontSize và đặt giá trị là 24.sp.
Text(
   text = from,
   fontSize = 24.sp
)
  1. Di chuyển đến hàm BirthdayCardPreview().
  2. Thêm một đối số String khác dùng để ký thiệp sinh nhật, chẳng hạn như "- from Emma".
BirthdayGreetingWithText( "Happy Birthday Sam!", "- from Emma")
  1. Nhấp vào Build & Refresh (Tạo và làm mới) trong ngăn Design (Thiết kế).
  2. Quan sát bản xem trước này.

44b80197db62db54.png

Một hàm có khả năng kết hợp có thể chuyển phát nhiều thành phần giao diện người dùng. Tuy nhiên, nếu bạn không cung cấp hướng dẫn về cách sắp xếp chúng, thì tính năng Soạn thư có thể sắp xếp các phần tử theo cách bạn không muốn. Ví dụ: mã trước tạo ra hai phần tử văn bản chồng chéo nhau vì chưa có hướng dẫn về cách sắp xếp hai thành phần kết hợp này.

Trong nhiệm vụ tiếp theo, bạn sẽ tìm hiểu cách sắp xếp các thành phần kết hợp trong một hàng và trong một cột.

9. Sắp xếp các thành phần văn bản trong một hàng và cột

Hệ phân cấp giao diện người dùng

Hệ phân cấp giao diện người dùng dựa trên vùng chứa, có nghĩa là một thành phần có thể chứa một hoặc nhiều thành phần khác, theo đó thỉnh thoảng bạn sẽ thấy xuất hiện các thuật ngữ như thành phần mẹ (parent) và con (child). Ngữ cảnh đề cập ở đây là các thành phần giao diện người dùng mẹ chứa các thành phần giao diện người dùng con. Đến lượt mình, các thành phần con này có thể chứa các thành phần giao diện người dùng con khác. Trong phần này, bạn sẽ tìm hiểu về các thành phần kết hợp Column (Cột), Row (Hàng) và Box (Hộp). Các thành phần này có thể hoạt động như các thành phần giao diện người dùng mẹ.

9270b7e10f954dcb.png

Ba thành phần bố cục chuẩn cơ bản trong Compose là các thành phần kết hợp Column, RowBox. Bạn có thể tìm hiểu thêm về thành phần kết hợp Box trong lớp học lập trình tiếp theo.

cột hiển thị ba thành phần được sắp xếp theo chiều dọc và hàng hiển thị 3 thành phần được sắp xếp theo chiều ngang

Column, RowBox là các hàm có khả năng kết hợp. Những hàm này sẽ nhận các nội dung có thể kết hợp làm đối số, vì vậy, bạn có thể đặt các thành phần bên trong các thành phần bố cục này. Ví dụ: mỗi thành phần con bên trong một thành phần kết hợp Row có thể đặt ngang hàng với nhau.

// Don't copy.
Row {
    Text("First column")
    Text("Second column")
}

Các thành phần văn bản này hiển thị bên cạnh nhau trên màn hình như thể hiện trong hình bên dưới.

Đường viền màu xanh dương chỉ nhằm mục đích minh họa và không hiển thị.

20c50a01cc9aa4cb.png

Cú pháp trailing lambda

Hãy lưu ý rằng trong đoạn mã trước đó, dấu ngoặc nhọn được dùng thay cho dấu ngoặc đơn trong hàm có khả năng kết hợp Row. Hành động này được gọi là Cú pháp Trailing Lambda. Bạn có thể tìm hiểu chi tiết về lambdas và cú pháp lambda ở phần sau trong khóa học này. Bây giờ, hãy làm quen với cú pháp Compose thường dùng.

Kotlin cung cấp một cú pháp đặc biệt để truyền các hàm đến các hàm khác dưới dạng tham số, trong đó tham số cuối cùng sẽ là một hàm.

6373d65802273065.png

Nếu muốn truyền một hàm dưới dạng tham số như vậy, bạn có thể sử dụng cú pháp trailing lambda. Thay vì đặt hàm cùng với tên hàm trong dấu ngoặc đơn, bạn sẽ đặt dấu ngoặc đơn sau tên hàm. Đây là một phương pháp phổ biến trong Compose, vì vậy bạn cần phải làm quen với cú pháp viết mã theo cách này.

Ví dụ: tham số cuối cùng trong hàm có khả năng kết hợp Row()content. Đây là một hàm dùng để chuyển phát các thành phần giao diện người dùng con. Giả sử bạn muốn tạo một hàng chứa ba thành phần văn bản. Mã này vẫn hoạt động tốt nhưng rất cồng kềnh:

Row(
    content = {
        Text("Some text")
        Text("Some more text")
        Text("Last text")
    }
)

Vì tham số content là tham số cuối cùng trong chữ ký hàm (function signature) và bạn truyền giá trị của tham số đó dưới dạng một biểu thức lambda (hiện tại, bạn không cần biết lambda là gì, chỉ cần làm quen với cú pháp), bạn có thể xoá tham số content và các dấu ngoặc đơn như sau:

Row {
    Text("Some text")
    Text("Some more text")
    Text("Last text")
}

Sắp xếp các thành phần văn bản trong một hàng

Trong nhiệm vụ này, bạn sẽ sắp xếp các thành phần văn bản trong ứng dụng thành một hàng để tránh chồng chéo.

  1. Trong tệp MainActivity.kt, di chuyển đến hàm BirthdayGreetingWithText().
  2. Thêm thành phần kết hợp Row xung quanh các thành phần văn bản này để hiển thị một cột gồm 2 thành phần văn bản.

Bây giờ, hàm này sẽ có dạng như đoạn mã sau:

@Composable
fun BirthdayGreetingWithText(message: String, from: String) {
   Row{
       Text(
           text = message,
           fontSize = 36.sp,
       )
       Text(
           text = from,
           fontSize = 24.sp,
       )
   }
}
  1. Nhấp vào Row được làm nổi bật trong đoạn mã.
  2. Lưu ý rằng Android Studio cung cấp nhiều lựa chọn lệnh nhập cho Row.
  3. Nhấp vào Import (Nhập).

Hàm Row được làm nổi bật với hai cửa sổ bật lên, một cửa sổ hiển thị lỗi chưa được giải quyết và cửa sổ còn lại hiển thị các tùy chọn cho lệnh nhập

  1. Chọn gói trong lớp androidx.compose.ui, bắt đầu bằng Row(androidx.compose.ui.Modifier, androidx.compose.foundation.layout.Argument.Horizontal, androidx....

dfad9fcfae49aa7a.png

  1. Nhấp vào Build & Refresh (Tạo và làm mới) để cập nhật bản xem trước trong ngăn Design (Thiết kế).

Lời chúc mừng sinh nhật và chữ ký sẽ hiển thị cạnh nhau trên một hàng.

Bản xem trước bây giờ đã đẹp hơn rất nhiều vì các thành phần không còn chồng chéo lẫn nhau. Tuy nhiên, giao diện này vẫn chưa đáp ứng yêu cầu của bạn vì không có đủ không gian cho phần chữ ký. Trong nhiệm vụ tiếp theo, bạn sẽ sắp xếp các thành phần văn bản trong một cột để xử lý vấn đề này.

Sắp xếp các thành phần văn bản trong một cột

Trong việc này, bạn cần thay đổi hàm BirthdayGreetingWithText() để sắp xếp các thành phần văn bản trong một cột. Sau khi bạn hoàn tất, đừng quên nhấp vào Tạo và làm mới để cập nhật bản xem trước. Bản xem trước này sẽ có dạng như sau:

Lời chúc mừng sinh nhật và chữ ký hiển thị trong một cột. Phần chữ ký ở dưới lời chúc mừng sinh nhật.

Bây giờ, bạn hãy thử tự kiểm tra mã của bạn với đoạn mã sau trong mã giải pháp:

@Composable
fun BirthdayGreetingWithText(message: String, from: String) {
   Column {
       Text(
           text = message,
           fontSize = 36.sp,
       )
       Text(
           text = from,
           fontSize = 24.sp,
       )
   }
}

Nhập gói này khi được Android Studio nhắc nhở:

import androidx.compose.foundation.layout.Column

10. Hiển thị trên thiết bị

Nếu thấy hài lòng với bản xem trước, bạn hãy chạy ứng dụng trên thiết bị hoặc trình mô phỏng.

  1. Trong tệp MainActivity.kt, chuyển đến hàm onCreate().
  2. Gọi hàm BirthdayGreetingWithText() trong khối lệnh Surface.
  3. Truyền lời chúc mừng sinh nhật và chữ ký của bạn vào hàm BirthdayGreetingWithText().

Hàm onCreate() hoàn chỉnh sẽ có dạng như đoạn mã sau:

class MainActivity : ComponentActivity() {
   override fun onCreate(savedInstanceState: Bundle?) {
       super.onCreate(savedInstanceState)
       setContent {
           HappyBirthdayTheme {
               // A surface container that uses the 'background' color from the theme
               Surface(color = MaterialTheme.colors.background) {
                   BirthdayGreetingWithText( "Happy Birthday Sam!", "- from Emma")
               }
           }
       }
   }
}
  1. Tạo và chạy ứng dụng trên trình mô phỏng.

1969df37dc980e41.png

11. Lấy mã giải pháp

MainActivity.kt hoàn chỉnh:

package com.example.android.happybirthday

import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.Column
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Surface
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.sp
import com.example.happybirthday.ui.theme.HappyBirthdayTheme

class MainActivity : ComponentActivity() {
   override fun onCreate(savedInstanceState: Bundle?) {
       super.onCreate(savedInstanceState)
       setContent {
           HappyBirthdayTheme {
               // A surface container that uses the 'background' color from the theme
               Surface(color = MaterialTheme.colors.background) {
                   BirthdayGreetingWithText( "Happy Birthday Sam!", "- from Emma")
               }
           }
       }
   }
}

@Composable
fun BirthdayGreetingWithText(message: String, from: String) {
   Column {
       Text(
           text = message,
           fontSize = 36.sp,
       )
       Text(
           text = from,
           fontSize = 24.sp,
       )
   }
}

@Preview(showBackground = false)
@Composable
fun BirthdayCardPreview() {
   HappyBirthdayTheme {
       BirthdayGreetingWithText( "Happy Birthday Sam!", "- from Emma")
   }
}

12. Kết luận

Bạn đã tạo ứng dụng Chúc mừng sinh nhật.

Trong lớp học lập trình tiếp theo, bạn sẽ thêm hình ảnh vào ứng dụng và thay đổi cách căn chỉnh để hiển thị các thành phần văn bản đẹp hơn.

Tóm tắt

  • Jetpack Compose là một bộ công cụ hiện đại giúp xây dựng giao diện người dùng Android. Jetpack Compose giúp đơn giản hóa và tăng tốc quá trình phát triển giao diện người dùng trên Android nhờ dùng ít mã hơn, các công cụ mạnh mẽ và API Kotlin trực quan.
  • Giao diện người dùng (UI) của một ứng dụng là những gì bạn thấy trên màn hình: văn bản, hình ảnh, nút lệnh và nhiều loại thành phần khác.
  • Các hàm có khả năng kết hợp là thành phần xây dựng cơ bản trong Compose. Hàm có khả năng kết hợp là một hàm mô tả một số thành phần trên giao diện người dùng.
  • Hàm có khả năng kết hợp được chú thích bằng chú thích @Composable; chú thích này sẽ thông báo cho trình biên dịch Compose biết rằng hàm này sẽ giúp chuyển đổi dữ liệu thành giao diện người dùng.
  • Ba thành phần bố cục chuẩn cơ bản trong Compose là Column, RowBox. Đây là các hàm có khả năng kết hợp và nhận tham số là các nội dung có thể kết hợp. Vì vậy, bạn có thể đặt các thành phần bên trong những hàm này. Ví dụ: mỗi thành phần con trong một Row sẽ được xếp cạnh nhau theo chiều ngang.

Tìm hiểu thêm