如何在关注EditText时阻止键盘

时间:2013-04-01 11:19:40

标签: android keyboard focus android-edittext hide

在我的Android应用程序中,我必须使用自定义数字键盘放在EditTexts旁边的视图中输入数字,所以我需要:

  1. 当用户点击它们时,EditText应该具有焦点,这样当用户点击某个键时我将有光标位置插入数字。
  2. 编辑文本聚焦时不应出现软键盘(但无法通过设置android:windowSoftInputMode =“stateHidden”完全隐藏键盘,因为屏幕上有一些搜索框仍然需要使用软键盘)
  3. 我搜索过并发现很多关于在显示时隐藏键盘的文章,或设置输入类型/可聚焦....不显示键盘....但它们不符合我的需要。

    任何人都有这种情况的解决方案请帮助我。

4 个答案:

答案 0 :(得分:1)

这个我从CsipSimple项目中获取灵感并实现了我自己的

这是相同的代码 这里创建自定义数字键盘是我的 拨号盘的布局只是1到9的按钮和*#

package com.xyz.custom;

import java.util.HashMap;
import java.util.Map;

import com.xyz.payphone.R;

import android.annotation.SuppressLint;
import android.content.Context;
import android.media.ToneGenerator;
import android.util.AttributeSet;
import android.util.SparseArray;
import android.widget.ImageButton;
import android.widget.TableLayout;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;

public class DialpadNovanet extends TableLayout implements OnClickListener {

    private OnDialKeyListener onDialKeyListener;
    @SuppressLint("UseSparseArrays")
    private static final Map<Integer, int[]> DIGITS_BTNS = new HashMap<Integer, int[]>();
    private static final String tag = "Dialpad";

    static {
        DIGITS_BTNS.put(R.id.button0, new int[] { ToneGenerator.TONE_DTMF_0,
                KeyEvent.KEYCODE_0 });
        DIGITS_BTNS.put(R.id.button1, new int[] { ToneGenerator.TONE_DTMF_1,
                KeyEvent.KEYCODE_1 });
        DIGITS_BTNS.put(R.id.button2, new int[] { ToneGenerator.TONE_DTMF_2,
                KeyEvent.KEYCODE_2 });
        DIGITS_BTNS.put(R.id.button3, new int[] { ToneGenerator.TONE_DTMF_3,
                KeyEvent.KEYCODE_3 });
        DIGITS_BTNS.put(R.id.button4, new int[] { ToneGenerator.TONE_DTMF_4,
                KeyEvent.KEYCODE_4 });
        DIGITS_BTNS.put(R.id.button5, new int[] { ToneGenerator.TONE_DTMF_5,
                KeyEvent.KEYCODE_5 });
        DIGITS_BTNS.put(R.id.button6, new int[] { ToneGenerator.TONE_DTMF_6,
                KeyEvent.KEYCODE_6 });
        DIGITS_BTNS.put(R.id.button7, new int[] { ToneGenerator.TONE_DTMF_7,
                KeyEvent.KEYCODE_7 });
        DIGITS_BTNS.put(R.id.button8, new int[] { ToneGenerator.TONE_DTMF_8,
                KeyEvent.KEYCODE_8 });
        DIGITS_BTNS.put(R.id.button9, new int[] { ToneGenerator.TONE_DTMF_9,
                KeyEvent.KEYCODE_9 });
        DIGITS_BTNS.put(R.id.buttonpound, new int[] {
                ToneGenerator.TONE_DTMF_P, KeyEvent.KEYCODE_POUND });
        DIGITS_BTNS.put(R.id.buttonstar, new int[] { ToneGenerator.TONE_DTMF_S,
                KeyEvent.KEYCODE_STAR });
    };

    private static final SparseArray<String> DIGITS_NAMES = new SparseArray<String>();

    static {
        DIGITS_NAMES.put(R.id.button0, "0");
        DIGITS_NAMES.put(R.id.button1, "1");
        DIGITS_NAMES.put(R.id.button2, "2");
        DIGITS_NAMES.put(R.id.button3, "3");
        DIGITS_NAMES.put(R.id.button4, "4");
        DIGITS_NAMES.put(R.id.button5, "5");
        DIGITS_NAMES.put(R.id.button6, "6");
        DIGITS_NAMES.put(R.id.button7, "7");
        DIGITS_NAMES.put(R.id.button8, "8");
        DIGITS_NAMES.put(R.id.button9, "9");
        DIGITS_NAMES.put(R.id.buttonpound, "pound");
        DIGITS_NAMES.put(R.id.buttonstar, "star");
    };

