android输入法01:SoftKeyboard源码解析03
4、SoftKeyboard
[java]view plaincopy
1./**
2. * Example of writing an input method for a soft keyboard.  This code i
s
3. * focused on simplicity over completeness, so it should in no way be c
onsidered
4. * to be a complete soft keyboard implementation.  Its purpose is to pr
ovide
5. * a basic example for how you would get started writing an input metho
d, to
6. * be fleshed out as appropriate.
7. */
8.public class SoftKeyboard extends InputMethodService
9.        implements KeyboardView.OnKeyboardActionListener {
10.    static final boolean DEBUG = false;
11.
12.    /**
13.    * This boolean indicates the optional example code for performing
14.    * processing of hard keys in addition to regular text generation
15.    * from on‐
screen interaction.  It would be used for input methods that
16.    * perform language translations (such as converting text entered o
n
17.    * a QWERTY keyboard to Chinese), but may not be used for input met
hods
18.    * that are primarily intended to be used for on‐
screen text entry.
19.    */
20.  //是否在用硬键盘,这里默认的是总可以使用,费柴变量
21.    static final boolean PROCESS_HARD_KEYS = true;
22.
23.  //键盘view对象,但不是自己定义的类
24.    private KeyboardView mInputView;
25.    //候选栏对象
26.    private CandidateView mCandidateView;
27.  //候选串之串
28.    private CompletionInfo[] mCompletions;
29.
30.    private StringBuilder mComposing = new StringBuilder();
31.    //这东西是决定能不能有候选条
32.    private boolean mPredictionOn;
33.  //决定auto是否需要显示在候选栏
34.    private boolean mCompletionOn;
35.
36.    private int mLastDisplayWidth;
37.    private boolean mCapsLock;
38.    private long mLastShiftTime;
39.    //matakey的按下状态,猜测是每种组合对应一个此值?
40.    private long mMetaState;
41.
42.    private LatinKeyboard mSymbolsKeyboard;
43.    private LatinKeyboard mSymbolsShiftedKeyboard;
44.    private LatinKeyboard mQwertyKeyboard;
45.
46.  //当前键盘
47.    private LatinKeyboard mCurKeyboard;
48.
49.    //默认的使得输入中断的字符
50.    private String mWordSeparators;
51.
52.    /**
53.    * Main initialization of the input method component.  Be sure to c
all
54.    * to super class.
55.    */
56.    @Override public void onCreate() {
57.        Create();
58.      //对resource这个东西有了一些了解:getResources是contextWrapper类
的函数,contextWrapper而是inputmethodservice
59.      //的间接基类
60.        mWordSeparators = getResources().getString(R.string.word_separa
tors);
61.        Log.i("mytest", "SoftKeyboard_onCreate");
62.    }
63.
64.    /**
65.    * This is the point where you can do all of your UI initialization
.  It
66.    * is called after creation and any configuration change.
67.    */
68.    @Override public void onInitializeInterface() {
69.        Log.i("mytest", "SoftKeyboard_onInitializeInterface");
70.        //这只加载键盘,类似于findViewById,离真正生成界面还早
71.        if (mQwertyKeyboard != null) {
72.            // Configuration changes can happen after the keyboard gets
recreated,
73.            // so we need to be able to re‐
build the keyboards if the available
74.            // space has changed.
75.            //可用的,最大屏幕宽度,好像也没什么用
76.            int displayWidth = getMaxWidth();
77.            if (displayWidth == mLastDisplayWidth) return;
78.          //难道就是为了记录最大宽度于mLastDisplayWidth?
79.            mLastDisplayWidth = displayWidth;
80.        }
81.        mQwertyKeyboard = new LatinKeyboard(this, R.xml.qwerty);
82.        mSymbolsKeyboard = new LatinKeyboard(this, R.xml.symbols);
83.        mSymbolsShiftedKeyboard = new LatinKeyboard(this, R.xml.symbols
_shift);
84.    }
85.
86.    /**
87.    * Called by the framework when your view for creating input needs
to
88.    * be generated.  This will be called the first time your input met
hod
89.    * is displayed, and every time it needs to be re‐
created such as due to
90.    * a configuration change.
91.    */
92.    @Override public View onCreateInputView() {
93.        Log.i("mytest", "SoftKeyboard_onCreateInputView");
94.        mInputView = (KeyboardView) getLayoutInflater().inflate(
95.                R.layout.input, null);
96.      //上边的函数findViewById对于keyboardView是不能用的
97.      //只对TextView等可以用
98.        mInputView.setOnKeyboardActionListener(this);
99.        mInputView.setKeyboard(mQwertyKeyboard);
100.        //通过这个return,自己定义的keyboardview类对象就与这个类绑定了
101.        return mInputView;
102.    }
103.
104.    /**
105.    * Called by the framework when your view for showing candidates  needs to
106.    * be generated, like {@link #onCreateInputView}.
107.    */
108.    @Override public View onCreateCandidatesView() {
109.        Log.i("mytest", "SoftKeyboard_onCreateCandidatesView");    110.        mCandidateView = new CandidateView(this);
111.        //为什么参数是this??因为activity,inputmethodservice,这都是context的派生类
112.        mCandidateView.setService(this);//在CandidateView类里面对这个类的描述中,参数就是个
113.        return mCandidateView; //这一步很重要,后面的
setCandidatesViewShown(false);就是个返回的结果造成的?
114.    }
115.
116.    /**
117.    * This is the main point where we do our initialization of the input method
118.    * to begin operating on an application.  At this point we have been
119.    * bound to the client, and are now receiving all of the detaile
d information
120.    * about the target of our edits.
121.    */
122.    @Override public void onStartInput(EditorInfo attribute, boolean  restarting) {
123.        StartInput(attribute, restarting);
124.        Log.i("mytest", "SoftKeyboard_onStartInput");
125.        // Reset our state.  We want to do this even if restarting, because
126.        // the underlying state of the text editor could have change
d in any way.
127.      //一个StringBuilder,前面定义的
128.        mComposing.setLength(0);
129.        updateCandidates();//可知此处的candidateview注定还不显示    130.
131.        if (!restarting) {
132.            // Clear shift states.
133.            mMetaState = 0;
134.        }
135.
136.        mPredictionOn = false; //猜测:是否需要显示候选词条,证实确实如此
137.        mCompletionOn = false; //允许auto的内容显示在后选栏中    138.        mCompletions = null;
139.
140.        // We are now going to initialize our state based on the typ
e of
141.        // text being edited.
142.      //一个靠谱的猜测:inputtype的给定值里面有那么几个掩码,但是从参数传来的具体inputtype值里面包含了所有的信息,不同的掩码能够得出不同的信息    143.      //例如TYPE_MASK_CLASS就能得出下面四种,这四种属于同一类期望信息,这个信息叫做CLASS,下面一个掩码TYPE_MASK_V
ARIATION按位与出来的是一类    144.      //叫做VARIATION的信息
145.        switch (attribute.inputType&EditorInfo.TYPE_MASK_CLASS) {    146.            case EditorInfo.TYPE_CLASS_NUMBER:
147.            case EditorInfo.TYPE_CLASS_DATETIME:
148.                // Numbers and dates default to the symbols keyboard , with
149.                // no extra features.
150.                mCurKeyboard = mSymbolsKeyboard;
151.                break;
152.
153.            case EditorInfo.TYPE_CLASS_PHONE:
154.                // Phones will also default to the symbols keyboard, though
155.                // often you will want to have a dedicated phone key board.
156.                mCurKeyboard = mSymbolsKeyboard;
157.                break;
158.
159.            case EditorInfo.TYPE_CLASS_TEXT:
160.                // This is general text editing.  We will default to  the
161.                // normal alphabetic keyboard, and assume that we sh ould
162.                // be doing predictive text (showing candidates as t he
163.                // user types).
164.                mCurKeyboard = mQwertyKeyboard;
165.                mPredictionOn = true;
166.
167.                // We now look for a few special variations of text that will
168.                // modify our behavior.
169.                int variation = attribute.inputType &  EditorInfo.TY PE_MASK_VARIATION;
170.                if (variation == EditorInfo.TYPE_TEXT_VARIATION_PASS WORD ||
171.                        variation == EditorInfo.TYPE_TEXT_VARIATION_ VISIBLE_PASSWORD) {
172.                    // Do not display predictions / what the user is  typing
173.                    // when they are entering a password.
174.                    mPredictionOn = false; //密码框的输入是不需要候选词条的
175.                }
176.
177.                if (variation == EditorInfo.TYPE_TEXT_VARIATION_EMAI L_ADDRESS
178.                        || variation == EditorInfo.TYPE_TEXT_VARIATI ON_URI
179.                        || variation == EditorInfo.TYPE_TEXT_VARIATI ON_FILTER) {
180.                    // Our predictions are not useful for e‐mail addresses
181.                    // or URIs.
为什么不显示输入法182.                    mPredictionOn = false;  //如果是网站或者是邮箱地址,不用候选词条
183.                }
184.
185.                if ((attribute.inputType&EditorInfo.TYPE_TEXT_FLAG_A UTO_COMPLETE) != 0) {
186.                    //开始界面的那个输入框,就是自动生成的
187.                    // If this is an auto‐
complete text view, then our predictions
188.                    // will not be shown and instead we will allow t he editor
189.                    // to supply their own.  We only show the editor 's
190.                    // candidates when in fullscreen mode, otherwise  relying
191.                    // own it displaying its own UI.