android 搜索关联输入法

2015-04-22 20:50:40 xiaoluo5238 阅读数 521

1、输入法在EditText之下:

在AndroidManifest下的对应的Activity中增加属性

<activity android:name=".AAA"
                  android:windowSoftInputMode="adjustPan|stateVisible"/>


2、让EditText默认不获得焦点:在EditText之上加一个空的LinearLayout,并让其获得焦点:

<LinearLayout
            android:focusable="true"
            android:focusableInTouchMode="true"
            android:layout_width="0px"
            android:layout_height="0px">
        <requestFocus/>
    </LinearLayout>

3、在代码中让EdiTtext不能输入,用其方法setFocusableInTouchMode(false);



2012-01-04 15:40:15 kuangjp 阅读数 1760

1. 在android Settings 应用中有个“用户词典” 的应用,该应用是跟“android 键盘” 输入法相关联,当该应用添加一些单词,词组什么的在"用户词典"应用的数据库中时,对应的androiid 输入法将会联想到对应的单词或词组。假如我们在“用户词典”中添加了“aaa” 这个单词,当我们输入“aa” 的时候,则有如下图的效果:




2. 但是我们有的时候会出现这样的问题,就是当我们输入“aa”的时候,不能看到对应的联想功能,比例出现如下图:


如果需要出现联想的功能,这里需要组件的对应方法setInputType 去设置是否显示联想功能,也可以通过android:inputType属性来设定。

在第二个图中是因为执行了

     // No prediction in soft keyboard mode. TODO: Create a better way to disable prediction
        editText.setInputType(InputType.TYPE_CLASS_TEXT
                | InputType.TYPE_TEXT_FLAG_AUTO_COMPLETE);

语句。具体的源码在packages/apps/Settings/src/com/android/settings/UserDictionarySettings.java文件的onCreateDialog方法中。

 3.具体inputtype的类型值请参考InputType.java, 源码的位置:frameworks/base/core/java/android/text/InputType。





2015-11-03 15:26:02 xutao3716 阅读数 2207

输入法的例子和源代码看了不少时间了,看得头很晕,很郁闷。静下心来把整个代码想了一遍,其实大部分代码都在处理绘制界面,以及事件的处理,核心代码很少,都被底层封装得很完美了。
先看看一般输入法的界面:

这里写图片描述

分为两个部分,上部分是候选窗口(CandidateView),用来显示候选词,现在常用的输入法都有这个功能,如在搜狗、google输入法中输入abc,输入框中就会显示很多相关联的中文词。下部分就是软键盘了,这个没什么好说的。

输入法中核心类是InputMethodService
其次就是:CandidateView 和KeyboardView
CandidateView为候选窗口,InputMethodService在启动过程中会调用接口public View onCreateCandidatesView() ,在这个方法
中把CandidateView对象返回后,InputMethodService内部会将其布局到相应的位置。
在android中没有CandidateView父类,得自己从头写,一般的做法是:
通过方法public void setService(InputMethodService listener) 将Service类传进来,然后再通过public void setSuggestions(List suggestions…) 方法将候选词列表传递过来,CandidateView将其显示到界面上,用户选择结束后,再通过service的方法pickSuggestionManually(mSelectedIndex) ,将选择的候选词在列表中的序号传递回去。至此, CandidateView 就完成了它神圣的使命。
android中KeyboardView有一个通用类,继承它可以通过简单的配置文件就显示出很专业软键盘。在源代码中,它绝大部分代码都在做 绘 制工作和事件处理,不过就其本质功能来说是相当地简单,用户摁下软键盘上的某个键后,它把这个键所代表的值传递给InputMethodService类 也完成了它的使命。InputMethodService在public View onCreateInputView() 方法中获得该View。
InputMethodService就是输入法的核心了,该类是一个Service,跟其它默默无闻的Service不同的是,它是一个带有View的Service。其内部有几个个重要的接口:
InputMethodImpl
InputMethodSessionImpl
InputConnection
InputMethodService通过这几个个类跟系统和输入框进行交互的。
输入框从InputMethodService获取信息是通过InputConnection来实现的, 在启动输入法时,InputConnection由客户端控件创建,并传递给输入法应用,由输入法应用调用,进行信息反馈
InputMethod接口定义了一套操纵输入法应用的方法。 如,bindInput, hideInput, startInput等。为了系统安全,这类接口只有系统可以访问,客户端控件无法直接调用这个接口。所有的输入法应用都需要客户端控件具有 BIND_INPUT_METHOD权限,作为系统的安全机制,否则将无法与输入法服务交互。
InputMethodSession作为InputMethod的辅助接口类,为 客户端控件开放了可直接调用的函数接口。包括向输入法应用分发键盘事件,更新光标位置,更新编辑区域内选择的问题信息等。客户端控件通过 IIputMethodSession对于输入法应用的交互是单向的,即只能向输入法应用传递信息,无法获取信息
以上几个点是从网上copy过来的,感觉这几点对于理解InputMethodService特别有用。
代码看得太多反而看不清本质,这几个类中最实用的是InputConnection的
public boolean commitText(CharSequence text, int newCursorPosition)

通过KeyboardView和CandidateView, InputMethodService类已经获得了想要的内容,然后通过这个方法把值传递给输入框。
按奈不住心中读源代码的郁闷,先来写一个输入法发泄一下:
先来一个CandidateView,设想的布局如下:

这里写图片描述

这个View中不进行任何自绘制,用android现有的View,两边各一个按钮(Button),用来滚动多个候选词,中间显示候选词(TextView),为了方便CandidateView继承RelativeLayout的内部类,便于加入子控件和控制,setService和 setSuggestions两个方法可以不用,反正是内部类,不过为了配合上面的说明,思量再三还是加上了:

public class helloIme extends InputMethodService {
    class CandidateView extends RelativeLayout {
        TextView tv; // 中间显示候选词
        Button btLeft, btRight; // 左右按钮
        helloIme listener; // helloIme 用于返回选中的 候选词下标
        List<String> suggestions; // 候选词列表, KeyboardView 不同的键按下后会设置相关的列表
        int mSelectedIndex = -1; // 当前 候选词下标

        public CandidateView(Context context) {
            super(context);
            tv = new TextView(context);
            tv.setId(1);
            RelativeLayout.LayoutParams lpCenter = new RelativeLayout.LayoutParams(200,
                    ViewGroup.LayoutParams.WRAP_CONTENT);
            lpCenter.addRule(RelativeLayout.CENTER_IN_PARENT);
            addView(tv, lpCenter);
            tv.setOnClickListener(new OnClickListener() {
                public void onClick(View v) {
                     listener.pickSuggestionManually(mSelectedIndex);
                }
            });
            btLeft = new Button(context);
            btLeft.setText("<");
            btLeft.setOnClickListener(new OnClickListener() {
                public void onClick(View arg0) {
                    mSelectedIndex = mSelectedIndex > 0 ? (mSelectedIndex - 1) : 0;
                    tv.setText(suggestions.get(mSelectedIndex));
                }
            });
            RelativeLayout.LayoutParams lpLeft = new RelativeLayout.LayoutParams(60,
                    ViewGroup.LayoutParams.WRAP_CONTENT);
            lpLeft.addRule(RelativeLayout.LEFT_OF, 1);
            addView(btLeft, lpLeft);
            btRight = new Button(context);
            btRight.setText(">");
            btRight.setOnClickListener(new OnClickListener() {
                public void onClick(View v) {
                    mSelectedIndex = mSelectedIndex >= suggestions.size() - 1 ? suggestions.size() - 1
                            : mSelectedIndex + 1;
                    tv.setText(suggestions.get(mSelectedIndex));
                }
            });
            RelativeLayout.LayoutParams lpRight = new RelativeLayout.LayoutParams(60,
                    ViewGroup.LayoutParams.WRAP_CONTENT);
            lpRight.addRule(RelativeLayout.RIGHT_OF, 1);
            addView(btRight, lpRight);
        }

        public void setService(helloIme listener) {
            this.listener = listener;
        }