    public DialpadNovanet(Context context) {
        super(context);
        LayoutInflater inflater = LayoutInflater.from(context);
        inflater.inflate(R.layout.dialpad_novanet, this, true);

    }

    public DialpadNovanet(Context context, AttributeSet attrs) {
        super(context, attrs);
        LayoutInflater inflater = LayoutInflater.from(context);
        inflater.inflate(R.layout.dialpad_novanet, this, true);
    }

    private void dispatchDialKeyEvent(int buttonId) {
        if (onDialKeyListener != null && DIGITS_BTNS.containsKey(buttonId)) {
            int[] datas = DIGITS_BTNS.get(buttonId);
            onDialKeyListener.onTrigger(datas[1], datas[0]);
        }
    }

    @Override
    public void onClick(View v) {
        dispatchDialKeyEvent(v.getId());

    }

    public void setOnDialKeyListener(OnDialKeyListener listener) {
        onDialKeyListener = listener;
    }

    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();

        for (int buttonId : DIGITS_BTNS.keySet()) {
            ImageButton button = (ImageButton) findViewById(buttonId);
            if (button != null) {
                button.setOnClickListener(this);
            }
        }

    }

    public interface OnDialKeyListener {

        /**
         * Called when the user make an action
         * 
         * @param keyCode
         *            keyCode pressed
         * @param dialTone
         *            corresponding dialtone
         */
        void onTrigger(int keyCode, int dialTone);
    }

    boolean mForceWidth = false;

    public void setForceWidth(boolean forceWidth) {
        mForceWidth = forceWidth;
    }

    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        if (mForceWidth) {
            setMeasuredDimension(MeasureSpec.getSize(widthMeasureSpec),
                    getMeasuredHeight());
        }
    };
    /*
     * public void applyTheme(Theme t) {
     * 
     * Log.d(tag, "Theming in progress"); for(int buttonId :
     * DIGITS_BTNS.keySet()) {
     * 
     * ImageButton b = (ImageButton) findViewById(buttonId); // We need to use
     * state list as reused t.applyBackgroundStateListDrawable(b, "btn_dial");
     * 
     * // Src of button Drawable src =
     * t.getDrawableResource("dial_num_"+DIGITS_NAMES.get(buttonId)); if(src !=
     * null) { b.setImageDrawable(src); }
     * 
     * // Padding of button t.applyLayoutMargin(b, "dialpad_btn_margin"); }
     * 
     * }
     */

}

现在创建自定义EditText

public class DialerEditText extends EditText {

    private static final String tag="DialerEditText";
    private Boolean isDigit=null;
    private Method showSoftInputOnFocus=null;

    public DialerEditText(Context context, AttributeSet attrs) {
        super(context, attrs);
         setIsDigit(true, false);
    }

    public synchronized void setIsDigit(boolean isDigit, boolean autofocus) {
        if(this.isDigit == null || this.isDigit != isDigit) {
            this.isDigit = isDigit;
            reflexSetShowSoftInputOnFocus(!isDigit);
            if (isDigit) {
                setRawInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS);
                setTextSize(TypedValue.COMPLEX_UNIT_PX, getContext().getResources().getDimension(R.dimen.dialpad_digits_text_size));
            } else {
                setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS
                        | InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS);
                setTextSize(TypedValue.COMPLEX_UNIT_SP, 14);
            }
        }
        applyKeyboardShowHide(autofocus);
    }



    @Override
    protected void onFocusChanged(boolean focused, int direction, Rect previouslyFocusedRect) {
        super.onFocusChanged(focused, direction, previouslyFocusedRect);
        if(focused) {
            applyKeyboardShowHide(false);
        }else {
            final InputMethodManager imm = ((InputMethodManager) getContext()
                    .getSystemService(Context.INPUT_METHOD_SERVICE));
            if(imm != null && imm.isActive(this)) {
                imm.hideSoftInputFromWindow(getApplicationWindowToken(), 0);
            }
        }
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        final boolean ret = super.onTouchEvent(event);
        // Must be done after super.onTouchEvent()
        applyKeyboardShowHide(false);
        return ret;
    }

