如何在自定义键盘上按一个键时禁用其他键?

时间:2017-12-19 07:24:05

标签: android android-softkeyboard android-custom-keyboard

我想在按下自定义键盘上的某些按键时禁用其他键的按键,我也想禁用我自定义键盘外部的触摸,因为触摸外面并按住某些键并按其他键自动在edittext.i中插入字符想要阻止它。

我的CustomKeyBoardClass在这里

public class CustomKeyboard extends View {

    int touchPosition;
    int id;

    /**
     * A link to the KeyboardView that is used to render this CustomKeyboard.
     */
    private KeyboardView mKeyboardView;
    /**
     * A link to the activity that hosts the {@link #mKeyboardView}.
     */
    private AppCompatActivity mHostActivity;
    private Keyboard mKeyBoard;
    private View mInflater;
    Boolean longpressded=false;
    View custom = LayoutInflater.from(getContext())
            .inflate(R.layout.kbpreview, new FrameLayout(getContext()));
    PopupWindow popup = new PopupWindow(this);


    /**
     * The key (code) handler.
     */
    private KeyboardView.OnKeyboardActionListener mOnKeyboardActionListener = new KeyboardView.OnKeyboardActionListener() {

        public final static int CodeDelete = -5; // Keyboard.KEYCODE_DELETE
        public final static int CodeCancel = -3; // Keyboard.KEYCODE_CANCEL
        public final static int CodePrev = 55000;
        public final static int CodeAllLeft = 55001;
        public final static int CodeLeft = 55002;
        public final static int CodeRight = 55003;
        public final static int CodeAllRight = 55004;
        public final static int CodeNext = 55005;
        public final static int CodeClear = 55006;

        public final static int CodeDone = 55007;
        public final static int CodeCaps = -1;
        public final static int QwertNumberKeypad = 1100;
        public final static int QwertNumericKeypad = 1101;
        public final static int CodeBackSpace = -4;
        private boolean caps = false;


        @Override
        public void onKey(final int primaryCode, int[] keyCodes) {
            // NOTE We can say '<Key android:codes="49,50" ... >' in the xml
            // file; all codes come in keyCodes, the first in this list in
            // primaryCode
            // Get the EditText and its Editable

            View focusCurrent = mHostActivity.getWindow().getCurrentFocus();
            if (focusCurrent == null
                    || focusCurrent.getClass() != AppCompatEditText.class)
                return;
            final AppCompatEditText edittext = (AppCompatEditText) focusCurrent;

            edittext.addTextChangedListener(new TextWatcher() {

                public void onTextChanged(CharSequence s, int start, int before, int count) {

                    String searchString = s.toString();
                    int textLength = searchString.length();
//                    edittext.setSelection(textLength);
                }

                public void beforeTextChanged(CharSequence s, int start, int count, int after) {

                }

                public void afterTextChanged(Editable s) {

                }

            });

            // System.out.println("print edit text id==="+edittext.getId());
            // if(edittext.getId()==R.id.ed_hack){
            //
            // // invisible the hack============fix it later
            // System.out.println("id matched");
            // //edittext.setVisibility(View.INVISIBLE);
            //
            // // make the layout visible==========
            //
            // mHostActivity.findViewById(R.id.ll_enter_id).setVisibility(View.VISIBLE);
            //
            // // Show the input field and focus on keypad
            // touched================
            // ((EditText)mHostActivity.findViewById(R.id.et_enter_id_landing)).requestFocus();
            //
            //
            // }

            Editable editables = edittext.getText();
            int start = edittext.getSelectionStart();
            int end = edittext.getSelectionEnd();

            // Apply the key to the edittext
            if (primaryCode == CodeCancel) {
                hideCustomKeyboard();
            } else if (primaryCode == CodeDelete) {
                if (editables != null && start > 0) {
                    editables.delete(start - 1, start);
                    edittext.setSelection(start - 1);
                }
            }



            /*
             * else if( primaryCode==CodeBackSpace ) { if( editable!=null && end
             * >0 ) editable.delete(end - 1, end); }
             */
            else if (primaryCode == CodeClear) {
                if (editables != null)
                    editables.clear();
            } else if (primaryCode == CodeLeft) {
                if (start > 0)
                    edittext.setSelection(start - 1);
            } else if (primaryCode == CodeRight) {
                if (start < edittext.length())
                    edittext.setSelection(start + 1);
            } else if (primaryCode == CodeAllLeft) {
                edittext.setSelection(0);
            } else if (primaryCode == CodeAllRight) {
                edittext.setSelection(edittext.length());
            } else if (primaryCode == CodePrev) {
                View focusNew = edittext.focusSearch(View.FOCUS_BACKWARD);
                if (focusNew != null)
                    focusNew.requestFocus();
            } else if (primaryCode == CodeNext) {
                View focusNew = edittext.focusSearch(View.FOCUS_FORWARD);
                if (focusNew != null)
                    focusNew.requestFocus();
            } else if (primaryCode == CodeDone) {
                hideCustomKeyboard();
            }

            // for capslock

            else if (primaryCode == CodeCaps) {
                caps = !caps;
                mKeyBoard.setShifted(caps);
                mKeyboardView.invalidateAllKeys();

//                edittext.setInputType(InputType.TYPE_TEXT_FLAG_CAP_CHARACTERS);
//
//                edittext.setFilters(new InputFilter[]{new
//                        InputFilter.AllCaps()});

            } else { // insert character

                if (primaryCode != QwertNumericKeypad && primaryCode != QwertNumberKeypad ) {
                    char code = (char) primaryCode;
                    if (Character.isLetter(code) && caps) {
                        code = Character.toUpperCase(code);
                    }
                    editables.insert(start, Character.toString((char) code));
                }

            }
            Log.d("Gajanand", "onKey: at first" + caps);
            if (primaryCode == QwertNumberKeypad) {
                mKeyboardView.setKeyboard(new Keyboard(mHostActivity,
                        R.xml.qwerty));
                mKeyboardView.invalidateAllKeys();
                Log.d("Gajanand", "onKey:in number keypad " + caps);
            }
            if (primaryCode == QwertNumericKeypad) {
                mKeyboardView.setKeyboard(new Keyboard(mHostActivity,
                        R.xml.qwerty_numbers));
                mKeyboardView.invalidateAllKeys();
                Log.d("Gajanand", "onKey:in numeric keypad " + caps);
            }

            popup.setContentView(custom);

            mKeyboardView.setOnTouchListener(new OnTouchListener() {
                @Override
                public boolean onTouch(View v, MotionEvent event) {

                    if (event.getAction() == MotionEvent.ACTION_DOWN) {
                        mKeyboardView.closing(); // Close popup keyboard if it's showing
                    }

                    return false;
                }
            });


        }

        @Override
        public void onPress(int arg0) {
            Log.d("Gajanand", "onPress:GK ");


        }

        @Override
        public void onRelease(int primaryCode) {
            Log.d("Gajanand", "onRelease: GK");

        }

        @Override
        public void onText(CharSequence text) {
        }

        @Override
        public void swipeDown() {
        }

        @Override
        public void swipeLeft() {
        }

        @Override
        public void swipeRight() {
        }

        @Override
        public void swipeUp() {
        }

    };