        public void setSuggestions(List<String> suggestions) {
            mSelectedIndex = 0;
            tv.setText(suggestions.get(mSelectedIndex));
            this.suggestions = suggestions;
        }
    }
}

上面最重要的是粗体的那两行,View的布局还是花费了很多代码:(
KeyboardView的布局预想如下:

这里写图片描述

就两个按钮,点if时往输入框中输出if(){}, if(){}else if(){}…,whie时往输入框中输出whie(){},这个类同样是继承于RelativeLayout的内部类:

class KeyboardView extends RelativeLayout {
    public KeyboardView(Context context) {
        super(context);
        Button btIf = new Button(context);
        btIf.setText("if");
        btIf.setId(1);
        RelativeLayout.LayoutParams lpIf = new RelativeLayout.LayoutParams(100, 50);
        lpIf.addRule(RelativeLayout.CENTER_HORIZONTAL);
        btIf.setOnClickListener(new OnClickListener() {
            public void onClick(View v) {
                setCandidatesViewShown(true); // 显示 CandidateView
                helloIme.this.onKey("if"); // 将点击按钮的值传回给 InputMethodService
            }
        });
        addView(btIf, lpIf);
        Button btWhile = new Button(context);
        btWhile.setText("while");
        RelativeLayout.LayoutParams lpWhile = new RelativeLayout.LayoutParams(100, 50);
        lpWhile.addRule(RelativeLayout.BELOW, 1);
        lpWhile.addRule(RelativeLayout.ALIGN_LEFT, 1);
        btWhile.setOnClickListener(new OnClickListener() {
            public void onClick(View v) {
                setCandidatesViewShown(true);
                helloIme.this.onKey("while");
            }
        });
        addView(btWhile, lpWhile);
    }
}

CandidateView默认是不显示的,所以需要调用InputMethodService 的setCandidatesViewShown()方法。
接下来把helloIme的代码贴出来:

public class helloIme extends InputMethodService {
    private List<String> suggestionlist; // 当前候选词表
    private Hashtable<String, List<String>> data; // 词典数据
    private KeyboardView mkeyView;
    private CandidateView mCandView;

    public void onInitializeInterface() { // InputMethodService在启动时,系统会调用该方法,具体内容下回再表
        // 初始化 词典数据
        data = new Hashtable<String, List<String>>();
        List<String> list = new ArrayList<String>();
        list.add("if(){}");
        list.add("if(){}else if(){}");
        list.add("if(){}else{}");
        data.put("if", list);
        list = new ArrayList<String>();
        list.add("while(){}");
        data.put("while", list);
    }

    public View onCreateInputView() {
        mkeyView = new KeyboardView(this);
        return mkeyView;
    }

    public View onCreateCandidatesView() {
        mCandView = new CandidateView(this);
        mCandView.setService(this);
        return mCandView;
    }

    public void pickSuggestionManually(int mSelectedIndex) {
        getCurrentInputConnection().commitText(suggestionlist.get(mSelectedIndex), 0); // 往输入框输出内容
        setCandidatesViewShown(false); // 隐藏 CandidatesView
    }

    public void onKey(CharSequence text) {
        // 根据按下的按钮设置候选词列表
        suggestionlist = data.get(text);
        mCandView.setSuggestions(suggestionlist);
    }

    class KeyboardView extends RelativeLayout {
        // ......
    }

    class CandidateView extends RelativeLayout {
        // ......
    }
}

代码写完,再来写配置文件,
在res目录下面建立一个新目录xml,然后创建一个method.xml

<?xml version="1.0" encoding="utf-8"?>
<!-- The attributes in this XML file provide configuration information -->
<!-- for the Search Manager. -->
<input-method
    xmlns:android="http://schemas.android.com/apk/res/android" />

设置Manifest.xml:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="test.helloIme"
      android:versionCode="1"
      android:versionName="1.0">
    <application android:icon="@drawable/icon" android:label="@string/app_name">
        <service android:name="helloIme"
        android:permission="android.permission.BIND_INPUT_METHOD">
            <intent-filter>
                <action android:name="android.view.InputMethod"/>
            </intent-filter>
            <meta-data android:name="android.view.im" android:resource="@xml/method"/>
        </service>
    </application>
    <uses-sdk android:minSdkVersion="5" />
</manifest>

直接运行程序,eclipse输出如下Log:
[2010-08-25 17:16:48 - helloIme]Installing helloIme.apk…
[2010-08-25 17:16:50 - helloIme]Success!
[2010-08-25 17:16:50 - helloIme]/helloIme/bin/helloIme.apk installed on device
[2010-08-25 17:16:50 - helloIme]Done!
嗯,安装成功了!呵呵,革命尚未成功,还需在模拟器上进行设置:
点击settings->Language & keyboard,在下部出现了一个test,右边有个checkbox,选上它。
找一个有输入框的应用,最简单到写短消息的画面,左键长按输入框,会弹出一个输入法选择提示框,点进去就会看到刚才创建的输入法了,点击右边的单选框,oh,my ime,漂亮的hello输入法就展现在面前了:

这里写图片描述

android果然很强大啊

转载地址:http://www.android100.org/html/201307/12/3560.html

2015-03-03 15:18:33 luoluoguo 阅读数 4414

步骤如下:

1、修改Editview属性:android:imeOptions="actionSearch"   在该Editview获得焦点的时候将“回车”键改为“搜索”

 android:singleLine="true"     不然回车【搜索】会换行

2.

@Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
                // 输入法中点击搜索
if (actionId == EditorInfo.IME_ACTION_SEARCH) {
                        //这里调用搜索方法
return true;
}
return false;
}
});

