android - 如何在android中使用自定义键盘应用程序编写编辑文本

标签 android

我正在做一个需要特殊键盘的应用程序,我可以通过按键将文本变成编辑文本。

公共(public)类 SecondActivity 扩展 Activity 实现 OnKeyboardActionListener,OnKeyListener {

private static final String TAG = SecondActivity.class.getName();
private EditText editText1, editText2, editText3;
private InputMethodManager imm;
private String mWordSeparators;
private StringBuilder mComposing = new StringBuilder();
private KeyboardView keyboardView;
private Keyboard keyboard;
private Keyboard miKeyboard;
private boolean mCapsLock;
private long mLastShiftTime;
private boolean mCompletionOn;
private long mMetaState;
private CompletionInfo[] mCompletions;

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_second);

    Button button3 = (Button) findViewById(R.id.button3);
    button3.setOnClickListener(new OnClickListener() {
        public void onClick(View v) {
            finish();
            Log.d("cambio estado", "onDestroy");
        }
    });

    Button button4 = (Button) findViewById(R.id.button4);
    button4.setOnClickListener(new OnClickListener() {
        public void onClick(View v) {
            finish();
            Log.d("cambio estado", "onDestroy");
        }
    });

    editText1 = (EditText) findViewById(R.id.editText1);
    editText2 = (EditText) findViewById(R.id.editText2);
    editText3 = (EditText) findViewById(R.id.editText3);

    imm = (InputMethodManager)getSystemService(INPUT_METHOD_SERVICE);
    imm.hideSoftInputFromWindow(editText1.getWindowToken(), 0);
    imm.hideSoftInputFromWindow(editText2.getWindowToken(), 0);
    imm.hideSoftInputFromWindow(editText3.getWindowToken(), 0);
    mWordSeparators = getResources().getString(R.string.word_separators);

    keyboardView = (KeyboardView) findViewById(R.id.keyboardView);
    keyboard = new Keyboard(this, R.xml.qwerty);
    miKeyboard = new Keyboard(this,R.xml.qwerty);
    keyboardView.setKeyboard(keyboard);
    keyboardView.setEnabled(true);
    keyboardView.setPreviewEnabled(true);
    keyboardView.setOnKeyListener(this);
    keyboardView.setOnKeyboardActionListener(this);
}

public void onStartInput(EditorInfo attribute, boolean restarting) {

    mComposing.setLength(0);
    updateCandidates();

    if (!restarting) {
        mMetaState = 0;
    }

    mCompletionOn = false;
    mCompletions = null;

    switch (attribute.inputType & InputType.TYPE_MASK_CLASS) {
        case InputType.TYPE_CLASS_NUMBER:
        case InputType.TYPE_CLASS_DATETIME:
            keyboard = miKeyboard;
            break;

        case InputType.TYPE_CLASS_PHONE:
            keyboard = miKeyboard;
            break;

        case InputType.TYPE_CLASS_TEXT:
            keyboard = miKeyboard;
            updateShiftKeyState(attribute);
            break;

        default:
            keyboard = miKeyboard;
            updateShiftKeyState(attribute);
    }
    }

 public void onDisplayCompletions(CompletionInfo[] completions) {
    if (mCompletionOn) {
        if (completions == null) {
            return;
        }
        List<String> stringList = new ArrayList<String>();
        for (int i = 0; i < completions.length; i++) {
            CompletionInfo ci = completions[i];
            if (ci != null) stringList.add(ci.getText().toString());
        }
    }
}

 private boolean translateKeyDown(int keyCode, KeyEvent event) {
     mMetaState = MetaKeyKeyListener.handleKeyDown(mMetaState,
             keyCode, event);
     int c = event.getUnicodeChar(MetaKeyKeyListener.getMetaState(mMetaState));
     mMetaState = MetaKeyKeyListener.adjustMetaAfterKeypress(mMetaState);
     InputConnection ic = getCurrentInputConnection();
     if (c == 0 || ic == null) {
         return false;
     }
     if ((c & KeyCharacterMap.COMBINING_ACCENT) != 0) {
         c = c & KeyCharacterMap.COMBINING_ACCENT_MASK;
     }  
     if (mComposing.length() > 0) {
         char accent = mComposing.charAt(mComposing.length() -1 );
         int composed = KeyEvent.getDeadChar(accent, c);
         if (composed != 0) {
             c = composed;
             mComposing.setLength(mComposing.length()-1);
         }
     } 
     onKey(c, null);
     return true;
 }

 private void hideDefaultKeyboard() {
      getWindow().setSoftInputMode(
        WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
     }

private void handleShift() {
    checkToggleCapsLock();
    keyboardView.setShifted(mCapsLock || !keyboardView.isShifted());
}

private void checkToggleCapsLock() {
    long now = System.currentTimeMillis();
    if (mLastShiftTime + 800 > now) {
        mCapsLock = !mCapsLock;
        mLastShiftTime = 0;
    } else {
        mLastShiftTime = now;
    }
}

private void updateCandidates() {
    if (!mCompletionOn) {
        if (mComposing.length() > 0) {
            ArrayList<String> list = new ArrayList<String>();
            list.add(mComposing.toString());
        }
    }
}

private void handleClose() {
    commitTyped(getCurrentInputConnection());
    keyboardView.closing();
}

private void handleCharacter(int primaryCode, int[] keyCodes) {
        if (keyboardView.isShifted()) {
            primaryCode = Character.toUpperCase(primaryCode);
        }
        else {
        getCurrentInputConnection().commitText(
                String.valueOf((char) primaryCode), 1);
    }
}

public void onText(CharSequence text) {
    Log.d(TAG, "onText? \"" + text + "\"");
    InputConnection ic = getCurrentInputConnection();
    if (ic == null) return;
    ic.beginBatchEdit();
    if (mComposing.length() > 0) {
        commitTyped(ic);
    }
    ic.commitText(text, 0);
    ic.endBatchEdit();
    updateShiftKeyState((EditorInfo) getCurrentInputEditorInfo());
}

private void updateShiftKeyState(EditorInfo attr) {
    if (attr != null 
            && keyboardView != null && keyboard == keyboardView.getKeyboard()) {
        int caps = 0;
        EditorInfo ei = (EditorInfo) getCurrentInputEditorInfo();
        if (ei != null && ei.inputType != InputType.TYPE_NULL) {
            caps = getCurrentInputConnection().getCursorCapsMode(attr.inputType);
        }
        keyboardView.setShifted(mCapsLock || caps != 0);
    }}

private void commitTyped(InputConnection inputConnection) {
    if (mComposing.length() > 0) {
        inputConnection.commitText(mComposing, mComposing.length());
        mComposing.setLength(0);
        updateCandidates();
    }
}

private String getWordSeparators() {
    return mWordSeparators;
}

public boolean isWordSeparator(int code) {
    String separators = getWordSeparators();
    return separators.contains(String.valueOf((char)code));
}

private void handleBackspace() {
    final int length = mComposing.length();
    if (length > 1) {
        mComposing.delete(length - 1, length);
        getCurrentInputConnection().setComposingText(mComposing, 1);
        updateCandidates();
    } else if (length > 0) {
        mComposing.setLength(0);
        getCurrentInputConnection().commitText("", 0);
        updateCandidates();
    } else {
        keyDownUp(KeyEvent.KEYCODE_DEL);
    }
    updateShiftKeyState(getCurrentInputEditorInfo());
}


private InputConnection getCurrentInputConnection() {
    return getCurrentInputConnection();
}

private EditorInfo getCurrentInputEditorInfo() {
    return getCurrentInputEditorInfo();
}

@Override
public void swipeUp() {
    Log.d(TAG, "swipeUp");
}

@Override
public void swipeRight() {
    Log.d(TAG, "swipeRight");
}

@Override
public void swipeLeft() {
    Log.d(TAG, "swipeLeft");
    handleBackspace();
}

@Override
public void swipeDown() {
    Log.d(TAG, "swipeDown");
    handleClose();
}

@Override
public void onRelease(int primaryCode) {
    Log.d(TAG, "onRelease? primaryCode=" + primaryCode);
}

@Override
public void onPress(int primaryCode) {
    Log.d(TAG, "onPress? primaryCode=" + primaryCode);
}

@Override
public void onKey(int primaryCode, int[] keyCodes) {
    Log.d(TAG, "onKey? primaryCode=" + primaryCode);
    int n1 = 0; // -1 count
    for (int keyCode : keyCodes) {
        if (keyCode == -1) {
            n1++;
            continue;
        }
        Log.v(TAG, "keyCode=" + keyCode);
    }
    Log.v(TAG, "keyCode=-1 *" + n1);
if (isWordSeparator(primaryCode)) {
    if (mComposing.length() > 0) {
        commitTyped(getCurrentInputConnection());
    }
    sendKey(primaryCode);
    updateShiftKeyState(getCurrentInputEditorInfo());
} else if (primaryCode == Keyboard.KEYCODE_DELETE) {
    handleBackspace();
} else if (primaryCode == Keyboard.KEYCODE_SHIFT) {
    handleShift();
} else if (primaryCode == Keyboard.KEYCODE_CANCEL) {
    handleClose();
} else if (primaryCode == Keyboard.KEYCODE_MODE_CHANGE
        && keyboardView != null) {
    Keyboard current = keyboardView.getKeyboard();
    keyboardView.setKeyboard(current);
} else {
    handleCharacter(primaryCode, keyCodes);
}

private void sendKey(int keyCode) {
    switch (keyCode) {
        case '\n':
            keyDownUp(KeyEvent.KEYCODE_ENTER);
            break;
        default:
            if (keyCode >= '0' && keyCode <= '9') {
                keyDownUp(keyCode - '0' + KeyEvent.KEYCODE_0);
            } else {
                getCurrentInputConnection().commitText(String.valueOf((char) keyCode), 1);
            }
            break;
    }
}

public boolean onKeyDown(int keyCode, KeyEvent event) {
    switch (keyCode) {
        case KeyEvent.KEYCODE_BACK:
            if (event.getRepeatCount() == 0 && keyboardView != null) {
                if (keyboardView.handleBack()) {
                    return true;
                }
            }
            break;    
        case KeyEvent.KEYCODE_DEL:
            if (mComposing.length() > 0) {
                onKey(Keyboard.KEYCODE_DELETE, null);
                return true;
            }
            break;
        case KeyEvent.KEYCODE_ENTER:
            return false;
        default:
            if (mCapsLock) {
                if (keyCode == KeyEvent.KEYCODE_SPACE
                        && (event.getMetaState()&KeyEvent.META_ALT_ON) != 0) {
                    InputConnection ic = getCurrentInputConnection();
                    if (ic != null) {
                        ic.clearMetaKeyStates(KeyEvent.META_ALT_ON);
                        keyDownUp(KeyEvent.KEYCODE_A);
                        keyDownUp(KeyEvent.KEYCODE_N);
                        keyDownUp(KeyEvent.KEYCODE_D);
                        keyDownUp(KeyEvent.KEYCODE_R);
                        keyDownUp(KeyEvent.KEYCODE_O);
                        keyDownUp(KeyEvent.KEYCODE_I);
                        keyDownUp(KeyEvent.KEYCODE_D);
                        return true;
                    }
                }
                if (translateKeyDown(keyCode, event)) {
                    return true;
                }
            }
    }
    return super.onKeyDown(keyCode, event);
}

private void keyDownUp(int keyEventCode) {
    getCurrentInputConnection().sendKeyEvent(
            new KeyEvent(KeyEvent.ACTION_DOWN, keyEventCode));
    getCurrentInputConnection().sendKeyEvent(
            new KeyEvent(KeyEvent.ACTION_UP, keyEventCode));
}

@Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
    hideDefaultKeyboard();
    Log.d(TAG, "onKey? keyCode=" + keyCode);
    return false;
}

最佳答案

在您的 Xml 文件中,在 editText 标记内,您会找到类似 android:inputType 属性的内容。您可以指定不同类型的输入类型,如 textEmail、phoneNumber、textPassword。

类型有很多种,如果你指定input type属性,它会根据输入类型显示自定义键盘,

如果您的 editText 输入类型是 phoneNumber,那么它将显示 Num KeyPad

如果您的 editText 输入类型是 textPassword,那么它将显示字符键盘

像这样,你可以有更多的自定义小键盘/键盘

对于密码键盘,

     <EditText android:id=..........
            android:inputType="textPassword" />

对于数字小键盘

     <EditText android:id=..........
            android:inputType="number" />

关于android - 如何在android中使用自定义键盘应用程序编写编辑文本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13937526/

相关文章:

android - 复选框 - 使按钮居中

iphone - 如何将纹理映射到曲面上?

android - Textview 上的 MotionEvent.ACTION_UP

java - Android Studio 的手机模拟器无法读取您的本地文件系统 : URL. openStream 抛出 FileNotFoundException

java - 如何在不使用任务监听器的情况下获取 Firebase Auth Token?

android - 如何解决 : AAPT: error: is incompatible with attribute src (attr) reference|color

android - UnsatisfiedLinkError : No implementation found for void mono. android.text.TextWatcherImplementor

java - 更改 onClick Android 中的按钮图像

android - Gradle 执行失败 : Unknown command-line option '--daemon'

java - Android Nougat 在捕获视频时返回 null