    /**
     * Create a custom keyboard, that uses the KeyboardView (with resource id
     * <var>viewid</var>) of the <var>host</var> activity, and load the keyboard
     * layout from xml file <var>layoutid</var> (see {@link Keyboard} for
     * description). Note that the <var>host</var> activity must have a
     * <var>KeyboardView</var> in its layout (typically aligned with the bottom
     * of the activity). Note that the keyboard layout xml file may include key
     * codes for navigation; see the constants in this class for their values.
     * Note that to enable EditText's to use this custom keyboard, call the
     * {@link #registerEditText(int)}.
     *
     * @param host     The hosting activity.
     * @param viewid   The id of the KeyboardView.
     * @param layoutid The id of the xml file containing the keyboard layout.
     */

    public CustomKeyboard(AppCompatActivity host, int viewid, int layoutid) {

        super(host);
        mHostActivity = host;
        mKeyboardView = (KeyboardView) mHostActivity.findViewById(viewid);
        mKeyBoard = new Keyboard(mHostActivity, layoutid);
        mKeyboardView.setKeyboard(mKeyBoard);
        mKeyboardView.setPreviewEnabled(false); // NOTE Do not show the preview
        // balloons
        mKeyboardView.setOnKeyboardActionListener(mOnKeyboardActionListener);
        // Hide the standard keyboard initially
        mHostActivity.getWindow().setSoftInputMode(
                WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
    }

//    @Override
//    protected void onSelectionChanged(int selStart, int selEnd) {
//        super.onSelectionChanged(selStart, selEnd);
//
//        Log.d("Gajanand", "onSelectionChanged: yes changed");
//    }

    public CustomKeyboard(AppCompatActivity host, View inflater, int viewid, int layoutid) {
        super(host);
        mHostActivity = host;
        mInflater = inflater;
        mKeyboardView = (KeyboardView) mInflater.findViewById(viewid);

        mKeyBoard = new Keyboard(mHostActivity, layoutid);
        mKeyboardView.setKeyboard(mKeyBoard);
        mKeyboardView.setPreviewEnabled(true); // NOTE Do not show the preview
        // balloons
        mKeyboardView.setOnKeyboardActionListener(mOnKeyboardActionListener);
        // Hide the standard keyboard initially
        mHostActivity.getWindow().setSoftInputMode(
                WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
    }

    /**
     * Returns whether the CustomKeyboard is visible.
     */
    public boolean isCustomKeyboardVisible() {
        return mKeyboardView.getVisibility() == View.VISIBLE;
    }

    /**
     * Make the CustomKeyboard visible, and hide the system keyboard for view v.
     */
    public void showCustomKeyboard(View v) {
        mKeyboardView.setVisibility(View.VISIBLE);
        mKeyboardView.setEnabled(true);
        if (v != null)
            ((InputMethodManager) mHostActivity
                    .getSystemService(AppCompatActivity.INPUT_METHOD_SERVICE))
                    .hideSoftInputFromWindow(v.getWindowToken(), 0);
    }

    /**
     * Make the CustomKeyboard invisible.
     */
    public void hideCustomKeyboard() {
        mKeyboardView.setVisibility(View.GONE);
        mKeyboardView.setEnabled(false);
        sendStatusToActivity("hide");
    }

    private void sendStatusToActivity(String msg) {

        Intent intent = new Intent("KEYPAD");
        intent.putExtra("Status", msg);
        LocalBroadcastManager.getInstance(mHostActivity).sendBroadcast(intent);
//        stopservice();
    }

    /**
     * Register <var>EditText<var> with resource id <var>resid</var> (on the
     * hosting activity) for using this custom keyboard.
     *
     * @param resid The resource id of the EditText that registers to the custom
     *              keyboard.
     */
    public void registerEditText(int resid) {
        // Find the EditText 'resid'
        AppCompatEditText edittext;

        /*View focusCurrent = mHostActivity.getWindow().getCurrentFocus();
        if (focusCurrent == null
                || focusCurrent.getClass() != AppCompatEditText.class)
            return;
        final AppCompatEditText edittext = (AppCompatEditText) focusCurrent;*/

        edittext = (AppCompatEditText) mHostActivity.findViewById(resid);
        if (edittext == null) {
            edittext = (AppCompatEditText) mInflater.findViewById(resid);
        }

        // Make the custom keyboard appear
        edittext.setOnFocusChangeListener(new View.OnFocusChangeListener() {
            // NOTE By setting the on focus listener, we can show the custom
            // keyboard when the edit box gets focus, but also hide it when the
            // edit box loses focus
            @Override
            public void onFocusChange(View v, boolean hasFocus) {

                if (hasFocus)
                    showCustomKeyboard(v);
                else
                    hideCustomKeyboard();
            }
        });
        edittext.setOnClickListener(new View.OnClickListener() {
            // NOTE By setting the on click listener, we can show the custom
            // keyboard again, by tapping on an edit box that already had focus
            // (but that had the keyboard hidden).
            @Override
            public void onClick(View v) {
                Log.d("kishan", "onClick: keypad");
                showCustomKeyboard(v);
            }
        });
        // Disable standard keyboard hard way
        // NOTE There is also an easy way:
        // 'edittext.setInputType(InputType.TYPE_NULL)' (but you will not have a
        // cursor, and no 'edittext.setCursorVisible(true)' doesn't work )
        edittext.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                Log.d("kishan", "onTouch: keypad");
                showCustomKeyboard(v);
                AppCompatEditText edittext = (AppCompatEditText) v;

                float x = event.getX();
                float y = event.getY();
                touchPosition = edittext.getOffsetForPosition(x, y);
                if (touchPosition > 0) {
                    edittext.setSelection(touchPosition);
                }

                int inType = edittext.getInputType(); // Backup the input type
                edittext.setInputType(InputType.TYPE_NULL); // Disable standard
                // keyboard
                edittext.onTouchEvent(event); // Call native handler
                edittext.setInputType(inType); // Restore input type
                return true; // Consume touch event
            }
        });
        // Disable spell check (hex strings look like words to Android)
        edittext.setInputType(edittext.getInputType()
                | InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS);
    }

    public void registerAutoCompleteEditText(int resid) {
        // Find the EditText 'resid'
        System.out.println("hello ");
        AutoCompleteTextView autoCompleteTextView;

        autoCompleteTextView = (AutoCompleteTextView) mHostActivity.findViewById(resid);
        if (autoCompleteTextView == null) {
            autoCompleteTextView = (AutoCompleteTextView) mInflater.findViewById(resid);
        }

        System.out.println("hello 1");
        // Make the custom keyboard appear
        autoCompleteTextView.setOnFocusChangeListener(new View.OnFocusChangeListener() {
            // NOTE By setting the on focus listener, we can show the custom
            // keyboard when the edit box gets focus, but also hide it when the
            // edit box loses focus
            @Override
            public void onFocusChange(View v, boolean hasFocus) {
                System.out.println("hello 2");
                if (hasFocus)
                    showCustomKeyboard(v);
                else
                    hideCustomKeyboard();
            }
        });
        autoCompleteTextView.setOnClickListener(new View.OnClickListener() {
            // NOTE By setting the on click listener, we can show the custom
            // keyboard again, by tapping on an edit box that already had focus
            // (but that had the keyboard hidden).
            @Override
            public void onClick(View v) {
                showCustomKeyboard(v);
            }
        });
        // Disable standard keyboard hard way
        // NOTE There is also an easy way:
        // 'edittext.setInputType(InputType.TYPE_NULL)' (but you will not have a
        // cursor, and no 'edittext.setCursorVisible(true)' doesn't work )
        autoCompleteTextView.setOnTouchListener(new View.OnTouchListener() {
            @TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                AutoCompleteTextView edittext = (AutoCompleteTextView) v;

                float x = event.getX();
                float y = event.getY();
                touchPosition = edittext.getOffsetForPosition(x, y);
                if (touchPosition > 0) {
                    edittext.setSelection(touchPosition);
                }

                int inType = edittext.getInputType(); // Backup the input type
                edittext.setInputType(InputType.TYPE_NULL); // Disable standard
                // keyboard
                edittext.onTouchEvent(event); // Call native handler
                edittext.setInputType(inType); // Restore input type
                return true; // Consume touch event
            }
        });
        // Disable spell check (hex strings look like words to Android)
        System.out.println("hello 5");
        autoCompleteTextView.setInputType(autoCompleteTextView.getInputType()
                | InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS);
    }

}

0 个答案:

没有答案