Android(安卓)AOSP输入法(LatinIME)大写判断分析
LatinIME源码地址:https://android.googlesource.com/platform/packages/inputmethods/LatinIME/+/android-5.1.1_r6
一、大写模式:
Android中字母大写有三种模式:textCapCharacters、textCapWords、textCapSentences,分别对应全大写、单词首字母大写、句子首字母大写,这三种模式在InputType中的定义分别是TYPE_TEXT_FLAG_CAP_CHARACTERS、TYPE_TEXT_FLAG_CAP_WORDS、TYPE_TEXT_FLAG_CAP_SENTENCES。而InputType中定义的这三个值又分别对应TextUtils中定义的CAP_MODE_CHARACTERS、CAP_MODE_WORDS、CAP_MODE_SENTENCES。而LatinIME判断大写模式时用的值是TextUtils定义的这三个值。
对应关系:
1.全字母大写:textCapCharacters(android:inputType) == TYPE_TEXT_FLAG_CAP_CHARACTERS(InputType)== CAP_MODE_CHARACTERS(TextUtils)
2.单词首字母大写:textCapWords(android:inputType) == TYPE_TEXT_FLAG_CAP_WORDS(InputType)== CAP_MODE_WORDS(TextUtils)
3.句子首字母大写:textCapSentences(android:inputType) == TYPE_TEXT_FLAG_CAP_SENTENCES(InputType) == CAP_MODE_SENTENCES(TextUtils)
二、核心方法分析:
1.判断大小写的入口函数是RichInutConnection中的getCursorCapsMode方法
public int getCursorCapsMode(final int inputType, final SpacingAndPunctuations spacingAndPunctuations, final boolean hasSpaceBefore) { mIC = mParent.getCurrentInputConnection(); if (null == mIC) return Constants.TextUtils.CAP_MODE_OFF; if (!TextUtils.isEmpty(mComposingText)) { if (hasSpaceBefore) { // If we have some composing text and a space before, then we should have // MODE_CHARACTERS and MODE_WORDS on. return (TextUtils.CAP_MODE_CHARACTERS | TextUtils.CAP_MODE_WORDS) & inputType; } else { // We have some composing text - we should be in MODE_CHARACTERS only. return TextUtils.CAP_MODE_CHARACTERS & inputType; } } // TODO: this will generally work, but there may be cases where the buffer contains SOME // information but not enough to determine the caps mode accurately. This may happen after // heavy pressing of delete, for example DEFAULT_TEXT_CACHE_SIZE - 5 times or so. // getCapsMode should be updated to be able to return a "not enough info" result so that // we can get more context only when needed. if (TextUtils.isEmpty(mCommittedTextBeforeComposingText) && 0 != mExpectedSelStart) { if (!reloadTextCache()) { Log.w(TAG, "Unable to connect to the editor. " + "Setting caps mode without knowing text."); } } // This never calls InputConnection#getCapsMode - in fact, it's a static method that // never blocks or initiates IPC. return CapsModeUtils.getCapsMode(mCommittedTextBeforeComposingText, inputType, spacingAndPunctuations, hasSpaceBefore); }
首先判断当前是不是处于候选词状态,这种情况下,会去判断再次输入的字符前是不是有空格,如果有空格就需要判断EditText的属性是不是设置全字符大写(CAP_MODE_CHARACTERS)和单词首字母大写(CAP_MODE_WORDS);如果没有空格,就只需要判断属性是不是全字符大写就可以了。 如果当前不是候选词状态,那么就需要调用CapsModeUtils.getCapsMode方法来判断单词大小写情况。
2.核心方法:CapsModeUtils.getCapsMode,
1.参数:它包含四个参数,分别是:
1) CharSequence cs:需要检查大写模式的文本(getCursorCapsMode传入的参数是之前提前的内容)
2) int reqModes:调用输入法的控件所设置的大写模式
3) SpacingAndPunctuations:当前空格、符合的设置
4) hasSpaceBefore:判断是否需要考虑cs后面插入的空格
2.返回值:返回当前位置实际的大写模式
3.分析:getCapsMode分三步来检查大写模式:
1.如果调用输入法的控件设置的是全字母大写,那么就可以直接返回TextUtils.CAP_MODE_CHARACTERS
// Step 1 : check for cap MODE_CHARACTERS. If it's looked for, it's always on. if ((reqModes & (TextUtils.CAP_MODE_WORDS | TextUtils.CAP_MODE_SENTENCES)) == 0) { // Here we are not looking for MODE_WORDS or MODE_SENTENCES, so since we already // evaluated MODE_CHARACTERS, we can return. return TextUtils.CAP_MODE_CHARACTERS & reqModes; }
2.跳过
更多相关文章
- android 判断是否有可用网络
- android中和c++中生产者和消费者模式
- Android判断当前的Activity
- android string.xml中添加特殊字符
- 短信的自动拦截
- android优化工具
- android NetWorkHelper 网络工具类
- android避免decodeResource图片时占用太大的内存。
- android判断是否连接网络