Search code examples
androidandroid-edittextandroid-dialogandroid-keypad

While clicking on editext box which is there in dialogbox. the implicit keyboard have to hide


I have a edittextbox on the dialog box. while i click on the editext box the keyboard must be disabled.

Here i have the following code where the edit tetxtbox is pressent.

public class NumberPicker extends LinearLayout implements OnClickListener, OnFocusChangeListener, OnLongClickListener {

private static final String TAG = "NumberPicker";
private static final int DEFAULT_MAX = 10;
private static final int DEFAULT_MIN = 1;
public static String quantityForOrder;

public interface OnChangedListener {
    void onChanged(NumberPicker picker, int oldVal, int newVal);
}

public interface Formatter {
    String toString(int value);
}

/*
 * Use a custom NumberPicker formatting callback to use two-digit
 * minutes strings like "01".  Keeping a static formatter etc. is the
 * most efficient way to do this; it avoids creating temporary objects
 * on every call to format().
 */
public static final NumberPicker.Formatter TWO_DIGIT_FORMATTER =
        new NumberPicker.Formatter() {
            final StringBuilder mBuilder = new StringBuilder();
            final java.util.Formatter mFmt = new java.util.Formatter(mBuilder);
            final Object[] mArgs = new Object[1];
            public String toString(int value) {
                mArgs[0] = value;
                mBuilder.delete(0, mBuilder.length());
                mFmt.format("%02d", mArgs);
                return mFmt.toString();
            }
    };

private final Handler mHandler;
private final Runnable mRunnable = new Runnable() {
    public void run() {
        if (mIncrement) {
            changeCurrent(mCurrent + 1);
            mHandler.postDelayed(this, mSpeed);
        } else if (mDecrement) {
            changeCurrent(mCurrent - 1);
            mHandler.postDelayed(this, mSpeed);
        }
    }
};

private final EditText mText;
private final InputFilter mNumberInputFilter;

private String[] mDisplayedValues;
protected int mStart;
protected int mEnd;
protected int mCurrent;
protected int mPrevious;
private OnChangedListener mListener;
private Formatter mFormatter;
private long mSpeed = 300;

private boolean mIncrement;
private boolean mDecrement;

public NumberPicker(Context context) {
    this(context, null);
}

public NumberPicker(Context context, AttributeSet attrs) {
    this(context, attrs, 0);
}

@SuppressWarnings({"UnusedDeclaration"})
public NumberPicker(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs);
    setOrientation(VERTICAL);
    LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    inflater.inflate(R.layout.number_picker, this, true);
    mHandler = new Handler();
    InputFilter inputFilter = new NumberPickerInputFilter();
    mNumberInputFilter = new NumberRangeKeyListener();
    mIncrementButton = (NumberPickerButton) findViewById(R.id.increment);
    mIncrementButton.setOnClickListener(this);
    mIncrementButton.setOnLongClickListener(this);
    mIncrementButton.setNumberPicker(this);
    mDecrementButton = (NumberPickerButton) findViewById(R.id.decrement);
    mDecrementButton.setOnClickListener(this);
    mDecrementButton.setOnLongClickListener(this);
    mDecrementButton.setNumberPicker(this);

    mText = (EditText) findViewById(R.id.timepicker_input);
    mText.setOnFocusChangeListener(this);
    mText.setFilters(new InputFilter[] {inputFilter});
    mText.setRawInputType(InputType.TYPE_CLASS_NUMBER);


    if (!isEnabled()) {
        setEnabled(false);
    }

