目录
文件目录结构:
/src 代码文件目录
/src/com/soling/inputMethod 主体逻辑类代码目录
/src/com/soling/inputMethod/EN 针对英文键盘逻辑代码目录[注:目前未使用]
/src/com/soling/inputMethod/JAPA 针对日语键盘逻辑代码目录
/src/com/soling/inputMethod/presenter P层业务逻辑接口以及实现类
/src/com/soling/inputMethod/Service 与AutoCore(音源管理apk)交互的代理实现类
/libs 日语SO库源码
/res 各资源文件目录
/res/xml 键盘布局定义文件目录
/….. 其余目录此处暂省略不再介绍
各类功能说明
类名 | 说明 |
BaseInputView.java | 继承LinearLayout,输入法的基础布局自定义类 |
CandidateFilter.java | 候选词过滤的工具类 |
CandidatesViewManager.java | 候选栏界面管理器的基类 |
CandidateTextView.java | 继承TextView,各候选词的装载容器 |
CandidateViewButton.java | 继承Button,同上 |
ComposingText.java | 用于处理提交文本的工具类 |
DefaultSoftKeyboard.java | 继承InputViewManager,用于处理各键盘的操作交互逻辑的基类 |
InputViewManager.java | 定义了键盘管理器中通用的管理接口 |
KeyAction.java | 按键动作实体类 |
Keyboard.java | 键盘布局的解析工具类 |
KeyboardView.java | 继承View,绘制键盘的自定义布局类 |
LetterConverter.java | 定义了文字转换工具相关的接口 |
OpenWnn.java | 继承于InputMethodService,输入法服务的实现基类,处理通用操作 |
OpenWnnEN.java | 继承于Openwnn类,英文输入法服务实现类,处理英文输入法[暂未使用] |
OpenWnnJAJP.java | 继承于Openwnn类,日语输入法服务实现类,处理日语输入法逻辑 |
TextCandidates1LineViewManager.java | 继承于CandidatesViewManager,一行式候选框的实现逻辑 |
TextCandidatesViewManager.java | 继承于CandidatesViewManager,多行式候选框的实现逻辑 |
DefaultSoftKeyboardJAJP.java | 继承于DefaultSoftKeyboard,用于处理日语输入法键盘中的交互逻辑,如输入事件分发,切换输入模式等等 |
IPersenter.java | P层业务接口定义 |
IPerserterImpl.java | 继承于IPersenter .P层业务接口实现类 |
AutoSetsProxy.java | 于AutoCore交互的代理类 |
…… | 其他类暂不介绍 |
部分改动修改记录说明
3.1 针对项目需求增加换肤功能
换肤功能由于输入法的特殊性输入法服务启动快于AutoCore,快于换肤模块启动,且输入法布局是以window形式存在所以无法使用通用的调用相关模块进行换肤,目前主要实现逻辑如下:
3.1.1 定义全局变量mSkin通过读取Setting中的值获取皮肤的值从而确定使用皮肤为哪一套
相关代码如下[ /src/com/soling/inputMethod/OpenWnn.java OnCreate()方法中]:
mSkin =Settings.System.getString(getContentResolver(),"zjb");
3.1.2 定义一个获取接口供给各类使用
相关代码如下[ /src/com/soling/inputMethod/OpenWnn.java]:
public String getmSkin(){
return TextUtils.isEmpty(mSkin)?SKIN_FUTURE:mSkin;
}
3.1.2 通过上面提供方法在有关布局加载的地方修改布局逻辑
例如:
键盘大背景修改,代码如下[ /src/com/soling/inputMethod/DefaultSoftKeyboard.java initView()方法中]:
mSkin = parent.getmSkin();
if (mSkin != null)
if (mSkin.equals(OpenWnn.SKIN_GIRL)) {
skin = "keyboard_simple";
} else if (mSkin.equals(OpenWnn.SKIN_STABLE)) {
skin = "keyboard_matla";
} else if (mSkin.equals(OpenWnn.SKIN_FUTURE)) {
skin = "keyboard_tech";
}
……
int id = parent.getResources().getIdentifier(skin, "layout", "com.soling.inputMethod");
mKeyboardView = (KeyboardView)mWnn.getLayoutInflater().inflate(id, null);
键盘候选框背景修改,代码如下
[ /src/com/soling/inputMethod/TextCandidates1LineViewManager.java initView()方法中]
mSkin = parent.getmSkin();
ll_candidatetext.setBackgroundResource(R.drawable.keyboard_words_display_bg);
if(mSkin!=null){
if(mSkin.equals(OpenWnn.SKIN_GIRL)){
ll_candidatetext.setBackgroundResource(R.drawable.keyboard_words_display_bg);
}elseif(mSkin.equals(OpenWnn.SKIN_STABLE)){
ll_candidatetext.setBackgroundResource(R.drawable.matla_keyboard_words_display_bg);
}elseif(mSkin.equals(OpenWnn.SKIN_FUTURE)){
ll_candidatetext.setBackgroundResource(R.drawable.tech_keyboard_words_display_bg);
}
}
……其余换肤[键盘按键,候选词等等]逻辑雷同不再举例写出。
3.2 针对项目需求增加行车警告功能
由于项目需求输入法在行车时不允许使用,需要出现弹框提示,主要实现逻辑如下:
3.2.1 通过AutoCore获取当前行车状态,并且对行车状态实时监听
AutoCore获取当前行车状态的接口为:isParking();
通过代理类在每次显示调用输入法时候去获取一次行车状态作为初始化状态值,代码如下[/src/com/soling/inputMethod/OpenWnn.javaonWindowShown()方法中]:
if(mPersenter!=null)
isParking = mPersenter.isParking();
if (mInputViewManager != null)
if(!isParking){
((DefaultSoftKeyboard)mInputViewManager).showDialogInkeyboard(true);
}else{
(DefaultSoftKeyboard)mInputViewManager).showDialogInkeyboard(false);
}
注册监听接口后回调为: onParkingResponse(int brakeStateFromMcu)
该回调通过P层传达到输入法应用服务层,交由应用服务层进行处理具体情况
代码如下 [/src/com/soling/inputMethod/OpenWnn.java]:
public void onParkingResponse(int brakeStateFromMcu){
isParking = (brakeStateFromMcu>0);
if(mInputViewManager!=null)
if(!isParking){
((DefaultSoftKeyboard)mInputViewManager).showDialogInkeyboard(true);
}else{
((DefaultSoftKeyboard)mInputViewManager).showDialogInkeyboard(false);
}
}
3.2.2 显示以及隐藏逻辑,主要在DefaultSoftKeyboard里面处理,其内部封装了showDialogInkeyboard方法对其显示和隐藏进行处理,通过发送Handler消息对UI进行处理。
代码如下[/src/com/soling/inputMethod/DefaultSoftKeyboard.java]:
public void showDialogInkeyboard(boolean isShow) {
if (handler != null) {
Message msg = handler.obtainMessage();
if (mWnn != null) {
if (isShow) {
isShowDialogTv = true;
if (mMainRl != null)
mViewGroup=(ViewGroup) mMainRl.getParent().getParent();
if (handler.hasMessages(MSG_SHOW_POP))
handler.removeMessages(MSG_SHOW_POP);
msg.what = MSG_SHOW_POP;
handler.sendMessage(msg);
} else {
isShowDialogTv = false;
if (handler.hasMessages(MSG_HIDE_POP))
handler.removeMessages(MSG_HIDE_POP);
msg.what = MSG_HIDE_POP;
handler.sendMessage(msg);
}
}
}
}
在handler进行重新计算大小然后显示和隐藏popwindow弹框,因为存在界面忙于接口show出来的问题,可能会出现错误,因此handler中进行了一个50ms的重发处理机制,具体代码查看源码[/src/com/soling/inputMethod/DefaultSoftKeyboard.javaMyHandler内部类中]。
3.3 切换语言后输入法弹框的行车警告框文字未变更问题处理
由于语言切换后popwindow的界面内容没有更新所以导致文字没有变更,所以处理机制为注册语言变换的广播接收器,当收到语言切换的广播后重新加载popwindow界面,具体代码如下:
[/src/com/soling/inputMethod/OpenWnn.java]
public class LocaleChangeReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if(intent.getAction().equals(Intent.ACTION_LOCALE_CHANGED)) {
if(mInputViewManager!=null)
((DefaultSoftKeyboard)mInputViewManager).updatePopWindow();
}
}
}
[/src/com/soling/inputMethod/OpenWnn.java onCreate()方法中注册广播接收器]
changeReceiver = new LocaleChangeReceiver();
IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_LOCALE_CHANGED);
registerReceiver(changeReceiver, filter);
[/src/com/soling/inputMethod/DefaultSoftKeyboard.java updatePopWindow()重新加载界面]
if(handler!=null){
if (handler.hasMessages(MSG_UPDATA_POP))
handler.removeMessages(MSG_UPDATA_POP);
handler.sendEmptyMessage(MSG_UPDATA_POP);
}
3.4 屏蔽预览弹框以及长按弹框
原版代码中输入法键盘触摸后会显示相应预览弹框以及部分按键候选词长按后会有弹框出现,由于不符合设计需求因此将其相关方法屏蔽。具体如下:
3.4.1 屏蔽预览弹框:
[/src/com/soling/inputMethod/DefaultSoftKeyboard.java setPreferences方法中将值设为false即不可使用]
……
if (OpenWnn.isXLarge()) {
mKeyboardView.setPreviewEnabled(false);
} else {
mKeyboardView.setPreviewEnabled(pref.getBoolean("popup_preview",
false));
mKeyboardView.clearWindowInfo();
}
3.4.2 屏蔽候选词长按后出现弹框:
[/src/com/soling/inputMethod/TextCandidates1LineViewManager
.java以及TextCandidatesViewManager.java]中屏蔽有关于displayDialog(v, mWord);方法的调用
或者在[/src/com/soling/inputMethod/CandidatesViewManager] 将displayDialog方法中的操作进行屏蔽
3.5 有关于键盘按键输入事件的分析
键盘按键的处理首先在KeyboardView.java中进行触摸(onTouch)事件的处理,其中涉及到长按,滑动等等特殊处理,当手指抬起后若符合条件则将按键事件传递给DefaultSoftKeyboard.java的子类[DefaultSoftKeyboardJAJP.java]中onKey事件中处理一系列事件,如切换键盘输入模式,输入文字等等事件的处理,里面根据所传的primaryCode【该值其实就是键盘实体类中的KeyCode】参数进行事件分类处理。切换键盘输入模式在该类中封装好了方法调用,而与输入文字相关的则进一步的传递给OpenWnn.java的子类[OpenWnnJAJP.java]中的onEvent事件进行相关事件处理。
3.6 五十音键盘功能开发
出于日本客户需求需要定制一个五十音全键键盘。
首先是定制键盘的布局,输入法键盘主体布局是由xml文件夹里各个.xml写成,文件书写格式其实就是自定义View布局书写方式具体内容可以查看源代码进行学习,自定义五十音相关的keycode值以及定义相应显示文本字符串,修改准备拿来替换的布局文件【注:AVN项目中修改了全角英文(FULL_ALPHABET)和全角数字(FULL_NUMBER)的键盘布局文件用来替换成五十音平假名和片假名的布局,借用两个存在的布局作为改写可以省下很多逻辑修改,如要真的新增两个键盘,则需要按照整体框架下修改大幅度的切换逻辑】,修改完的xml将会通过Keyboard.java类进行数据解析生成各个键盘的实体类数据,然后通过keyboardView绘制展示出来。接下来则按照3.5所描述内容进行事件处理,增加新的Event事件书写新的case分支处理相关输入逻辑。