重写InputMethodService,手动切换输入法问题
2017-01-14 10:01
369 查看
实现输入法的步骤:
输入法程序的核心是一个服务类,这个类必须继承自InputMethodService。
下面先来看看实现一个基本的输入法程序的步骤。
(1)建立一个继承自android.inputmethodservice.InputMethodService的类,称为输入法的服务类。
(2)在AndroidManifest.xml文件中配置这个服务类。
(3)编写一个用于显示软键盘的布局文件。
(4)覆盖InputMethodService类的onCreateInputView方法。
(5)onCreateInputView方法需要返回与第3步建立的布局文件对应的View对象。在返回之前,一般需要设置相应控件的事件,如软键盘按钮单击事件。
(6)在输入法服务类或其他类中编写响应软键盘中按键事件的代码,如按钮单击事件、物理键盘事件等。
下面就来实现一个简单的输入法程序。
第一步:新建一个Android工程命名为simple_inputmethod目录结构如下图:
第二步:建立一个AndroidInputMethodService类,该类继承自InputMethodService,然后在Android.Manifest.xml文件中配置:
AndroidInputMethodService类:
[java] view
plain copy
package net.csdn.leigo.inputmethod;
import net.csdn.leigo.inputmethod.R;
import android.inputmethodservice.InputMethodService;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputConnection;
import android.widget.Button;
public class AndroidInputMethodService extends InputMethodService implements
OnClickListener {
}
AndroidManifest.xml:
[html] view
plain copy
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="net.csdn.leigo.inputmethod"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="10"
android:targetSdkVersion="10" />
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<!-- Optional: an activity for controlling the IME settings -->
<activity android:name="net.csdn.leigo.inputmethod..InputMethodSetting" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
</intent-filter>
</activity>
<!-- Declares the input method service -->
<service
android:name="net.csdn.leigo.inputmethod.AndroidInputMethodService"
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>
</manifest>
配置输入法服务时必须设置
[html] view
plain copy
android.permission.BIND_INPUT_METHOD"
权限,并且在<intent-filter>标签中添加一个
[html] view
plain copy
"android.view.InputMethod"
动作。
在<service>标签中还加入一个<meta-data>标签,用于配置输入法,也就是在“语言与键盘”设置界面可以看到我们编写的输入法,其中android:resource属性制定了
一个输入法资源ID。这个资源文件(method.xml)在res\xml目录中,代码如下:
[html] view
plain copy
<?xml version="1.0" encoding="UTF-8"?>
<input-method xmlns:android="http://schemas.android.com/apk/res/android"
android:settingsActivity="net.csdn.leigo.inputmethod.InputMethodSetting"/>
<input-method>标签的android:settingActivity属性可以制定输入法设置窗口。
InputMethodSetting.java:
[java] view
plain copy
package net.csdn.leigo.inputmethod;
import android.app.Activity;
import android.os.Bundle;
public class InputMethodSetting extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.setting);
}
}
setting.xml:
[html] view
plain copy
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="horizontal" >
<TextView
android:id="@+id/textview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="输入法设置窗口" />
</LinearLayout>
第三步:编写一个布局文件。这个布局文件实际上就是软键盘的布局。在这个布局中有5个水平排列的按钮,其中前4个用于输入4个字符串(就是<Button>标签的android:text属性值),最后一个按钮用于隐藏软键盘:
keyboard.xml:
[java] view
plain copy
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal" >
<Button
android:id="@+id/btn1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="a" />
<Button
android:id="@+id/btn2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="6dp"
android:text="b" />
<Button
android:id="@+id/btn3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="6dp"
android:text="c" />
<Button
android:id="@+id/btn4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="6dp"
android:text="d" />
<Button
android:id="@+id/btn_hide"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="6dp"
android:text="Hide" />
</LinearLayout>
第四步:修改AndroidInputMethodService类的代码,首先覆盖onCreateInputView方法,然后在onCreateInputView方法中装载keyboard,xml布局文件,并设置按钮的单击事件,最后返回软键盘的View对象。
[java] view
plain copy
@Override
public View onCreateInputView() {
// 装载keyboard.xml文件
View view = getLayoutInflater().inflate(R.layout.keyboard, null);
// 设置布局中5个按钮的单击事件
view.findViewById(R.id.btn1).setOnClickListener(this);
view.findViewById(R.id.btn2).setOnClickListener(this);
view.findViewById(R.id.btn3).setOnClickListener(this);
view.findViewById(R.id.btn4).setOnClickListener(this);
view.findViewById(R.id.btn_hide).setOnClickListener(this);
Log.d(TAG, "onCreateInputView()");
// 返回View对象
return view;
}
注意:输入法界面(软键盘)并不许要我们自己建立Activity,这个Activity是由系统提供的,而我们只需要在Activity上显示的View对象即可,也就是onCreateInputView方法的返回值。
最后一部需要处理按钮的单击动作,AndroidInputMethodService类需要实现OnClickListener接口。
[java] view
plain copy
@Override
public void onClick(View v) {
if (v.getId() == R.id.btn_hide) {
// 隐藏软键盘
hideWindow();
} else {
Button button = (Button) v;
// 获得InputConnection对象
InputConnection inputConnection = getCurrentInputConnection();
if (button.getId() == R.id.btn1) {
// 设置预输入文本
// setComposingText方法的第2个参数值为1,表示在当前位置预输入文本
inputConnection.setComposingText(button.getText(), 1);
} else {
// 向当前获得焦点的EditText控件输出文本
// commitText方法第2个参数值为1,表示在当前位置插入文本
inputConnection.commitText(button.getText(), 1);
}
}
}
通过InoutConnection.setComposingText方法可以预输入文本。预输入文本一般会在输入的文本下方显示一个下划线,直到将其替换成正式输入的文本,否则下划线一直存在。
运行工程查看效果图:
经测试,如果EditText的inputType属性为默认时,点击可以输入,但是若是其他的例如phone或者email之类,点击就没有什么效果。这个可以参考文档或者在下一篇会有介绍。
输入法程序的核心是一个服务类,这个类必须继承自InputMethodService。
下面先来看看实现一个基本的输入法程序的步骤。
(1)建立一个继承自android.inputmethodservice.InputMethodService的类,称为输入法的服务类。
(2)在AndroidManifest.xml文件中配置这个服务类。
(3)编写一个用于显示软键盘的布局文件。
(4)覆盖InputMethodService类的onCreateInputView方法。
(5)onCreateInputView方法需要返回与第3步建立的布局文件对应的View对象。在返回之前,一般需要设置相应控件的事件,如软键盘按钮单击事件。
(6)在输入法服务类或其他类中编写响应软键盘中按键事件的代码,如按钮单击事件、物理键盘事件等。
下面就来实现一个简单的输入法程序。
第一步:新建一个Android工程命名为simple_inputmethod目录结构如下图:
第二步:建立一个AndroidInputMethodService类,该类继承自InputMethodService,然后在Android.Manifest.xml文件中配置:
AndroidInputMethodService类:
[java] view
plain copy
package net.csdn.leigo.inputmethod;
import net.csdn.leigo.inputmethod.R;
import android.inputmethodservice.InputMethodService;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputConnection;
import android.widget.Button;
public class AndroidInputMethodService extends InputMethodService implements
OnClickListener {
}
AndroidManifest.xml:
[html] view
plain copy
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="net.csdn.leigo.inputmethod"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="10"
android:targetSdkVersion="10" />
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<!-- Optional: an activity for controlling the IME settings -->
<activity android:name="net.csdn.leigo.inputmethod..InputMethodSetting" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
</intent-filter>
</activity>
<!-- Declares the input method service -->
<service
android:name="net.csdn.leigo.inputmethod.AndroidInputMethodService"
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>
</manifest>
配置输入法服务时必须设置
[html] view
plain copy
android.permission.BIND_INPUT_METHOD"
权限,并且在<intent-filter>标签中添加一个
[html] view
plain copy
"android.view.InputMethod"
动作。
在<service>标签中还加入一个<meta-data>标签,用于配置输入法,也就是在“语言与键盘”设置界面可以看到我们编写的输入法,其中android:resource属性制定了
一个输入法资源ID。这个资源文件(method.xml)在res\xml目录中,代码如下:
[html] view
plain copy
<?xml version="1.0" encoding="UTF-8"?>
<input-method xmlns:android="http://schemas.android.com/apk/res/android"
android:settingsActivity="net.csdn.leigo.inputmethod.InputMethodSetting"/>
<input-method>标签的android:settingActivity属性可以制定输入法设置窗口。
InputMethodSetting.java:
[java] view
plain copy
package net.csdn.leigo.inputmethod;
import android.app.Activity;
import android.os.Bundle;
public class InputMethodSetting extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.setting);
}
}
setting.xml:
[html] view
plain copy
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="horizontal" >
<TextView
android:id="@+id/textview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="输入法设置窗口" />
</LinearLayout>
第三步:编写一个布局文件。这个布局文件实际上就是软键盘的布局。在这个布局中有5个水平排列的按钮,其中前4个用于输入4个字符串(就是<Button>标签的android:text属性值),最后一个按钮用于隐藏软键盘:
keyboard.xml:
[java] view
plain copy
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal" >
<Button
android:id="@+id/btn1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="a" />
<Button
android:id="@+id/btn2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="6dp"
android:text="b" />
<Button
android:id="@+id/btn3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="6dp"
android:text="c" />
<Button
android:id="@+id/btn4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="6dp"
android:text="d" />
<Button
android:id="@+id/btn_hide"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="6dp"
android:text="Hide" />
</LinearLayout>
第四步:修改AndroidInputMethodService类的代码,首先覆盖onCreateInputView方法,然后在onCreateInputView方法中装载keyboard,xml布局文件,并设置按钮的单击事件,最后返回软键盘的View对象。
[java] view
plain copy
@Override
public View onCreateInputView() {
// 装载keyboard.xml文件
View view = getLayoutInflater().inflate(R.layout.keyboard, null);
// 设置布局中5个按钮的单击事件
view.findViewById(R.id.btn1).setOnClickListener(this);
view.findViewById(R.id.btn2).setOnClickListener(this);
view.findViewById(R.id.btn3).setOnClickListener(this);
view.findViewById(R.id.btn4).setOnClickListener(this);
view.findViewById(R.id.btn_hide).setOnClickListener(this);
Log.d(TAG, "onCreateInputView()");
// 返回View对象
return view;
}
注意:输入法界面(软键盘)并不许要我们自己建立Activity,这个Activity是由系统提供的,而我们只需要在Activity上显示的View对象即可,也就是onCreateInputView方法的返回值。
最后一部需要处理按钮的单击动作,AndroidInputMethodService类需要实现OnClickListener接口。
[java] view
plain copy
@Override
public void onClick(View v) {
if (v.getId() == R.id.btn_hide) {
// 隐藏软键盘
hideWindow();
} else {
Button button = (Button) v;
// 获得InputConnection对象
InputConnection inputConnection = getCurrentInputConnection();
if (button.getId() == R.id.btn1) {
// 设置预输入文本
// setComposingText方法的第2个参数值为1,表示在当前位置预输入文本
inputConnection.setComposingText(button.getText(), 1);
} else {
// 向当前获得焦点的EditText控件输出文本
// commitText方法第2个参数值为1,表示在当前位置插入文本
inputConnection.commitText(button.getText(), 1);
}
}
}
通过InoutConnection.setComposingText方法可以预输入文本。预输入文本一般会在输入的文本下方显示一个下划线,直到将其替换成正式输入的文本,否则下划线一直存在。
运行工程查看效果图:
经测试,如果EditText的inputType属性为默认时,点击可以输入,但是若是其他的例如phone或者email之类,点击就没有什么效果。这个可以参考文档或者在下一篇会有介绍。
相关文章推荐
- 重写InputMethodService编写一个简单的输入法
- Android窗口管理服务WindowManagerService对输入法窗口(Input Method Window)的管理分析
- Android窗口管理服务WindowManagerService对输入法窗口(Input Method Window)的管理分析
- Android窗口管理服务WindowManagerService对输入法窗口(Input Method Window)的管理分析
- android 输入法 回调一:IInputMethodWrapper通过MethodCallback来回调InputMethodManagerService方法
- Android窗口管理服务WindowManagerService对输入法窗口(Input Method Window)的管理分析
- Android窗口管理服务WindowManagerService对输入法窗口(Input Method Window)的管理分析
- InputMethodManagerService处理输入法——监听APK变动
- Android 3.0 r1中文API文档(103) —— InputMethodManager [输入法]
- c# 输入法全角/半角切换问题
- 在Android中创建一种新的输入法(Creating an Input Method))
- JQuery:在input中只能输入数字,并且不能复制粘贴,不能切换输入法
- Android 3.0 r1中文API文档(103) —— InputMethodManager [输入法]
- 解决文本框在updatepanel中得到焦点,输入法不能切换到中文的问题
- 解决文本框在updatepanel中得到焦点,输入法不能切换到中文的问题
- VNC访问时不能切换Fcitx输入法的问题
- EditText 输入法问题(setContentView切换两个view,抢焦点问题)
- 长按输入框跳出select all,cut,input method等菜单,点击input method跳出所有得到的输入法列表
- 解决word2003不能切换输入法的问题
- win7 输入法不能切换问题