Android輸入法開發 新手學習指引

TA遠方發表於2019-09-29

①,先做輸入法設定介面

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:一個輸入設定頁面,用於測試輸入,另一個是底部彈出的輸入佈局, 第一次用,需要在系統輸入法裡面設定該輸入法,並勾選啟用即可

Android輸入法開發 新手學習指引

對了,參考來源也獻上:

一,輸入法的開發入門: 點這

二,輸入法的游標操作: 點這


相關文章