1. Trước khi bắt đầu
Trong lớp học lập trình này, bạn sẽ sử dụng mã nguồn giải pháp từ lớp học lập trình Giới thiệu về trạng thái trong Compose để tạo một công cụ tính tiền boa mang tính tương tác. Công cụ này có thể tự động tính toán và làm tròn số tiền boa khi bạn nhập số tiền trên hoá đơn và tỷ lệ phần trăm boa. Dưới đây là ảnh chụp màn hình khi ứng dụng đã hoàn thiện.
Điều kiện tiên quyết
- Lớp học lập trình Giới thiệu về trạng thái trong Compose.
- Khả năng thêm thành phần kết hợp
Text
vàTextField
vào một ứng dụng. - Kiến thức về hàm
remember()
, trạng thái, chuyển trạng thái lên trên (state hoisting) và sự khác biệt giữa các hàm có khả năng kết hợp có trạng thái và không có trạng thái
Kiến thức bạn sẽ học được
- Cách thêm nút hành động vào bàn phím ảo.
- Thành phần kết hợp
Switch
là gì và cách sử dụng nó. - Thêm biểu tượng ở đầu vào trường văn bản.
Sản phẩm bạn sẽ tạo ra
- Một ứng dụng Tip Time tính số tiền boa dựa trên số tiền trên hoá đơn và tỷ lệ boa mà người dùng nhập.
Bạn cần
- Phiên bản mới nhất của Android Studio
- Mã nguồn giải pháp từ lớp học lập trình Giới thiệu về trạng thái trong Compose
2. Lấy đoạn mã khởi đầu
Để bắt đầu, hãy tải mã khởi đầu xuống:
Ngoài ra, bạn có thể sao chép kho lưu trữ GitHub cho mã:
$ git clone https://github.com/google-developer-training/basic-android-kotlin-compose-training-tip-calculator.git $ cd basic-android-kotlin-compose-training-tip-calculator $ git checkout state
Bạn có thể duyệt xem mã này trong Kho lưu trữ GitHub Tip Time
.
3. Tổng quan về ứng dụng khởi đầu
Lớp học lập trình này bắt đầu bằng ứng dụng Tip Time trong lớp học lập trình trước (Giới thiệu về trạng thái trong Compose). Ứng dụng này cung cấp giao diện người dùng cần thiết để tính tiền boa với tỷ lệ phần trăm tiền boa cố định. Hộp văn bản Bill amount (Số tiền trên hoá đơn) cho phép người sử dụng nhập chi phí dịch vụ. Ứng dụng sẽ tính toán và hiển thị số tiền boa trong thành phần kết hợp Text
.
Chạy ứng dụng Tip Time (Tính tiền boa)
- Mở dự án Tip Time trong Android Studio và chạy ứng dụng trên trình mô phỏng hoặc thiết bị.
- Nhập số tiền trên hoá đơn. Ứng dụng sẽ tự động tính toán và hiển thị số tiền boa.
Theo cách tính hiện tại, tỷ lệ phần trăm tiền boa được nhập trực tiếp vào mã nguồn là 15%. Trong lớp học lập trình này, bạn mở rộng tính năng này bằng một trường văn bản để ứng dụng có thể tùy chỉnh tỷ lệ phần trăm tiền boa và làm tròn số tiền boa.
Thêm các tài nguyên chuỗi cần thiết
- Trong thẻ Project (Dự án), hãy nhấp vào res > values > strings.xml (tài nguyên > giá trị > strings.xml).
- Ở giữa các thẻ
<resources>
của tệpstrings.xml
, hãy thêm các tài nguyên chuỗi sau:
<string name="how_was_the_service">Tip Percentage</string>
<string name="round_up_tip">Round up tip?</string>
Tệp strings.xml
sẽ có dạng như đoạn mã này, bao gồm cả các chuỗi từ lớp học lập trình trước:
strings.xml
<resources>
<string name="app_name">Tip Time</string>
<string name="calculate_tip">Calculate Tip</string>
<string name="bill_amount">Bill Amount</string>
<string name="how_was_the_service">Tip Percentage</string>
<string name="round_up_tip">Round up tip?</string>
<string name="tip_amount">Tip Amount: %s</string>
</resources>
4. Thêm trường văn bản tip-percentage
Khách hàng có thể muốn boa nhiều hoặc ít hơn tuỳ vào chất lượng dịch vụ họ nhận được và các lý do khác. Để đáp ứng yêu cầu này, ứng dụng phải cho phép người dùng tùy chỉnh số tiền boa. Trong phần này, bạn sẽ thêm một trường văn bản để người dùng nhập phần trăm tiền boa tuỳ chỉnh như trong hình sau:
Bạn đã có trường văn bản Bill Amount (Số tiền trên hoá đơn) trong ứng dụng, đây là hàm có khả năng kết hợp EditNumberField()
không có trạng thái. Trong lớp học lập trình trước, bạn đã đưa trạng thái amountInput
từ thành phần kết hợp EditNumberField()
vào thành phần kết hợp TipTimeLayout()
, điều này khiến thành phần kết hợp EditNumberField()
không có trạng thái.
Để thêm một trường văn bản, bạn có thể sử dụng lại thành phần kết hợp EditNumberField()
, nhưng với nhãn khác. Để thay đổi như vậy, bạn cần truyền nhãn dưới dạng một tham số, thay vì nhập trực tiếp nhãn này vào trong hàm có khả năng kết hợp EditNumberField()
.
Giúp hàm có khả năng kết hợp EditNumberField()
có thể được tái sử dụng:
- Ở tệp
MainActivity.kt
trong tham số của hàm kết hợpEditNumberField()
, hãy thêm tài nguyên chuỗilabel
thuộc kiểuInt
:
@Composable
fun EditNumberField(
label: Int,
value: String,
onValueChanged: (String) -> Unit,
modifier: Modifier = Modifier
)
- Trong phần thân hàm, hãy thay thế mã của tài nguyên chuỗi đã cố định giá trị trong mã bằng tham số
label
:
@Composable
fun EditNumberField(
//...
) {
TextField(
//...
label = { Text(stringResource(label)) },
//...
)
}
- Để biểu thị tham số
label
được kỳ vọng là tham chiếu tài nguyên chuỗi, hãy chú giải tham số hàm bằng chú thích@StringRes
:
@Composable
fun EditNumberField(
@StringRes label: Int,
value: String,
onValueChanged: (String) -> Unit,
modifier: Modifier = Modifier
)
- Nhập các mục sau đây:
import androidx.annotation.StringRes
- Trong lệnh gọi hàm
EditNumberField()
của hàm có khả năng kết hợpTipTimeLayout()
, hãy đặt tham sốlabel
thành tài nguyên chuỗiR.string.bill_amount
:
EditNumberField(
label = R.string.bill_amount,
value = amountInput,
onValueChanged = { amountInput = it },
modifier = Modifier.padding(bottom = 32.dp).fillMaxWidth()
)
- Không thay đổi bất kỳ điều gì đối với hình ảnh trong ngăn Preview (Xem trước).
- Trong hàm có khả năng kết hợp
TipTimeLayout()
sau lệnh gọi hàmEditNumberField()
, hãy thêm một trường văn bản khác cho tỷ lệ phần trăm tiền boa tuỳ chỉnh. Gọi một hàm có khả năng kết hợpEditNumberField()
với các tham số sau:
EditNumberField(
label = R.string.how_was_the_service,
value = "",
onValueChanged = { },
modifier = Modifier.padding(bottom = 32.dp).fillMaxWidth()
)
Thao tác này sẽ thêm một hộp văn bản khác cho tỷ lệ phần trăm tiền boa tuỳ chỉnh.
- Bản xem trước ứng dụng hiện hiển thị trường văn bản Tip Percentage (Phần trăm tiền boa) như trong hình sau:
- Ở đầu hàm có khả năng kết hợp
TipTimeLayout()
, hãy thêm một thuộc tínhvar
có tên làtipInput
cho biến trạng thái của trường văn bản đã thêm. Hãy dùngmutableStateOf("")
để khởi tạo biến và kết hợp với lệnh gọi bằng hàmremember
:
var tipInput by remember { mutableStateOf("") }
- Trong lệnh gọi hàm mới
EditNumberField
()
, hãy đặt tham số có tênvalue
thành biếntipInput
và sau đó cập nhật biếntipInput
trong biểu thức lambdaonValueChanged
:
EditNumberField(
label = R.string.how_was_the_service,
value = tipInput,
onValueChanged = { tipInput = it },
modifier = Modifier.padding(bottom = 32.dp).fillMaxWidth()
)
- Trong hàm
TipTimeLayout()
sau định nghĩa biếntipInput
. Hãy xác địnhval
có tên làtipPercent
sẽ chuyển đổi biếntipInput
thành loạiDouble
. Hãy sử dụng toán tử Elvis và trả về0
nếu giá trị lànull
. Giá trị này có thể lànull
nếu trường văn bản trống.
val tipPercent = tipInput.toDoubleOrNull() ?: 0.0
- Trong hàm
TipTimeLayout()
, hãy cập nhật lệnh gọi hàmcalculateTip()
, truyền biếntipPercent
làm tham số thứ hai:
val tip = calculateTip(amount, tipPercent)
Đoạn mã cho hàm TipTimeLayout()
sẽ trông giống như sau:
@Composable
fun TipTimeLayout() {
var amountInput by remember { mutableStateOf("") }
var tipInput by remember { mutableStateOf("") }
val amount = amountInput.toDoubleOrNull() ?: 0.0
val tipPercent = tipInput.toDoubleOrNull() ?: 0.0
val tip = calculateTip(amount, tipPercent)
Column(
modifier = Modifier.padding(40.dp),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center
) {
Text(
text = stringResource(R.string.calculate_tip),
modifier = Modifier
.padding(bottom = 16.dp)
.align(alignment = Alignment.Start)
)
EditNumberField(
label = R.string.bill_amount,
value = amountInput,
onValueChanged = { amountInput = it },
modifier = Modifier
.padding(bottom = 32.dp)
.fillMaxWidth()
)
EditNumberField(
label = R.string.how_was_the_service,
value = tipInput,
onValueChanged = { tipInput = it },
modifier = Modifier
.padding(bottom = 32.dp)
.fillMaxWidth()
)
Text(
text = stringResource(R.string.tip_amount, tip),
style = MaterialTheme.typography.displaySmall
)
Spacer(modifier = Modifier.height(150.dp))
}
}
- Chạy ứng dụng trên trình mô phỏng hoặc thiết bị, sau đó nhập số tiền trên hóa đơn và tỷ lệ phần trăm tiền boa. Ứng dụng có tính đúng số tiền boa không?
5. Đặt nút hành động
Trong lớp học lập trình trước, bạn đã tìm hiểu cách dùng lớp KeyboardOptions
để cài đặt loại bàn phím. Trong phần này, bạn sẽ tìm hiểu cách thiết lập nút hành động trên bàn phím cũng với KeyboardOptions
. Nút hành động trên bàn phím là nút nằm dưới cùng bàn phím. Bạn có thể thấy một số ví dụ trong bảng này:
Thuộc tính | Nút hành động trên bàn phím |
| |
| |
|
Trong tác vụ này, bạn cài đặt 2 nút hành động khác nhau cho các hộp văn bản:
- Nút hành động Next (Tiếp theo) cho hộp văn bản Bill Amount (Số tiền hoá đơn), cho biết người dùng đã nhập xong và muốn chuyển sang hộp văn bản tiếp theo.
- Nút hành động Done (Xong) cho hộp văn bản Tip Percentage (phần trăm tiền boa) cho biết người dùng đã nhập xong thông tin đầu vào.
Bạn có thể xem ví dụ về bàn phím với các nút hành động trong các hình sau:
Thêm tuỳ chọn bàn phím:
- Trong lệnh gọi hàm
TextField()
của hàmEditNumberField()
, hãy truyền hàm khởi tạoKeyboardOptions
, một đối số có tênimeAction
được đặt thành giá trịImeAction.Next
. Sử dụng hàmKeyboardOptions.Default.copy()
để đảm bảo bạn sử dụng các lựa chọn mặc định khác.
import androidx.compose.ui.text.input.ImeAction
@Composable
fun EditNumberField(
//...
) {
TextField(
//...
keyboardOptions = KeyboardOptions.Default.copy(
keyboardType = KeyboardType.Number,
imeAction = ImeAction.Next
)
)
}
- Chạy ứng dụng trên trình mô phỏng hoặc thiết bị. Giờ đây, bàn phím hiển thị nút hành động Tiếp theo như có thể thấy trong hình sau:
Lưu ý rằng bàn phím hiển thị cùng nút hành động Tiếp theo khi chọn trường văn bản Tip Percentage (Phần trăm tiền boa). Tuy nhiên, bạn cần 2 nút hành động khác nhau cho các trường văn bản. Bạn sẽ sớm khắc phục được vấn đề này.
- Kiểm tra hàm
EditNumberField()
. Tham sốkeyboardOptions
trong hàmTextField()
được mã hóa cứng. Để tạo những nút hành động khác cho các trường văn bản, bạn cần truyền đối tượngKeyboardOptions
dưới dạng một đối số. Đây là việc bạn sẽ thực hiện trong bước tiếp theo.
// No need to copy, just examine the code.
fun EditNumberField(
@StringRes label: Int,
value: String,
onValueChanged: (String) -> Unit,
modifier: Modifier = Modifier
) {
TextField(
//...
keyboardOptions = KeyboardOptions.Default.copy(
keyboardType = KeyboardType.Number,
imeAction = ImeAction.Next
)
)
}
- Trong định nghĩa hàm
EditNumberField()
, hãy thêm một tham sốkeyboardOptions
thuộc loạiKeyboardOptions
. Trong phần nội dung hàm, hãy chỉ định hàm này vào tham số có tênkeyboardOptions
của hàmTextField()
:
@Composable
fun EditNumberField(
@StringRes label: Int,
keyboardOptions: KeyboardOptions,
// ...
){
TextField(
//...
keyboardOptions = keyboardOptions
)
}
- Trong hàm
TipTimeLayout()
, hãy cập nhật lệnh gọi hàmEditNumberField()
đầu tiên, truyền tham số có tênkeyboardOptions
vào trường văn bản Bill Amount (Số tiền trên hoá đơn):
EditNumberField(
label = R.string.bill_amount,
keyboardOptions = KeyboardOptions.Default.copy(
keyboardType = KeyboardType.Number,
imeAction = ImeAction.Next
),
// ...
)
- Ở lệnh gọi hàm thứ hai
EditNumberField()
, thay đổi phần trăm tiền boa của trường văn bảnimeAction
thànhImeAction.Done
. Hàm của bạn phải trông giống như đoạn mã sau:
EditNumberField(
label = R.string.how_was_the_service,
keyboardOptions = KeyboardOptions.Default.copy(
keyboardType = KeyboardType.Number,
imeAction = ImeAction.Done
),
// ...
)
- Chạy ứng dụng. Thành phần này hiển thị các nút hành động Tiếp theo và Xong như có thể thấy trong các hình sau:
- Nhập số tiền trên hoá đơn bất kỳ và nhấp vào nút hành động Tiếp theo, sau đó nhập tỷ lệ phần trăm tiền boa bất kỳ rồi nhấp vào nút hành động Xong. Thao tác đó sẽ đóng bàn phím.
6. Thêm một nút chuyển
Nút chuyển có trạng thái bật/tắt của một mục.
Nút bật/tắt có hai trạng thái cho phép người dùng chọn giữa hai 2 lựa chọn. Một nút bật/tắt có 2 phần thumb và track cùng với một biểu tượng tuỳ ý như trong các hình sau:
Nút chuyển là một lựa chọn kiểm soát có thể được dùng để nhập quyết định hoặc khai báo tuỳ chọn, chẳng hạn như các chế độ cài đặt bạn có thể thấy trong hình sau:
Người dùng có thể kéo nút thumb qua lại để đánh dấu lựa chọn hoặc chỉ cần nhấn vào nút chuyển để bật/tắt. Bạn có thể xem một ví dụ khác về nút bật/tắt trong ảnh GIF này, trong đó chế độ cài đặt Visual options (Tuỳ chọn hiển thị) được chuyển thành Dark mode (Chế độ tối):
Để tìm hiểu thêm về nút chuyển, hãy tìm đọc tài liệu về Nút chuyển.
Bạn sử dụng thành phần kết hợp Switch
để người dùng có thể chọn làm tròn số tiền boa lên số nguyên gần nhất như có thể thấy trong hình sau:
Thêm một hàng cho thành phần kết hợp Text
và Switch
:
- Sau hàm
EditNumberField()
, hãy thêm một hàm có khả năng kết hợpRoundTheTipRow()
rồi truyền mộtModifier
mặc định làm đối số tương tự như hàmEditNumberField()
:
@Composable
fun RoundTheTipRow(modifier: Modifier = Modifier) {
}
- Triển khai hàm
RoundTheTipRow()
, thêm một thành phần kết hợp bố cụcRow
vớimodifier
sau đây để đặt chiều rộng của các thành phần con thành mức tối đa trên màn hình, căn giữa và đảm bảo kích thước là48dp
:
Row(
modifier = modifier
.fillMaxWidth()
.size(48.dp),
verticalAlignment = Alignment.CenterVertically
) {
}
- Nhập các mục sau đây:
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.size
- Trong khối lambda của bố cục thành phần kết hợp
Row
, hãy thêm một thành phần kết hợpText
sử dụng tài nguyên chuỗiR.string.round_up_tip
để hiển thị một chuỗiRound up tip?
:
Text(text = stringResource(R.string.round_up_tip))
- Sau thành phần kết hợp
Text
, hãy thêm một thành phần kết hợpSwitch
và truyền tham số có tênchecked
được đặt thànhroundUp
và một tham số có tênonCheckedChange
được đặt thànhonRoundUpChanged
.
Switch(
checked = roundUp,
onCheckedChange = onRoundUpChanged,
)
Bảng này chứa thông tin về các tham số bạn đã xác định cho hàm RoundTheTipRow()
:
Tham số | Mô tả |
| Liệu nút chuyển này có được kiểm tra hay không. Đây là trạng thái của thành phần kết hợp |
| Lệnh gọi lại sẽ được gọi khi nút chuyển được nhấp. |
- Nhập các mục sau đây:
import androidx.compose.material3.Switch
- Trong hàm
RoundTheTipRow()
, hãy thêm tham sốroundUp
thuộc loạiBoolean
và hàm lambdaonRoundUpChanged
nhậnBoolean
và không trả về giá trị nào:
@Composable
fun RoundTheTipRow(
roundUp: Boolean,
onRoundUpChanged: (Boolean) -> Unit,
modifier: Modifier = Modifier
)
Việc này sẽ chuyển trạng thái của nút chuyển.
- Trong thành phần kết hợp
Switch
, hãy thêmmodifier
này để căn chỉnh thành phần kết hợpSwitch
đến cuối màn hình:
Switch(
modifier = modifier
.fillMaxWidth()
.wrapContentWidth(Alignment.End),
//...
)
- Nhập các mục sau đây:
import androidx.compose.foundation.layout.wrapContentWidth
- Trong hàm
TipTimeLayout()
, hãy thêm một biến var cho trạng thái của thành phần kết hợpSwitch
. Tạo một biếnvar
có tên làroundUp
, đặt biến đó thànhmutableStateOf()
, trong đófalse
là giá trị ban đầu. Bao quanh lệnh gọi bằngremember { }
.
fun TipTimeLayout() {
//...
var roundUp by remember { mutableStateOf(false) }
//...
Column(
...
) {
//...
}
}
Đây là biến cho trạng thái thành phần kết hợp Switch
và false sẽ là trạng thái mặc định.
- Trong khối
TipTimeLayout()
của hàmColumn
sau trường văn bản Tip Percentage (Phần trăm tiền boa), hãy gọi hàmRoundTheTipRow()
với các đối số sau: tham số có tênroundUp
được đặt thànhroundUp
và tham số có tênonRoundUpChanged
được đặt thành lệnh gọi lại lambda cập nhật giá trịroundUp
:
@Composable
fun TipTimeLayout() {
//...
Column(
...
) {
Text(
...
)
Spacer(...)
EditNumberField(
...
)
EditNumberField(
...
)
RoundTheTipRow(
roundUp = roundUp,
onRoundUpChanged = { roundUp = it },
modifier = Modifier.padding(bottom = 32.dp)
)
Text(
...
)
}
}
Thao tác này sẽ hiển thị hàng Round up tip? (Làm tròn tiền boa?).
- Chạy ứng dụng. Ứng dụng sẽ hiển thị nút bật/tắt Round up tip (Làm tròn tiền boa).
- Nhập số tiền trên hoá đơn và tỷ lệ phần trăm của tiền boa, sau đó chọn nút bật/tắt Round up tip? (Làm tròn tiền boa?). Số tiền boa sẽ không được làm tròn vì bạn vẫn cần phải cập nhật hàm
calculateTip()
trong phần tiếp theo.
Cập nhật hàm calculateTip()
để làm tròn tiền boa
Sửa đổi hàm calculateTip()
để chấp nhận biến Boolean
nhằm làm tròn tiền boa lên số nguyên gần nhất:
- Để làm tròn tiền boa, hàm
calculateTip()
phải biết trạng thái của nút chuyển, đó làBoolean
. Trong hàmcalculateTip()
, hãy thêm tham sốroundUp
thuộc loạiBoolean
:
private fun calculateTip(
amount: Double,
tipPercent: Double = 15.0,
roundUp: Boolean
): String {
//...
}
- Trong hàm
calculateTip()
trước câu lệnhreturn
, hãy thêm một điều kiệnif()
kiểm tra giá trịroundUp
. NếuroundUp
làtrue
, hãy xác định một biếntip
rồi đặt thành hàmkotlin.math.
ceil
()
rồi truyền hàm đó vớitip
làm đối số:
if (roundUp) {
tip = kotlin.math.ceil(tip)
}
Hàm calculateTip()
hoàn chỉnh sẽ có dạng như đoạn mã dưới đây:
private fun calculateTip(amount: Double, tipPercent: Double = 15.0, roundUp: Boolean): String {
var tip = tipPercent / 100 * amount
if (roundUp) {
tip = kotlin.math.ceil(tip)
}
return NumberFormat.getCurrencyInstance().format(tip)
}
- Trong hàm
TipTimeLayout()
, hãy cập nhật lệnh gọi hàmcalculateTip()
rồi truyền một tham sốroundUp
:
val tip = calculateTip(amount, tipPercent, roundUp)
- Chạy ứng dụng. Giờ đây, nó sẽ làm tròn số tiền boa như bạn thấy ở những hình sau:
7. Thêm tuỳ chọn hỗ trợ cho hướng ngang
Thiết bị Android có nhiều kiểu dáng, bao gồm điện thoại, máy tính bảng, thiết bị có thể gập lại và thiết bị ChromeOS, với nhiều kích thước màn hình. Ứng dụng của bạn phải hỗ trợ cả hướng dọc và ngang.
- Kiểm thử ứng dụng ở chế độ ngang, bật chế độ Tự động xoay.
- Xoay trình mô phỏng hoặc thiết bị sang trái, để ý bạn sẽ không thấy số tiền boa. Để giải quyết vấn đề này, bạn cần có một thanh cuộn dọc để cuộn màn hình ứng dụng.
- Thêm
.verticalScroll(rememberScrollState())
vào đối tượng sửa đổi để cho phép cột có thể cuộn theo chiều dọc.rememberScrollState()
tạo và tự động ghi nhớ trạng thái cuộn.
@Composable
fun TipTimeLayout() {
// ...
Column(
modifier = Modifier
.padding(40.dp)
.verticalScroll(rememberScrollState()),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center
) {
//...
}
}
- Nhập các mục sau đây:
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
- Chạy lại ứng dụng. Hãy thử cuộn ở chế độ ngang!
8. Thêm biểu tượng ở đầu vào trường văn bản (không bắt buộc)
Các biểu tượng có thể làm cho trường văn bản trở nên hấp dẫn hơn và cung cấp thêm thông tin về trường văn bản đó. Có thể sử dụng các biểu tượng để truyền đạt thông tin về mục đích của trường văn bản, chẳng hạn như loại dữ liệu dự kiến hoặc loại dữ liệu đầu vào cần thiết. Ví dụ: biểu tượng điện thoại bên cạnh trường văn bản có thể cho biết người dùng cần nhập số điện thoại.
Có thể sử dụng các biểu tượng để định hướng hoạt động đầu vào của người dùng bằng cách đưa ra chỉ dẫn bằng hình ảnh về những gì sẽ xảy ra tiếp theo. Ví dụ: biểu tượng lịch bên cạnh trường văn bản có thể cho người dùng biết sẽ phải nhập ngày tháng.
Sau đây là ví dụ về trường văn bản kèm theo biểu tượng tìm kiếm, cho bạn biết phải nhập cụm từ tìm kiếm ở trường này.
Thêm một tham số khác vào thành phần kết hợp EditNumberField()
có tên là leadingIcon
thuộc loại Int
. Chú thích hàm này bằng @DrawableRes
.
@Composable
fun EditNumberField(
@StringRes label: Int,
@DrawableRes leadingIcon: Int,
keyboardOptions: KeyboardOptions,
value: String,
onValueChanged: (String) -> Unit,
modifier: Modifier = Modifier
)
- Nhập các mục sau đây:
import androidx.annotation.DrawableRes
import androidx.compose.material3.Icon
- Thêm biểu tượng ở đầu vào trường văn bản.
leadingIcon
nhận một thành phần kết hợp, bạn sẽ truyền thành phần kết hợpIcon
sau.
TextField(
value = value,
leadingIcon = { Icon(painter = painterResource(id = leadingIcon), null) },
//...
)
- Chuyển biểu tượng ở đầu vào trường văn bản. Các biểu tượng đã có sẵn trong mã nguồn khởi đầu để thuận tiện cho bạn.
EditNumberField(
label = R.string.bill_amount,
leadingIcon = R.drawable.money,
// Other arguments
)
EditNumberField(
label = R.string.how_was_the_service,
leadingIcon = R.drawable.percent,
// Other arguments
)
- Chạy ứng dụng.
Xin chúc mừng! Ứng dụng của bạn hiện có khả năng tính toán số tiền boa tuỳ chỉnh.
9. Lấy mã giải pháp
Để tải xuống mã cho lớp học lập trình đã kết thúc, bạn có thể sử dụng lệnh git này:
$ git clone https://github.com/google-developer-training/basic-android-kotlin-compose-training-tip-calculator.git
Ngoài ra, bạn có thể tải kho lưu trữ xuống dưới dạng tệp zip, sau đó giải nén và mở tệp đó trong Android Studio.
Nếu bạn muốn xem mã giải pháp, hãy xem mã đó trên GitHub.
10. Kết luận
Xin chúc mừng! Bạn đã thêm chức năng tiền boa tuỳ chỉnh vào ứng dụng Tip Time của mình. Giờ đây, ứng dụng cho phép người dùng nhập một tỷ lệ phần trăm tiền boa tuỳ chỉnh và làm tròn số tiền boa đó. Chia sẻ thành quả của bạn lên mạng xã hội với hashtag #AndroidBasics!