———通過EditText輸入小數(shù)時(shí)盆驹,可指定整數(shù)或小數(shù)的位數(shù)
如需下載源碼,請?jiān)L問
https://github.com/fengchuanfang/DecimalInput
文章原創(chuàng)滩愁,轉(zhuǎn)載請注明出處:
Android EditText 小數(shù)輸入優(yōu)化
運(yùn)行效果如下:
在xml布局文件中躯喇,設(shè)置EditText的inputType屬性為“numberDecimal”,可限制EditText只能輸入帶小數(shù)點(diǎn)的浮點(diǎn)數(shù)硝枉,如下:
android:inputType="numberDecimal"
但是廉丽,在實(shí)際開發(fā)應(yīng)用中,發(fā)現(xiàn)只設(shè)置這個(gè)屬性來限制EditText只可輸入小數(shù)所帶來的用戶體驗(yàn)并不是很好妻味,無法滿足實(shí)際應(yīng)用場景的需求正压。
例如以下非正常格式的浮點(diǎn)數(shù)也可輸入
在主流的app中,例如支付寶和微信對以上問題的處理也不是很好责球,
例如支付寶充值金額界面焦履,如下;
首位是“.”時(shí),不具有自動補(bǔ)“0”的邏輯
微信發(fā)紅包界面雏逾,輸入金額時(shí)嘉裤,首位是“.”會自動補(bǔ)“0”,但是不具有自動刪除首位無效“0”的邏輯校套,如下:
而且在實(shí)際應(yīng)用時(shí)价脾,大部分情況需要限制整數(shù)或小數(shù)的位數(shù),而只通過xml設(shè)置EditText的屬性并不能很好的實(shí)現(xiàn)笛匙。
下面我們通過EditText的addTextChangedListener(TextWatcher watcher)方法侨把,添加一個(gè)文本監(jiān)視器,并結(jié)合正則表達(dá)式實(shí)現(xiàn)以上需求妹孙,同事對原始的EditText的外觀進(jìn)行美化秋柄。
寫一個(gè)小數(shù)輸入監(jiān)視類DecimalInputTextWatcher繼承自TextWatcher,代碼如下:
/**
* 功能描述:小數(shù)輸入文本觀察類
*
* @author (作者) edward(馮豐楓)
* @link http://www.reibang.com/u/f7176d6d53d2
* 創(chuàng)建時(shí)間: 2018/3/12
*/
public class DecimalInputTextWatcher implements TextWatcher {
private Pattern mPattern;
/**
* 不限制整數(shù)位數(shù)和小數(shù)位數(shù)
*/
public DecimalInputTextWatcher() {
}
/**
* 限制整數(shù)位數(shù)或著限制小數(shù)位數(shù)
*
* @param type 限制類型
* @param number 限制位數(shù)
*/
public DecimalInputTextWatcher(Type type, int number) {
if (type == Type.decimal) {
mPattern = Pattern.compile("^[0-9]+(\\.[0-9]{0," + number + "})?$");
} else if (type == Type.integer) {
mPattern = Pattern.compile("^[0-9]{0," + number + "}+(\\.[0-9]{0,})?$");
}
}
/**
* 既限制整數(shù)位數(shù)又限制小數(shù)位數(shù)
*
* @param integers 整數(shù)位數(shù)
* @param decimals 小數(shù)位數(shù)
*/
public DecimalInputTextWatcher(int integers, int decimals) {
mPattern = Pattern.compile("^[0-9]{0," + integers + "}+(\\.[0-9]{0," + decimals + "})?$");
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
@Override
public void afterTextChanged(Editable editable) {
String text = editable.toString();
if (TextUtils.isEmpty(text)) return;
if ((editable.length() > 1) && (editable.charAt(0) == '0') && editable.charAt(1) != '.') { //刪除整數(shù)首位的“0”
editable.delete(0, 1);
return;
}
if (text.equals(".")) { //首位是“.”自動補(bǔ)“0”
editable.insert(0, "0");
return;
}
if (mPattern != null && !mPattern.matcher(text).matches() && editable.length() > 0) {
editable.delete(editable.length() - 1, editable.length());
return;
}
//TODO:可在此處額外添加代碼
}
public enum Type {
integer, decimal
}
}
在方法afterTextChanged(Editable s)中對于不規(guī)范的浮點(diǎn)數(shù)輸入進(jìn)行處理蠢正,刪除首位無效的“0”骇笔,以及首位是“.”時(shí),自動補(bǔ)“0”嚣崭。
提供三個(gè)用于初始化的構(gòu)造方法笨触,
1、不限制整數(shù)位數(shù)和小數(shù)位數(shù)
/**
* 不限制整數(shù)位數(shù)和小數(shù)位數(shù)
*/
public DecimalInputTextWatcher() {
}
2雹舀、限制整數(shù)位數(shù)或著限制小數(shù)位數(shù)
/**
* 限制整數(shù)位數(shù)或著限制小數(shù)位數(shù)
*
* @param type 限制類型
* @param number 限制位數(shù)
*/
public DecimalInputTextWatcher(Type type, int number) {
if (type == Type.decimal) {
mPattern = Pattern.compile("^[0-9]+(\\.[0-9]{0," + number + "})?$");
} else if (type == Type.integer) {
mPattern = Pattern.compile("^[0-9]{0," + number + "}+(\\.[0-9]{0,})?$");
}
}
3芦劣、既限制整數(shù)位數(shù)又限制小數(shù)位數(shù)
/**
* 既限制整數(shù)位數(shù)又限制小數(shù)位數(shù)
*
* @param integers 整數(shù)位數(shù)
* @param decimals 小數(shù)位數(shù)
*/
public DecimalInputTextWatcher(int integers, int decimals) {
mPattern = Pattern.compile("^[0-9]{0," + integers + "}+(\\.[0-9]{0," + decimals + "})?$");
}
在Activity中的使用示例如下:
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
EditText decimalInputEt1 = findViewById(R.id.decimal_input_et1);
//不限制整數(shù)位數(shù)和小數(shù)位數(shù)
decimalInputEt1.addTextChangedListener(new DecimalInputTextWatcher());
EditText decimalInputEt2 = findViewById(R.id.decimal_input_et2);
//不限制整數(shù)位數(shù),限制小數(shù)位數(shù)為2位
decimalInputEt2.addTextChangedListener(new DecimalInputTextWatcher(DecimalInputTextWatcher.Type.decimal, 2));
EditText decimalInputEt3 = findViewById(R.id.decimal_input_et3);
//限制整數(shù)位數(shù)為4位说榆,不限制小數(shù)位數(shù)
decimalInputEt3.addTextChangedListener(new DecimalInputTextWatcher(DecimalInputTextWatcher.Type.integer, 4));
EditText decimalInputEt4 = findViewById(R.id.decimal_input_et4);
//限制整數(shù)位數(shù)為4位虚吟,小數(shù)位數(shù)為2位
decimalInputEt4.addTextChangedListener(new DecimalInputTextWatcher( 4, 2));
}
}
同時(shí)在xml布局文件中寸认,通過設(shè)置EditText的background屬性對EditText焦點(diǎn)輸入,失去焦點(diǎn)串慰,功能禁用時(shí)的外觀進(jìn)行美化
<EditText
android:id="@+id/decimal_input_et00"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:padding="10dp"
android:gravity="start"
android:textSize="14sp"
android:inputType="numberDecimal"
android:background="@drawable/input_edit_selector"/>
input_edit_selector.xml的代碼為:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_enabled="false" android:drawable="@drawable/input_disabled_shape"/>
<item android:state_focused="true" android:drawable="@drawable/input_focused_shape"/>
<item android:drawable="@drawable/input_normal_shape"/>
</selector>
input_disabled_shape.xml的代碼為:
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<corners android:radius="4dp"/>
<stroke android:color="@color/input_disabled_edit" android:width="1dp"/>
<solid android:color="@color/input_disabled_edit"/>
</shape>
input_focused_shape.xml的代碼為:
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<corners android:radius="4dp"/>
<stroke android:color="@color/input_stroke_blue" android:width="1dp"/>
<solid android:color="@color/input_solid_white"/>
</shape>
input_normal_shape.xml的代碼為:
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<corners android:radius="4dp"/>
<stroke android:color="@color/input_stroke_grey" android:width="1dp"/>
<solid android:color="@color/input_solid_white"/>
</shape>
colors.xml中的各顏色值為:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="input_disabled_edit">#dbdbdb</color>
<color name="input_stroke_blue">#7393D5</color>
<color name="input_stroke_grey">#979797</color>
<color name="input_solid_white">#FFFFFF</color>
</resources>
運(yùn)行之后的界面為: