Trên các thiết bị màn hình lớn, người dùng thường tương tác với các ứng dụng bằng cách sử dụng bàn phím, chuột, bàn di chuột, bút cảm ứng hoặc tay điều khiển trò chơi. Để cho phép ứng dụng chấp nhận dữ liệu đầu vào từ các thiết bị ngoại vi, hãy làm như sau:
- Kiểm thử khả năng hỗ trợ bàn phím cơ bản, chẳng hạn như Ctrl+Z để hoàn tác, Ctrl+C để sao chép và Ctrl+S để lưu. Hãy xem bài viết Xử lý các thao tác trên bàn phím để biết danh sách các phím tắt mặc định.
- Kiểm tra khả năng hỗ trợ bàn phím nâng cao, ví dụ: điều hướng bằng bàn phím bằng phím Tab và phím mũi tên, phím Enter để xác nhận mục nhập văn bản, và phím Cách để phát và tạm dừng trong các ứng dụng đa phương tiện.
- Thử nghiệm các hoạt động tương tác cơ bản với chuột, bao gồm cả thao tác nhấp chuột phải để mở trình đơn theo bối cảnh, thay đổi biểu tượng khi di chuột và con lăn chuột hoặc sự kiện cuộn trên bàn di chuột trên các thành phần tuỳ chỉnh.
- Thử nghiệm các thiết bị đầu vào dành riêng cho ứng dụng, chẳng hạn như bút cảm ứng, tay điều khiển trò chơi và bộ điều khiển MIDI của ứng dụng nhạc.
- Cân nhắc việc hỗ trợ thiết bị đầu vào nâng cao để giúp ứng dụng trở nên nổi bật trong môi trường máy tính, ví dụ: bàn di chuột như một thiết bị thanh trượt cho các ứng dụng DJ, chụp chuột trong các trò chơi và các phím tắt cho người dùng bàn phím thành thạo.
Bàn phím
Cách ứng dụng phản hồi dữ liệu nhập bằng bàn phím góp phần mang lại trải nghiệm người dùng trên màn hình lớn. Có 3 cách nhập bằng bàn phím: di chuyển,tổ hợp phím và phím tắt.
Điều hướng
Tính năng di chuyển trên bàn phím hiếm khi được triển khai trong các ứng dụng tập trung vào thao tác chạm, nhưng người dùng mong đợi điều này khi họ sử dụng ứng dụng và bàn phím. Thao tác bằng bàn phím có thể là yếu tố cần thiết trên điện thoại, máy tính bảng, thiết bị gập và máy tính cho những người dùng có nhu cầu hỗ trợ tiếp cận.
Đối với nhiều ứng dụng, thao tác di chuyển bằng phím mũi tên và phím Tab được khung Android xử lý tự động. Ví dụ: theo mặc định, một số thành phần kết hợp có thể lấy tiêu điểm, chẳng hạn như Button hoặc thành phần kết hợp có đối tượng sửa đổi clickable; hoạt động điều hướng bằng bàn phím thường sẽ hoạt động mà không cần thêm mã nào. Để bật tính năng di chuyển bằng bàn phím cho các thành phần kết hợp tuỳ chỉnh không thể lấy tiêu điểm theo mặc định, hãy thêm đối tượng sửa đổi focusable:
var color by remember { mutableStateOf(Green) } Box( Modifier .background(color) .onFocusChanged { color = if (it.isFocused) Blue else Green } .focusable() ) { Text("Focusable 1") }
Để biết thêm thông tin, hãy xem bài viết Tạo thành phần kết hợp có thể lấy tiêu điểm.
Khi tiêu điểm được bật, khung Android sẽ tạo một mục ánh xạ điều hướng cho tất cả các thành phần có thể lấy tiêu điểm dựa vào vị trí của chúng. Phương thức này thường hoạt động như dự kiến và bạn không cần phát triển thêm.
Tuy nhiên, Compose không phải lúc nào cũng xác định được mục tiếp theo chính xác cho chế độ điều hướng bằng thẻ đối với các thành phần kết hợp phức tạp như thẻ và danh sách, chẳng hạn như khi một trong các thành phần kết hợp là thành phần có thể di chuyển theo chiều ngang và không hiển thị đầy đủ.
Để kiểm soát hành vi lấy tiêu điểm, hãy thêm đối tượng sửa đổi focusGroup vào thành phần kết hợp mẹ của một tập hợp các thành phần kết hợp. Tiêu điểm di chuyển đến nhóm, sau đó đi qua nhóm trước khi di chuyển đến thành phần có thể lấy tiêu điểm tiếp theo, ví dụ:
Row {
Column(Modifier.focusGroup()) {
Button({}) { Text("Row1 Col1") }
Button({}) { Text("Row2 Col1") }
Button({}) { Text("Row3 Col1") }
}
Column(Modifier.focusGroup()) {
Button({}) { Text("Row1 Col2") }
Button({}) { Text("Row2 Col2") }
Button({}) { Text("Row3 Col2") }
}
}
Để biết thêm thông tin, hãy xem bài viết Cung cấp chế độ điều hướng nhất quán bằng các nhóm tiêu điểm.
Chỉ dùng bàn phím để kiểm thử quyền truy cập vào mọi phần tử trên giao diện người dùng của ứng dụng. Người dùng có thể truy cập vào các phần tử thường dùng mà không cần sử dụng chuột hoặc chạm.
Lưu ý rằng hỗ trợ bàn phím có thể rất cần thiết cho những người dùng có nhu cầu hỗ trợ tiếp cận tính năng.
Thao tác phím
Đối với văn bản nhập bằng bàn phím ảo trên màn hình (IME), chẳng hạn như đối vớiTextField, ứng dụng sẽ hoạt động như dự kiến trên các thiết bị màn hình lớn mà không cần nhà phát triển phải làm gì thêm. Đối với các tổ hợp phím khung không thể đoán trước được, ứng dụng cần phải tự xử lý hành vi. Điều này đặc biệt đúng đối với các ứng dụng có chế độ xem tuỳ chỉnh.
Một số ví dụ là ứng dụng trò chuyện sử dụng phím Enter để gửi tin nhắn, ứng dụng nghe nhìn bắt đầu và dừng phát bằng phím cách, và các trò chơi điều khiển chuyển động bằng các phím w, a, s và d.
Bạn có thể xử lý từng lần nhấn phím bằng đối tượng sửa đổi onKeyEvent. Đối tượng này chấp nhận một hàm lambda được gọi khi thành phần đã sửa đổi nhận được một sự kiện chính.
Thuộc tính KeyEvent#type cho phép bạn xác định xem sự kiện đó là thao tác nhấn phím (KeyDown) hay nhả phím (KeyUp):
Box(
modifier = Modifier.focusable().onKeyEvent {
if(
it.type == KeyEventType.KeyUp &&
it.key == Key.S
) {
doSomething()
true
} else {
false
}
}
) {
Text("Press S key")
}
Ngoài ra, bạn có thể ghi đè lệnh gọi lại onKeyUp() và thêm hành vi dự kiến cho mỗi mã phím nhận được:
kotlin
override fun onKeyUp(keyCode: Int, event: KeyEvent): Boolean {
return when (keyCode) {
KeyEvent.KEYCODE_ENTER -> {
sendChatMessage()
true
}
KeyEvent.KEYCODE_SPACE -> {
playOrPauseMedia()
true
}
else -> super.onKeyUp(keyCode, event)
}
}
Sự kiện onKeyUp xảy ra khi một phím được nhả. Khi dùng lệnh gọi lại này, ứng dụng sẽ không cần phải xử lý nhiều sự kiện onKeyDown nếu một phím được nhấn giữ hoặc thả chậm. Các trò chơi và ứng dụng cần phát hiện thời điểm một phím được nhấn hoặc liệu người dùng có đang nhấn và giữ một phím hay không có thể theo dõi sự kiện onKeyDown và tự xử lý các sự kiện onKeyDown lặp lại.
Để biết thêm thông tin, hãy xem bài viết Xử lý thao tác trên bàn phím.
Lối tắt
Bạn nên sử dụng các phím tắt thông thường trên bàn phím cứng, bao gồm các phím Ctrl, Alt, Shift và Meta. Nếu một ứng dụng không triển khai phím tắt, người dùng sẽ cảm thấy khó chịu với trải nghiệm đó. Người dùng nâng cao cũng đánh giá cao các phím tắt cho các tác vụ thường dùng trong ứng dụng. Phím tắt giúp ứng dụng dễ sử dụng hơn và đem lại sự khác biệt của nó đối với ứng dụng không có phím tắt.
Một số phím tắt phổ biến bao gồm Ctrl+S (lưu), Ctrl+Z (huỷ) và Ctrl+Shift+Z (làm lại). Để xem danh sách các phím tắt mặc định, hãy xem phần Xử lý các thao tác bằng bàn phím.
Đối tượng KeyEvent có các thuộc tính sau cho biết liệu các khoá sửa đổi có được nhấn hay không:
Ví dụ:
Box(
Modifier.onKeyEvent {
if (it.isAltPressed && it.key == Key.A) {
println("Alt + A is pressed")
true
} else {
false
}
}
.focusable()
)
Để biết thêm thông tin, hãy xem phần dưới đây:
Bút cảm ứng
Nhiều thiết bị màn hình lớn có bút cảm ứng. Các ứng dụng Android xử lý bút cảm ứng dưới dạng thao tác trên màn hình cảm ứng. Một số thiết bị cũng có thể có USB hoặc bảng vẽ Bluetooth, như Wacom Intuos. Các ứng dụng Android có thể nhận đầu vào bằng Bluetooth nhưng không nhận đầu vào bằng USB.
Để truy cập vào các đối tượng bút cảm ứng MotionEvent, hãy thêm đối tượng sửa đổi pointerInteropFilter vào một bề mặt vẽ. Triển khai một lớp ViewModel bằng một phương thức xử lý các sự kiện chuyển động; truyền phương thức này dưới dạng lambda onTouchEvent của đối tượng sửa đổi pointerInteropFilter:
@Composable
@OptIn(ExperimentalComposeUiApi::class)
fun DrawArea(modifier: Modifier = Modifier) {
Canvas(modifier = modifier
.clipToBounds()
.pointerInteropFilter {
viewModel.processMotionEvent(it)
}
) {
// Drawing code here.
}
}
Đối tượng MotionEvent chứa thông tin về sự kiện:
MotionEvent#getToolType()trả vềTOOL_TYPE_FINGER,TOOL_TYPE_STYLUShoặcTOOL_TYPE_ERASERtuỳ thuộc vào công cụ đã tiếp xúc với màn hìnhMotionEvent#getPressure()báo cáo áp lực vật lý áp dụng cho bút cảm ứng (nếu được hỗ trợ)MotionEvent#getAxisValue()thông quaMotionEvent.AXIS_TILTvàMotionEvent.AXIS_ORIENTATIONcung cấp độ nghiêng vật lý và hướng của bút cảm ứng (nếu được hỗ trợ)
Điểm trước đó
Android phân chia hàng loạt sự kiện đầu vào và phân phối chúng cho mỗi khung. Bút cảm ứng có thể báo cáo các sự kiện có tần suất cao hơn nhiều so với màn hình. Khi tạo các ứng dụng vẽ, hãy kiểm tra các sự kiện có thể xảy ra trong quá khứ gần bằng cách sử dụng các API getHistorical:
MotionEvent#getHistoricalX()MotionEvent#getHistoricalY()MotionEvent#getHistoricalPressure()MotionEvent#getHistoricalAxisValue()
Tính năng chống tì tay
Khi người dùng vẽ, viết hoặc tương tác với ứng dụng của bạn bằng bút cảm ứng, đôi khi người dùng chạm lòng bàn tay vào màn hình. Sự kiện chạm (được đặt thành ACTION_DOWN hoặc ACTION_POINTER_DOWN) có thể được báo cáo cho ứng dụng của bạn trước khi hệ thống nhận dạng và bỏ qua thao tác chạm vô tình.
Android huỷ các sự kiện chạm tay bằng cách gửi một MotionEvent. Nếu ứng dụng của bạn nhận được ACTION_CANCEL, hãy huỷ cử chỉ. Nếu ứng dụng của bạn nhận được ACTION_POINTER_UP, hãy kiểm tra xem FLAG_CANCELED đã được đặt hay chưa. Nếu có, hãy huỷ cử chỉ.
Đừng chỉ tìm kiếm FLAG_CANCELED. Trên Android 13 (cấp độ API 33) trở lên, hệ thống sẽ đặt FLAG_CANCELED cho các sự kiện ACTION_CANCEL, nhưng hệ thống không đặt cờ trên các phiên bản Android thấp hơn.
Android 12
Trên Android 12 (cấp độ API 32) trở xuống, bạn chỉ có thể phát hiện tính năng từ chối cảm ứng bằng lòng bàn tay đối với các sự kiện chạm con trỏ một lần. Nếu thao tác chạm lòng bàn tay là sự kiện con trỏ duy nhất, hệ thống sẽ huỷ sự kiện bằng cách đặt ACTION_CANCEL trên đối tượng sự kiện chuyển động. Nếu các con trỏ khác không hoạt động, hệ thống sẽ đặt ACTION_POINTER_UP, điều này không đủ để phát hiện tính năng từ chối cảm ứng bằng lòng bàn tay.
Android 13
Trên Android 13 (API cấp 33) trở lên, nếu thao tác chạm lòng bàn tay là sự kiện con trỏ duy nhất, hệ thống sẽ huỷ sự kiện bằng cách đặt ACTION_CANCEL và FLAG_CANCELED trên đối tượng sự kiện chuyển động. Nếu các con trỏ khác không hoạt động, hệ thống sẽ đặt ACTION_POINTER_UP và FLAG_CANCELED.
Bất cứ khi nào ứng dụng của bạn nhận được một sự kiện chuyển động bằng ACTION_POINTER_UP, hãy kiểm tra
FLAG_CANCELED để xác định xem sự kiện đó có cho thấy việc từ chối cảm ứng bằng lòng bàn tay (hoặc sự kiện nào đó bị huỷ) hay không.
Ứng dụng ghi chú
ChromeOS có một ý định đặc biệt là hiển thị các ứng dụng ghi chú đã đăng ký cho người dùng. Để đăng ký một ứng dụng làm ứng dụng ghi chú, hãy thêm đoạn mã sau vào tệp kê khai ứng dụng:
<intent-filter>
<action android:name="org.chromium.arc.intent.action.CREATE_NOTE" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
Khi một ứng dụng được đăng ký với hệ thống, người dùng có thể chọn ứng dụng đó làm ứng dụng ghi chú mặc định. Khi có yêu cầu ghi chú mới, ứng dụng sẽ tạo một ghi chú trống để sẵn sàng nhập văn bản bằng bút cảm ứng. Khi người dùng muốn chú thích một hình ảnh (chẳng hạn như ảnh chụp màn hình hoặc hình ảnh đã tải xuống), ứng dụng sẽ chạy với ClipData chứa một hoặc nhiều mục có URI content://. Ứng dụng sẽ tạo một ghi chú sử dụng hình ảnh đính kèm đầu tiên làm hình nền và chuyển sang chế độ người dùng có thể vẽ trên màn hình bằng bút cảm ứng.
Kiểm thử ý định ghi chú không cần bút cảm ứng
Để kiểm tra xem một ứng dụng có phản hồi chính xác các ý định ghi chú không cần dùng bút cảm ứng đang hoạt động hay không, hãy sử dụng phương thức sau để hiển thị các tuỳ chọn ghi chú trên ChromeOS:
- Chuyển sang chế độ nhà phát triển và đặt thiết bị ở chế độ có thể ghi
- Nhấn tổ hợp phím Ctrl+Alt+F2 để mở một thiết bị đầu cuối
- Chạy lệnh
sudo vi /etc/chrome_dev.conf - Nhấn
iđể chỉnh sửa và thêm--ash-enable-palettevào một dòng mới ở cuối tệp - Lưu bằng cách nhấn Esc rồi nhập :, w, q và nhấn Enter
- Nhấn tổ hợp phím Ctrl+Alt+F1 để quay lại giao diện người dùng ChromeOS thông thường
- Đăng xuất rồi đăng nhập lại
Lúc này, bạn sẽ thấy một trình đơn bút cảm ứng trên kệ:
- Nhấn vào nút bút cảm ứng trên kệ và chọn Ghi chú mới. Thao tác này sẽ mở một bản ghi chú trống.
- Chụp ảnh màn hình. Từ kệ, hãy chọn nút bút cảm ứng > Chụp màn hình hoặc tải ảnh xuống. Bạn nên chọn Chú thích hình ảnh trong thông báo. Thao tác này sẽ mở ra ứng dụng có hình ảnh đã sẵn sàng chú thích.
Hỗ trợ chuột và bàn di chuột
Hầu hết các ứng dụng thường chỉ cần xử lý 3 sự kiện tập trung vào màn hình lớn: nhấp chuột phải, di chuột và kéo và thả.
Nhấp chuột phải
Mọi thao tác khiến ứng dụng hiển thị trình đơn theo bối cảnh, chẳng hạn như chạm và giữ một mục trong danh sách, cũng phải phản ứng với các sự kiện nhấp chuột phải.
Để xử lý các sự kiện nhấp chuột phải, ứng dụng cần đăng ký View.OnContextClickListener:
Box(modifier = Modifier.fillMaxSize()) {
AndroidView(
modifier = Modifier.fillMaxSize(),
factory = { context ->
val rootView = FrameLayout(context)
val onContextClickListener =
View.OnContextClickListener { view ->
showContextMenu()
true
}
rootView.setOnContextClickListener(onContextClickListener)
rootView
},
)
}
Để biết thông tin chi tiết về cách tạo trình đơn theo bối cảnh, hãy xem phần Tạo trình đơn theo bối cảnh.
Khoảng cách di
Bạn có thể khiến bố cục ứng dụng của mình trông gọn gàng và dễ sử dụng hơn bằng cách xử lý các sự kiện di chuột. Điều này đặc biệt đúng đối với các thành phầntuỳ chỉnh:
Hai ví dụ phổ biến nhất về vấn đề này là:
- Cho người dùng biết liệu một phần tử có hành vi tương tác hay không, chẳng hạn như có thể nhấp hoặc chỉnh sửa bằng cách thay đổi biểu tượng con trỏ chuột
- Thêm phản hồi bằng hình ảnh vào các mục trong một danh sách lớn hoặc dạng lưới khi con trỏ đang di chuột qua các mục đó
Kéo và thả
Trong môi trường nhiều cửa sổ, người dùng muốn có thể kéo và thả các mục giữa các ứng dụng. Điều này đúng với các thiết bị máy tính bàn cũng như máy tính bảng, điện thoại và thiết bị gập cho người dùng ở chế độ chia đôi màn hình.
Cân nhắc xem liệu người dùng có khả năng kéo các mục vào ứng dụng của bạn hay không. Ví dụ: trình chỉnh sửa ảnh phải nhận được ảnh, trình phát âm thanh sẽ phải nhận được tệp âm thanh và chương trình vẽ sẽ phải nhận được ảnh.
Để thêm hỗ trợ kéo và thả, hãy xem phần Kéo và thả và xem bài đăng trên blog Android trên ChromeOS – Triển khai tính năng kéo và thả.
Những điều cần đặc biệt lưu ý đối với ChromeOS
- Hãy nhớ yêu cầu quyền bằng
requestDragAndDropPermissions()để truy cập vào các mục được kéo vào từ bên ngoài ứng dụng Một mục phải gắn cờ
View.DRAG_FLAG_GLOBALđể được kéo vào các ứng dụng khácXem phần Bắt đầu sự kiện kéo
Hỗ trợ con trỏ nâng cao
Các ứng dụng xử lý đầu vào bằng chuột và bàn di chuột nâng cao phải triển khai một đối tượng sửa đổi
pointerInput để nhận được PointerEvent:
@Composable private fun LogPointerEvents(filter: PointerEventType? = null) { var log by remember { mutableStateOf("") } Column { Text(log) Box( Modifier .size(100.dp) .background(Color.Red) .pointerInput(filter) { awaitPointerEventScope { while (true) { val event = awaitPointerEvent() // handle pointer event if (filter == null || event.type == filter) { log = "${event.type}, ${event.changes.first().position}" } } } } ) } }
Kiểm tra đối tượng PointerEvent để xác định những thông tin sau:
PointerType: Chuột, bút cảm ứng, thao tác chạm, v.v. từPointerEvent#changesPointerEventType: Các thao tác bằng con trỏ, chẳng hạn như nhấn, di chuyển, cuộn và thả
Tay điều khiển trò chơi
Một số thiết bị Android màn hình lớn hỗ trợ lên đến bốn tay điều khiển trò chơi. Sử dụng các API tay điều khiển trò chơi Android tiêu chuẩn để xử lý tay điều khiển trò chơi (xem phần Hỗ trợ tay điều khiển trò chơi).
Các nút trên tay điều khiển trò chơi được liên kết tới các giá trị chung theo một liên kết chung. Nhưng không phải tất cả các nhà sản xuất tay điều khiển trò chơi đều tuân thủ cùng một quy ước liên kết. Bạn có thể cung cấp trải nghiệm tốt hơn nhiều nếu cho phép người dùng chọn cách sắp xếp tay điều khiển phổ biến khác nhau. Hãy xem bài viết Xử lý nhấn nút trên tay điều khiển trò chơi để biết thêm thông tin.
Chế độ dịch dữ liệu đầu vào
Theo mặc định, ChromeOS cho phép bật chế độ dịch. Đối với hầu hết ứng dụng Android, chế độ này giúp các ứng dụng hoạt động như mong muốn trong môi trường máy tính. Một số ví dụ bao gồm việc tự động cho phép lăn chuột bằng hai ngón tay trên bàn di chuột, cuộn con lăn chuột và ánh xạ toạ độ màn hình thô đến toạ độ cửa sổ. Nhìn chung, các nhà phát triển ứng dụng không cần thiết phải thực thi bất kỳ hành vi nào trong số này.
Nếu một ứng dụng triển khai hành vi nhập dữ liệu tuỳ chỉnh, chẳng hạn như xác định một thao tác chụm bàn di chuột bằng hai ngón tay tuỳ chỉnh, hoặc các bản dịch đầu vào này không cung cấp các sự kiện nhập như ứng dụng mong đợi, bạn có thể tắt chế độ dịch đầu vào bằng cách thêm thẻ sau vào tệp kê khai Android:
<uses-feature
android:name="android.hardware.type.pc"
android:required="false" />