解读Softkeyboard键盘源码.docx
《解读Softkeyboard键盘源码.docx》由会员分享,可在线阅读,更多相关《解读Softkeyboard键盘源码.docx(48页珍藏版)》请在冰豆网上搜索。
解读Softkeyboard键盘源码
解读键盘
第一天:
学习keyboard整体架构,浏览整体代码!
/src/jiao.jiao目录下有四个java文件:
(1)CandidateView.java
(2)LatinKeyboard.java
(3)LatinKeyboardView.java
(4)SoftKeyboard.java
第二天:
解读理解LatinKeyboard.java
/*
*Copyright(C)2008-2009GoogleInc.
*
*LicensedundertheApacheLicense,Version2.0(the"License");youmaynot
*usethisfileexceptincompliancewiththeLicense.Youmayobtainacopyof
*theLicenseat
*
*http:
//www.apache.org/licenses/LICENSE-2.0
*
*Unlessrequiredbyapplicablelaworagreedtoinwriting,software
*distributedundertheLicenseisdistributedonan"ASIS"BASIS,WITHOUT
*WARRANTIESORCONDITIONSOFANYKIND,eitherexpressorimplied.Seethe
*Licenseforthespecificlanguagegoverningpermissionsandlimitationsunder
*theLicense.
*/
packagejiao.jiao;
importandroid.content.Context;
importandroid.content.res.Resources;
importandroid.content.res.XmlResourceParser;
importandroid.inputmethodservice.Keyboard;
//只要加载了EditorInfo的包,就可以使用其中的常量
importandroid.view.inputmethod.EditorInfo;
publicclassLatinKeyboardextendsKeyboard{
/*
*Keyboard类:
加载一个xml文件,此文件包含键盘的描述,并且存储了各个按键的键值
*本类中加载的xml文件是qwerty.xml文件
*/
privateKeymEnterKey;//定义回车键
//LatinKeyboard的构造方法
publicLatinKeyboard(Contextcontext,intxmlLayoutResId){
super(context,xmlLayoutResId);
}
//LatinKeyboard的构造方法
publicLatinKeyboard(Contextcontext,intlayoutTemplateResId,
CharSequencecharacters,intcolumns,inthorizontalPadding){
super(context,layoutTemplateResId,characters,columns,horizontalPadding);
}
@Override
protectedKeycreateKeyFromXml(Resourcesres,Rowparent,intx,inty,
XmlResourceParserparser){
//描绘键盘时候自动调用?
?
是不是在此类的构造函数中就使用了?
肯定是自己的函数调用这个函数。
Keykey=newLatinKey(res,parent,x,y,parser);
//android:
codes="10"在qwerty中定义的回车键
if(key.codes[0]==10){//重载的目的,好像仅仅是为了记录回车键的值而已(以Key型记录)然后下一个函数要用到
mEnterKey=key;//无非就是想对回车键做改观
}
returnkey;
}
/**
*Thislooksattheimeoptionsgivenbythecurrenteditor,tosetthe
*appropriatelabelonthekeyboard'senterkey(ifithasone).
*/
voidsetImeOptions(Resourcesres,intoptions){
//在SoftKeyboard的StartInput函数最后用到了
//传入了EditorInfo.imeOptions类型的options参数。
此变量地位与EditorInfo.inputType类似。
但作用截然不同
if(mEnterKey==null){
return;
}
//惊爆:
只要加载了EditorInfo的包,就可以使用其中的常量,
//所熟知的TextView类中的常量,经过试验也是可以任意使用的,猜测这些都是静态变量
switch(options&(EditorInfo.IME_MASK_ACTION|EditorInfo.IME_FLAG_NO_ENTER_ACTION)){
//难道后面两个或的天生就是为了联接在一起跟别人与?
caseEditorInfo.IME_ACTION_GO:
mEnterKey.iconPreview=null;//将键的图片资源设为空
mEnterKey.icon=null;//把图片设为空,并不代表就是空,只是下面的Lable可以代替之
mEnterKey.label=res.getText(R.string.label_go_key);//将按键标签设为“GO”
break;
caseEditorInfo.IME_ACTION_NEXT:
mEnterKey.iconPreview=null;
mEnterKey.icon=null;
mEnterKey.label=res.getText(R.string.label_next_key);
break;
caseEditorInfo.IME_ACTION_SEARCH:
mEnterKey.icon=res.getDrawable(
R.drawable.sym_keyboard_search);
mEnterKey.label=null;
break;
caseEditorInfo.IME_ACTION_SEND:
mEnterKey.iconPreview=null;
mEnterKey.icon=null;
mEnterKey.label=res.getText(R.string.label_send_key);
break;
default:
mEnterKey.icon=res.getDrawable(
R.drawable.sym_keyboard_return);
mEnterKey.label=null;
break;
}
}
staticclassLatinKeyextendsKeyboard.Key{
publicLatinKey(Resourcesres,Keyboard.Rowparent,intx,inty,XmlResourceParserparser){
super(res,parent,x,y,parser);//用的是老一辈的构造函数
}
/**
*Overridingthismethodsothatwecanreducethetargetareaforthekeythat
*closesthekeyboard.
*/
@Override
publicbooleanisInside(intx,inty){
returnsuper.isInside(x,codes[0]==KEYCODE_CANCEL?
y-10:
y);
//只有一个左下角cancel键跟super的此函数不一样,其余相同
//仅仅为了防止错误的点击?
将cancel键的作用范围减小了10,其余的,如果作用到位,都返回true
}
}
}
上述代码中用到了EditorInfo类,该类描述了一个文本编辑对象的几个属性,属性如下:
Constants
int
IME_ACTION_DONE
BitsofIME_MASK_ACTION:
theactionkeyperformsa"done"operation,typicallymeaningtheIMEwillbeclosed.
int
IME_ACTION_GO
BitsofIME_MASK_ACTION:
theactionkeyperformsa"go"operationtotaketheusertothetargetofthetexttheytyped.
int
IME_ACTION_NEXT
BitsofIME_MASK_ACTION:
theactionkeyperformsa"next"operation,takingtheusertothenextfieldthatwillaccepttext.
int
IME_ACTION_NONE
BitsofIME_MASK_ACTION:
thereisnoavailableaction.
int
IME_ACTION_PREVIOUS
BitsofIME_MASK_ACTION:
LikeIME_ACTION_NEXT,butformovingtothepreviousfield.
int
IME_ACTION_SEARCH
BitsofIME_MASK_ACTION:
theactionkeyperformsa"search"operation,takingtheusertotheresultsofsearchingforthetextthehavetyped(inwhatevercontextisappropriate).
int
IME_ACTION_SEND
BitsofIME_MASK_ACTION:
theactionkeyperformsa"send"operation,deliveringthetexttoitstarget.
int
IME_ACTION_UNSPECIFIED
BitsofIME_MASK_ACTION:
nospecificactionhasbeenassociatedwiththiseditor,lettheeditorcomeupwithitsownifitcan.
int
IME_FLAG_NAVIGATE_NEXT
FlagofimeOptions:
usedtospecifythatthereissomethinginterestingthataforwardnavigationcanfocuson.
int
IME_FLAG_NAVIGATE_PREVIOUS
FlagofimeOptions:
likeIME_FLAG_NAVIGATE_NEXT,butspecifiesthereissomethinginterestingthatabackwardnavigationcanfocuson.
int
IME_FLAG_NO_ACCESSORY_ACTION
FlagofimeOptions:
usedinconjunctionwithIME_MASK_ACTION,thisindicatesthattheactionshouldnotbeavailableasanaccessorybuttonwhentheinputmethodisfull-screen.
int
IME_FLAG_NO_ENTER_ACTION
FlagofimeOptions:
usedinconjunctionwithIME_MASK_ACTION,thisindicatesthattheactionshouldnotbeavailablein-lineasareplacementfor"enter"key.
int
IME_FLAG_NO_EXTRACT_UI
FlagofimeOptions:
usedtospecifythattheIMEdoesnotneedtoshowitsextractedtextUI.
int
IME_FLAG_NO_FULLSCREEN
FlagofimeOptions:
usedtorequestthattheIMEnevergointofullscreenmode.
int
IME_MASK_ACTION
SetofbitsinimeOptionsthatprovidealternativeactionsassociatedwiththe"enter"key.
int
IME_NULL
GenericunspecifiedtypeforimeOptions.
在LatinKeyboard.类是继承了Keyboard类,Keyboard类:
加载一个xml文件,此文件包含键盘的描述,并且存储了各个按键的键值,键盘的布局文件大致如下
android:
keyWidth="%10p"
android:
keyHeight="50px"
android:
horizontalGap="2px"
android:
verticalGap="2px">
keyWidth="32px">
keyLabel="A"/>
...
...
第三天:
解读LatinKeyboardView.java
/*
*Copyright(C)2008-2009GoogleInc.
*
*LicensedundertheApacheLicense,Version2.0(the"License");youmaynot
*usethisfileexceptincompliancewiththeLicense.Youmayobtainacopyof
*theLicenseat
*
*http:
//www.apache.org/licenses/LICENSE-2.0
*
*Unlessrequiredbyapplicablelaworagreedtoinwriting,software
*distributedundertheLicenseisdistributedonan"ASIS"BASIS,WITHOUT
*WARRANTIESORCONDITIONSOFANYKIND,eitherexpressorimplied.Seethe
*Licenseforthespecificlanguagegoverningpermissionsandlimitationsunder
*theLicense.
*/
packagejiao.jiao;
importandroid.content.Context;
importandroid.inputmethodservice.Keyboard;
importandroid.inputmethodservice.KeyboardView;
importandroid.inputmethodservice.Keyboard.Key;
importandroid.util.AttributeSet;
publicclassLatinKeyboardViewextendsKeyboardView{
//当继承View的时候,会有个一个含有AttributeSet参数的构造方法,
//通过此类就可以得到自己定义的xml属性,也可以是android的内置的属性
//此类是用来自定义一个键盘视图View,这是关键!
先看看input.xml文件
/*
*xmlns:
android="
android:
id="@+id/keyboard"
android:
layout_alignParentBottom="true"
android:
layout_width="match_parent"
android:
layout_height="wrap_content"
/>
*/
//本类定义好后就跟咱们直接使用Button来定义一个控件一样来定义一个键盘,不过要使用自己的包名
staticfinalintKEYCODE_OPTIONS=-100;//干什么用的?
好像是设了一个无用的键值,等到后面调用
//构造方法一
publicLatinKeyboardView(Contextcontext,AttributeSetattrs){
super(context,attrs);//就是把自己的构造函数搞成人家基类的构造函数
}
//构造方法二
publicLatinKeyboardView(Contextcontext,AttributeSetattrs,intdefStyle){
super(context,attrs,defStyle);
}
@Override
protectedbooleanonLongPress(Keykey){
if(key.codes[0]==Keyboard.KEYCODE_CANCEL){
//codes[0]代表当前按的值.按时间长了就失去了效果(cancel)
getOnKeyboardActionListener().onKey(KEYCODE_OPTIONS,null);
//KeyboardView类的自带函数
returntrue;
}else{
returnsuper.onLongPress(key);
}
}
}
第四天:
解读键盘:
CandidateView.java
此类是用来定义候选区的视图
/*
*Copyright(C)2008-2009GoogleInc.
*
*LicensedundertheApacheLicense,Version2.0(the"License");youmaynot
*usethisfileexceptincompliancewiththeLicense.Youmayobtainacopyof
*theLicenseat
*
*http:
//www.apache.org/licenses/LICENSE-2.0
*
*Unlessrequiredbyapplicablelaworagreedtoinwriting,software
*distributedundertheLicenseisdistributedonan"ASIS"BASIS,WITHOUT
*WARRANTIESORCONDITIONSOFANYKIND,eitherexpressorimplied.Seethe
*Licenseforthespecificlanguagegoverningpermissionsandlimitationsunder
*theLicense.
*/
packagejiao.jiao;
importandroid.content.Context;
importandroid.content.res.Resources;
importandroid.graphics.Canvas;
importandroid.graphics.Paint;
importandroid.graphics.Rect;
importandroid.graphics.drawable.Drawable;
importandroid.view.GestureDetector;
importandroid.view.MotionEvent;
importandroid.view.View;
importjava.util.ArrayList;
importjava.util.List;
//自定义候选区视图,继承View
publicclassCandidateViewextendsVie