①,先做输入法设置界面
public class InputSetsActivity extends Activity {
@Override protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_input_sets);
}
}②,设置界面的布局,文件名:activity_input_sets.xml
<TextView
android:id="@+id/textView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="输入法设置窗口" />
<EditText
android:id="@+id/editText"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginEnd="8dp"
android:ems="10"
android:inputType="textMultiLine|textPersonName"
android:lines="3"
android:text="Name"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/textView"
android:gravity="left|top"/>
③,做出弹出输入法界面处理的类,需要继承InputMethodService类
/**
* 参考来自 CSDN: android -> 输入法开发 (入门)
* https://blog.csdn.net/mft8899/article/details/84815696
*/
public class MyInputService extends InputMethodService implements View.OnClickListener, ClipboardManager.OnPrimaryClipChangedListener {
private ClipboardManager cm;
private TextView tvClipboard;
@Override
public View onCreateInputView() {
//return super.onCreateInputView();
View v = getLayoutInflater().inflate(R.layout.layout_keyboard, null);
v.findViewById(R.id.button1_inputkb).setOnClickListener(this);
v.findViewById(R.id.button2_inputkb).setOnClickListener(this);
v.findViewById(R.id.button3_inputkb).setOnClickListener(this);
v.findViewById(R.id.button4_hide_inputkb).setOnClickListener(this);
v.findViewById(R.id.button5_del_inputkb).setOnClickListener(this);
v.findViewById(R.id.buttonMoveUp_kb).setOnClickListener(this);
v.findViewById(R.id.button2MoveDown_kb).setOnClickListener(this);
v.findViewById(R.id.button3MoveLeft_kb).setOnClickListener(this);
v.findViewById(R.id.button4MoveRigth_kb).setOnClickListener(this);
v.findViewById(R.id.button8_Copy_kb).setOnClickListener(this);
v.findViewById(R.id.button7_Paste_kb).setOnClickListener(this);
v.findViewById(R.id.button6_Shear_kb).setOnClickListener(this);
v.findViewById(R.id.button5_AllSelect_kv).setOnClickListener(this);
tvClipboard = v.findViewById(R.id.textView3_clipboard_kb);
//对复制的内容变化做侦听
cm = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE);
cm.setPrimaryClip(ClipData.newPlainText("",""));
cm.addPrimaryClipChangedListener(this);
return v;
}
@Override
public void onClick(View v) {
int id = v.getId();
if (id == R.id.button4_hide_inputkb){
hideWindow();
} else if (moveInputFoucsCorsor(id)) {
}else{
InputConnection ic = getCurrentInputConnection();
if (id == R.id.button1_inputkb){
//ic.commitText("1",1);
ic.setComposingText("1", 1);
}else if (id == R.id.button2_inputkb){
ic.commitText("2",1);
}else if (id == R.id.button3_inputkb){
ic.commitText("3",1);
}else if (id == R.id.button5_del_inputkb){
ic.deleteSurroundingText(1, 0);
}
}
}
/**
* 对复制的内容变化做侦听。
* 只有剪贴板上复制内容发生变化的时候才会调用
*/
@Override
public void onPrimaryClipChanged() {
ClipData cd = cm.getPrimaryClip();
String newText = "";
if( cd.getItemCount()>0){
newText = cd.getItemAt(0).getText().toString();
}
tvClipboard.setText(newText);
}
/**
* 输入法中的文本操作(选中、移动等)
* http://www.apkbus.com/ask.php?mod=item&tid=167671
* @return
*/
private boolean moveInputFoucsCorsor(int vid){
if (vid == R.id.buttonMoveUp_kb){
sendDownUpKeyEvents(KeyEvent.KEYCODE_DPAD_UP);
}else if (vid == R.id.button2MoveDown_kb) {
sendDownUpKeyEvents(KeyEvent.KEYCODE_DPAD_DOWN);
}else if (vid == R.id.button3MoveLeft_kb) {
sendDownUpKeyEvents(KeyEvent.KEYCODE_DPAD_LEFT);
}else if (vid == R.id.button4MoveRigth_kb) {
sendDownUpKeyEvents(KeyEvent.KEYCODE_DPAD_RIGHT);
}else if (vid == R.id.button8_Copy_kb){
InputConnection ic = getCurrentInputConnection();
ic.performContextMenuAction(android.R.id.copy);
}else if (vid == R.id.button7_Paste_kb){
InputConnection ic = getCurrentInputConnection();
ic.performContextMenuAction(android.R.id.paste);
}else if (vid == R.id.button6_Shear_kb){
InputConnection ic = getCurrentInputConnection();
ic.performContextMenuAction(android.R.id.cut);
}else if (vid == R.id.button5_AllSelect_kv){
InputConnection ic = getCurrentInputConnection();
ic.performContextMenuAction(android.R.id.selectAll);
}else {
//剩下选中、移动改变选中范围操作,不知该如何实现
//原来只要按住Shift键,再使用上面移动光标(上下左右)的代码,就可以实现选中状态时移动上下左右。按住Shift键只要发送按键事件
//http://www.apkbus.com/ask.php?mod=item&tid=167671
return false;
}
return true;
}
}④,然后,设置属性关联上输入法页面
一个是输入设置页面关联,需要在res文件的xml文件夹里添加一个method.xml文件,具体内容如下
<?xml version="1.0" encoding="utf-8"?>
<input-method xmlns:android="http://schemas.android.com/apk/res/android"
android:settingsActivity="com.example.myapplicationlib.InputSetsActivity"/>另一个是弹出的输入页面关联,需要在layout文件夹添加布局,文件名是设置页面的布局文件,上面已经提到,
接着是AndroidManifest.xml文件里的,相关修改如下
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".InputSetsActivity"></activity>
<service
android:name=".service.MyInputService"
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>⑤,可以尝试编译运行,成功安装后,运行效果图如下,
PS:一个输入设置页面,用于测试输入,另一个是底部弹出的输入布局, 第一次用,需要在系统输入法里面设置该输入法,并勾选启用即可
对了,参考来源也献上:
一,输入法的开发入门: 点这
二,输入法的光标操作: 点这