You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Jetpack Compose中处理游戏控制器操作及构建手柄友好UI?

Jetpack Compose 极简启动器:游戏手柄适配方案

一、检测游戏手柄并显示操作提示

利用Android设备广播监听和InputDevice API,结合Compose副作用函数实现手柄连接状态检测,动态展示操作提示。

实现步骤

  1. 注册广播接收器监听ACTION_DEVICE_ADDED和ACTION_DEVICE_REMOVED事件,捕捉设备连接/断开动作
  2. 通过InputDevice.isGamepad()判断设备是否为游戏手柄
  3. 用Compose状态变量维护连接状态,根据状态显示对应提示文本

代码示例

@Composable
fun GamepadConnectionIndicator() {
    var isGamepadConnected by remember { mutableStateOf(false) }
    val context = LocalContext.current

    LaunchedEffect(Unit) {
        val deviceReceiver = object : BroadcastReceiver() {
            override fun onReceive(ctx: Context?, intent: Intent?) {
                intent?.let {
                    val deviceId = it.getIntExtra(InputDevice.EXTRA_DEVICE_ID, -1)
                    val device = InputDevice.getDevice(deviceId)
                    isGamepadConnected = device?.isGamepad == true
                }
            }
        }

        val filter = IntentFilter().apply {
            addAction(Intent.ACTION_DEVICE_ADDED)
            addAction(Intent.ACTION_DEVICE_REMOVED)
        }
        context.registerReceiver(deviceReceiver, filter)

        // 初始化检查已连接的手柄
        val connectedGamepads = InputDevice.getDeviceIds()
            .mapNotNull { InputDevice.getDevice(it) }
            .filter { it.isGamepad }
        isGamepadConnected = connectedGamepads.isNotEmpty()

        onDispose {
            context.unregisterReceiver(deviceReceiver)
        }
    }

    if (isGamepadConnected) {
        Text(
            text = "按Y/Triangle键打开应用列表",
            modifier = Modifier.padding(16.dp)
        )
    }
}

二、自定义按键映射与手柄导航

通过Compose的Modifier.onKeyEvent处理全局按键,结合焦点管理实现应用列表的手柄导航逻辑。

1. 全局按键映射

在启动器根布局添加onKeyEvent修饰符,监听指定按键并触发应用列表的显示/隐藏:

@Composable
fun LauncherRoot() {
    var showAppList by remember { mutableStateOf(false) }
    val focusManager = LocalFocusManager.current

    Box(
        modifier = Modifier
            .fillMaxSize()
            .onKeyEvent { event ->
                if (event.action != KeyEvent.ACTION_DOWN) return@onKeyEvent false

                when (event.keyCode) {
                    // 同时监听Xbox Y键和PS三角键
                    KeyEvent.KEYCODE_BUTTON_Y, KeyEvent.KEYCODE_BUTTON_TRIANGLE -> {
                        showAppList = !showAppList
                        if (showAppList) {
                            // 列表显示后自动转移焦点
                            focusManager.moveFocus(FocusDirection.Down)
                        }
                        true
                    }
                    else -> false
                }
            }
    ) {
        MainScreenContent()

        if (showAppList) {
            AppListView()
        }
    }
}

2. 应用列表的手柄导航

Compose的LazyColumn默认支持焦点导航,只需为列表和列表项添加focusable(true)修饰符,即可通过手柄方向键实现导航:

@Composable
fun AppListView() {
    val appList = remember { listOf("微信", "抖音", "设置", "相册") }
    val focusRequester = remember { FocusRequester() }

    LazyColumn(
        modifier = Modifier
            .fillMaxWidth()
            .background(Color.White.copy(alpha = 0.9f))
            .focusable(true)
            .focusRequester(focusRequester)
            .padding(16.dp)
    ) {
        items(appList) { appName ->
            Text(
                text = appName,
                fontSize = 18.sp,
                modifier = Modifier
                    .fillMaxWidth()
                    .padding(vertical = 12.dp)
                    .focusable(true)
                    .onFocusChanged { state ->
                        // 焦点变化时的视觉反馈
                        this@Text.color = if (state.isFocused) Color.Blue else Color.Black
                    }
            )
        }
    }

    // 列表显示时自动请求焦点
    LaunchedEffect(Unit) {
        focusRequester.requestFocus()
    }
}

关键注意点

  • 按键兼容性:不同厂商手柄的按键映射可能存在差异,建议同时监听多平台对应按键码
  • 焦点管理:通过FocusRequester确保列表显示时自动获取焦点,提升操作流畅度
  • 事件消费:处理按键时返回true表示消费该事件,避免事件传递到其他组件

内容的提问来源于stack exchange,提问作者Бодя павук

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 19:20:13