拼音输入法(MPinyinIME)
来源:互联网 发布:大数据 应用 编辑:程序博客网 时间:2024/05/09 20:17
目录结构
jni/ - Java Native Interface, 用C/C++实现拼音输入法的功能,供上层Java代码调用的底层代码。
lib/ - 用AIDL文件给上层JAVA应用定义了jni可用的接口集IPinyinDecoderService。AIDL请参考
res/ - Android项目的资源目录(系统静态字典数据文件dict_pinyin.dat也放在这个目录下的raw子目录里)
broadcast delayed
输入法编译选项:
framework里面也有个这种配置 不过device下面的又设置了一次,把framework的覆盖了
http://blog.csdn.net/jianguo_liao19840726/article/details/25370407
http://blog.csdn.net/pi9nc/article/details/9196779
http://blog.csdn.net/z_guijin/article/details/6728197 输入法 DEBUG调式.
第一步,需要理解输入法的XML原理,改界面布局需要改这里.
还需要调用语言什么的?
===================================================
PinyinIME.java
=== 输入法主界面 public View onCreateInputView() {
R.layout.skb_container ->
类似,只是processkey用true作为第二个参数。 Processkey调用commitResultText/sendKeyChar等输入法框架函数把键码送到输入处理。PinyinIME里commitResultText对全键盘和九宫格的处理也不一样,一个是通过SkbContainer处理,一个是直接调用各输入法的commitResultText实现。
com.android.inputmethod.pinyin.SkbContainer
com.android.inputmethod.pinyin.SoftKeyboardView
=== 候选区界面 public View onCreateCandidatesView() {
R.layout.floating_container -> com.android.inputmethod.pinyin.ComposingView
=== 输入法配置界面 SettingsActivity.java settings.xml
=== public boolean onKeyDown(int keyCode, KeyEvent event) {
-----------------------------------
skb_phone.xml
数字键盘有BUG ,需要改写,添加移动方框.
XmlKeyboardLoader.java
public SoftKeyboard loadKeyboard(int resourceId, int skbWidth, int skbHeight) { 调用
SoftKeyboard.java 键值的处理. (添加 beginNewRow, addSoftKey)
private List<KeyRow> mKeyRows;
public class SoftKey { 一个键值的属性.
----------------------------
如何判断是数字键盘,还是字符键盘的.
在 InputModeSwitcher.java 中的 getSkblayout 函数.
requestInputWithHkb
现在的问题是 当用户选择按键后,代码中是如何显示出去的???
public void responseSoftKeyEvent(SoftKey sKey) {
==================================
===================================
ondraw(... ...{
RectF outerRect = new RectF(left, top, right, bottom);
Paint paint = new Paint();
paint.setColor(Color.WHITE);
paint.setAntiAlias(true);
paint.setStyle(Paint.Style.STROKE);//设置空心
canvas.drawRoundRect(outerRect, 5, 5, paint);
==================================
==================================
XML 键盘布局分析
==================================
【如何创建一个 键盘 布局】
需要添加土耳其或者其它国际化的版本的.
第一个必须是 <keyboard
# 一行的键值. 比如 1, 2, 3, -
<row>
<key # 如果是普通的键值 可以考虑 keys
<toggle_state # 如果需要添加按键 效果.
... ...
... ...
</row>
#
结尾 </keyboard>
keyboard 的属性值说明:
# 数字
balloon="false" : 是否显示提示框.
height="25%p"
key_type="0"
repeat="false"
skb_template="@xml/skb_template1"
width="25%p"
# 字母
balloon="true"
height="25%p"
key_type="0"
qwerty="true"
qwerty_uppercase="true"
repeat="false"
skb_cache_flag="true"
skb_template="@xml/skb_template1"
width="10%p"
# 符号
balloon="true"
height="25%p"
key_type="0"
repeat="false"
skb_cache_flag="true"
skb_template="@xml/skb_template1"
width="10%p"
==================================
各个过程分析记录
==================================
当鼠标点击 软键盘 输出字符到编辑框的过程
SKbContainer.java
鼠标点击软键盘的过程.
public boolean onTouchEvent(MotionEvent event) {
// 绘制了按下的颜色.
case MotionEvent.ACTION_DOWN: // 按下的时候
mSoftKeyDown = mSkv.onKeyPress(x - mSkvPosInContainer[0], y
- mSkvPosInContainer[1], mLongPressTimer, false);
case MotionEvent.ACTION_UP: // 起来的时候
// 去掉按下的颜色
// 字符提示窗口
// 输入字符到编辑框
if (null != mSkv) {
mSkv.onKeyRelease(x - mSkvPosInContainer[0], y
- mSkvPosInContainer[1]);
}
SoftKeryboardView.java
public SoftKey onKeyRelease(int x, int y) { // 去掉按下的颜色 字符提示窗口
responseKeyEvent(mSoftKeyDown); // 输入字符到编辑框
((PinyinIME) mService).responseSoftKeyEvent(sKey); // 发送按键字符.
============================================
============================================
遥控器移动点击OK输出字符到编辑框的过程: (痛鼠标按下的过程差不过的)
realAction : 用于判断为 按下(false) 和松开(true)!!!
SdbContainer.java
按键按下的时候:
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) { // PinYinIME.java
private boolean processKey(KeyEvent event, boolean realAction) { // PinYinIME.java
private boolean processFunctionKeys(int keyCode, boolean realAction) { // PinYinIME.java
private boolean processEnterKeys(int keyCode, boolean isAccfter) { // PinYinIME.java
public void actionForEnterDown() {
mSkv.onKeyPress(mSoftKeyDown.mLeft - mSkvPosInContainer[0], mSoftKeyDown.mTop
- mSkvPosInContainer[1], mLongPressTimer, false); // SoftKeryboardView.java
按键起来的时候:
@Override
public boolean onKeyUp(int keyCode, KeyEvent event) { // PinyinIME.java
private boolean processKey(KeyEvent event, boolean realAction) {
private boolean processFunctionKeys(int keyCode, boolean realAction) {
private boolean processEnterKeys(int keyCode, boolean isAccfter) { // PinyinIME.java
public void actionForEnterUp() { // SkbContainer.java
mSkv.onKeyRelease(mSoftKeyDown.mLeft - mSkvPosInContainer[0], mSoftKeyDown.mTop
- mSkvPosInContainer[1]); // 恢复按下的键
responseKeyEvent(mSoftKeyDown); // 发送字符 SoftKeryboardView.java
=============================================
输入法布局XML界面的解析过程分析
=============================================
skbCoreWidth:1280/skbCoreHeight:280 这里主要根据 width="10%p" ,然后换算出来的按键宽度.
XmlKeyboardLoader.java
@Override
public void onStartInputView(EditorInfo editorInfo, boolean restarting) { // PinyinIME.java
public void updateInputMode() { // SkbContainer.java
private void updateSkbLayout() { // SkbContainer.java
switch (mSkbLayout) {
case R.xml.skb_qwerty:
majorSkb = skbPool.getSoftKeyboard(R.xml.skb_qwerty,
R.xml.skb_qwerty, screenWidth, skbHeight, mContext); // 解析XML布局.
getSoftKeyboard --- SkbPool.java
public SoftKeyboard loadKeyboard(int resourceId, int skbWidth, int skbHeight) {
while (mXmlEventType != XmlResourceParser.END_DOCUMENT) {
if (XMLTAG_KEYBOARD.compareTo(attr) == 0) {
---- 当软键盘又点击切换的时候,
public void responseSoftKeyEvent(SoftKey sKey) { // PinyinIME.java
if (sKey.isUserDefKey()) {
updateIcon(mInputModeSwitcher.switchModeForUserKey(keyCode));
resetToIdleState(false);
mSkbContainer.updateInputMode(); // 更新输入模式.
if (mDecInfo.isCandidatesListEmpty()) {
dismissCandidateWindow();
}
// ... ...
public void responseSoftKeyEvent(SoftKey sKey) {
if (!mSkbContainer.isCurrentSkbSticky()) {
updateIcon(mInputModeSwitcher.requestBackToPreviousSkb());
resetToIdleState(false);
mSkbContainer.updateInputMode();
}
// 中英文切换
<key start_pos_x="0%p" start_pos_y="75%p"
width="20%p" height="25%p" code="-2" label="中/英文" key_type="1"
repeat="true">
<toggle_state state_id="@string/toggle_en_lower" label="英/中文" code="-2"/>
<toggle_state state_id="@string/toggle_en_upper" label="英/中文" code="-2"/>
</key>
// ?12
<key code="-3" key_type="2" label="\?12"/>
// 删除
<key code="67" key_type="1"
repeat="true"/>
// 空格
<key key_type="5" code="62" icon="@drawable/space_icon"
icon_popup="@drawable/space_popup_icon" width="30.608%p" />
// 句号
<key id="7" start_pos_x="65.304%p" start_pos_y="75%p"
width="14.696%p" height="25%p" label="." key_type="0"
icon="@drawable/period_icon" icon_popup="@drawable/period_popup_icon"/>
// 获取字体颜色
mNormalKeyTextSize = env.getKeyTextSize(false);
mFunctionKeyTextSize = env.getKeyTextSize(true);
// 初始化按键
public boolean setSoftKeyboard(SoftKeyboard softSkb) {
if (null == softSkb) {
return false;
}
mSoftKeyboard = softSkb;
Drawable bg = softSkb.getSkbBackground();
//mSoftKeyboard.getKeyRowForDisplay(0).mSoftKeys.get(0).setKeySelected(true);
// mSoftKeyboard.setOneKeySelected(3,4);
mSoftKeyboard.setOneKeySelected(0,0); // 第0个焦点.
=============================
输入法候选框过程分析
=============================
setCandidatesViewShown(true); 是否显示候选框.
public View onCreateCandidatesView() { // pinyinIME.java
mCandidatesContainer = (CandidatesContainer) inflater.inflate(
R.layout.candidates_container, null); // 候选区
public void showCandidates(PinyinIME.DecodingInfo decInfo, // CandidatesContainer.java
for (int i = 0; i < mFlipper.getChildCount(); i++) {
CandidateView cv = (CandidateView) mFlipper.getChildAt(i);
cv.setDecodingInfo(mDecInfo); // 显示传入的拼音字符.
}
==================================
中/英 文切换过程.
==================================
// SkbContainer.java
private void responseKeyEvent(SoftKey sKey) {
((PinyinIME) mService).responseSoftKeyEvent(sKey);
// PinyinIME.java
public void responseSoftKeyEvent(SoftKey sKey) {
if (sKey.isUserDefKey()) {
// updateIcon(mInputModeSwitcher.switchModeForUserKey(keyCode)); // 中/英 切换.
resetToIdleState(false);
mSkbContainer.updateInputMode();
if (mDecInfo.isCandidatesListEmpty()) {
dismissCandidateWindow(); // 候选框窗口.
}
========================================
中文处理过程
========================================
// PinyinIME.java
private boolean processKey(KeyEvent event, boolean realAction) {
else if (mInputModeSwitcher.isChineseText()) { // 中文
if (mImeState == ImeState.STATE_IDLE ||
mImeState == ImeState.STATE_APP_COMPLETION) {
mImeState = ImeState.STATE_IDLE;
return processStateIdle(keyChar, keyCode, event, realAction);
} else if (mImeState == ImeState.STATE_INPUT) {
return processStateInput(keyChar, keyCode, event, realAction);
} else if (mImeState == ImeState.STATE_PREDICT) { /* 中文 */
return processStatePredict(keyChar, keyCode, event, realAction);
} else if (mImeState == ImeState.STATE_COMPOSING) {
return processStateEditComposing(keyChar, keyCode, event,
realAction);
}
private void updateDecInfoForSearch(int totalChoicesNum) {
private void chooseAndUpdate(int candId) {
if (ImeState.STATE_PREDICT != mImeState) {
// Get result candidate list, if choice_id < 0, do a new decoding.
// If choice_id >=0, select the candidate, and get the new candidate
// list.
mDecInfo.chooseDecodingCandidate(candId); // 搜索中文词组.
private void chooseDecodingCandidate(int candId) {
if (mPosDelSpl < 0) {
totalChoicesNum = mIPinyinDecoderService
.imSearch(mPyBuf, length()); // 搜索中文词组.
private void updateDecInfoForSearch(int totalChoicesNum) {
--------------------------------------------------------
public boolean preparePage(int pageNo) {
private void getCandiagtesForCache() {
mTotalChoicesNum =4
preparePage
mDecInfo.mPageStart
点击中文输出.. ...到编辑框. PinyinIME.java
public void onClickChoice(int choiceId) {
private void onChoiceTouched(int activeCandNo) {
########################
private boolean processStateInput(int keyChar, int keyCode, KeyEvent event,
boolean realAction) {
if (skbFocusEnable) // 防止执行下面的操作.
return true;
if (keyCode == KeyEvent.KEYCODE_DPAD_LEFT) {
mCandidatesContainer.activeCurseBackward();
} else if (keyCode == KeyEvent.KEYCODE_DPAD_RIGHT) {
mCandidatesContainer.activeCurseForward();
# 也许需要改这里.
private boolean processDirectionKeys(int keyCode) {
只有中文才可以上移动去上面,需要改.
########################
不隐藏输入法,遥控器遥控上,编辑框可以去移动光标.
http://www.iteedu.com/handset/android/androidcnapi5/51.php
加入方向上移动,编辑框可以移动光标,而不用退出输入法界面. (研究)
ic.sendKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, keyCode));
ic.sendKeyEvent(new KeyEvent(KeyEvent.ACTION_UP, keyCode));
可以参考这个!!
if (SIMULATE_KEY_DELETE) { // 模拟,点击软键盘上删除.
Log.d(TAG, "bbbbbbbb:" + keyCode);
simulateKeyEventDownUp(keyCode);
修改,给编辑框发送移动.
ic.sendKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DPAD_LEFT));
ic.sendKeyEvent(new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_DPAD_LEFT));
/**
* 在这里加入当打字的时候,没有了,显示出快捷方式出来.
*/
if (mDecInfo != null && mDecInfo.isCandidatesListEmpty()) {
mCandidatesContainer.setInputMethodCandState(CandidateView.INPUT_METHOD_FASTER_STATE); // 设置快捷方式.
}
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="100dp"
android:orientation="vertical" >
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:orientation="horizontal" >
<!-- 头像 -->
<com.open.srx.widgets.CircleImageView
android:id="@+id/active_iv"
android:layout_width="80dp"
android:layout_height="80dp"
android:layout_marginRight="10dp"
android:src="@drawable/radio_kafeiguan_bg" />
<!-- 名字 -->
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical" >
<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="冰雪情缘" />
<TextView
android:id="@+id/textView11"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="学霸" />
</LinearLayout>
</LinearLayout>
<EditText
android:id="@+id/editText1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ems="10" >
<requestFocus />
</EditText>
<EditText
android:id="@+id/editText2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ems="10" />
<Button
android:id="@+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button" />
<Button
android:id="@+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="发布课程" />
<Button
android:id="@+id/button3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="查询课程" />
</LinearLayout>
http://www.360doc.com/content/12/1024/08/1538436_243412962.shtml 语言模型在搜狗输入法中的使用.
http://www.oschina.net/p/libpinyin 开源拼音词库
输入法中文词库分析:
com.android.inputmethod.pinyin/
PinyinDecoderService.java
jni/android/
com_android_inputmethod_pinyin_pinyine_PinyinDe...cpp
-------------------------
/**
* Connection used for binding to the Pinyin decoding service.
* 拼音词库服务的aidl服务连接.
*/
public class PinyinDecoderServiceConnection implements ServiceConnection {
public void onServiceConnected(ComponentName name, IBinder service) {
mDecInfo.mIPinyinDecoderService = IPinyinDecoderService.Stub
.asInterface(service);
}
public void onServiceDisconnected(ComponentName name) {
}
}
----------------------------------
0 0
- 拼音输入法(MPinyinIME)
- 拼音输入法
- 拼音输入法
- 也说搜狗拼音输入法
- QQ拼音输入法
- ubuntu拼音输入法
- 汉字编码 拼音输入法
- 用谷歌拼音输入法
- ubuntu 拼音输入法
- 拼音输入法程序
- google拼音输入法
- 拼音输入法简评
- 拼音输入法实现
- 韩语拼音输入法
- 卸载微软拼音输入法图解
- 删除微软拼音输入法
- Google推出拼音输入法了!
- 谷歌拼音输入法
- SELECT INTO , INSERT INTO SELECT 和 CREATE TABLE AS SELECT 的区别
- 查看网卡流量
- Objective-C学习笔记九:继承一
- 8天玩转并行开发——第六天 异步编程模型
- 使用Java获取IP地址实例
- 拼音输入法(MPinyinIME)
- linux系统调用分析
- HDU1021 - Fibonacci Again (水题 找规律)
- STM32F4——TFT-LCD原理及FSMC
- Objective-C学习笔记十:继承二
- mongoDB 3.0安全权限访问控制
- MFC友好信息提示类
- spring jdbc的使用
- 激活硬盘被关闭的DMA模式