对于搜狗输入法~actionId如下~



//一般输入法或搜狗输入法点击搜索按键
if (actionId == EditorInfo.IME_ACTION_SEARCH || actionId == EditorInfo.IME_ACTION_UNSPECIFIED) {
        //这里调用搜索方法
return true;
}

rn true;
}
综合如下:
if (actionId == EditorInfo.IME_ACTION_SEARCH) {

            return true;
} else if (actionId == EditorInfo.IME_ACTION_UNSPECIFIED && event != null) {
          if (event.getAction() == KeyEvent.ACTION_DOWN && event.getKeyCode() == KeyEvent.KEYCODE_ENTER) {        
         
                return true;
          }
}

3
4
5
//一般输入法或搜狗输入法点击搜索按键
if (actionId == EditorInfo.IME_ACTION_SEARCH || actionId == EditorInfo.IME_ACTION_UNSPECIFIED) {
        //这里调用搜索方法
return true;
}
2017-02-06 17:08:48 mfzabc 阅读数 13220

输入法编辑器(IME)是一个便于用户输入文本的控件。Android提供了一个可扩展的输入法框架,允许应用程序提供可替代的输入法,比如屏幕上的键盘或者语音输入。在安装
输入法后,用户可以通过系统选项选择想要使用的输入法。

想要添加一个输入法,你需要创建一个Android应用并包含一个继承自InputMethodService的类。此外,同城创建一个设置页面来承载输入发的各个选项。你可以自行定义一个设置的UI。

下面讲述以下几个内容:
· 输入法的生命周期
· 在应用的清单文件中定义输入法组件
· 输入法相关接口
· 设计一个款输入法的UI
· 发送文本到应用
· 输入法子类型的使用

一、输入法的生命周期

输入法的生命周期如下图所示:

输入法生命周期

下面的部分讲述如何根据输入法的生命周期实现UI和输入法功能。

二、在清单文件中定义输入法组件
在Android系统中,IME是一个包含特殊IME服务的应用程序。应用的清单文件必须声明输入法服务,请求必须的权限,提供一个intent filter来匹配 action.view.InputMethod,并提供定义了IME特征的元数据(metadata)。此外,可以定义一个设置页面来提供用户修改IME配置的接口,它可以被系统设置所启动。
下面的代码片段声明了一个IME服务。请求了 BIND_INPUT_METHOD 权限来允许服务连接到系统的IME,建立intent filter和metadata:

<!-- Declares the input method service -->
    <service android:name="FastInputIME"
        android:label="@string/fast_input_label"
        android:permission="android.permission.BIND_INPUT_METHOD">
        <intent-filter>
            <action android:name="android.view.InputMethod" />
        </intent-filter>
        <meta-data android:name="android.view.im"
