700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > android edittext 英文数字键盘 Adroid EditText限制输入数字与英文默认弹出数字键盘...

android edittext 英文数字键盘 Adroid EditText限制输入数字与英文默认弹出数字键盘...

时间:2022-05-12 01:06:54

相关推荐

android edittext 英文数字键盘 Adroid EditText限制输入数字与英文默认弹出数字键盘...

终于要写博客了,以前总觉得技术大牛才能写博客,后面想想,分享个人想法与技术探讨也是一种不错的交流方式。今天讲讲我在项目中遇到的一个实际需求,也许很多人也遇到过:

EditText要求限制输入数字和英文,但是最好默认弹出数字键盘。

我也上网搜过很多种方式,将自己的总结经验带给大家参考:

方法一 在xml里面设置 android:digits

android:digits="0123456789abcdefghigklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"

结果:可以实现限制输入数字和英文的效果,但是默认弹出的全键盘而不是数字键盘。

方法二 为EditText添加监听器

tvPassword.addTextChangedListener(new TextWatcher() {

@Override

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

}

@Override

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

}

@Override

public void afterTextChanged(Editable edt) {

try {

String temp = edt.toString();

String tem = temp.substring(temp.length() - 1, temp.length());

char[] temC = tem.toCharArray();

int mid = temC[0];

if (mid >= 48 && mid <= 57) {//数字

return;

}

if (mid >= 65 && mid <= 90) {//大写字母

return;

}

if (mid > 97 && mid <= 122) {//小写字母

return;

}

edt.delete(temp.length() - 1, temp.length());

} catch (Exception e) {

e.printStackTrace();

}

}

});

结果:如果客户只输入数字或英文或中文的情况下是奏效的,但是如果在中文键盘下同时输入汉字与英文(比如:是非得失vvvv),这时候汉字也会显示出来,达不到效果,而且也是全键盘。

以上两种方式都是默认全键盘,那么有些朋友就会说,不是可以设置InputType吗?

设置InputType确实可以实现默认弹出数字键盘,但是你也会发现:刚刚已经设置好的digits或者监听来限制输入数字和英文的,现在变成只能输入数字了!!!

方法三 设置EditText的KeyListener

通过TextView源码,发现了源码里面设置digits是这样的:

//TextView构造方法

……

case com.android.internal.R.styleable.TextView_digits:

digits = a.getText(attr);

break;

……

else if (digits != null) {

createEditorIfNeeded();

mEditor.mKeyListener = DigitsKeyListener.getInstance(digits.toString());

// If no input type was specified, we will default to generic

// text, since we can't tell the IME about the set of digits

// that was selected.

mEditor.mInputType = inputType != EditorInfo.TYPE_NULL

? inputType : EditorInfo.TYPE_CLASS_TEXT;

}

……

从上面可以看出,系统在拿到xml里面设置的digits之后做了这样的操作:

mEditor.mKeyListener = DigitsKeyListener.getInstance(digits.toString());

这个就是创建了一个DigitsKeyListener,并赋值给TextView的mKeyListener ;那么我们也可以为EditText手动设置KeyListener:

String digists = "0123456789abcdefghigklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";

tvPassword.setKeyListener(DigitsKeyListener.getInstance(digists));

结果:默认弹出数字键盘,限制输入数字和英文效果实现。

到了这里大家有没有觉得奇怪,为什么xml里面设置digits默认弹出的是全键盘,而代码设置却默认弹出的是数字键盘?源码里面不也是这样设置的吗?

其实决定弹出什么键盘是由InputType决定的,上面源码里面设置DigitsKeyListener.getInstance(digists)之后设置了InputType为EditorInfo.TYPE_CLASS_TEXT;这表示键盘是输入字符的,而DigitsKeyListener.getInstance源码里面已经设置了InputType

//TextView调用的getInstance

public static DigitsKeyListener getInstance(String accepted) {

// TODO: do we need a cache of these to avoid allocating?

DigitsKeyListener dim = new DigitsKeyListener();

dim.mAccepted = new char[accepted.length()];

accepted.getChars(0, accepted.length(), dim.mAccepted, 0);

return dim;

}

public DigitsKeyListener() {

this(false, false);

}

/** * Allocates a DigitsKeyListener that accepts the digits 0 through 9, * plus the minus sign (only at the beginning) and/or decimal point * (only one per field) if specified. */

public DigitsKeyListener(boolean sign, boolean decimal) {

mSign = sign;

mDecimal = decimal;

int kind = (sign ? SIGN : 0) | (decimal ? DECIMAL : 0);

mAccepted = CHARACTERS[kind];

}

public int getInputType() {

//因为构造方法传入的mSign和mDecimal都是false,所以返回的是InputType.TYPE_CLASS_NUMBER

int contentType = InputType.TYPE_CLASS_NUMBER;

if (mSign) {

contentType |= InputType.TYPE_NUMBER_FLAG_SIGNED;

}

if (mDecimal) {

contentType |= InputType.TYPE_NUMBER_FLAG_DECIMAL;

}

return contentType;

}

由此看出DigitsKeyListener返回的InputType是InputType.TYPE_CLASS_NUMBER,而TextView并没有使用DigitsKeyListener的InputType,而是自己设置了EditorInfo.TYPE_CLASS_TEXT;故弹出的是全键盘。

我们用代码设置的setKeyListener的源码是这样的

public void setKeyListener(KeyListener input) {

setKeyListenerOnly(input);

fixFocusableAndClickableSettings();

if (input != null) {

createEditorIfNeeded();

try {

mEditor.mInputType = mEditor.mKeyListener.getInputType();

} catch (IncompatibleClassChangeError e) {

mEditor.mInputType = EditorInfo.TYPE_CLASS_TEXT;

}

// Change inputType, without affecting transformation.

// No need to applySingleLine since mSingleLine is unchanged.

setInputTypeSingleLine(mSingleLine);

} else {

if (mEditor != null) mEditor.mInputType = EditorInfo.TYPE_NULL;

}

InputMethodManager imm = InputMethodManager.peekInstance();

if (imm != null) imm.restartInput(this);

}

这里的:

InputMethodManager imm = InputMethodManager.peekInstance();

if (imm != null) imm.restartInput(this);

将软键盘重置了,故使用的软键盘是其自己getInputType方法得到的数字键盘模式。

为什么会弹出数字键盘已经分析完了,这样大家觉得大功告成了?还没完!

注意:弹出数字键盘还能输英文的前提是,可以从数字键盘切换到全键盘!!

应该说大部分输入法的数字键盘都可以返回到全键盘的,但是有少数输入法(比如:三星输入法)不能切换回去!

可能有人想要在后面再给EditText设置setInputType(InputType.TYPE_CLASS_TEXT);让其弹出全键盘,结果是:虽然弹出了全键盘,但是之前设置的digits限制失效了!原因是:

/**TextView 里面的setInputType方法*/

public void setInputType(int type) {

……

//这里相当于从新设置了软键盘模式

InputMethodManager imm = InputMethodManager.peekInstance();

if (imm != null) imm.restartInput(this);

}

setInputType方法将软键盘重置成全键盘模式,前面设置的DigitsKeyListener 完全失效!

总结:

如果想要在代码里面实现设置输入字符的限制(digits)就只能弹出数字键盘,而数字键盘并不是所有都能返回到全键盘,所以,这种方法并不可行,原因是android没有为DigitsKeyListener提供设置inputType这样的接口

如果有高手找出更好的方法,欢迎留言点评,博主将感激不尽!!!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。