    mStart = DEFAULT_MIN;
    mEnd = DEFAULT_MAX;

// mText.setText(mStart); }

@Override
public void setEnabled(boolean enabled) {
    super.setEnabled(enabled);
    mIncrementButton.setEnabled(enabled);
    mDecrementButton.setEnabled(enabled);
    mText.setEnabled(enabled);
}

public void setOnChangeListener(OnChangedListener listener) {
    mListener = listener;
}

public void setFormatter(Formatter formatter) {
    mFormatter = formatter;
}

/**
 * Set the range of numbers allowed for the number picker. The current
 * value will be automatically set to the start.
 *
 * @param start the start of the range (inclusive)
 * @param end the end of the range (inclusive)
 */
public void setRange(int start, int end) {
    mStart = start;
    mEnd = end;
    mCurrent = start;
    updateView();
}

/**
 * Set the range of numbers allowed for the number picker. The current
 * value will be automatically set to the start. Also provide a mapping
 * for values used to display to the user.
 *
 * @param start the start of the range (inclusive)
 * @param end the end of the range (inclusive)
 * @param displayedValues the values displayed to the user.
 */
public void setRange(int start, int end, String[] displayedValues) {
    mDisplayedValues = displayedValues;
    mStart = start;
    mEnd = end;
    mCurrent = start;
    updateView();
}

public void setCurrent(int current) {
    mCurrent = current;
    updateView();
}

/**
 * The speed (in milliseconds) at which the numbers will scroll
 * when the the +/- buttons are longpressed. Default is 300ms.
 */
public void setSpeed(long speed) {
    mSpeed = speed;
}

public void onClick(View v) {
    validateInput(mText);
    if (!mText.hasFocus()) mText.requestFocus();

    // now perform the increment/decrement
    if (R.id.increment == v.getId()) {
        changeCurrent(mCurrent + 1);
    } else if (R.id.decrement == v.getId()) {
        changeCurrent(mCurrent - 1);
    }
}

private String formatNumber(int value) {
    return (mFormatter != null)
            ? mFormatter.toString(value)
            : String.valueOf(value);
}

protected void changeCurrent(int current) {

    // Wrap around the values if we go past the start or end
    if (current > mEnd) {
        current = mStart;
    } else if (current < mStart) {
        current = mEnd;
    }
    mPrevious = mCurrent;
    mCurrent = current;

    notifyChange();
    updateView();
}

protected void notifyChange() {
    if (mListener != null) {
        mListener.onChanged(this, mPrevious, mCurrent);
    }
}

protected void updateView() {

    /* If we don't have displayed values then use the
     * current number else find the correct value in the
     * displayed values for the current number.
     */
    if (mDisplayedValues == null) {
        mText.setText(formatNumber(mCurrent));
    } else {
        mText.setText(mDisplayedValues[mCurrent - mStart]);
    }
    mText.setSelection(mText.getText().length());
    System.out.println("my value in number picker"+mText.getText().length());
    System.out.println("my value in number picker"+mText.getText().toString());
    quantityForOrder = mText.getText().toString();
    System.out.println("my value with static : "+quantityForOrder);
}

private void validateCurrentView(CharSequence str) {
    int val = getSelectedPos(str.toString());
    if ((val >= mStart) && (val <= mEnd)) {
        if (mCurrent != val) {
            mPrevious = mCurrent;
            mCurrent = val;
            notifyChange();
        }
    }
    updateView();
}

public void onFocusChange(View v, boolean hasFocus) {

    /* When focus is lost check that the text field
     * has valid values.
     */
    if (!hasFocus) {
        validateInput(v);
    }
}

private void validateInput(View v) {
    String str = String.valueOf(((TextView) v).getText());
    if ("".equals(str)) {

        // Restore to the old value as we don't allow empty values
        updateView();
    } else {

        // Check the new value and ensure it's in range
        validateCurrentView(str);
    }
}

/**
 * We start the long click here but rely on the {@link NumberPickerButton}
 * to inform us when the long click has ended.
 */
public boolean onLongClick(View v) {

    /* The text view may still have focus so clear it's focus which will
     * trigger the on focus changed and any typed values to be pulled.
     */
    mText.clearFocus();

    if (R.id.increment == v.getId()) {
        mIncrement = true;
        mHandler.post(mRunnable);
    } else if (R.id.decrement == v.getId()) {
        mDecrement = true;
        mHandler.post(mRunnable);
    }
    return true;
}

public void cancelIncrement() {
    mIncrement = false;
}

public void cancelDecrement() {
    mDecrement = false;
}

private static final char[] DIGIT_CHARACTERS = new char[] {
    '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'
};

private NumberPickerButton mIncrementButton;
private NumberPickerButton mDecrementButton;

private class NumberPickerInputFilter implements InputFilter {
    public CharSequence filter(CharSequence source, int start, int end,
            Spanned dest, int dstart, int dend) {
        if (mDisplayedValues == null) {
            return mNumberInputFilter.filter(source, start, end, dest, dstart, dend);
        }
        CharSequence filtered = String.valueOf(source.subSequence(start, end));
        String result = String.valueOf(dest.subSequence(0, dstart))
                + filtered
                + dest.subSequence(dend, dest.length());
        String str = String.valueOf(result).toLowerCase();
        for (String val : mDisplayedValues) {
            val = val.toLowerCase();
            if (val.startsWith(str)) {
                return filtered;
            }
        }
        return "";
    }
}

private class NumberRangeKeyListener extends NumberKeyListener {

