简介
最近项目涉及到了金额输入,觉得这不是个小case,真正实现起来发现一时不太好弄,于是搜了一些博客看了一下,使用以后,发现多少有些bug,还是觉得不如自己实现。简单看一下效果描述:
小数点后保留两位
输入
- 没有输入显示:¥0.00
- 输入一位显示:¥0.03 (输入3)
- 再输一位显示:¥0.37 (输入7)
- 继续输入显示:¥3.78 (输入8) –>¥378.42 (输入4,2)
删除
- 删除一位:¥ 37.84 (删除2)
- 再删一位:¥3.78 (删除4)
- 再删一位:¥0.37 (删除8)
- 继续删除:¥0.03 (删除7) –> ¥0.00 (删除3)
实现
思路
误区:
纠结于数字,把金额当做数字处理,强行通过计算去实现。不能说不可实现,但是需要不断补漏洞。
正确思路
把金额当做字符串处理,3步实现:
- 先把小数点去掉
- 判断数字串位数,>3,如果第一个数字为0,去掉;<3,前补0,直到达到3位(如 “001”)
- 最后在第二位和第三位之间点上“.”,保留2位小数,b如 “0.01”
代码
mEtamount.requestFocus();
mEtAmount.addTextChangeListener(new TextWatcher() {
String numberStr;//定义一个字符串来得到处理后的金额
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
if (TextUtils.isEmpty(getAmount())){//如果金额为空,重新设置金额,光标移到最后
numberStr = "0.00";
setAmount(numberStr);
moveCursorEnd(numberStr.length());
}
if (isChanged()){//如果金额发生改变,格式化金额
numberStr = getMoneyStr(s.toString());
}
}
@Override
public void afterTextChanged(Editable s) {
String _etStr = getView().getAmount();
//UtilLogs.e(_etStr + "====" + numberStr);
//判断输入框的值是否等于金额的值,如果不相同则赋值,如果不断判断TextWatch将会死循环
if (isChanged()) {//重要:如果文字沒有改变,不再为EditText重新赋值
setAmount(numberStr);//为EditText赋值
moveCursorEnd(numberStr.length());//将光标定位到结尾
}
}
private boolean isChanged(){
String _etStr = getAmount();
return !TextUtils.isEmpty(getAmount()) && !_etStr.equals(numberStr);
}
/*获得金额,此方法做了格式化金额操作,移动小数点,删0,补0*/
private String getMoneyStr(String pMoney){
//定义一个StringBuilder,便于操作字符串
StringBuilder _moneyBuf = new StringBuilder(pMoney);
//①删除小数点(如果有)
int _dotIndex = _moneyBuf.indexOf(".");
if (!(_dotIndex < 0)) {
_moneyBuf.deleteCharAt(_dotIndex);
}
//②判断字符串长度,>3,第一个字符为"0",删除掉;<3,前面补0,保持至少三位数
int _len = _moneyBuf.length();
if (_len > 3 && "0".equals(_moneyBuf.substring(0, 1))) {
_moneyBuf.deleteCharAt(0);
} else {
for (int i = 0; i < 3 - _len; i++) {
_moneyBuf.insert(0, "0");
}
}
//③将小数点插入倒数第二位和第三位之间,保证两位小数
_moneyBuf.insert(_moneyBuf.length() - 2, ".");
return _moneyBuf.toString();
}
});
/*获得输入框中的金额*/
private String getAmount(){
return mEtAmount.getText().toString();
}
/*输入框设置金额*/
private void setAmount(String pAmount){
mEtAmount.setText(pAmount);
}
/*将光标移到最后*/
private void moveCursorEnd(int pEnd){
mEtAmount.setSelection(pEnd);
}
布局
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="80dp"
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:layout_marginTop="20dp"
android:background="#ffffff"
android:gravity="center_vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="20dp"
android:text="交易金额"
android:textSize="16sp"
android:textColor="#333333"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottom="@+id/query_et_transaction_amount"
android:layout_toLeftOf="@id/query_et_transaction_amount"
android:paddingBottom="@dimen/x3"
android:text="¥"
android:textColor="#fc353c"
/>
<EditText
android:id="@id/query_et_transaction_amount"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_marginRight="20dpp"
android:background="#00000000"
android:focusable="true"
android:gravity="right"
android:imeOptions="actionNext"
android:inputType="numberDecimal"
android:maxLength="11"
android:numeric="decimal"
android:text="0.00"
android:textColor="#fc353c"
android:textColorHint="#fc353c"
android:textSize="20sp"
android:textStyle="bold"
/>
</RelativeLayout>