android:resource="@xml/method" />
    </service>

下面的代码片段声明了IME的设置页面,它拥有 ACTION_MAIN 的intent filter来表示它是IME程序的主入口。

<!-- Optional: an activity for controlling the IME settings -->
    <activity android:name="FastInputIMESettings"
        android:label="@string/fast_input_settings">
        <intent-filter>
            <action android:name="android.intent.action.MAIN"/>
        </intent-filter>
    </activity>

也可以从IME的UI提供直接进入设置的入口。

三、输入法API
与IME相关的类在 android.inputmethodservice 和 android.view.inputmethod 包中。KeyEvent 类对于处理键盘特征至关重要。
IME的核心部分是一个服务组件,即一个继承自InputMethodService的类。此外为了实现一般服务的生命周期,这个类提供了IME的UI,处理用户输入和传输文本到指定区域以及当前焦点的回调。InputMethodService类提供了绝大多数管理IME状态和与当前输入区域交互的实现。

下面几个类也很重要。
BaseInputConnection
定义了输入法和应用之间接收输入的交互通道。使用它来读取光标周围的文本,提交文本到输入框以及发送键盘事件给应用。应用应该集成此类。

KeyboardView
一个View的扩展,描绘了一个键盘和用户输入事件的响应。键盘的布局是被Keyboard的实例指定,可以定义一个XML文件。

四、设计输入法UI
IME有两个主要的视觉元素:即输入视图和备选视图。你只需要实现和你设计的输入法有关的元素。

1.输入视图
输入视图是用户使用按键,手写或者手势在表单中输入文本的UI。
当IME第一次显示,系统会调用 onCreateInputView() 回调。在你实现的这个方法中,你创建你想要的IME窗口的布局并返回给系统。下面片段是一个例子:

@Override
    public View onCreateInputView() {
        MyKeyboardView inputView =
            (MyKeyboardView) getLayoutInflater().inflate( R.layout.input, null);

        inputView.setOnKeyboardActionListener(this);
inputView.setKeyboard(mLatinKeyboard);

        return mInputView;
    }

这里的MyKeyboardView是一个自定义的实现了 KeyboardView 的实例,如果你构建的是一个传统的QWERTY键盘,请查看 KeyboardView 类。

2.候选视图
候选视图是供用户选择可选词和推荐词的视图。在IME的生命周期中,系统在准备好显示备选视图的时候会调用onCreateCandidatesView()。在你实现的这个方法中,返回显示词汇建议的布局,当什么都不显示时,返回null。
若要查看实现用户建议词汇的例子,请查看SoftKeyboard示例应用。

3.UI设计依据
此部分介绍了一些IME的UI设计思想。

· 应对多元化的屏幕尺寸
你的IME的UI必须可以适配不同屏幕的尺寸,且必须处理竖屏和横屏两种方向。在非全屏模式下,为应用程序留出足够的空间以显示文本字段和任何相关联的上下文,使得IME不会占用屏幕一半以上的空间。在全屏模式下没有这个问题。

· 处理不同的输入类型
Android的输入框允许你选择一个特殊的输入类型,比如自由文本,数字,网址,邮箱地址,收索内容等。当你实现一个新的IME,您需要检测每个字段的输入类型,并为其提供适当的接口。但是,你不必设置IME以检查用户输入的文本对输入类型有效; 这是拥有文本字段的应用程序的责任。

当输入字段接收焦点并且您的IME启动时,系统调用 onStartInputView(),传递一个 EditorInfo 对象,该对象包含有关文本字段的输入类型和其他属性的详细信息。 在此对象中,inputType 字段包含文本字段的输入类型。
输入类型字段是一个包含用于各种输入类型设置的位模式的int参数。 要测试它的文本字段的输入类型,用常量TYPE_MASK_CLASS屏蔽它,像这样:
inputType & InputType.TYPE_MASK_CLASS
输入类型位模式可以具有几个值中的一个,包括:
TYPE_CLASS_NUMBER
用于输入数字的文本字段。
TYPE_CLASS_DATETIME
用于输入日期和时间的文本字段。
TYPE_CLASS_PHONE
用于输入电话号码的文本字段。
TYPE_CLASS_TEXT
用于输入所有支持的字符的文本字段。

