Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android自定義View接收輸入法輸入的內容

Android自定義View接收輸入法輸入的內容

編輯:關於Android編程

前言

可能對於很多新人來講,看到這個題目,想到的能接收輸入法輸入的內容大概只有EditText和TextView這兩個控件了,其實不然,只要是View的子類,都可以接收輸入法輸入的內容。

現在我們一步一步來實現,第一步我們得有一個View的子類。

實現方法

//首先我們得重寫View中的一個方法,返回true,就是讓這個View變成文本可編輯的狀態,默認返回false。
@Override
public boolean onCheckIsTextEditor() { 
  return true;
}

//第二個就是重寫
public InputConnection onCreateInputConnection(EditorInfo outAttrs);
//方法,需要返回一個InputConnect對象,這個是和輸入法輸入內容的橋梁。

// outAttrs就是我們需要設置的輸入法的各種類型最重要的就是:
outAttrs.imeOptions = EditorInfo.IME_FLAG_NO_EXTRACT_UI;
outAttrs.inputType = InputType.TYPE_NULL;

這裡我只是隨便設置,重要的是返回的InputConnect對象。

//一般我們都是些一個BaseInputConnection的子類,而BaseInputConnection是實現了InputConnection接口的。

需要注意的就是幾個方法注意重寫。

@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:這個是當輸入法輸入了字符,包括表情,字母、文字、數字和符號。我們可以通過text篩選出我們不想讓顯示到自定義view上面。
//有文本輸入,當然也有按鍵輸入,也別注意的是有些輸入法輸入數字並非用commitText方法傳遞,而是用按鍵來代替,比如KeyCode_1是代表1等。

 @Override
 public boolean sendKeyEvent(KeyEvent event) {
  /** 當手指離開的按鍵的時候 */
  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:這裡我只做了刪除,回車按鍵的處理,由於會觸發動作按下和松開兩次,所以在這裡只做了按下的處理。
//當然刪除的時候也會觸發
@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() {
  //結束組合文本輸入的時候
  Log.d("hickey", "finishComposingText");
  return true;
 }
//這個方法基本上會出現在切換輸入法類型,點擊回車(完成、搜索、發送、下一步)點擊輸入法右上角隱藏按鈕會觸發。

這裡引申出多個問題,比如說當我們點擊View上的時候,需要彈出輸入法咋辦?

我們可以通過InputMethodManager來控制輸入法彈起和縮回。

 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;
  }
 }
 /**
  * 顯示軟鍵盤
  *
  * @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);
  }
 }

在非全屏狀態下,我們可以通過布局大小的改變來監聽輸入法的彈起和縮回,但是在全屏狀態下呢,抱歉,目前是不可以的。比如說用戶點擊了輸入法的隱藏按鈕,只會觸發finishComposingText這個方法,但是其他時候也會觸發此方法,所以想通過此方法監聽輸入法縮回是不可行的,InputMethodManager也沒有提供相關的API,試過獲取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();
 }

都沒有任何成效。

還有一種情況是當前Activity退出了,輸入法還健在,且輸入了沒有任何內容。而且我們試過所有隱藏輸入法的方法,都無法正常的隱藏輸入法。

這裡告訴告訴大家一個比較賤的方法,在輸入法健在的時候,我們點擊返回按鈕,都會主動隱藏輸入法,再次點擊才會把按鍵事件分發傳遞到Activity上。

所以,我們就需要模擬一個返回的事件。

new Thread(new Runnable() {
    @Override
    public void run() {
     RedFinger.simulationEvent = true;
     Instrumentation instrumentation = new Instrumentation();
     instrumentation.sendKeyDownUpSync(KeyEvent.KEYCODE_BACK);
    }
   }).start();

//這裡弄了個bool標志是防止輸入已經隱藏還會分發返回按鍵事件到Activity上,所以需要在可能退出到的頁面上做處理。

總結

以上就是這篇文章的全部內容了,希望本文的內容對各位Android開發者們能帶來一定的幫助,如果有疑問大家可以留言交流。

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved