基础知识

1. 物理键盘(Physical Keyboard)

定义

物理键盘指的是设备上真实存在的、可以按压的键盘。例如:

  • 早期的 Android 手机(如黑莓、摩托罗拉 Milestone)自带的 QWERTY 键盘
  • 外接的蓝牙/USB 键盘
  • 平板或 Chromebook 上的实体键盘

特点

  • 输入响应快,无需屏幕空间
  • 支持快捷键、组合键
  • 适合大量文字输入或开发者使用

开发相关

  • 可以通过 KeyEvent 监听物理键盘事件
  • 物理键盘连接时,系统通常会自动隐藏软键盘

2. 软件盘(Soft Keyboard / 虚拟键盘)

定义

软件盘是指在屏幕上弹出的虚拟键盘。绝大多数 Android 设备都内置了软键盘(如 Gboard、百度输入法等)。

特点

  • 触摸屏幕输入
  • 可根据输入场景切换布局(数字、符号、表情等)
  • 支持多语言、手写、语音输入等扩展功能
  • 会占用部分屏幕空间

开发相关

  • 通过 InputMethodManager 控制软键盘的显示与隐藏
  • 可以在 EditText 上设置输入类型(如数字、密码等)
  • 软键盘弹出时,可能会影响界面布局(如遮挡输入框),需要合理处理(如使用 android:windowSoftInputMode)

3. 物理键盘与软键盘的关系

  • 如果设备连接了物理键盘,Android 系统通常会自动隐藏软键盘,除非用户手动调出。
  • 开发者可以通过代码判断当前是否有物理键盘连接(如 Configuration.keyboard)。
  • 某些场景下,开发者可以强制显示软键盘,即使有物理键盘。

4. 常见开发场景

  • 监听键盘事件:通过 onKeyDown、onKeyUp 监听物理键盘输入。
  • 软键盘控制:通过 InputMethodManager.showSoftInput() 和 hideSoftInputFromWindow() 控制软键盘。
  • 适配键盘弹出:使用 android:windowSoftInputMode 控制界面适配。

5. 相关 API

  • KeyEvent:物理键盘事件
  • InputMethodManager:软键盘管理
  • Configuration.keyboard:判断当前键盘类型

需求

一个需求,当连接外接键盘的时候,用外接,没有就用系统的。

Android 系统默认就会这样处理,但如果你需要更精确的控制,可以通过以下方式实现:

1. 检测键盘类型

首先需要检测当前是否有物理键盘连接:

public class KeyboardManager {/*** 检测是否有物理键盘连接*/public static boolean hasPhysicalKeyboard(Context context) {Configuration config = context.getResources().getConfiguration();return config.keyboard == Configuration.KEYBOARD_QWERTY ||config.keyboard == Configuration.KEYBOARD_12KEY;}/*** 检测是否有外接键盘*/public static boolean hasExternalKeyboard(Context context) {// 方法1:通过Configuration检测Configuration config = context.getResources().getConfiguration();boolean hasHardwareKeyboard = config.keyboard != Configuration.KEYBOARD_UNDEFINED;// 方法2:通过InputDevice检测(更精确)InputManager inputManager = (InputManager) context.getSystemService(Context.INPUT_SERVICE);int[] deviceIds = inputManager.getInputDeviceIds();for (int deviceId : deviceIds) {InputDevice device = inputManager.getInputDevice(deviceId);if (device != null && device.isExternal()) {// 检查是否是键盘设备int sources = device.getSources();if ((sources & InputDevice.SOURCE_KEYBOARD) != 0) {return true;}}}return hasHardwareKeyboard;}/*** 根据键盘状态显示或隐藏软键盘*/public static void handleKeyboard(Context context, View view) {if (hasExternalKeyboard(context)) {// 有外接键盘时,隐藏软键盘hideSoftKeyboard(context, view);} else {// 没有外接键盘时,显示软键盘showSoftKeyboard(context, view);}}/*** 显示软键盘*/public static void showSoftKeyboard(Context context, View view) {InputMethodManager imm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);if (imm != null) {imm.showSoftInput(view, InputMethodManager.SHOW_IMPLICIT);}}/*** 隐藏软键盘*/public static void hideSoftKeyboard(Context context, View view) {InputMethodManager imm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);if (imm != null) {imm.hideSoftInputFromWindow(view.getWindowToken(), 0);}}
}

2. 在Activity中使用

public class MainActivity extends AppCompatActivity {private EditText editText;private KeyboardManager keyboardManager;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);editText = findViewById(R.id.edit_text);// 监听键盘状态变化registerKeyboardStateReceiver();// 初始处理键盘状态handleKeyboardState();}private void handleKeyboardState() {if (KeyboardManager.hasExternalKeyboard(this)) {// 有外接键盘时的处理editText.setHint("使用外接键盘输入");KeyboardManager.hideSoftKeyboard(this, editText);} else {// 没有外接键盘时的处理editText.setHint("点击输入");editText.setOnFocusChangeListener((v, hasFocus) -> {if (hasFocus) {KeyboardManager.showSoftKeyboard(this, editText);}});}}private void registerKeyboardStateReceiver() {// 注册配置变化监听器registerReceiver(new BroadcastReceiver() {@Overridepublic void onReceive(Context context, Intent intent) {if (Intent.ACTION_CONFIGURATION_CHANGED.equals(intent.getAction())) {// 键盘配置发生变化时重新处理handleKeyboardState();}}}, new IntentFilter(Intent.ACTION_CONFIGURATION_CHANGED));}@Overrideprotected void onDestroy() {super.onDestroy();// 记得注销广播接收器}
}

