Input compatibility
On ChromeOS devices, many users interact with apps using a keyboard, mouse,
trackpad, stylus, or gamepad. While these input devices are also used on Android
phones, they are not as common and are often overlooked by developers.
Developers who want their app to work well with input on ChromeOS, and other
large screen Android capable devices, should look at the
following optimizations:
The way your app responds to keyboard input contributes to a good desktop
experience. There are three kinds of keyboard input: Navigation,
Keystrokes, and Shortcuts.
Mục lục bài viết
Navigation
Keyboard navigation is rarely implemented in touch-centric apps, but users
expect it when they are using an app and have their hands on a keyboard.
It can also be essential for users with accessibility needs on both phones
and desktop devices.
For many apps, simple arrow key and tab navigation is all that is needed and is
mostly handled automatically by the Android framework. For example, a view of
a Button
is focusable by default, and keyboard navigation should generally
work without any additional code. In order to enable keyboard navigation for
views that are not focusable by default, developers should mark them as
focusable. This can be done programmatically or in XML, as shown below. See the
Focus Handling
documentation for more information.
Kotlin
yourView.
isFocusable =
true
Alternatively you can set the focusable
attribute in your layout file:
XML
android:focusable="true"
Once focus is enabled, the Android framework will create a navigational mapping
for all focusable views based on their position. This usually works as expected
and no further work is needed. When the default mapping is not correct for an
app’s needs, it can be overridden as follows:
Kotlin
yourView.
nextFocusLeftId =
R.
id.
view_to_left
yourView.
nextFocusRightId =
R.
id.
view_to_right
yourView.
nextFocusTopId =
R.
id.
view_above
yourView.
nextFocusBottomId =
R.
id.
view_below
yourView.
nextFocusForwardId =
R.
id.
next_view
It is good practice to try to access every piece of your app’s functionality
before each release using the keyboard only. It should be easy to access the
most common actions without mouse of touch input.
Remember, keyboard support might be essential for users with accessibility needs.
Keystrokes
For text input that would be handled by an on-screen virtual keyboard
(IME) such as an EditText
,
apps should behave as expected on ChromeOS with no additional work from the
developer. For keystrokes that cannot be anticipated by the framework, apps
will need to handle the behavior themselves. This is especially true for apps
with custom views.
Some examples are chat apps that use the enter key to send a message,
media apps that start/stop playback with the space key, and games that control
movement with the w,a,s, and d keys.
Most apps override the
onKeyUp
event and add the expected behavior for each received keycode, as shown below.
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)
}
}
Using onKeyUp
prevents apps from receiving multiple events if a key is held
down or released slowly. Games and apps that expect users to hold down keyboard
keys can look for the
onKeyDown
event.
Depending on an app’s needs, overriding onKeyUp
for the entire Activity
usually provides the needed behavior. If desired, an
onKeyListener can be added to a
specific view instead. For example an app may only listen for the Enter key in
specific EditText, and not the Activity, in order to implement send
functionality only when the user is typing in a chat box.
When you add keyboard support, follow the Android
Keyboard handling documentation.
Shortcuts
Common Ctrl, Alt, and Shift-based shortcuts are expected in desktop
environments. If an app does not implement them, the experience can feel
frustrating and broken to users. Advanced users also
appreciate shortcuts for frequently used app-specific tasks. Shortcuts make an
app easier to use and differentiate it from apps that don’t have shortcuts.
Some common shortcuts include save (Ctrl+S), undo (Ctrl+Z), and
redo (Ctrl+Shift+Z). For an example of some more advanced shortcuts, see the
list of
VLC Media Player shortcut keys.
Shortcuts can be implemented using
dispatchKeyShortcutEvent.
This intercepts all meta-key combinations (Alt, Ctrl, and Shift) for a given
keycode. To check for a specific meta-key, use
KeyEvent.isCtrlPressed(),
KeyEvent.isShiftPressed(),
KeyEvent.isAltPressed(),
or KeyEvent.hasModifiers().
Separating shortcut code from other keystroke handling (such as onKeyUp
or
onKeyDown
) can make code maintenance easier and maintains the default acceptance
of meta-keys without having to manually implement meta-key checks in every case.
Allowing all meta-key combinations can also be more convenient for users who
are accustomed to different keyboard layouts and operating systems.
Kotlin
override
fun
dispatchKeyShortcutEvent
(
event:
KeyEvent)
:
Boolean {
return
when
(
event.
keyCode)
{
KeyEvent.
KEYCODE_O ->
{
openFile
(
)
true
}
KeyEvent.
KEYCODE_Z->
{
if
(
event.
isCtrlPressed)
{
if
(
event.
isShiftPressed)
{
redoLastAction
(
)
true
}
else
{
undoLastAction
(
)
true
}
}
}
else
->
{
return
super
.
dispatchKeyShortcutEvent
(
event)
}
}
}
You can also implement shortcuts in onKeyUp
by checking for
KeyEvent.isCtrlPressed(),
KeyEvent.isShiftPressed(),
or KeyEvent.isAltPressed()
in the same manner as above. This can be easier to maintain if the meta-behavior
is more of a modification to an app behavior than a shortcut. For example, when
W means “walk forward” and Shift+W means “run forward”.
Kotlin
override
fun
onKeyUp
(
keyCode:
Int,
event:
KeyEvent)
:
Boolean {
return
when
(
keyCode)
{
KeyEvent.
KEYCODE_W->
{
if
(
event.
isShiftPressed)
{
if
(
event.
isCtrlPressed)
{
flyForward
(
)
true
}
else
{
runForward
(
)
true
}
}
else
{
walkForward
(
)
}
}
else
->
super
.
onKeyUp
(
keyCode,
event)
}
}