簡體   English   中英

Android SoftKeyboard onKeyDown / Up沒有檢測到“替代”鍵

[英]Android SoftKeyboard onKeyDown/Up not detecting 'alternative' keys

我有一個為我處理輸入的視圖,我彈出一個鍵盤並將視圖設置為可聚焦。 現在我可以得到某些按鍵......

@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
    if (keyCode == KeyEvent.KEYCODE_DEL) {
    } else if (keyCode == KeyEvent.KEYCODE_BACK) {
    } else if (keyCode == KeyEvent.KEYCODE_ENTER) {
    } else {
    }
}

等等......按下我使用的字符

event.getDisplayLabel()

只要我只想要正常的字母AZ,那就有效。 在其他語言中,通過長按軟鍵盤上的普通字母可以達到更多字母...但是,onKeyDown / Up無法檢測到這些替代字母。 我只能檢測正常的字母,軟鍵盤的標簽。 現在我的應用程序必須處理外國輸入和字母,我已將鍵盤更改為土耳其語,我可以在鍵盤上找到類似í“ú”的字母,但如果我按下它們,我就不會得到任何回復。 不是與event.getDisplayLabel或event.getUnicodeChar(); 我該如何檢測這些字母?

當鍵盤打開時, onKeyDown()onKeyUp()方法無法正常工作,因為Android將屏幕鍵盤視為單獨的活動。

實現所需的最簡單方法是在視圖上覆蓋onKeyPreIme()方法。 例如,如果您嘗試從EditText捕獲onKeyDown,請創建一個擴展EditText的新類,並覆蓋onKeyPreIme()方法:

public class LoseFocusEditText extends EditText {

    private Context mContext;

    protected final String TAG = getClass().getName();

    public LoseFocusEditText(Context context) {
        super(context);
        mContext = context;
    }

    public LoseFocusEditText(Context context, AttributeSet attrs) {
        super(context, attrs);
        mContext = context;
    }

    public LoseFocusEditText(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        mContext = context;
    }

    @Override
    public boolean onKeyPreIme(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_BACK) {

            //hide keyboard
            InputMethodManager mgr = (InputMethodManager) mContext.getSystemService(Context.INPUT_METHOD_SERVICE);
            mgr.hideSoftInputFromWindow(this.getWindowToken(), 0);

            //lose focus
            this.clearFocus();

            return true;
        }
        return false;
    }
}

這是在kitkat / htc上測試的。

編輯:

我不確定是什么導致onKeyDown根本不被調用。 也許這是你的觀點的問題? 因此,可能有比我的解決方案更好的答案。 無論哪種方式,這可能有效:

不是在視圖中使用onKeyDown,而是在活動級別覆蓋dispatchKeyEvent。 這將在到達窗口管理器之前處理您的鍵事件,因此請確保在未明確處理的任何鍵事件上調用super。

使用ACTION_DOWN的示例(因為每個事件都有ACTION_UP和ACTION_DOWN),因為您的示例在onKeyDown上使用:

@Override
public boolean dispatchKeyEvent(KeyEvent event){
    if(event.getAction() == KeyEvent.ACTION_UP) {
        return super.dispatchKeyEvent(event);
    }

    if (keyCode == KeyEvent.KEYCODE_DEL) {
    } else if (keyCode == KeyEvent.KEYCODE_BACK) {
    } else if (keyCode == KeyEvent.KEYCODE_ENTER) {
    } else {
        return super.dispatchKeyEvent(event);
    }
}

現在 (抱歉)

你可以試試:

char key = (char)event.getUnicodeChar();

代替

char key = event.getDisplayLabel();

getDisplayLabel()只會給你鍵盤上顯示的鍵,正如你所指出的那樣,鍵不一定是用戶選擇的字符。

得到它了 :)

public boolean onKey(View v, int keyCode, KeyEvent event) {
    if(event.getAction()==KeyEvent.ACTION_DOWN) return true;
    if(keyCode==KeyEvent.KEYCODE_ALT_LEFT || keyCode==KeyEvent.KEYCODE_ALT_RIGHT || keyCode==KeyEvent.KEYCODE_SHIFT_LEFT || keyCode==KeyEvent.KEYCODE_SHIFT_RIGHT) return true;

    if (keyCode == KeyEvent.KEYCODE_DEL) {
        doBackspace();
        return true;
    } else if (keyCode == KeyEvent.KEYCODE_BACK) {
        if(this.avl!=null) this.avl.onInputCancelled(this);
        return false;
    } else if (keyCode == KeyEvent.KEYCODE_ENTER) {
        inputstarted=false;
        if(this.avl!=null) this.avl.onInputFinished(this,this.text,celldata);
        return true;
    }   

    String key = "";
    if (event.getAction()==KeyEvent.ACTION_UP) key = String.valueOf((char)event.getUnicodeChar()).toUpperCase();
    else if (event.getAction()==KeyEvent.ACTION_MULTIPLE) key = String.valueOf(event.getCharacters()).toUpperCase();
    return process(key);
}

重要的部分是阻止ALT_LEFT / SHIFT_LEFT / etc鍵碼並區分ACTION_UP / ACTION_MULTIPLE並使用event.getUnicodeChar()或event.getCharacters()。

它現在有效,我可以獲得所有的字符甚至KEYCODE_DEL在移動設備上工作。 但是在平板電腦上,我仍然沒有收到刪除密鑰的回調。 看起來像一個壞的錯誤,因為今天早上它甚至在平板電腦上工作正常。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM