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.跳过


更多相关文章

  1. android中和c++中生产者和消费者模式
  2. Android单词查找器
  3. android修改进入工程模式
  4. Android 小说阅读护眼模式
  5. Mac修改环境变量路径中带空格的处理
  6. Android生命周期和启动模式
  7. Android开发模式:MVP Vs MVVM
  8. Android设计模式系列--工厂方法模式
  9. Activity 的四种加载模式

随机推荐

  1. 固定定位,父元素具有转换
  2. 49、html基础认识&常用标签(1)
  3. html5第十课时,简单的计算器
  4. [转]Html position(static、relative、abs
  5. 零基础HTML5游戏制作教程 第3章 图形的移
  6. MonoRail学习笔记十三:NVelocity的增强功
  7. [模仿]html5游戏_别踩白块
  8. 的良好实践是什么?它可以替换还是只用于
  9. HTML5的重点知识小结——整体布局(浮动布
  10. 浏览器加载和渲染html的顺序