浅谈Android输入法(IME)架构

news2024/11/15 11:47:41

简介:

输入法 (IME) 是一种可让用户输入文本的用户控件。Android
提供了一种可扩展的输入法框架。借助该框架,应用可以为用户提供备选输入法,例如屏幕键盘,甚至语音输入。安装所需的 IME
后,用户可以从系统设置中选择要使用的 IME,并在整个系统中使用该 IME;同时只能启用一个 IME。
如何开发一个简单的输入法,这得先了解一下Android中自带的输入法框架IMF

1.IME生命周期:


输入法本质就是一个Service,假设用户现在刚刚启动一个APP,焦点首次进入文本编辑框时,Android就会通知Service开始进行初始化,便有了生命周期图中所示的:

  • 首先执行onCreate方法,该方法做了一些字符串变量分隔符的初始化。

  • 其次执行onCreateInputView方法,在要显示用户输入的区域时,Android自带框架会调用这个方法,该方法对inputview进行初始化,读取布局文件信息,设置onKeyboardActionListener,并初始设置keyboard。

  • 然后执行onCreateCandidatesView方法,在要显示一些候选词的视图时由框架调用,和上面的onCreateInputView方法类似,在这里是对candidateview进行初始化。

  • 最后执行onStartInputView方法,将 inputview跟当前的keyboard重新关联起来。

2.Android输入法架构图:

在这里插入图片描述
图中一些名词含义解释:

  • IMMS:输入法管理服务InputMethodManagerService
  • IMM:输入法管理 InputMethodManager
  • IMS:输入法服务 InputMethodService

3.框架中部分组件使用

在 Android 系统中,IME 是包含一项特殊 IME 服务的 Android 应用。
应用的清单文件必须声明该服务,请求必需的权限,提供一个与操作 action.view.InputMethod 匹配的 Intent
过滤器,并提供定义 IME 特征的元数据。

BIND_MIDI_DEVICE_SERVICE权限
在这里插入图片描述

以下代码段声明了一项 IME 服务:

<!-- Declares the input method service -->
<service android:name="FastInputIME"
    android:label="@string/fast_input_label"
    android:permission="android.permission.BIND_INPUT_METHOD">
    ***//请求BIND_MIDI_DEVICE_SERVICE让此服务可以将IME连接到系统***
    <intent-filter>
   //设置一个与InputMethod操作匹配的intent过滤器
        <action android:name="android.view.InputMethod" />
        
    </intent-filter>
    ***//定义此IME的元数据***
    <meta-data android:name="android.view.im"
               android:resource="@xml/method" />
</service>

控制IME 设置的 Activity

<!-- Optional: an activity for controlling the IME settings -->
<activity android:name="FastInputIMESettings"
    android:label="@string/fast_input_settings">
    <intent-filter>
        <action android:name="android.intent.action.MAIN"/>
    </intent-filter>
</activity>

输入法API

android.inputmethodservice 和 android.view.inputmethod 软件包中提供了 IME
专用的类。KeyEvent 类对于处理键盘字符非常重要。

KeyboardView

用于呈现键盘和响应用户输入事件的 View 的扩展。键盘布局由 Keyboard 的实例指定,可以在 XML 文件中定义该实例

BaseInputConnection

定义从 InputMethod
返回到接收其输入的应用的通信渠道。可以使用该类读取光标周围的文本,将文本提交至文本框,然后将原始按键事件发送到应用。应用应扩展该类,而不是实现基接口
InputConnection。

设计输入法界面:

输入视图

输入视图是指用户以点击按键、手写或手势的形式输入文本的界面。当 IME 首次显示时,系统会调用 onCreateInputView()
回调。

  • onCreateInputView 创建键盘区域视图,返回 layout 布局.

候选试图

候选视图是指 IME 显示可能的字词更正或文字建议供用户选择的界面。在 IME 生命周期中,系统会在准备好显示候选视图时调用
onCreateCandidatesView()。

  • onCreateCandidatesView 创建候选框区域视图,返回 layout 布局.该视图是非必要的,如果不想显示任何内容可以返回Null,事实上,Null的响应是默认行为,该方法可以不实现。

4.编写一个简单的输入法

在AndroidManifest.xml中:

<!-- 输入法服务 -->
<service
    android:name="com.....自定义InputMethodService"
    android:label="@string/app_name"
    android:permission="android.permission.BIND_INPUT_METHOD" >//请求权限绑定输入法,请求 InputMethodService 服务,只有系统才能使用。
    <intent-filter>
        <action android:name="android.view.InputMethod" />
    </intent-filter>
    <meta-data
        android:name="android.view.im"
        android:resource="@xml/method" />
</service>
<!-- 输入法设置界面 -->
<activity android:name="com.....setting.自定义SettingsActivity" >
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
    </intent-filter>
</activity>

method.xml

<input-method xmlns:android="http://schemas.android.com/apk/res/android"
    android:isDefault="true"
    
    android:settingsActivity="com.....setting.自定义SettingsActivity" />
    //输入法设置界面

以下是部分功能的方法

1.光标的左右移动

/**
	 * 输入框的光标向右移动
	 */
	public void setCursorRightMove() {
		int cursorPos = getSelectionStart();
		cursorPos++;
		getCurrentInputConnection().setSelection(cursorPos, cursorPos);
	}

	/**
	 * 输入框的光标向左移动
	 */
	public void setCursorLeftMove() {
		int cursorPos = getSelectionStart();
		cursorPos--;
		if (cursorPos < 0)
			cursorPos = 0;
		getCurrentInputConnection().setSelection(cursorPos, cursorPos);
	}

2.文字输入到EditText

	/**
	 * 文字输入到EditText
	 */
public void commitResultText(String resultText) {
    InputConnection ic = getCurrentInputConnection();
    if (null != ic && !TextUtils.isEmpty(resultText)) {
	    ic.commitText(resultText, 1);
    }
}

3.输入法显示不占据全屏

	/**
	 * 输入法显示不占据全屏
	 */
@Override
public boolean onEvaluateFullscreenMode() {
    return false;
}

洪荣键
原文地址:https://blog.csdn.net/m0_56202936/article/details/128056382

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

每日一题:斐波那契数列

每日一题&#xff1a;斐波那契数列 我们先来看一下斐波那契数列的定义&#xff1a; 斐波那契数列&#xff08;Fibonacci sequence&#xff09;&#xff0c;又称黄金分割数列&#xff0c;因数学家莱昂纳多斐波那契&#xff08;Leonardo Fibonacci&#xff09;以兔子繁殖为例子而…

Linux进程调度(二)——主动调度

目录 分析__schedule() 第一步&#xff1a; 第二步&#xff1a; pick_next_task的实现如下&#xff1a; 第三步&#xff1a; 进程上下文切换 内存空间的切换&#xff1a; 寄存器和栈的切换switch_to 指令指针的保存与恢复 总结 进程的调度分为两种方式&#xff0c;本篇…

MOOC——多项式加法(5分)好难!

1.多项式加法&#xff08;5分&#xff09; 题目内容&#xff1a; 一个多项式可以表达为x的各次幂与系数乘积的和&#xff0c;比如&#xff1a; 2x63x512x36x20 现在&#xff0c;你的程序要读入两个多项式&#xff0c;然后输出这两个多项式的和&#xff0c;也就是把对应的幂…

java GUI 实现的socket在线聊天系统项目源码运行教程

大家好&#xff0c;今天给大家演示一下一个简单的图形界面的聊天程序&#xff0c;上次我们演示的是Java实现的群聊程序&#xff0c;还可以发送文件&#xff0c;今天这个小程序只能聊天&#xff0c;不能发文件&#xff0c;功能非常简单&#xff0c;可在局域网内实现互相聊天&…

html当当书网站 html网上在线书城 html在线小说书籍网页 当当书城网页设计

&#x1f389;精彩专栏推荐 &#x1f4ad;文末获取联系 ✍️ 作者简介: 一个热爱把逻辑思维转变为代码的技术博主 &#x1f482; 作者主页: 【主页——&#x1f680;获取更多优质源码】 &#x1f393; web前端期末大作业&#xff1a; 【&#x1f4da;毕设项目精品实战案例 (10…

社区系统项目复盘-7

文章目录Spring Security权限控制置顶、加精、删除Redis高级数据类型网站数据统计使用Spring Security进行权限控制&#xff0c;对登录检查功能进行了重写。对不同的登录账号授予不同的权限&#xff0c;实现了置顶、加精、删除功能。使用Redis高级数据类型HyperLogLog和Bitmap实…

2-分类问题 SVM 核函数

目录 一&#xff0c;核函数的引入 二&#xff0c;核函数的定义 三&#xff0c;核函数介绍&#xff1a; 四&#xff0c;核函数总结&#xff1a; 一&#xff0c;核函数的引入 世界上本来没有两个完全一样的物体&#xff0c;对于所有的两个物体&#xff0c;我们可以通过增加维…

ES6 Reflect

前言 此文总结了Reflect对象的部分语法&#xff0c;对比了与Object方法的差异性&#xff0c;希望对你有用。 语法 Reflect与Math类似&#xff0c;都是JavaScript内置对象&#xff0c;提供了工具方法。 typeof Reflect // objectget Reflect.get(target, property, receiver) …

冷热电气多能互补的微能源网鲁棒优化调度(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

Linux——VIM编辑器(详细)

目录 一、基本简介 1.1 基本简介 1.2 我们怎么使用终端进入到桌面&#xff1f; 1.3 模式间转换 二、一般模式 2.1 操作指令 2.2 什么情况下是一般模式呢&#xff1f; 2.3 怎么进行光标的快速移动&#xff1f; 2.4 复制粘贴操作 2.5 删除操作 三、编辑模式 四、命令行…

Java项目:SSM教师师资管理系统

作者主页&#xff1a;源码空间站2022 简介&#xff1a;Java领域优质创作者、Java项目、学习资料、技术互助 文末获取源码 项目介绍 本项目包含管理员与教师两种角色&#xff1b; 管理员角色包含以下功能&#xff1a; 管理员角色登录,教师管理,教师授课管理,审批教师的项目开…

【前沿技术RPA】 一文了解UiPath 文件与文件夹自动化功能

&#x1f40b;作者简介&#xff1a;博主是一位.Net开发者&#xff0c;同时也是RPA和低代码平台的践行者。 &#x1f42c;个人主页&#xff1a;会敲键盘的肘子 &#x1f430;系列专栏&#xff1a;UiPath &#x1f980;专栏简介&#xff1a;UiPath在传统的RPA&#xff08;Robotic…

[YOLOv7/YOLOv5系列改进NO.40]融入适配GPU的轻量级 G-GhostNet

文章目录前言一、解决问题二、基本原理三、​添加方法四、总结前言 作为当前先进的深度学习目标检测算法YOLOv7&#xff0c;已经集合了大量的trick&#xff0c;但是还是有提高和改进的空间&#xff0c;针对具体应用场景下的检测难点&#xff0c;可以不同的改进方法。此后的系列…

头歌计算机组成原理汉字字库存储芯片扩展实验

全部答案点击底部 <?xml version"1.0" encoding"UTF-8" standalone"no"?> <project source"2.15.0.2.exe" version"1.0"> This file is intended to be loaded by Logisim http://logisim.altervista.org &…

如何在 Spring 或 Spring Boot 中使用键集分页

介绍 在本文中&#xff0c;我将向您展示如何在 Spring 或 Spring Boot 中使用键集分页技术。 虽然 Spring DataPagingAndSortingRepository提供的基于偏移量的默认分页在许多情况下很有用&#xff0c;但如果您必须迭代大型结果集&#xff0c;那么键集分页或查找方法技术可以提…

使用awk聚合和排序

用awk聚合和排序 文章目录用awk聚合和排序一、需求1.1 源文件格式1.2 需求二、用awk实现2.1 写法2.2 效果一、需求 1.1 源文件格式 一份csv文件&#xff08;默认逗号分隔&#xff09;一共五列&#xff0c;其中一列是用户名文件名&#xff1a;日志文件.csv type日记idusernam…

Android使用ListView,DrawerLayout实现简单注册功能界面

1.效果展示 2.实现 1.主页面activity_main.xml 主页面就是简单的几个TextView和EditText以及单选框组成的一个注册表单。 <?xml version"1.0" encoding"utf-8"?> <LinearLayoutxmlns:android"http://schemas.android.com/apk/res/andro…

[附源码]JAVA毕业设计口腔医院网站(系统+LW)

[附源码]JAVA毕业设计口腔医院网站&#xff08;系统LW&#xff09; 目运行 环境项配置&#xff1a; Jdk1.8 Tomcat8.5 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&…

java通过lock实现同步锁

这里我们是一个卖票的演示代码 其实 同步锁 远不止一个synchronized 它本身有一个 加上锁 和释放锁的过程 为了 让我们更好的理解这个过程 JDK5之后 为我们提供了一个单独的锁工具 lock lock是一个接口 他提供了 synchronized 方法 和 更广泛的语句操作 lock方法 获得锁 unl…

【C语言】函数传参与指针理解

文章目录指针与变量注意指针的本质指针和变量的用法函数与传参传变量与传指针的区别传变量与传指针的时机指针与变量 大三&#xff0c;但是C语言。目标&#xff1a;高屋建瓴&#xff0c;深入浅出。 注意 所有人在最开始学C语言的时候&#xff0c;老师都会和你说指针指向一个…