最近做一个android的app应用,当中需要动态添加edittext,并设置它的inputtype,
按照在layout文件中的写法
android:inputType="numberDecimal|numberSigned"
在代码当中写成了这个样子,
editAlt.setInputType(InputType.TYPE_NUMBER_FLAG_DECIMAL|InputType.TYPE_NUMBER_FLAG_SIGNED);
本以为不会有任何问题,可是跑起来发现,根本没生效。恼火~~~~~~
好吧,研究一下吧。
首先搞清楚java里面的2个运算符,按位与(&)和按位或(|),例子:
2 | 1 = 3 2 | 1 = 0
首先把10进制数变成2进制数,然后按位执行与和或的操作。
那么 InputType.TYPE_NUMBER_FLAG_DECIMAL = 8192 = 10000000000000
InputType.TYPE_NUMBER_FLAG_SIGNED = 4096 = 1000000000000
按位或的结果是 11000000000000
找到 TextView .setInputType()方法,有这么一段:
final int cls = type & EditorInfo.TYPE_MASK_CLASS;
KeyListener input;
if (cls == EditorInfo.TYPE_CLASS_TEXT) {
boolean autotext = (type & EditorInfo.TYPE_TEXT_FLAG_AUTO_CORRECT) != 0;
TextKeyListener.Capitalize cap;
if ((type & EditorInfo.TYPE_TEXT_FLAG_CAP_CHARACTERS) != 0) {
cap = TextKeyListener.Capitalize.CHARACTERS;
} else if ((type & EditorInfo.TYPE_TEXT_FLAG_CAP_WORDS) != 0) {
cap = TextKeyListener.Capitalize.WORDS;
} else if ((type & EditorInfo.TYPE_TEXT_FLAG_CAP_SENTENCES) != 0) {
cap = TextKeyListener.Capitalize.SENTENCES;
} else {
cap = TextKeyListener.Capitalize.NONE;
}
input = TextKeyListener.getInstance(autotext, cap);
} else if (cls == EditorInfo.TYPE_CLASS_NUMBER) {
input = DigitsKeyListener.getInstance(
(type & EditorInfo.TYPE_NUMBER_FLAG_SIGNED) != 0,
(type & EditorInfo.TYPE_NUMBER_FLAG_DECIMAL) != 0);
} else if (cls == EditorInfo.TYPE_CLASS_DATETIME) {
switch (type & EditorInfo.TYPE_MASK_VARIATION) {
case EditorInfo.TYPE_DATETIME_VARIATION_DATE:
input = DateKeyListener.getInstance();
break;
case EditorInfo.TYPE_DATETIME_VARIATION_TIME:
input = TimeKeyListener.getInstance();
break;
default:
input = DateTimeKeyListener.getInstance();
break;
}
} else if (cls == EditorInfo.TYPE_CLASS_PHONE) {
input = DialerKeyListener.getInstance();
} else {
input = TextKeyListener.getInstance();
}
看这段代码,我们期望能够进到 if (cls == EditorInfo.TYPE_CLASS_NUMBER) {
这个判断里面去,可是事实呢?
请注意 final int cls = type & EditorInfo.TYPE_MASK_CLASS;
这个 EditorInfo.TYPE_MASK_CLASS = 15 = 1111
那么它和刚才传进去的 11000000000000 按位与的结果是cls = 0,
而 EditorInfo.TYPE_CLASS_NUMBER = 2,显然无法进入。
略一思考,把原来的
editAlt.setInputType(InputType.TYPE_NUMBER_FLAG_DECIMAL|InputType.TYPE_NUMBER_FLAG_SIGNED);
变成
editAlt.setInputType(InputType.TYPE_CLASS_NUMBER|InputType.TYPE_NUMBER_FLAG_DECIMAL|InputType.TYPE_NUMBER_FLAG_SIGNED);
加上红色部分即可。
进一步的思考:
这样的设计很有趣,应该会有更多的场景可以用到。
比如一款健身类的app,我们可能希望根据用户的各种不同属性把用户加以区分,
比如:性别,年龄,职业,健身习惯,身高体重比等等。
如果建过多的字典表,用过多的字段标志不同的属性,显得非常的臃肿。
那么下面这样的设计是不是会让我们愉悦起来:
从右到左,依次表示性别、年龄区间、职业类型、健身习惯、身高体重比的区间。
再加上简单的解析类。
问题就解决了!