检索android

时间:2015-06-11 17:03:37

标签: android-keypad

我使用Android的自定义键盘来构建键盘。 android中的OnKeyboardActionListener返回被按下的键的“keyCode”。但我特别想要那个键的屏幕x和y坐标(使用或不使用keyCode)。

P.S:即使是钥匙中心的坐标也会有所帮助。我找到了一个方法“squaredDistanceFrom”,它返回键的中心和触摸屏幕的点之间的平方距离。是否有一个返回中心坐标的函数?

1 个答案:

答案 0 :(得分:2)

我知道这个问题现在已经很老了,但过去两周我一直在研究一个项目,并且有类似的要求,我一直在寻找解决方案。所以这就是我的建议:

构建工作键盘

首先,让我们从功能键盘开始。一些非常有用的资源:

获取按下的键的坐标

我还没有找到从API中按下的键检索坐标的直接方法。

但是,我们可以确定并检索按下的键的实际实例。首先,我们需要在KeyboardView上创建onTouchListener。这将允许我们在视图中检索MotionEvent并因此检索触摸事件的坐标。

然后,Keyboard类中有一个名为getKeys的方法,返回Keys列表。然后,我们可以使用isInside类中的Key方法验证先前检索到的坐标是否在键内,从而检索按下的键的实例。

我们需要在每次显示时从当前键盘检索键列表。这样,即使用户从一个布局切换到另一个布局(例如,通过使用符号或数字),我们也可以获得正确的密钥集。我们可以通过覆盖我们班级的onStartInputView方法来实现。

示例

检索密钥:

public void retrieveKeys() {
    keyList = kv.getKeyboard().getKeys();
}

覆盖显示键盘时调用的onStartInputView:

@Override
public void onStartInputView(EditorInfo info, boolean restarting) {
    super.onStartInputView(info, restarting);
    retrieveKeys();
}

为KeyboardView创建一个onTouchListener:

@Override
public View onCreateInputView() {
    kv = (KeyboardView)getLayoutInflater().inflate(R.layout.keyboard, null);
    kv.setOnKeyboardActionListener(this);
    keyboard = new Keyboard(this, R.xml.qwerty);
    kv.setKeyboard(keyboard);

    retrieveKeys();

    // Set the onTouchListener to be able to retrieve a MotionEvent
    kv.setOnTouchListener(new View.OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            // For each key in the key list
            for (Keyboard.Key k : keyList) {
                // If the coordinates from the Motion event are inside of the key
                if (k.isInside((int) event.getX(), (int) event.getY())) {
                    // k is the key pressed
                    Log.d("Debugging",
                            "Key pressed: X=" + k.x + " - Y=" + k.y);
                    int centreX, centreY;
                    centreX = (k.width/2) + k.x;
                    centreY = (k.width/2) + k.x;
                    // These values are relative to the Keyboard View
                    Log.d("Debugging",
                            "Centre of the key pressed: X="+centreX+" - Y="+centreY);
                }
            }
            // Return false to avoid consuming the touch event
            return false;
        }
    });

    return kv;
}

整个示例(没有包和导入):

public class MyTestKeyboard extends InputMethodService
        implements KeyboardView.OnKeyboardActionListener {

    private KeyboardView kv;
    private Keyboard keyboard;
    private boolean caps = false;

    private List<Keyboard.Key> keyList;

    public void retrieveKeys() {
        keyList = kv.getKeyboard().getKeys();
    }

    @Override
    public void onStartInputView(EditorInfo info, boolean restarting) {
        super.onStartInputView(info, restarting);
        retrieveKeys();
    }

    @Override
    public View onCreateInputView() {
        kv = (KeyboardView)getLayoutInflater().inflate(R.layout.keyboard, null);
        kv.setOnKeyboardActionListener(this);
        keyboard = new Keyboard(this, R.xml.qwerty);
        kv.setKeyboard(keyboard);

        retrieveKeys();

        // Set the onTouchListener to be able to retrieve a MotionEvent
        kv.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                // For each key in the key list
                for (Keyboard.Key k : keyList) {
                    // If the coordinates from the Motion event are inside of the key
                    if (k.isInside((int) event.getX(), (int) event.getY())) {
                        // k is the key pressed
                        Log.d("Debugging",
                                "Key pressed: X=" + k.x + " - Y=" + k.y);
                        int centreX, centreY;
                        centreX = (k.width/2) + k.x;
                        centreY = (k.width/2) + k.x;
                        // These values are relative to the Keyboard View
                        Log.d("Debugging",
                                "Centre of the key pressed: X="+centreX+" - Y="+centreY);
                    }
                }
                // Return false to avoid consuming the touch event
                return false;
            }
        });

        return kv;
    }

    @Override
    public void onKey(int primaryCode, int[] keyCodes) {
        InputConnection ic = getCurrentInputConnection();
        switch(primaryCode){
            case Keyboard.KEYCODE_DELETE :
                ic.deleteSurroundingText(1, 0);
                break;
            case Keyboard.KEYCODE_SHIFT:
                caps = !caps;
                keyboard.setShifted(caps);
                kv.invalidateAllKeys();
                break;
            case Keyboard.KEYCODE_DONE:
                ic.sendKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_ENTER));
                break;
            default:
                char code = (char)primaryCode;
                if(Character.isLetter(code) && caps){
                    code = Character.toUpperCase(code);
                }
                ic.commitText(String.valueOf(code),1);
        }
    }

    @Override
    public void onPress(int primaryCode) {}

    @Override
    public void onRelease(int primaryCode) {}

    @Override
    public void onText(CharSequence text) {}

    @Override
    public void swipeLeft() {}

    @Override
    public void swipeRight() {}

    @Override
    public void swipeDown() {}

    @Override
    public void swipeUp() {}
}

注意:在摩托罗拉Moto G XT1039 Android 5.1 API 22上测试