Android系统应用开发(五)android 输入法类说明
原文地址:http://blog.csdn.net/jianguo_liao19840726/article/details/25370407
源码里面有3套输入法,位置:Z:\myandroid\packages\inputmethods
openwnn是一家日本公司开发的开源输入法框架,涉及中文、日文、韩文。目前已经加入到了Android源码之中。因此你打开一个模拟器时,会发现其中有一个japanese ime的输入法,其服务名为openwnn,这个就是openwnn的日文输入法
latin 虚拟即盘
google是PinyinIME ,后续我们加入了手写,为第三方库支持,13年10月份合并手写和拼音输入法!
现在合并后的为PateoIME
上面截图原因,还有个XmlKeyboardLoader.Java
一、ComposingView
- /**
- * View used to show composing string (The Pinyin string for the unselected
- * syllables and the Chinese string for the selected syllables.)
- * 拼音字符串View,用于显示输入的拼音
- */
- public class ComposingView extends View {
其需要设置的字符通过下面方法传入PateoIME.DecodingInfo decInfo,decInfo中包含了输入的字符,同时进行刷新view
- /**
- * Set the composing string to show. If the IME status is
- * {@link PateoIME.ImeState#STATE_INPUT}, the composing view's status will
- * be set to {@link ComposingStatus#SHOW_PINYIN}, otherwise the composing
- * view will set its status to {@link ComposingStatus#SHOW_STRING_LOWERCASE}
- * or {@link ComposingStatus#EDIT_PINYIN} automatically.
- * 设置 解码操作对象,然后刷新View
- */
- public void setDecodingInfo(PateoIME.DecodingInfo decInfo,
- PateoIME.ImeState imeStatus) {
其主要绘制在onDraw的drawForPinyin(canvas);方法中,通过canvas.drawText写入
而上面的setDecodingInfo方法主要在InputMethodService的继承的子类中被调用如下:
- private void updateComposingText(boolean visible) {
- if (!visible) {
- mComposingView.setVisibility(View.INVISIBLE);
- } else {
- mComposingView.setDecodingInfo(mDecInfo, mImeState);
- mComposingView.setVisibility(View.VISIBLE);
- }
- mComposingView.invalidate();
- }
二、SoundManager
- /**
- * Class used to manage related sound resources.
- * 按键声音管理类、单例
- */
- public class SoundManager {
播放声音前需要注册相应的音频策略,下面为播放声音代码:
- public void playKeyDown() {
- if (mAudioManager == null) {
- updateRingerMode();
- }
- if (!mSilentMode) {
- int sound = AudioManager.FX_KEYPRESS_STANDARD;
- mAudioManager.playSoundEffect(sound, FX_VOLUME);
- }
- }
相应的上面响应按键的方法被调用在SoftKeyboardView类的下面方法中
- // If movePress is true, means that this function is called because user
- // moves his finger to this button. If movePress is false, means that this
- // function is called when user just presses this key.
- public SoftKey onKeyPress(int x, int y,
- SkbContainer.LongPressTimer longPressTimer, boolean movePress) {
- if (!movePress) {
- tryPlayKeyDown();
- tryVibrate();
- }
我们项目中是另外的处理方式,其中特别要注意,在应用监听案件事件的时候需要返回true,不然可能按下键盘键听到两次按键音
三、SoftKeyToggle
- /**
- * Class for soft keys which defined in the keyboard xml file. A soft key can be
- * a basic key or a toggling key.
- *
- * @see com.android.inputmethod.pateoime.SoftKey
- */
- public class SoftKeyToggle extends SoftKey {
上面主要定义的为切换键,相应的配置<toggle_state>
四、class SoftKey
上面主要为相应的按键
五、SoftKeyboard
- /**
- * Class used to represent a soft keyboard definition, including the height, the
- * background image, the image for high light, the keys, etc.
- */
- public class SoftKeyboard {
上面主要是软键盘的定义,包括布局和高宽
此类中有个很关键的函数,就是通过xy坐标值找到相应的临近按键
- public SoftKey mapToKey(int x, int y) {
六、SkbTemplate
- /**
- * Soft keyboard template used by soft keyboards to share common resources. In
- * this way, memory cost is reduced.
- */
- public class SkbTemplate {
上面主要为:共享公共资源软键盘模板,对应xml资源包下的skb_template.xml、可以根据不同的设备来加载不同的公共资源,其他自由也类似
七、SkbPool
- /**
- * Class used to cache previously loaded soft keyboard layouts.
- */
- public class SkbPool {
上面说明:用来缓存以前加载的软键盘布局,是一个软键盘缓存池,该类有如下两个变量
- private Vector<SkbTemplate> mSkbTemplates = new Vector<SkbTemplate>();
- private Vector<SoftKeyboard> mSoftKeyboards = new Vector<SoftKeyboard>();
即上面看出缓存了布局模板和软键盘两个列表
八、SkbContainer
- /**
- * The top container to host soft keyboard view(s).
- */
- public class SkbContainer extends RelativeLayout implements OnTouchListener {
上面所说:顶层容器【集装箱】来承载软键盘视图
- /**
- * 更新软键盘布局
- */
- private void updateSkbLayout() {
- int screenWidth = mEnvironment.getScreenWidth();
- int keyHeight = mEnvironment.getKeyHeight();
- int skbHeight = mEnvironment.getSkbHeight();
- Resources r = mContext.getResources();
- if (null == mSkbFlipper) {
- mSkbFlipper = (ViewFlipper) findViewById(R.id.alpha_floatable);
- }
- mMajorView = (SoftKeyboardView) mSkbFlipper.getChildAt(0);
- SoftKeyboard majorSkb = null;
- SkbPool skbPool = SkbPool.getInstance();
- switch (mSkbLayout) {
- case R.xml.skb_qwerty:
- majorSkb = skbPool.getSoftKeyboard(R.xml.skb_qwerty,
- R.xml.skb_qwerty, screenWidth, skbHeight, mContext);
- break;
- case R.xml.skb_sym1:
- majorSkb = skbPool.getSoftKeyboard(R.xml.skb_sym1, R.xml.skb_sym1,
- screenWidth, skbHeight, mContext);
- break;
- case R.xml.skb_sym2:
- majorSkb = skbPool.getSoftKeyboard(R.xml.skb_sym2, R.xml.skb_sym2,
- screenWidth, skbHeight, mContext);
- break;
- case R.xml.skb_smiley:
- majorSkb = skbPool.getSoftKeyboard(R.xml.skb_smiley,
- R.xml.skb_smiley, screenWidth, skbHeight, mContext);
- break;
- case R.xml.skb_phone:
- majorSkb = skbPool.getSoftKeyboard(R.xml.skb_phone,
- R.xml.skb_phone, screenWidth, skbHeight, mContext);
- break;
- default:
- }
- if (null == majorSkb || !mMajorView.setSoftKeyboard(majorSkb)) {
- return;
- }
- mMajorView.setBalloonHint(mBalloonOnKey, mBalloonPopup, false);
- mMajorView.invalidate();
- }
- @Override
- public boolean onTouchEvent(MotionEvent event) {
- super.onTouchEvent(event);
- if (mSkbFlipper.isFlipping()) {
- resetKeyPress(0);
- return true;
- }
- int x = (int) event.getX();
- int y = (int) event.getY();
- // Bias correction
- y = y + mYBiasCorrection;
- // Ignore short-distance movement event to get better performance.
- if (event.getAction() == MotionEvent.ACTION_MOVE) {
- if (Math.abs(x - mXLast) <= MOVE_TOLERANCE
- && Math.abs(y - mYLast) <= MOVE_TOLERANCE) {
- return true;
- }
- }
- mXLast = x;
- mYLast = y;
- if (!mPopupSkbShow) {
- // mGestureDetector的监听器在输入法服务PinyinIME中。
- if (mGestureDetector.onTouchEvent(event)) {
- resetKeyPress(0);
- mDiscardEvent = true;
- return true;
- }
- }
- switch (event.getAction()) {
- case MotionEvent.ACTION_DOWN:
- resetKeyPress(0);
- mWaitForTouchUp = true;
- mDiscardEvent = false;
- mSkv = null;
- mSoftKeyDown = null;
- mSkv = inKeyboardView(x, y, mSkvPosInContainer);
- if (null != mSkv) {
- mSoftKeyDown = mSkv.onKeyPress(x - mSkvPosInContainer[0], y
- - mSkvPosInContainer[1], mLongPressTimer, false);
- }
- break;
- case MotionEvent.ACTION_MOVE:
- if (x < 0 || x >= getWidth() || y < 0 || y >= getHeight()) {
- break;
- }
- if (mDiscardEvent) {
- resetKeyPress(0);
- break;
- }
- if (mPopupSkbShow && mPopupSkbNoResponse) {
- break;
- }
- SoftKeyboardView skv = inKeyboardView(x, y, mSkvPosInContainer);
- if (null != skv) {
- if (skv != mSkv) {
- mSkv = skv;
- mSoftKeyDown = mSkv.onKeyPress(x - mSkvPosInContainer[0], y
- - mSkvPosInContainer[1], mLongPressTimer, true);
- } else if (null != skv) {
- if (null != mSkv) {
- mSoftKeyDown = mSkv.onKeyMove(
- x - mSkvPosInContainer[0], y
- - mSkvPosInContainer[1]);
- if (null == mSoftKeyDown) {
- mDiscardEvent = true;
- }
- }
- }
- }
- break;
- case MotionEvent.ACTION_UP:
- if (mDiscardEvent) {
- resetKeyPress(0);
- break;
- }
- mWaitForTouchUp = false;
Android系统应用开发(五)android 输入法类说明相关推荐
- Android系统级开发进程清理功能的一些记录和发现(一)
Android系统级开发清理功能的一些记录和发现 客户需求做一键清理所有后台进程的功能,在查阅网上相关博客以及自己研究以后找到以下几种方法: killBackgroundProcesses() 这种方 ...
- Android系统级开发进程清理功能的一些记录和发现
Android系统级开发清理功能的一些记录和发现 客户需求做一键清理所有后台进程的功能,在查阅网上相关博客以及自己研究以后找到以下几种方法: killBackgroundProcesses() 这种方 ...
- android原生系统开发板,刷android系统到开发板上.doc
刷android系统到开发板上 将安卓系统刷系统到开发板上 马亲民 2014.12.20 1.擦除NAND FLASH中原有的Windows CE1 2.加载USB引导文件4 3.下载Linux内核9 ...
- 视频教程-基于NDK、C++、FFmpeg的android视频播放器开发实战-Android
基于NDK.C++.FFmpeg的android视频播放器开发实战 夏曹俊:南京捷帝科技有限公司创始人,南京大学计算机硕士毕业,有15年c++跨平台项目研发的经验,领导开发过大量的c++虚拟仿真,计算 ...
- Android 音视频开发(六) -- Android Mediaprojection 截屏和录屏
Android 音视频开发(一) – 使用AudioRecord 录制PCM(录音):AudioTrack播放音频 Android 音视频开发(二) – Camera1 实现预览.拍照功能 Andro ...
- Android 系统(188)---Android开发:ListView、AdapterView、RecyclerView全面解析
Android开发:ListView.AdapterView.RecyclerView全面解析 目录 ListView.AdapterView.RecyclerView全面解析.png Adapter ...
- android系统nfc开发,GitHub - hanjie511/MyNFC: android的NFC开发入门
MyNFC android的NFC开发入门 NFC简述 近距离无线通信 (NFC) 是一组近距离无线技术,通常只有在距离不超过 4 厘米时才能启动连接.借助 NFC,您可以在 NFC 标签与 Andr ...
- android系统应用开发_利用ADB工具免root停用Android系统应用
最近迷上了安卓的开发,写篇冻结app的教程吧. 主要是实现,免root冻结系统中的某些应用,你懂得哈哈 利用ADB工具免root停用Android系统应用 - Hanadahanada.info 上 ...
- Android 系统(252)---Android:BLE智能硬件开发详解
Android:BLE智能硬件开发详解 目录 前言 BLE是个什么鬼 BLE中的角色分工 主要的关键词和概念 GATT(Generic Attribute Profile ) Characteris ...
最新文章
- [转]Oracle DB 复制数据库
- php接口 接受ios或android端图片; php接收NSData数据
- log4j2 配置文件
- 批量提取 caffe 特征 (python, C++, Matlab)(待续)
- 计算机启动时运行ccleaner,Ccleaner的使用方法
- JAVA使用FTPClient类读写FTP
- webgis从基础到开发实践_开源WebGIS教程系列——11.1 GISLite 的开发背景与设计
- 【转载】网站从百度云转入阿里云服务器
- 线上redis一般安在linux_Redis企业级应用-Linux安装搭建一个完整的linxu线上服务(上)...
- 用Visual Studio 2008编写Win32汇编程序
- api 定位 微信小程序 精度_微信小程序城市定位(百度地图API)
- IIS7.5应用程序池集成模式和经典模式的区别介绍
- J1939CANTP
- 3DMax设置长度单位
- 传输层协议介绍(深入学习)
- 设计模式——工厂方法模式
- 老板让全体员工《致加西亚的信》
- 服务器pci数据捕获和信号处理控制器驱动,PCI数据捕获和信号处理控制器是哪个驱动...
- 2017CNCC会议总结(一)
- 人机交互期末复习笔记
热门文章
- Linux C高阶(7)异步处理框架C实现
- php similartext 中文,推荐10款similar_text源码(收藏)
- python 报错:Empty suite
- 想工作嘛!让你[肝]一个月有多累
- 红黑棋子交换java,象棋大挪移 红黑棋子 红先黑后,输了不臭
- 帆软报表设置单元格填报以及根据值的大小进行排名方法
- Allegro基本规则设置指导书之Analysis Modes
- 视频教程-【直通华为HCNA/HCNP系列R篇3】路由器接口配置与管理-华为认证
- Qt 5.15 LTS(长期支持版本)正式发布
- 4年功能测试跳槽,最后选择了学习自动化测试,月薪18K实现逆袭