这些常量在 InputType 的参考文档中有更详细的描述。
inputType字段可以包含指示文本字段类型的其他位,例如:
TYPE_TEXT_VARIATION_PASSWORD
用于输入密码的TYPE_CLASS_TEXT 的变体。 输入法将显示标记,而不是实际文本。
TYPE_TEXT_VARIATION_URI
用于输入网址和其他统一资源标识符(URI)的TYPE_CLASS_TEXT 的变体。
TYPE_TEXT_FLAG_AUTO_COMPLETE
TYPE_CLASS_TEXT 的变体,用于输入应用程序从字典,搜索或其他工具中“自动完成”的文本。
记住在测试这些变量时,用适当的常数掩蔽输入类型。 可用的掩码常数在输入类型的参考文档中列出。

注意:在您自己的IME中,确保在将其发送到密码字段时正确处理文本。 在输入视图和候选视图中的用户界面中隐藏密码。 还要记住,您不应该在设备上存储密码。 要了解更多信息,请参阅“为安全性设计”指南。

五、向应用程序发送文本
当用户使用IME输入文本时,您可以通过发送单个键事件或在应用程序的文本字段中编辑光标周围的文本来向应用程序发送文本。 在任一情况下,您都使用 InputConnection 的实例来传递文本。 要获取此实例,请调用 InputMethodService.getCurrentInputConnection() 。

1.编辑光标周围的文本
当处理文本字段中现有文本的编辑时,BaseInputConnection 中一些更有用的方法是:
getTextBeforeCursor()
返回包含当前光标位置之前的请求字符数的 CharSequence 。
getTextAfterCursor()
返回包含当前光标位置后的请求字符数的 CharSequence 。
deleteSurroundingText()
删除当前光标位置前后的指定数量的字符。
commitText()
向文本字段提交 CharSequence 并设置新的光标位置。

例如,以下代码段显示如何使用文本“Hello!”替换光标左侧的四个字符:

InputConnection ic = getCurrentInputConnection();

    ic.deleteSurroundingText(4, 0);

    ic.commitText("Hello", 1);

    ic.commitText("!", 1);

2.在提交之前撰写文本
如果您的IME执行文本预测或需要多个步骤来组成字形或单词,则可以在文本字段中显示进度,直到用户提交单词,然后您可以用完成的文本替换部分组合。 当你传递给 setComposingText()时,你可以通过添加一个“span”来对文本进行特殊处理。
以下代码段显示了如何在文本字段中显示进度:

  InputConnection ic = getCurrentInputConnection();

    ic.setComposingText("Composi", 1);
...

    ic.setComposingText("Composin", 1);

...

    ic.commitText("Composing ", 1);

以下屏幕截图显示了用户看到的页面:
这里写图片描述这里写图片描述这里写图片描述

3.拦截硬件按键事件
即使输入法窗口没有明确的焦点,它首先接收硬件键事件,并且可以选择使用它们或将它们转发到应用程序。 例如,您可能想要使用方向键在UI中导航以在组合期间选择候选项。 您可能还想捕获返回键以关闭源自输入法窗口的任何弹出窗口。
要拦截硬件键,重写onKeyDown()和 onKeyUp()。 请参阅 SoftKeyboard 示例应用程序的示例。
记住要为你不想处理的键调用super()方法。

六、创建IME子类型
子类型允许IME公开IME支持的多种输入模式和语言。 子类型可以表示:
· 区域设置,如en_US或fr_FR
· 输入模式,如语音,键盘或手写
· IME特有的其他输入样式,表单或属性,例如10键或qwerty键盘布局。

基本上,模式可以是诸如“键盘”,“语音”等的任何文本。 子类型还可以暴露这些的组合。
子类型信息用于IME切换器对话框,该对话框可从通知栏和IME设置中使用。 该信息还允许框架直接引出IME的特定子类型。 当构建IME时,使用子类型工具,因为它有助于用户识别和在不同的IME语言和模式之间切换。

您可以使用元素在输入法的XML资源文件之一中定义子类型。 以下代码段定义了一个具有两个子类型的IME:美国英语语言环境的键盘子类型,法国的法语语言环境的另一个键盘子类型

<input-method xmlns:android="http://schemas.android.com/apk/res/android"
        android:settingsActivity="com.example.softkeyboard.Settings"
        android:icon="@drawable/ime_icon"
    <subtype android:name="@string/display_name_english_keyboard_ime"
            android:icon="@drawable/subtype_icon_english_keyboard_ime"
            android:imeSubtypeLanguage="en_US"
            android:imeSubtypeMode="keyboard"
            android:imeSubtypeExtraValue="somePrivateOption=true"
    />
    <subtype android:name="@string/display_name_french_keyboard_ime"
            android:icon="@drawable/subtype_icon_french_keyboard_ime"
            android:imeSubtypeLanguage="fr_FR"
            android:imeSubtypeMode="keyboard"
            android:imeSubtypeExtraValue="foobar=30,someInternalOption=false"
    />
    <subtype android:name="@string/display_name_german_keyboard_ime"
            ...
    />
/>

1.从通知栏中选择TIME子类型
Android系统管理所有IME公开的所有子类型。 IME子类型被视为它们所属的IME的模式。 在通知栏中,用户可以为当前设置的IME选择可用的子类型,如以下屏幕截图所示:
这里写图片描述

这里写图片描述

2.从系统设置选择IME子类型
用户可以在“系统设置”区域的“语言和输入”设置面板中控制子类型的使用方式。 在 SoftKeyboard 示例应用程序中,文件InputMethodSettingsFragment.java包含一个在IME设置中实现子类型启用程序的实现。 有关如何在IME中支持输入法子类型的更多信息,请参阅Android SDK中的 SoftKeyboard 示例应用程序。

这里写图片描述

3.在IME子类型之间切换
您可以允许用户通过提供切换键(如球形语言图标)作为键盘的一部分,在多个IME子类型之间轻松切换。 这样做大大提高了键盘的可用性,并可以帮助避免用户的失望。 要启用此类切换,请执行以下步骤:
(1). 在输入法的XML资源文件中声明 supportsSwitchingToNextInputMethod = “true” 。 您的声明应类似于以下代码段:

<input-method xmlns:android="http://schemas.android.com/apk/res/android"
        android:settingsActivity="com.example.softkeyboard.Settings"
        android:icon="@drawable/ime_icon"
        android:supportsSwitchingToNextInputMethod="true">

(2). 调用 shouldOfferSwitchingToNextInputMethod() 方法。
(3). 如果方法返回true,则显示切换键。
(4). 当用户点击切换键时,调用 switchToNextInputMethod(),将false传递给第二个参数。 值false表示系统平等对待所有子类型,而不管它们属于什么IME。 指定true要求系统在当前IME中循环遍历子类型。

注意:在Android 5.0(API级别21)之前,switchToNextInputMethod()不知道 supportsSwitchingToNextInputMethod 属性。 如果用户切换到IME而没有切换键,他可能会卡在该IME中,无法轻松地切换出来。

七、一般IME注意事项
以下是您实现IME时需要考虑的其他事项:
· 为用户提供一种直接从IME的UI设置选项的方法。
· 因为设备上可以安装多个IME,所以提供了用于用户从输入法UI直接切换到不同的IME的方式。
· 快速启动IME的UI。根据需要预加载或加载任何大型资源,以便用户在点击文本字段时看到IME。缓存资源和视图,用于后续调用输入法。
· 相反,您应该在隐藏输入法窗口后立即释放大量内存分配,以便应用程序可以有足够的内存来运行。如果IME处于隐藏状态几秒钟,请考虑使用延迟消息来释放资源。
· 请确保用户可以为与IME关联的语言或区域设置输入尽可能多的字符。请记住,用户可以在密码或用户名中使用标点符号,因此您的IME必须提供许多不同的字符,以允许用户输入密码并访问设备。