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
,Column
vàRow
. - Cách hiển thị văn bản trong ứng dụng theo bố cục.
- Cách định dạng văn bản, chẳng hạn như thay đổi kích thước văn bản.
Sản phẩm bạn sẽ tạo ra
- Một ứng dụng Android hiển thị lời chào sinh nhật ở định dạng văn bản, như ảnh chụp màn hình này khi hoàn tất:
Bạn cần có
- Máy tính đã cài đặt Android Studio
2. Thiết lập ứng dụng Happy Birthday
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 Activity (Hoạt động 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 hoá.
Tạo dự án Hoạt động trống
- 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).
- Trong hộp thoại New Project (Dự án mới), hãy chọn Empty Activity (Hoạt động trống) rồi nhấp vào Next (Tiếp theo).
- Trong trường Name (Tên), hãy nhập
Happy Birthday
rồi chọn mức API tối thiểu là 24 (Nougat) trong trường Minimum SDK (SDK tối thiểu) và nhấp vào Finish (Hoàn tất).
- Chờ Android Studio tạo các tệp dự án và tạo bản dựng cho dự án.
- Nhấp vào Run ‘app' (Chạy "ứng dụng").
Ứng dụng sẽ có dạng như ảnh chụp màn hình sau:
Khi tạo ứng dụng Happy Birthday này bằng mẫu Empty Activity (Hoạt động trống), Android Studio sẽ thiết lập tài nguyên cho ứng dụng Android cơ bản, bao gồm một 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 một nút có thể nhấp vào, 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.
Nút có thể nhấp
Tin nhắn văn bản bên trong một Thẻ
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 có khả năng nhấp hoặc trường nhập dữ liệu có thể chỉnh sửa hoặc có thể là hình ảnh trang trí.
Trong các ứng dụng sau, hãy cố gắng tìm càng nhiều phần tử trên giao diện người dùng càng tốt.
Trong lớp học lập trình này, bạn sẽ làm việc với một phần tử trên giao diện người dùng để hiển thị văn bản có tên là phần tử Text
.
3. 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 hoá 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, đây là hàm có khả năng kết hợp, cho phép lấy dữ liệu và mô tả các phần tử trê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 trên màn hình.
Chú giải
Chú giải 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ú giải bằng cách thêm tiền tố chú giải chứa ký tự @
ở đầu phần khai báo. Bạn có thể chú giải 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:
Đ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ú giải chứa tham số
Chú giải 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ú giải @Preview
có và không có tham số.
Chú giải không chứa tham số
Chú giải xem trước phần nền
Chú giải chứa tiêu đề xem trước
Bạn có thể truyền nhiều đối số vào chú giải, như minh hoạ dưới đây.
Ảnh chụp màn hình Android Studio cho thấy đoạn mã và bản xem trước
Chú giải 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ú giải được tích hợp sẵn. Đến thời điểm này, bạn đã xem qua các chú giải @Composable
và @Preview
trong khoá học này. Bạn sẽ tìm hiểu thêm về chú giải 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ú giải cho hàm có khả năng kết hợp bằng cách sử dụng chú giải @Composable
. Tất cả hàm có khả năng kết hợp phải dùng chú giải này. Chú giải 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:
- Jetpack Compose được xây dựng xung quanh các hàm có khả năng kết hợp. Các hàm này cho phép bạn xác định giao diện người dùng của ứng dụng theo cách lập trình bằng việc mô tả giao diện đó, thay vì tập trung vào quy trình xây dựng giao diện người dùng. Để tạo một hàm có khả năng kết hợp, chỉ cần thêm chú giải
@Composable
vào tên hàm. - Các hàm có khả năng kết hợp có thể chấp nhận các đối 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, phần tử trê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.
Lưu ý về hàm có khả năng kết hợp trong mã
- Trong Android Studio, mở tệp
MainActivity.kt
. - Di chuyển đến hàm
GreetingPreview()
. Hàm có khả năng kết hợp này giúp bạn xem trước hàmGreeting()
. 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 đó. Hãy đổi tên hàm này thànhBirthdayCardPreview()
.
@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ú giải khác, chú giải @Preview
, có chứa một tham số đặt trước chú giải @Composable
. Bạn có thể tìm hiểu thêm về các đối số được truyền đến chú giải @Preview
trong phần sau của khoá 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à có chú giải @Composable
PHẢI được đặt tên 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 lạc đà là tất cả từ trong kiểu Pascal đều phải viết hoa chữ cái đầu tiên. Trong kiểu viết lạc đà, từ đầu tiên có thể ở cả hai trường hợp.
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()
Để 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) {}
4. Ngăn thiết kế trong 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.
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 nên xem trước hàm Greeting()
trực tiếp. 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")
}
}
Cách xem bản xem trước:
- Trong hàm
BirthdayCardPreview()
, hãy thay đổi đối số"Android"
trong hàmGreeting()
thành tên của bạn.
@Preview(showBackground = true)
@Composable
fun BirthdayCardPreview() {
HappyBirthdayTheme {
Greeting("James")
}
}
- Bản xem trước sẽ tự động cập nhật.
Bạn sẽ thấy bản xem trước được cập nhật.
5. Thêm một phần tử văn bản mới
Trong nhiệm vụ này, bạn xoá lời chào Hello $name!
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
- Trong tệp
MainActivity.kt
, hãy xoá phần định nghĩa hàmGreeting()
. 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.
Xoá mã sau
@Composable
fun Greeting(name: String, modifier: Modifier = Modifier) {
Text(
text = "Hello $name!",
modifier = modifier
)
}
- Bên trong hàm
onCreate()
, hãy lưu ý rằng lệnh gọi hàmGreeting()
hiện có màu đỏ. Điều này cho thấy đã xảy ra lỗi. Di con trỏ qua lệnh gọi hàm này và Android Studio sẽ cho thấy thông tin về lỗi.
- Xoá lệnh gọi hàm
Greeting()
cùng các đối số của hàm này từ các hàmonCreate()
vàBirthdayCardPreview()
. TệpMainActivity.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(
modifier = Modifier.fillMaxSize(),
color = MaterialTheme.colorScheme.background
) {
}
}
}
}
}
@Preview(showBackground = true)
@Composable
fun BirthdayCardPreview() {
HappyBirthdayTheme {
}
}
- Trước hàm
BirthdayCardPreview()
, thêm một hàm mới tên làGreetingText()
. Đừng quên thêm chú giải@Composable
trước hàm này vì đây là một hàm có khả năng kết hợp dùng để mô tả một thành phần kết hợpText
.
@Composable
fun GreetingText() {
}
- Phương pháp hay nhất là để Thành phần kết hợp chấp nhận tham số
Modifier
và truyềnmodifier
đó đến phần tử con đầu tiên của nó. Bạn sẽ tìm hiểu thêm vềModifier
và các phần tử con trong các nhiệm vụ và lớp học lập trình tiếp theo. Bây giờ, hãy thêm tham sốModifier
vào hàmGreetingText()
.
@Composable
fun GreetingText(modifier: Modifier = Modifier) {
}
- Thêm tham số
message
có kiểuString
vào hàm có khả năng kết hợpGreetingText()
.
@Composable
fun GreetingText(message: String, modifier: Modifier = Modifier) {
}
- Trong hàm
GreetingText()
, thêm một thành phần kết hợpText
, 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 GreetingText(message: String, modifier: Modifier = Modifier) {
Text(
text = message
)
}
Hàm GreetingText()
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 GreetingText()
trong ngăn Design (Thiết kế).
- Gọi hàm
GreetingText()
bên trong hàmBirthdayCardPreview()
. - Truyền một đối số
String
đến hàmGreetingText()
. Đây là một lời chào sinh nhật gửi đến bạn bè của bạn. Nếu muốn thì bạn có thể chỉnh lại lời chào theo tên bạn bè của mình, chẳng hạn như"Happy Birthday Sam!"
.
@Preview(showBackground = true)
@Composable
fun BirthdayCardPreview() {
HappyBirthdayTheme {
GreetingText(message = "Happy Birthday Sam!")
}
}
- Ngăn Design (Thiết kế) sẽ tự động cập nhật. Xem trước các thay đổi.
6. Thay đổi kích thước phông 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.
- Trong tệp
MainActivity.kt
, di chuyển đến thành phần kết hợpText()
trong hàmGreetingText()
. - 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ành100.
sp
.
Text(
text = message,
fontSize = 100.sp
)
Android Studio sẽ đánh dấu 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.
- Nhấp vào mã
.sp
được Android Studio đánh dấu ở trên. - Nhấp vào Nhập trong cửa sổ bật lên để nhập
androidx.compose.ui.unit.sp
nhằm sử dụng thuộc tính mở rộng.sp
.
- 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ệnhimport androidx.compose.ui.unit.sp
. Điều này có nghĩa là Android Studio sẽ thêm gói này vào tệp.
- Lưu ý phần thay đổi kích thước phông chữ trong bản xem trước đã cập nhật. Bạn cần chỉ định chiều cao dòng để giải quyết lý do khiến thông điệp bị chồng chéo.
- Cập nhật thành phần kết hợp
Text
để thêm chiều cao dòng.
@Composable
fun GreetingText(message: String, modifier: Modifier = Modifier) {
Text(
text = message,
fontSize = 100.sp,
lineHeight = 116.sp,
)
}
Bây giờ, bạn có thể thử nghiệm với nhiều kích thước phông chữ.
7. Thêm một phần tử 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.
- Trong tệp
MainActivity.kt
, di chuyển đến hàmGreetingText()
. - Truyền vào hàm này tham số
from
có kiểuString
cho phần chữ ký của bạn.
fun GreetingText(message: String, from: String, modifier: Modifier = Modifier)
- 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ợpText
khác chấp nhận đối sốtext
được đặt thành giá trịfrom
.
@Composable
fun GreetingText(message: String, from: String, modifier: Modifier = Modifier) {
Text(
// ...
)
Text(
text = from
)
}
- Thêm đối số có tên
fontSize
và đặt giá trị là36.sp
.
Text(
text = from,
fontSize = 36.sp
)
- Di chuyển đến hàm
BirthdayCardPreview()
. - Thêm một đối số
String
khác dùng để ký thiệp sinh nhật, chẳng hạn như"From Emma"
.
GreetingText(message = "Happy Birthday Sam!", from = "From Emma")
- Quan sát bản xem trước này.
Một hàm có khả năng kết hợp có thể mô tả nhiều phần tử trê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ì Compose 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.
8. Sắp xếp các phần tử 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 phần tử mẹ trên giao diện người dùng chứa các phần tử con trên giao diện người dùng. Đến lượt mình, các phần tử con này có thể chứa các phần tử con trên giao diện người dùng. Trong phần này, bạn sẽ tìm hiểu về các thành phần kết hợp Column
, Row
và Box
. Những thành phần kết hợp này có thể đóng vai trò là phần tử mẹ trên giao diện người dùng.
3 thành phần bố cục tiêu chuẩn, cơ bản trong Compose là các thành phần kết hợp Column
, Row
, và Box
. 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.
Column
, Row
và Box
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 hoạ và không hiển thị.
Cú pháp lambda theo sau
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 khoá 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.
Khi truyền một hàm làm tham số đó, bạn có thể sử dụng cú pháp lambda theo sau. Thay vì đặt hàm bên trong dấu ngoặc đơn, bạn có thể đặt hàm đó bên ngoài dấu ngoặc đơn trong dấu ngoặc nhọn. Đây là một phương pháp phổ biến và được đề xuất 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()
là content
. Đây là một hàm dùng để mô tả các phần tử con trên giao diện người dùng. Giả sử bạn muốn tạo một hàng chứa 3 phần tử văn bản. Mã này sẽ hoạt động tốt, nhưng việc sử dụng tham số có tên cho hàm lambda theo sau là 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.
- Trong tệp
MainActivity.kt
, hãy di chuyển đến hàmGreetingText()
. - Thêm thành phần kết hợp
Row
xung quanh các phần tử văn bản này để hiện 1 hàng gồm 2 phần tử văn bản. Chọn 2 thành phần kết hợpText
, nhấp vào bóng đèn. Chọn Surround with widget (Bao quanh bằng tiện ích) > Surround with Row (Bao quanh bằng hàng).
Bây giờ, hàm này sẽ có dạng như đoạn mã sau:
@Composable
fun GreetingText(message: String, from: String, modifier: Modifier = Modifier) {
Row {
Text(
text = message,
fontSize = 100.sp,
lineHeight = 116.sp,
)
Text(
text = from,
fontSize = 36.sp
)
}
}
- Android Studio sẽ tự động nhập hàm
Row
cho bạn. Cuộn lên trên cùng và để ý phần nhập. Bạn phải thêmimport androidx.compose.foundation.layout.Row
. - Quan sát bản xem trước đã cập nhật trong ngăn Design (Thiết kế). Tạm thời thay đổi kích thước phông chữ cho lời chúc sinh nhật thành
30.sp
.
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 GreetingText()
để sắp xếp các thành phần văn bản trong một cột. Bản xem trước sẽ có dạng như ảnh chụp màn hình sau:
Giờ bạn đã thử tự làm việc này, hãy kiểm tra đoạn mã của bạn với đoạn mã giải pháp dưới đây:
@Composable
fun GreetingText(message: String, from: String, modifier: Modifier = Modifier) {
Column {
Text(
text = message,
fontSize = 100.sp,
lineHeight = 116.sp,
)
Text(
text = from,
fontSize = 36.sp
)
}
}
Hãy để ý đến gói mà Android Studio tự động nhập vào:
import androidx.compose.foundation.layout.Column
Hãy nhớ rằng bạn cần truyền tham số của đối tượng sửa đổi đến các phần tử con trong thành phần kết hợp. Tức là bạn cần truyền tham số của đối tượng sửa đổi tới thành phần kết hợp Column
.
@Composable
fun GreetingText(message: String, from: String, modifier: Modifier = Modifier) {
Column(modifier = modifier) {
Text(
text = message,
fontSize = 100.sp,
lineHeight = 116.sp,
)
Text(
text = from,
fontSize = 36.sp
)
}
}
9. Thêm lời chào vào ứng dụng
Khi đã hài lòng với bản xem trước, giờ đã đến lúc để thêm thành phần kết hợp vào ứng dụng trên thiết bị hoặc trình mô phỏng.
- Trong tệp
MainActivity.kt
, chuyển đến hàmonCreate()
. - Gọi hàm
GreetingText()
trong khối lệnhSurface
. - Truyền lời chúc mừng sinh nhật và chữ ký của bạn vào hàm
GreetingText()
.
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 using the 'background' color from the theme
Surface(
modifier = Modifier.fillMaxSize(),
color = MaterialTheme.colorScheme.background
) {
GreetingText(message = "Happy Birthday Sam!", from = "From Emma")
}
}
}
}
}
- Tạo bản dựng và chạy ứng dụng trên trình mô phỏng.
Căn chỉnh lời chào vào chính giữa
- Để căn chỉnh lời chào ở giữa màn hình, hãy thêm một tham số có tên là
verticalArrangement
, thiết lập tham số này thànhArrangement.Center
. Bạn sẽ tìm hiểu thêm vềverticalArrangement
trong một lớp học lập trình sau này.
@Composable
fun GreetingText(message: String, from: String, modifier: Modifier = Modifier) {
Column(
verticalArrangement = Arrangement.Center,
modifier = modifier
) {
// ...
}
}
- Thêm khoảng đệm
8.dp
xung quanh cột. Bạn nên sử dụng giá trị khoảng đệm theo gia số4.dp
.
@Composable
fun GreetingText(message: String, from: String, modifier: Modifier = Modifier) {
Column(
verticalArrangement = Arrangement.Center,
modifier = modifier.padding(8.dp)
) {
// ...
}
}
- Để làm đẹp ứng dụng của bạn, hãy căn chỉnh văn bản lời chào đó vào giữa bằng
textAlign
.
Text(
text = message,
fontSize = 100.sp,
lineHeight = 116.sp,
textAlign = TextAlign.Center
)
Trong ảnh chụp màn hình ở trên, chỉ lời chào được căn giữa do tham số textAlign
. Chữ ký Người gửi: Emma có căn chỉnh mặc định ở bên trái.
- Thêm khoảng đệm vào chữ ký và căn chỉnh sang phải.
Text(
text = from,
fontSize = 36.sp,
modifier = Modifier
.padding(16.dp)
.align(alignment = Alignment.End)
)
Áp dụng phương pháp hay
Bạn nên truyền (các) thuộc tính đối tượng sửa đổi cùng với đối tượng sửa đổi đó qua thành phần kết hợp mẹ. Cập nhật tham số đối tượng sửa đổi trong GreetingText()
như sau:
onCreate()
Surface(
//...
) {
GreetingText(
message = "Happy Birthday Sam!",
from = "From Emma",
modifier = Modifier.padding(8.dp)
)
}
GreetingText()
@Composable
fun GreetingText(message: String, from: String, modifier: Modifier = Modifier) {
Column(
verticalArrangement = Arrangement.Center,
modifier = modifier
) {
// ...
}
}
Tạo bản dựng và chạy ứng dụng của bạn trên trình mô phỏng để xem kết quả cuối cùng.
10. Lấy mã giải pháp
MainActivity.kt
hoàn chỉnh:
package com.example.happybirthday
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
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 using the 'background' color from the theme
Surface(
modifier = Modifier.fillMaxSize(),
color = MaterialTheme.colorScheme.background
) {
GreetingText(
message = "Happy Birthday Sam!",
from = "From Emma",
modifier = Modifier.padding(8.dp)
)
}
}
}
}
}
@Composable
fun GreetingText(message: String, from: String, modifier: Modifier = Modifier) {
Column(
verticalArrangement = Arrangement.Center,
modifier = modifier
) {
Text(
text = message,
fontSize = 100.sp,
lineHeight = 116.sp,
textAlign = TextAlign.Center
)
Text(
text = from,
fontSize = 36.sp,
modifier = Modifier
.padding(16.dp)
.align(alignment = Alignment.End)
)
}
}
@Preview(showBackground = true)
@Composable
fun BirthdayCardPreview() {
HappyBirthdayTheme {
GreetingText(message = "Happy Birthday Sam!", from = "From Emma")
}
}
11. 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 hoá 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ú giải bằng chú giải
@Composable
; chú giải 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
,Row,
vàBox
. Đâ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ộtRow
sẽ được xếp cạnh nhau theo chiều ngang.