Ngành Thiết kế mỹ thuật số là một trong những ngành học đang được các bạn học sinh, các bậc phụ huynh quan tâm hiện tại. Chính vì vậy, nhiều...
Xử lý các hoạt động tương tác của người dùng | Jetpack Compose | Android Developers
Tài liệu về Cử chỉ trong Compose gồm có cách những thành phần Compose xử lý sự kiện con trỏ cấp thấp, ví dụ điển hình như chuyển dời con trỏ và lượt nhấp. Ngoài ra, Compose tóm tắt những sự kiện cấp thấp đó thành những lượt tương tác cấp cao hơn – ví dụ : một loạt những lượt nhấp con trỏ hoàn toàn có thể thêm vào bằng một lần nhấn và thả nút. Việc hiểu những khái niệm trừu tượng cấp cao hơn hoàn toàn có thể giúp bạn tùy chỉnh cách giao diện người dùng phản hồi cho người dùng. Ví dụ : bạn hoàn toàn có thể muốn tùy chỉnh cách giao diện của một thành phần biến hóa khi người dùng tương tác với thành phần đó hoặc hoàn toàn có thể bạn chỉ muốn duy trì nhật ký của những hoạt động giải trí người dùng đó. Tài liệu này phân phối cho bạn thông tin thiết yếu để sửa đổi những thành phần giao diện người dùng tiêu chuẩn hoặc phong cách thiết kế của riêng bạn .
Lượt tương tác
Trong nhiều trường hợp, bạn không cần phải biết thành phần Compose đang diễn giải lượt tương tác của người dùng như thế nào. Ví dụ: Button
dựa vào Modifier.clickable
để tìm hiểu xem người dùng có nhấp vào nút này hay không. Nếu thêm một nút thông thường vào ứng dụng, bạn có thể xác định mã onClick
của nút đó và Modifier.clickable
sẽ chạy mã đó khi thích hợp. Điều đó có nghĩa là bạn không cần phải biết người dùng đã nhấn vào màn hình hay chọn nút bằng bàn phím; Modifier.clickable
nhận thấy người dùng đã thực hiện lượt nhấp và phản hồi bằng cách chạy mã onClick
của bạn.
Tuy nhiên, nếu muốn tùy chỉnh phản hồi của thành phần giao diện người dùng đối với hành vi của người dùng, bạn có thể cần biết thêm về những gì đang diễn ra. Phần này cung cấp cho bạn một vài thông tin đó.
Khi người dùng tương tác với một thành phần giao diện người dùng, hệ thống đại diện cho hành vi của họ bằng cách tạo một số sự kiện Interaction
. Ví dụ: nếu người dùng nhấn vào một nút, thì nút đó sẽ tạo raPressInteraction.Press
.
Nếu người dùng nhấc ngón tay ra khỏi nút, nút này sẽ tạo ra PressInteraction.Release
, cho nút đó nhận biết lượt nhấp đã hoàn tất. Tuy nhiên, nếu người dùng kéo ngón tay ra khỏi nút rồi nhấc ngón tay lên, nút đó sẽ tạo ra PressInteraction.Cancel
để cho biết Thao tác nhấn trên nút đã bị hủy, chưa hoàn tất.
Những lượt tương tác này không hợp lý. Điều này có nghĩa là các sự kiện tương tác cấp thấp không có ý định diễn giải ý nghĩa của hành động của người dùng hoặc trình tự của chúng. Chúng cũng không giải thích hành động nào của người dùng có thể được ưu tiên hơn các hành động khác.
Các hoạt động tương tác này thường đi theo cặp, bắt đầu và kết thúc. Lượt tương tác thứ hai chứa một thông tin tham chiếu đến bản tương tác đầu tiên. Ví dụ: nếu người dùng nhấn vào một nút rồi nhấc ngón tay lên, thì thao tác nhấn đó sẽ tạo ra một lượt tương tác PressInteraction.Press
và bản phát hành tạo ra PressInteraction.Release
; Release
có thuộc tính press
xác định tên viết tắt PressInteraction.Press
ban đầu.
Bạn có thể xem các lượt tương tác của một thành phần cụ thể bằng cách quan sát InteractionSource
. InteractionSource
được xây dựng dựa trên Kotlin flows, vì thế bạn có thể thu thập các lượt tương tác từ luồng này giống như cách bạn làm việc với bất kỳ luồng nào khác.
Trạng thái tương tác
Bạn nên mở rộng chức năng tích hợp sẵn của các thành phần bằng cách tự theo dõi các hoạt động tương tác đó. Ví dụ: có thể bạn muốn một nút thay đổi màu khi bạn nhấn vào. Cách đơn giản nhất để theo dõi các tương tác là quan sát trạng thái tương tác thích hợp. InteractionSource
cung cấp một số phương thức để biết nhiều trạng thái tương tác dưới dạng trạng thái. Ví dụ: nếu muốn xem liệu một nút cụ thể có được nhấn hay không, bạn có thể gọi phương thức InteractionSource.collectIsPressedAsState()
:
val interactionSource = remember { MutableInteractionSource() }
val isPressed by interactionSource.collectIsPressedAsState()
Button(
onClick = { /* do something */ },
interactionSource = interactionSource) {
Text(if (isPressed) "Pressed!" else "Not pressed")
}
Lưu ý:
InteractionSource
cung cấp luồng tương tác chỉ được đọc, trong khi MutableInteractionSource
cho phép bạn thêm các lượt tương tác mới vào luồng này.
Khi tạo thành phần của riêng mình, bạn nên sử dụng và hiển thị MutableInteractionSource
, ngay cả khi bạn hiện không định tự thêm các lượt tương tác.
Ngoài collectIsPressedAsState()
, tính năng Compose còn cung cấp collectIsFocusedAsState()
, collectIsDraggedAsState()
và collectIsHoveredAsState()
. Các phương thức này thực sự tiện dụng được xây dựng dựa trên các API InteractionSource
cấp thấp hơn. Trong một số trường hợp, bạn có thể muốn sử dụng các hàm cấp thấp hơn đó.
Ví dụ: giả sử bạn cần biết liệu một nút có đang được nhấn hay không, cũng như liệu nút đó có đang được kéo hay không. Nếu bạn sử dụng cả collectIsPressedAsState()
và collectIsDraggedAsState()
, thì Compose có nhiều tác vụ trùng lặp và không có gì đảm bảo bạn sẽ nhận được tất cả các lượt tương tác theo đúng thứ tự. Đối với các tình huống như thế này, bạn nên làm việc trực tiếp với InteractionSource
. Phần sau đây mô tả cách bạn có thể tự theo dõi các lượt tương tác, và chỉ nhận thông tin mà bạn cần.
Làm việc với InteractiveSource
Nếu cần thông tin cấp thấp về các lượt tương tác với một thành phần, bạn có thể sử dụng API luồng chuẩn cho InteractionSource
của thành phần đó.
Ví dụ: giả sử bạn muốn duy trì một danh sách các tương tác nhấn và kéo vào InteractionSource
. Mã này thực hiện một nửa công việc, thêm các thao tác nhấn mới vào danh sách khi chúng xuất hiện:
val interactionSource = remember { MutableInteractionSource() }
val interactions = remember { mutableStateListOf() }
LaunchedEffect(interactionSource) {
interactionSource.interactions.collect { interaction ->
when (interaction) {
is PressInteraction.Press -> {
interactions.add(interaction)
}
is DragInteraction.Start -> {
interactions.add(interaction)
}
}
}
}
Tuy nhiên, ngoài việc thêm những lượt tương tác mới, bạn cũng phải xóa những lượt tương tác khi nó kết thúc ( ví dụ : khi người dùng nhấc ngón tay lên khỏi thành phần ). Điều này rất dễ thực thi, vì lượt tương tác sau cuối luôn tham chiếu đến lượt tương tác bắt đầu được link. Mã này cho biết cách bạn sẽ xóa những lượt tương tác đã kết thúc :
val interactions = remember { mutableStateListOf() }
LaunchedEffect(interactionSource) {
interactionSource.interactions.collect { interaction ->
when (interaction) {
is PressInteraction.Press -> {
interactions.add(interaction)
}
is PressInteraction.Release -> {
interactions.remove(interaction.press)
}
is PressInteraction.Cancel -> {
interactions.remove(interaction.press)
}
is DragInteraction.Start -> {
interactions.add(interaction)
}
is DragInteraction.Stop -> {
interactions.remove(interaction.start)
}
is DragInteraction.Cancel -> {
interactions.remove(interaction.start)
}
}
}
}
Bây giờ, nếu muốn biết thành phần hiện đang được nhấn hay kéo, bạn chỉ cần kiểm tra xem interactions
có trống hay không:
val isPressedOrDragged = interactions.isNotEmpty()
Nếu muốn biết lượt tương tác gần đây nhất, bạn chỉ cần xem mục sau cuối trong list. Ví dụ : đây là cách tiến hành chính sách Compose ripple thống kê giám sát lớp phủ trạng thái thích hợp để sử dụng cho lượt tương tác gần đây nhất :
val lastInteraction = when (interactions.lastOrNull()) {
is DragInteraction.Start -> "Dragged"
is PressInteraction.Press -> "Pressed"
else -> "No state"
}
Xem ví dụ
Để xem cách bạn hoàn toàn có thể tạo thành phần với một phản hồi tùy chỉnh cho mục nhập, dưới đây là ví dụ về nút đã sửa đổi. Trong trường hợp này, giả sử bạn muốn có một nút phản hồi về những lần nhấn bằng cách đổi khác giao diện của nút :
Để làm việc này, hãy tạo một thành phần kết hợp tùy chỉnh dựa trên Button
và yêu cầu tham số icon
bổ sung để vẽ biểu tượng (trong trường hợp này là giỏ hàng). Bạn gọi collectIsPressedAsState()
để theo dõi xem người dùng có di chuột qua nút hay không; khi nút được nhấn, bạn sẽ thêm biểu tượng vào. Dưới đây là giao diện của mã:
@Composable
fun PressIconButton(
onClick: () -> Unit,
icon: @Composable () -> Unit,
text: @Composable () -> Unit,
modifier: Modifier = Modifier,
interactionSource: MutableInteractionSource =
remember { MutableInteractionSource() },
) {
val isPressed by interactionSource.collectIsPressedAsState()
Button(onClick = onClick, modifier = modifier,
interactionSource = interactionSource) {
AnimatedVisibility(visible = isPressed) {
if (isPressed) {
Row {
icon()
Spacer(Modifier.size(ButtonDefaults.IconSpacing))
}
}
}
text()
}
}
Dưới đây là giao diện khi sử dụng thành phần phối hợp mới :
PressIconButton(
onClick = {},
icon = { Icon(Icons.Filled.ShoppingCart, contentDescription = null) },
text = { Text("Add to cart") }
)
Vì PressIconButton
mới này được tạo dựa trên Tài liệu Button
hiện có, nó này phản ứng với các hành động tương tác của người dùng theo mọi cách thông thường. Khi người dùng nhấn nút, nút này sẽ thay đổi độ mờ một chút, giống như một Tài liệu thông thường Button
. Ngoài ra, nhờ mã mới, HoverIconButton
tự động phản hồi khi di chuột bằng cách thêm biểu tượng.
Source: https://vh2.com.vn
Category : Truyền Thông