    // XXX This doesn't allow for range limits when controlled by a
    // soft input method!
    public int getInputType() {
        return InputType.TYPE_CLASS_NUMBER;
    }

    @Override
    protected char[] getAcceptedChars() {
        return DIGIT_CHARACTERS;
    }

    @Override
    public CharSequence filter(CharSequence source, int start, int end,
            Spanned dest, int dstart, int dend) {

        CharSequence filtered = super.filter(source, start, end, dest, dstart, dend);
        if (filtered == null) {
            filtered = source.subSequence(start, end);
        }

        String result = String.valueOf(dest.subSequence(0, dstart))
                + filtered
                + dest.subSequence(dend, dest.length());

        if ("".equals(result)) {
            return result;
        }
        int val = getSelectedPos(result);

        /* Ensure the user can't type in a value greater
         * than the max allowed. We have to allow less than min
         * as the user might want to delete some numbers
         * and then type a new number.
         */
        if (val > mEnd) {
            return "";
        } else {
            return filtered;
        }
    }
}

private int getSelectedPos(String str) {
    if (mDisplayedValues == null) {
        return Integer.parseInt(str);
    } else {
        for (int i = 0; i < mDisplayedValues.length; i++) {

            /* Don't force the user to type in jan when ja will do */
            str = str.toLowerCase();
            if (mDisplayedValues[i].toLowerCase().startsWith(str)) {
                return mStart + i;
            }
        }

        /* The user might have typed in a number into the month field i.e.
         * 10 instead of OCT so support that too.
         */
        try {
            return Integer.parseInt(str);
        } catch (NumberFormatException e) {

            /* Ignore as if it's not a number we don't care */
        }
    }
    return mStart;
}

/**
 * @return the current value.
 */
public int getCurrent() {
    return mCurrent;
}

}

if i am editing the editetxt box via keyboard then i am getting the following bug.

10-08 16:16:01.194: WARN/System.err(27016): java.lang.NumberFormatException: unable to parse 'null' as integer 10-08 16:16:01.202: WARN/System.err(27016): at java.lang.Integer.parseInt(Integer.java:406) 10-08 16:16:01.202: WARN/System.err(27016): at java.lang.Integer.parseInt(Integer.java:382) 10-08 16:16:01.202: WARN/System.err(27016): at com.cpt.coffee.activity.CoffeeOrder$EfficientAdapter$1$1.onClick(CoffeeOrder.java:316) 10-08 16:16:01.202: WARN/System.err(27016): at android.view.View.performClick(View.java:2408) 10-08 16:16:01.202: WARN/System.err(27016): at android.view.View$PerformClick.run(View.java:8816) 10-08 16:16:01.202: WARN/System.err(27016): at android.os.Handler.handleCallback(Handler.java:587) 10-08 16:16:01.202: WARN/System.err(27016): at android.os.Handler.dispatchMessage(Handler.java:92) 10-08 16:16:01.202: WARN/System.err(27016): at android.os.Looper.loop(Looper.java:123) 10-08 16:16:01.202: WARN/System.err(27016): at android.app.ActivityThread.main(ActivityThread.java:4627) 10-08 16:16:01.212: WARN/System.err(27016): at java.lang.reflect.Method.invokeNative(Native Method) 10-08 16:16:01.212: WARN/System.err(27016): at java.lang.reflect.Method.invoke(Method.java:521) 10-08 16:16:01.212: WARN/System.err(27016): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868) 10-08 16:16:01.212: WARN/System.err(27016): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626) 10-08 16:16:01.212: WARN/System.err(27016): at dalvik.system.NativeStart.main(Native Method)


Solution

  • Hide the keyboard using

    InputMethodManager imm = (InputMethodManager)getSystemService(
      Context.INPUT_METHOD_SERVICE);
      imm.hideSoftInputFromWindow(myEditText.getWindowToken(), 0);
    

    Also you can try setting it in listener,so it is not called in dialog itself:

    dialog.setOnShowListener(new OnShowListener() {
    @Override
     public void onShow(DialogInterface dialog) {
         InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
         imm.showSoftInput(textEdit, InputMethodManager.SHOW_IMPLICIT);
    }
    });