/*
    @Override
    public boolean requestFocus(int direction, Rect previouslyFocusedRect) {
        boolean ret = false;
        if(!isDigit) {
            ret = super.requestFocus(direction, previouslyFocusedRect);
        }
        applyKeyboardShowHide(false);
        return ret;
    }
*/

    private void applyKeyboardShowHide(boolean autofocus) {
        final InputMethodManager imm = ((InputMethodManager) getContext()
                .getSystemService(Context.INPUT_METHOD_SERVICE));
        if (imm != null) {
            if(isDigit) {
                if(imm.isActive(this)) {
                    imm.hideSoftInputFromWindow(getApplicationWindowToken(), 0);
                }
            }else if(autofocus) {
                imm.showSoftInput(this, 0);
            }
        }
    }

    @Override
    public void sendAccessibilityEventUnchecked(AccessibilityEvent event) {
        if (event.getEventType() == AccessibilityEvent.TYPE_VIEW_TEXT_CHANGED) {
            // Since we're replacing the text every time we add or remove a
            // character, only read the difference. (issue 5337550)
            final int added = event.getAddedCount();
            final int removed = event.getRemovedCount();
            final int length = event.getBeforeText().length();
            if (added > removed) {
                event.setRemovedCount(0);
                event.setAddedCount(1);
                event.setFromIndex(length);
            } else if (removed > added) {
                event.setRemovedCount(1);
                event.setAddedCount(0);
                event.setFromIndex(length - 1);
            } else {
                return;
            }
        } else if (event.getEventType() == AccessibilityEvent.TYPE_VIEW_FOCUSED) {
            // The parent EditText class lets tts read "edit box" when this View
            // has a focus, which
            // confuses users on app launch (issue 5275935).
            return;
        }
        super.sendAccessibilityEventUnchecked(event);
    }

    @Override
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
        super.onLayout(changed, left, top, right, bottom);
        // Here we ensure that we hide the keyboard
        // Since this will be fired when virtual keyboard this will probably
        // blink but for now no better way were found to hide keyboard for sure
        applyKeyboardShowHide(false);
    }

    private void reflexSetShowSoftInputOnFocus(boolean show) {
        if(showSoftInputOnFocus != null) {
            UtilityWrapper.safelyInvokeMethod(showSoftInputOnFocus, this, show);
        }
    }

}

现在你可以使用它作为xml避免填充和东西导致我的应用程序特定

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >


        <com.novanet.custom.DialerEditText
            android:id="@+id/edtDialer"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="70" />



    <com.novanet.custom.DialpadNovanet
        android:id="@+id/dial_pad"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_gravity="center_vertical"
        android:layout_weight="65"
        android:paddingBottom="10dip"
        android:paddingLeft="5dip"
        android:paddingRight="5dip" />



</LinearLayout>

现在,在你的活动中你可以做到这一点

edtText=(DialerEditText)findViewById(R.id.edtDialer);
        dialPad=(DialpadNovanet)findViewById(R.id.dial_pad);
        dialPad.setOnDialKeyListener(new OnDialKeyListener() {

            @Override
            public void onTrigger(int keyCode, int dialTone) {
                Log.v(tag,"Key "+keyCode);
                KeyEvent event=new KeyEvent(KeyEvent.ACTION_DOWN, keyCode);
         edtText.onKeyDown(keyCode, event);

            }
        });

答案 1 :(得分:0)

在清单文件中,您的活动代码必须编写类似

的属性
android:windowSoftInputMode="stateHidden"

然后它会隐藏键盘直到按下edittext ...

在我的情况下,我在活动标签中使用这样的方式隐藏软键盘,直到按下edittext ...

<activity
            android:name="EnglishRadioActivity"
            android:configChanges="orientation"
            android:windowSoftInputMode="stateHidden" >
        </activity>
希望这能解决你的问题 快乐的编码...

答案 2 :(得分:0)

android:windowSoftInputMode="stateHidden|adjustPan"

在相应的Activity名称后面的清单文件中添加它。这将限制默认软键盘出现在屏幕上。

答案 3 :(得分:0)

使用android:windowSoftInputMode="stateHidden"

android:windowSoftInputMode="adjustPan"