3. 在布局文件中配置

<EditTextandroid:id="@+id/edit_text"android:layout_width="match_parent"android:layout_height="wrap_content"android:hint="输入文字"android:inputType="text"android:windowSoftInputMode="adjustResize" />

4. 更高级的实现(监听键盘连接/断开)

public class KeyboardStateManager {private Context context;private OnKeyboardStateChangeListener listener;public interface OnKeyboardStateChangeListener {void onExternalKeyboardConnected();void onExternalKeyboardDisconnected();}public KeyboardStateManager(Context context, OnKeyboardStateChangeListener listener) {this.context = context;this.listener = listener;}public void startMonitoring() {// 监听USB设备连接IntentFilter usbFilter = new IntentFilter();usbFilter.addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED);usbFilter.addAction(UsbManager.ACTION_USB_DEVICE_DETACHED);context.registerReceiver(new BroadcastReceiver() {@Overridepublic void onReceive(Context context, Intent intent) {String action = intent.getAction();if (UsbManager.ACTION_USB_DEVICE_ATTACHED.equals(action)) {// 检查是否是键盘设备UsbDevice device = intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);if (isKeyboardDevice(device)) {listener.onExternalKeyboardConnected();}} else if (UsbManager.ACTION_USB_DEVICE_DETACHED.equals(action)) {UsbDevice device = intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);if (isKeyboardDevice(device)) {listener.onExternalKeyboardDisconnected();}}}}, usbFilter);}private boolean isKeyboardDevice(UsbDevice device) {if (device == null) return false;// 检查设备类是否为HID(Human Interface Device)return device.getDeviceClass() == UsbConstants.USB_CLASS_HID;}
}

5. 使用示例

// 在Activity中使用
KeyboardStateManager keyboardStateManager = new KeyboardStateManager(this, new KeyboardStateManager.OnKeyboardStateChangeListener() {@Overridepublic void onExternalKeyboardConnected() {// 外接键盘连接时的处理KeyboardManager.hideSoftKeyboard(MainActivity.this, editText);Toast.makeText(MainActivity.this, "外接键盘已连接", Toast.LENGTH_SHORT).show();}@Overridepublic void onExternalKeyboardDisconnected() {// 外接键盘断开时的处理Toast.makeText(MainActivity.this, "外接键盘已断开", Toast.LENGTH_SHORT).show();}
});keyboardStateManager.startMonitoring();

主要特点:

  1. 自动检测:通过 Configuration 和 InputDevice 检测键盘状态
  1. 实时响应:监听配置变化和USB设备连接/断开
  1. 智能切换:根据键盘状态自动显示/隐藏软键盘
  1. 用户体验:提供适当的提示和反馈

这样实现后,你的应用就能智能地在物理键盘和软键盘之间切换了!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/news/916765.shtml
繁体地址,请注明出处:http://hk.pswp.cn/news/916765.shtml
英文地址,请注明出处:http://en.pswp.cn/news/916765.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

SuperClaude Framework 使用指南

SuperClaude Framework 使用指南SuperClaude Framework 是一个开源配置框架&#xff0c;将 Claude Code 从通用 AI 助手转变为专业的上下文感知开发伙伴。该框架通过模板驱动架构应用软件工程原理&#xff0c;为专业软件开发工作流程提供了强大的增强功能。目前该项目处于 v3.0…

Ruby 发送邮件 - SMTP

Ruby 发送邮件 - SMTP 在互联网的世界中,邮件服务已经成为我们日常生活中不可或缺的一部分。而在开发过程中,使用Ruby发送邮件是一项基本技能。SMTP(Simple Mail Transfer Protocol)是互联网上用于发送电子邮件的标准协议。本文将详细介绍如何在Ruby中使用SMTP发送邮件。 …

Docker运行Ollama

1.docker-compose启动ollama 按照 ollama docker-compose配置说明 配置并启动ollama容器&#xff0c;启动成功后&#xff0c;浏览器访问 http://localhost:11434 如果显示如下即代表成功 如果你的服务器支持GPU&#xff0c;可添加GPU参数支持&#xff0c;参考&#xff1a;htt…

轻松管理 WebSocket 连接!easy-websocket-client

在前端开发中&#xff0c;WebSocket 是实现实时通信的核心技术&#xff0c;但原生 WebSocket 的连接管理&#xff08;如断连重连、心跳维护、事件监听&#xff09;往往需要编写大量重复代码。今天给大家分享一个好用的 WebSocket 连接管理库 —— easy-websocket-client&#x…

人工智能赋能社会治理:深度解析与未来展望

一、核心应用场景与技术实现1. 公共安全&#xff1a;智能防控与风险预警技术应用&#xff1a;立体化治安防控&#xff1a;AI摄像头集成人脸识别、行为分析、多目标追踪技术&#xff0c;提升破案率与公共安全能力。例如&#xff0c;深圳某区通过AI系统使盗窃案件破案率提升40%。…

解决使用vscode连接服务器出现“正在下载 VS Code 服务器...”

# 解决使用vscode连接服务器出现“正在下载 VS Code 服务器...”## 首先在vscode的输出中获取 commit idtext [17:17:41.679] Using commit id "c306e94f98122556ca081f527b466015e1bc37b0" and quality "stable" for server 从上面的体制中可以看出&#…

React 项目中使用 Redux 实现公共状态共享

在 React 项目中使用 Redux 实现公共下拉选状态共享并通知各组件更新的完整方案如下&#xff1a;1. 安装 Redux 必要依赖 npm install reduxjs/toolkit react-redux2. 创建 Redux Store 和 Slice store/selectSlice.js import { createSlice } from reduxjs/toolkit;const init…

彻底清理ArcGIS 10.2残留的步骤

文章目录前言一、彻底清理ArcGIS 10.2残留的步骤总结前言 提示&#xff1a;这里可以添加本文要记录的大概内容&#xff1a; 提示&#xff1a;以下是本篇文章正文内容&#xff0c;下面案例可供参考 一、彻底清理ArcGIS 10.2残留的步骤 &#x1f527; 彻底清理ArcGIS 10.2残留的…

JDK主流版本及推荐版本

根据当前Java生态发展&#xff08;截至2025年7月&#xff09;&#xff0c;结合主流企业实践、技术特性和支持周期&#xff0c;以下是JDK主流版本及推荐版本的详细分析&#xff1a;&#x1f9e9; 一、主流JDK版本现状​​JDK 8 (LTS)​​​​使用比例​​&#xff1a;约30-35%&a…

如何从 Web2 转型到 Web3

如何从 Web2 转型到 Web3如何从 Web2 转型到 Web3引言Web2 与 Web3 的核心差异转型的实用步骤1. 打基础&#xff1a;学区块链和 Web3 概念2. 学核心技术栈&#xff1a;从 Solidity 到 dApp3. 重新设计产品&#xff1a;混合模式起步4. 应对坑&#xff1a;技术、监管和安全5. 建社…

RuoYi-Vue 项目 Docker 容器化部署 + DockerHub 上传全流程

本文详细记录本人在实际项目从 RuoYi-Vue 二次开发到 Docker 镜像打包、DockerHub 上传、异地一键部署的完整实战全过程。涵盖前后端打包产物准备、SQL初始化、docker-compose 管理、DockerHub 镜像上传、Gitee 代码管理、子模块大坑、数据库404等所有可能出错细节&#xff0c;…

【C语言进阶】题目练习

目录 1.箭形图案 思路&#xff1a; 代码&#xff1a; 2. 公务员面试 分析&#xff1a; 代码 &#xff1a; 3. 判断结构体大小&#xff08;1&#xff09; 答案&#xff1a; 分析&#xff1a; 4.判断结构体大小&#xff08;2&#xff09; 答案: 分析: 5.宏定义计算…

Blender入门笔记——建模篇(二)

前言 在数字建模的世界中&#xff0c;快捷键和高效的操作是提高工作效率的关键。本手册为您提供了常用的建模快捷键及操作技巧&#xff0c;帮助您在各种建模软件中更加得心应手。无论是进行点、线、面操作&#xff0c;还是调整视图、切换模式&#xff0c;这些快捷方式都将成为…

sqlite3学习---基础知识、增删改查和排序和限制、打开执行关闭函数

目录 一、数据库基础知识 1.分类 2.名词 3.嵌入式数据库 4.特点 5.sqlite3的安装 5.1在线安装 5.2编译 5.3验证是否安装成功 5.4sqlite3的使用 6.创建一个数据库 7.系统维护命令 二、数据库的创建和删除 1.创建一个表 1.1用法 1.2代码示例 2.删除一个表 2.1用…

Class24AlexNet

Class24AlexNet AlexNet AlexNet于2012年ImageNet 图像识别挑战赛&#xff08;ILSVRC-2012&#xff09;中以 top-5 错误率15.3%获得冠军&#xff0c;远远领先第二名。它首次在大型图像数据集上证明了深层卷积神经网络的强大能力。 AlexNet 的总体结构 AlexNet 总共有 8 层具有学…

枚举中间位置高级篇

参考资料来源灵神在力扣所发的题单&#xff0c;仅供分享学习笔记和记录&#xff0c;无商业用途。 核心思路&#xff1a;参考枚举中间位置基础篇-CSDN博客 力扣题单练习(灵神题单中摘取题目) 447. 回旋镖的数量 核心思路&#xff1a; 因给出的点都不相同&#xff0c;所以不会…

主数据管理系统能代替数据中台吗?

目录 一、主数据管理系统≠数据中台 1. 主数据管理系统&#xff1a;管的是 “不变的核心数据” 2. 数据中台&#xff1a;管的是 “流动中的价值” 二、为什么企业更该先建 MDM&#xff1f; 1. 数据中台解决不了数据本身问题 2. MDM 可以解决常见的基础问题 3. 数字化转型…

Nmap 终极教程:安装、常用命令及法律法规指南

Nmap 终极教程&#xff1a;安装、常用命令及法律法规指南 Nmap&#xff08;Network Mapper&#xff09;是一款强大的 网络扫描和安全审计工具&#xff0c;广泛用于渗透测试、网络探测和系统管理。本教程涵盖 安装方法、常用命令详解、输出解析 以及 法律法规注意事项&#xff…

开源嵌入式数组引擎TileDB的简单使用

TileDB 是C编写的存储和访问通用多维数组引擎&#xff0c;它的官方Github网站https://github.1git.de/TileDB-Inc/TileDB 1.下载源代码和二进制库 源代码https://github.1git.de/TileDB-Inc/TileDB/archive/refs/tags/2.28.1.tar.gz 选择符合你的机器CPU架构和操作系统的库 二进…

AI对服务器行业的冲击与启示:从挑战走向重构

更多云服务器知识&#xff0c;尽在hostol.comAI&#xff08;人工智能&#xff09;技术的迅猛发展&#xff0c;已深刻影响了多个行业&#xff0c;服务器行业亦不例外。在过去&#xff0c;服务器的主要任务是简单地提供存储、计算和传输数据的服务。然而&#xff0c;随着AI的崛起…