Android自定義View接收輸入法輸入的內(nèi)容
前言
可能對(duì)于很多新人來(lái)講,看到這個(gè)題目,想到的能接收輸入法輸入的內(nèi)容大概只有EditText和TextView這兩個(gè)控件了,其實(shí)不然,只要是View的子類(lèi),都可以接收輸入法輸入的內(nèi)容。
現(xiàn)在我們一步一步來(lái)實(shí)現(xiàn),第一步我們得有一個(gè)View的子類(lèi)。
實(shí)現(xiàn)方法
//首先我們得重寫(xiě)View中的一個(gè)方法,返回true,就是讓這個(gè)View變成文本可編輯的狀態(tài),默認(rèn)返回false。
@Override
public boolean onCheckIsTextEditor() {
return true;
}
//第二個(gè)就是重寫(xiě)
public InputConnection onCreateInputConnection(EditorInfo outAttrs);
//方法,需要返回一個(gè)InputConnect對(duì)象,這個(gè)是和輸入法輸入內(nèi)容的橋梁。
// outAttrs就是我們需要設(shè)置的輸入法的各種類(lèi)型最重要的就是:
outAttrs.imeOptions = EditorInfo.IME_FLAG_NO_EXTRACT_UI;
outAttrs.inputType = InputType.TYPE_NULL;
這里我只是隨便設(shè)置,重要的是返回的InputConnect對(duì)象。
//一般我們都是些一個(gè)BaseInputConnection的子類(lèi),而B(niǎo)aseInputConnection是實(shí)現(xiàn)了InputConnection接口的。
需要注意的就是幾個(gè)方法注意重寫(xiě)。
@Override
public boolean commitText(CharSequence text, int newCursorPosition) {
Log.d("hickey", "commitText:" + text + "\t" + newCursorPosition);
if (containsEmoji(text.toString())) {
Log.d("hickey", "send emoji");
return true;
}
if (mPlayer != null && mPlayFragment.isInputMethodStatus()) {
Log.d("hickey", "text:" + text);
mPlayerView.sendCharEvent(text.toString());
}
return true;
}
note:這個(gè)是當(dāng)輸入法輸入了字符,包括表情,字母、文字、數(shù)字和符號(hào)。我們可以通過(guò)text篩選出我們不想讓顯示到自定義view上面。
//有文本輸入,當(dāng)然也有按鍵輸入,也別注意的是有些輸入法輸入數(shù)字并非用commitText方法傳遞,而是用按鍵來(lái)代替,比如KeyCode_1是代表1等。
@Override
public boolean sendKeyEvent(KeyEvent event) {
/** 當(dāng)手指離開(kāi)的按鍵的時(shí)候 */
if (event.getAction() == KeyEvent.ACTION_DOWN) {
Log.d("hickey", "sendKeyEvent:KeyCode=" + event.getKeyCode());
if (event.getKeyCode() == KeyEvent.KEYCODE_DEL) {
mPlayerView.sendFunctionKeyCodeEvent(KeyEvent.KEYCODE_DEL);
} else if (event.getKeyCode() == KeyEvent.KEYCODE_ENTER) {
mPlayerView.sendFunctionKeyCodeEvent(KeyEvent.KEYCODE_ENTER);
mPlayFragment.setInputMethodStatus(false, 1);
} else {
mPlayerView.sendCharKeyCodeEvent(event.getKeyCode());
}
}
return true;
}
note:這里我只做了刪除,回車(chē)按鍵的處理,由于會(huì)觸發(fā)動(dòng)作按下和松開(kāi)兩次,所以在這里只做了按下的處理。
//當(dāng)然刪除的時(shí)候也會(huì)觸發(fā)
@Override
public boolean deleteSurroundingText(int beforeLength, int afterLength) {
Log.d("hickey", "deleteSurroundingText " + "beforeLength=" + beforeLength + " afterLength=" + afterLength);
mPlayerView.sendFunctionKeyCodeEvent(KeyEvent.KEYCODE_DEL);
return true;
}
@Override
public boolean finishComposingText() {
//結(jié)束組合文本輸入的時(shí)候
Log.d("hickey", "finishComposingText");
return true;
}
//這個(gè)方法基本上會(huì)出現(xiàn)在切換輸入法類(lèi)型,點(diǎn)擊回車(chē)(完成、搜索、發(fā)送、下一步)點(diǎn)擊輸入法右上角隱藏按鈕會(huì)觸發(fā)。
這里引申出多個(gè)問(wèn)題,比如說(shuō)當(dāng)我們點(diǎn)擊View上的時(shí)候,需要彈出輸入法咋辦?
我們可以通過(guò)InputMethodManager來(lái)控制輸入法彈起和縮回。
InputMethodHelper(Context mContext) {
inputMethodManager = (InputMethodManager) mContext.getSystemService(Context.INPUT_METHOD_SERVICE);
}
public synchronized static InputMethodHelper getInstance(Context mContext) {
synchronized (InputMethodHelper.class) {
if (inputMethodHelper == null) {
inputMethodHelper = new InputMethodHelper(mContext);
}
return inputMethodHelper;
}
}
/**
* 顯示軟鍵盤(pán)
*
* @param view
*/
public void showSoftInput(View view) {
inputMethodManager.showSoftInput(view, 0);
}
/**
* 隱藏輸入法
*/
public void hideSoftInput(View view) {
if (inputMethodManager.isActive()) {
Log.d("hickey", "hideSoftInput:" + "hideSoftInputFromWindow");
inputMethodManager.hideSoftInputFromWindow(view.getWindowToken(), 0);
}
}
在非全屏狀態(tài)下,我們可以通過(guò)布局大小的改變來(lái)監(jiān)聽(tīng)輸入法的彈起和縮回,但是在全屏狀態(tài)下呢,抱歉,目前是不可以的。比如說(shuō)用戶(hù)點(diǎn)擊了輸入法的隱藏按鈕,只會(huì)觸發(fā)finishComposingText這個(gè)方法,但是其他時(shí)候也會(huì)觸發(fā)此方法,所以想通過(guò)此方法監(jiān)聽(tīng)輸入法縮回是不可行的,InputMethodManager也沒(méi)有提供相關(guān)的API,試過(guò)獲取IMM的提供的
public boolean isActive(View view){
return inputMethodManager.isActive(view);
}
public boolean isActive(){
return inputMethodManager.isActive();
}
public boolean isWatchingCursor (View view){
return inputMethodManager.isWatchingCursor(view);
}
public boolean isAcceptingText(){
return inputMethodManager.isAcceptingText();
}
都沒(méi)有任何成效。
還有一種情況是當(dāng)前Activity退出了,輸入法還健在,且輸入了沒(méi)有任何內(nèi)容。而且我們?cè)囘^(guò)所有隱藏輸入法的方法,都無(wú)法正常的隱藏輸入法。
這里告訴告訴大家一個(gè)比較賤的方法,在輸入法健在的時(shí)候,我們點(diǎn)擊返回按鈕,都會(huì)主動(dòng)隱藏輸入法,再次點(diǎn)擊才會(huì)把按鍵事件分發(fā)傳遞到Activity上。
所以,我們就需要模擬一個(gè)返回的事件。
new Thread(new Runnable() {
@Override
public void run() {
RedFinger.simulationEvent = true;
Instrumentation instrumentation = new Instrumentation();
instrumentation.sendKeyDownUpSync(KeyEvent.KEYCODE_BACK);
}
}).start();
//這里弄了個(gè)bool標(biāo)志是防止輸入已經(jīng)隱藏還會(huì)分發(fā)返回按鍵事件到Activity上,所以需要在可能退出到的頁(yè)面上做處理。
總結(jié)
以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)各位Android開(kāi)發(fā)者們能帶來(lái)一定的幫助,如果有疑問(wèn)大家可以留言交流。
- Android 顯示和隱藏輸入法實(shí)現(xiàn)代碼
- Android程序打開(kāi)和對(duì)輸入法的操作(打開(kāi)/關(guān)閉)
- Android中Activity啟動(dòng)默認(rèn)不顯示輸入法解決方法
- Android的文本和輸入之創(chuàng)建輸入法教程
- Android輸入法彈出時(shí)覆蓋輸入框問(wèn)題的解決方法
- Android中系統(tǒng)默認(rèn)輸入法設(shè)置的方法(輸入法的顯示和隱藏)
- Android監(jiān)聽(tīng)輸入法彈窗和關(guān)閉的實(shí)現(xiàn)方法
- Android 點(diǎn)擊屏幕空白處收起輸入法軟鍵盤(pán)(手動(dòng)打開(kāi))
- Android InputMethodManager輸入法簡(jiǎn)介
- Android實(shí)現(xiàn)彈出輸入法時(shí)頂部固定中間部分上移的效果
相關(guān)文章
Android?Flutter控件封裝之視頻進(jìn)度條的實(shí)現(xiàn)
這篇文章主要來(lái)和大家分享一個(gè)很簡(jiǎn)單的控制器封裝案例,包含了基本的播放暫停,全屏和退出全屏,文中的示例代碼講解詳細(xì),感興趣的可以了解一下2023-06-06
Android 自定義圖片地圖坐標(biāo)功能的實(shí)現(xiàn)
最近項(xiàng)目要求實(shí)現(xiàn)一個(gè)在自定義地圖圖片上添加坐標(biāo)信息的功能,類(lèi)似于在圖片做標(biāo)注的功能,這種功能糾結(jié)該如何實(shí)現(xiàn)呢?下面小編通過(guò)實(shí)例代碼給大家介紹Android 自定義地圖的實(shí)現(xiàn),需要的朋友參考下吧2021-07-07
Android中RecyclerView布局代替GridView實(shí)現(xiàn)類(lèi)似支付寶的界面
RecyclerView比GridView來(lái)得更加強(qiáng)大,不僅是在分割線(xiàn)的繪制方面,在條目的編輯上也做得同樣出色,下面就來(lái)看一下Android中RecyclerView布局代替GridView實(shí)現(xiàn)類(lèi)似支付寶的界面的實(shí)例2016-06-06
Android基于MLKit實(shí)現(xiàn)條形碼掃碼的代碼示例
這篇文章將借助開(kāi)源庫(kù)?MLKit?實(shí)現(xiàn)條形碼掃描,對(duì)于商品條形碼也可以很好地識(shí)別成功,該庫(kù)的使用內(nèi)容非常豐富,除了條碼識(shí)別,還有文字識(shí)別、圖像標(biāo)記、人臉檢測(cè)等等,本文篇文章就只介紹最基本的條形碼掃描使用,需要的朋友可以參考下2023-08-08

