`
zhenzxie
  • 浏览: 68324 次
  • 性别: Icon_minigender_1
  • 来自: 济南
社区版块
存档分类
最新评论

Android学习之路——9.Creating an IME(译)

阅读更多
   学习Android,SDK里的文档是一份很好的材料。但是官方的都是英文的,对于我这样的英语白痴,这样的文档真心只想看一遍。所以这次就把看到的翻译成中文,以便以后可以查看。水平有限,翻译的不准,请参看原文。
附上原文地址:
http://developer.android.com/guide/topics/text/creating-input-method.html

   学习的是Creating an IME。
   首先IME是什么:IME 是Input Method Editor 的缩写,大概就是输入法的意思吧。看到这里,可以决定是否要继续看下去了。

   1。IME is input method editor,是一个用户控制,允许用户输入文本。Android提供了用户可替换的输入方法,比如屏幕键盘,甚至是语音输入。一旦应用安装了,用户就可以从系统设置中选择哪一种IME,并且在整个系统范围内使用。同时只能有一种IME被选择。

   2。为了添加IME到android系统中,我们可以创建一个应用,这个应用中包含继承了InputMethodService的类。除此之外,我们通常还可以创建一个“setting” Activity,用来传递选项给IME Service。我们也可以定义一个setting UI,表现为System settings 的一部分。

   3。IME的生命周期:onCreate()-->onCreateInputView()-->onCreateCandidateViews()-->onStartInputView()-->....看截图吧。



   4。在Manifest中声明一个IME组件。在android系统中,一个IME是一个含有特殊IME Service的android app,应用的Manifest文件中必须声明这个Service,设置必要的权限(BIND_INPUT_METHOD),提供一个匹配action.view.InputMethods这个action的intent filter,提供定义IME特征的原数据。除此之外,提供一个设置接口,以允许用户修改IME的行为,当然我们可以定义能从System setting中被启动的setting Activity。下面的代码是声明一个IME的Manifest的例子:
  
    <!-- 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>
   

   setting Activity可以这样声明:
 
    <!-- 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>

   可以提供从这个UI直接达到IME设置项。

   5。The Input Method API定义IME的类可以在android.inputmethodservice和android.view.inputmethod包里找到。KeyEvent是一个处理键盘字符很重要的类。IME的核心组件是一个继承InputMethodService的类。除了实现基本的服务的生命周期外,这个类还有一些回调函数提供给我们的IME的UI,用来处理用户输入,传递文本到当前焦点所在的Field。默认情况下,InputMethodService类提供了大部分实现来管理IME的可见性和与当前焦点坐在Field的联系。
   以下这些类也很重要:
   BaseInputConnection
      定义类InputMethod回归到接受输入的应用的通信信道。我们可以使用它来读取光标旁的文本,提交文本到text box中,发送生的key event到应用。应用应该继承这个类,而不是实现基本的抽象接口InputConnection.
   KeyboardView
      View的一个拓展,渲染了一个键盘,相应用户的输入,键盘布局是可以用定义在XML文件中的Keyboard实例来指定的。

   6。设计IME的UI
   IME主要有两个抽象元素,input view和candidate view。我们只需实现那个和我们期望相关的元素。
   Input view
      input view 是用户可以输入文本,触摸事件,手写或者手势的UI。当IME第一个展现出来的时候,系统调用onCreateInputView()这个回调函数。在我们实现的这个方法中,我们可以创建出我们所想要展现的IME窗口的布局,然后返回给系统。下面是onCreateInputView()的一个例子:

    @Override 
    public View onCreateInputView() { 
        MyKeyboardView inputView = 
            (MyKeyboardView) getLayoutInflater().inflate(R.layout.input, null);
        inputView.setOnKeyboardActionListener(this); 
        inputView.setKeyboard(mLatinKeyboard); 
        return mInputView; 
    } 

   在这个例子中,MyKeyboardView是一个实现了可以渲染Keyboard的KeyboardView的自定制的实例。如果我们想要创建一个传统的QWERTY键盘,请参考 Soft Keyboard sample app ,学习怎样继承使用KeyboardView这个类。
   Candidates View
      Candidates View是IME用来展现提供用户选择的可能正确或
者建议的单词的UI。在IME的生命周期中,当需要Candidates View时系统调用onCreateCandidatesView()。在我们实现这个方法之中,返回一个显示建议单词的布局,或者返回null如果你不想显示什么。(一个null值是表示默认行为,所以我们不用实现这个如果我们不想提供任何建议的话)。

   7。UI设计的思考
   处理不同屏幕大小
      我们的IME UI必须能够为不同屏幕尺寸缩放,它必须能够处理横屏和竖屏两种情况。在非全屏的IME模式下,能够留出足够的空间给应用来展示text Field或者任何相关的上下文环境,所以IME不应该占据一半的屏幕大小,在全屏模式下,这就不是问题了。
   处理不同的输入类型
      android的text Field允许我们设置不同的输入类型,比如普通的文本输入,数字,URL,email地址和查找串。当我们实现一个新的IME时,我们要检查输入类型,为它提供适当的接口。然而,我们不用让我们的IME去检查用户输入是否是有效的输入类型,这是拥有这个text field的应用的工作。
      当一个输入域获得焦点,我们的IME启动,系统会调用onStartInputView(),传递一个EditorInfo对象,包含了输入类型的细节和text field的其他属性。这个对象中inputType域包含了输入类型。
      inputType域是一个int值,包含了多种不同的输入类型设置的bit pattern。(The inputType field is an int that contains bit patterns for various input type settings. )检查他的text field 的输入类型,可以用他和TYPE_MASH_CLASS常量相与,比如:inputType & InputType.TYPE_MASK_CLASS 。。可能值一下一些值:TYPE_CLASS_NUMBER,TYPE_CLASS_DATETIME,TYPE_CLASS_PHONE,TYPE_CLASS_TEXT,更多请参看InputType文档。
      在我们的IME中,当传递密码时要确定能够正确的处理文本。在 UI的input view和candidate view中隐藏密码,并且不能保存密码到设备上。

   8。发送文本到应用上
   当用户输入文本到我们的IME中时,我们可以通过发送独立的键事件或者应用中text field光标旁的文本来把文本发送给应用。不管什么发送方法,我们都要使用InputConnection的一个实例来传递文本,为了获得这样的一个一个实例,我们可以调用InputMehodService.getCurrentInputConnection。
   编辑光标旁的文本
      当我们处理编辑text field中存在的文本时,一些在BaseInputConnection更加有用的方法是:getTextBeforeCursor(),getTextAfterCursor(),deleteSurroundingText(),commitText()。比如:下面的小例子展示怎么样替换“Fell”左边的文本,改为“Hello!”

        InputConnection ic = getCurrentInputConnection();
	ic.deleteSurroundingText(4, 0);
	ic.commitText("Hello", 1);
	ic.commitText("!", 1);

   在提交之前排列文本(这部分不会翻译,这个苦逼的英语水平啊)当我们的IME做文本预处理( doe硬件的s text prediction )或者需要多个步骤来排列图形和单词时,我们可以在text field中展示这些过程之到用户提交单词输入,我们可以用完整的文本替换掉部分组成的文本。比如,我们可以通过输入“span”来特别对待输入的文本当我们传递它到InputConnection.setComposingText()。

   9。拦截硬件的键事件
   即使IME的窗口没有明确的的焦点,它也可以先接手到硬件的键事件,然后选择处理它们,或者传递他们到应用中去。例如,我们想要处理方向键来在排列的期间中在我们的UI中去选择候选单词(you may want to consume the directional keys to navigate within your UI for candidate selection during composition.)拦截硬件的键事件,我们可以复写onKeyDown()和onKeyUp()。记得调用super方法如果我们不想自己处理的话。

   10。创建IME的子类型
   子类型允许IME提供多中输入模式,支持多种语言。一个子类型能够表示:
      当地语言,英语,法语
      输入模式,比如声音,键盘,手写
      其他的输入风格,组织,IME的属性,比如传统键盘布局或者10键布局
   子类型的信息用于notification bar上的可以选择IME转换对话框,也可以用于IME设置。消息也允许框架自己直接生成特殊的IME子类型。(The information also allows the framework to bring up a specific subtype of an IME directly.)当我们自己创建一个IME时,可以灵巧地使用子类型,因为他可以帮助用户分辨和转换IME的语言和模式。我们可以在input method的XML文件中定义子类型,使用<subtype>元素。比如:下面例子定义了两张子类型,一种是给本地语言是英语的,一中是给本地语言是法语的

<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"
            .../>
/>

   为了保证我们的子类型在 UI中正确的被标识,我们可以使用%s来获得和本地子类型标签一样的子类型标签。下面有两个代码例子。第一个如下,展示了input method XML文件的一部分:
<subtype
        android:label="@string/label_subtype_generic"
        android:imeSubtypeLocale="en_US"
        android:icon="@drawable/icon_en_us"
        android:imeSubtypeMode="keyboard" />

   第二个如下,是strings.xml的一部分,字符串label_subtype_generic是IME UI 定义中用来设置子类型的标签的,如下声明:
<string name="label_subtype_generic">%s</string>

   This sets the subtype’s display name to “English (United States)” in any English language locale, or to the appropriate localization in other locales.(只可意会不可言传)
   从notification bar上选择IME子类型
      Android系统管理所有IME的所有子类型。IME子类型,被当作他们所属的IME的一种模式。在notification bar,用户可以选择一种当前设置的IME的一种可以用的子类型。
   从系统设置中选择IME子类型
      用户可以在System setting中的Language&Input中设置子类型怎么使用。在Soft Keyboard 例子中,文件InputMethodSettingsFragment.java contains an implementation that facilitates a subtype enabler in the IME settings.请自行参看android SDK中例子,来获取更多信息。

   11。一般IME要考虑的:
   当我们实现自己的IME时,我们应该考虑一下几点:
   提供一种方法让用户可以直接从IME的 UI中设置选项。
   因为会有多种IME安装在设备上,所以我们要提供一种方便的方式来让用户从我们的IME中转换到其他的IME。
   能够很快启动IME,预加载或加载需要的很大的资源以使用户在他们tap到text field时就可以看到IME。为后面再次使用IME缓存资源和视图。
   相反,当IME窗口隐藏的时候我们要释放大的内存分配,所以应用可以有足够的内存空间运行。如果IME只是隐藏很短的时间请考虑使用延时信息去释放资源。
   确定用户能够输入和语言或者locale一样多的字符。请记住用户可能在密码或者用户名中使用标点符号,所以我们的IME必须提供足够多的不同字符来允许用户输入密码和用户名。


因为是刚开始接触这部分,里面有些概念不理解,可能翻译有误,望指正。
  • 大小: 86.8 KB
1
0
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics