安卓定制的EditText(货币格式) [英] Android custom EditText(currency format)
问题描述
我有自定义的EditText将输入,也能够扭转其转换。然而它将始终使输入的小数,与输入后面1或2的值。现在我做一些计算应用程序,这需要整数。如何让这个自定义的EditText只取整数的输入和输出?
在code:
@TargetApi(Build.VERSION_ codeS.GINGERBREAD)
公共类NumericEditText扩展的EditText {
私人最终字符GROUPING_SEPARATOR = DecimalFormatSymbols.getInstance()getGroupingSeparator()。
私人最终字符DECIMAL_SEPARATOR = DecimalFormatSymbols.getInstance()getDecimalSeparator()。
私人最终字符串LEADING_ZERO_FILTER_REGEX =^ 0 +(?!$);
私人字符串mDefaultText = NULL;
私人串M previousText =;
私人字符串mNumberFilterRegex =[^ \\Ð\\+ DECIMAL_SEPARATOR +];
/ **
*接口,当数值已被更改或清除通知监听器
* /
公共接口NumericValueWatcher {
/ **
*当射击数值已更改
*参数为newValue新的数值
* /
无效调用onChanged(双newValue)以;
/ **
*当射击数值已被清除(文本字段为空)
* /
无效onCleared();
}
私人列表< NumericValueWatcher> mNumericListeners =新的ArrayList< NumericValueWatcher>();
私人最终TextWatcher mTextWatcher =新TextWatcher(){
私人布尔validateLock = FALSE;
@覆盖
公共无效afterTextChanged(编辑S){
如果(validateLock){
返回;
}
//有效的十进制数不应该超过2小数点分隔符
如果(StringUtils.countMatches(s.toString(),将String.valueOf(DECIMAL_SEPARATOR))→1){
validateLock = TRUE;
的setText(M previousText); //取消变更并恢复到previous输入
setSelection(M previousText.length());
validateLock = FALSE;
返回;
}
如果(s.length()== 0){
handleNumericValueCleared();
返回;
}
setTextInternal(格式(s.toString()));
setSelection(gettext的()长度());
handleNumericValueChanged();
}
@覆盖
公共无效beforeTextChanged(CharSequence中,诠释开始,诠释计数,之后INT){
// 没做什么
}
@覆盖
公共无效onTextChanged(CharSequence中,诠释开始,诠释之前,诠释计数){
// 没做什么
}
};
私人无效handleNumericValueCleared(){
米previousText =;
对于(NumericValueWatcher听众:mNumericListeners){
listener.onCleared();
}
}
私人无效handleNumericValueChanged(){
:M previousText =的getText()的toString();
对于(NumericValueWatcher听众:mNumericListeners){
listener.onChanged(getNumericValue());
}
}
公共NumericEditText(上下文的背景下,ATTRS的AttributeSet){
超(背景下,ATTRS);
addTextChangedListener(mTextWatcher);
setOnClickListener(新View.OnClickListener(){
@覆盖
公共无效的onClick(视图v){
//禁用移动光标
setSelection(gettext的()长度());
}
});
}
/ **
*添加监听数值变化事件
* @参数观察者监听器添加
* /
公共无效addNumericValueChangedListener(NumericValueWatcher观察者){
mNumericListeners.add(守望者);
}
/ **
*删除所有听众数值变化事件
* /
公共无效removeAllNumericValueChangedListeners(){
而(!mNumericListeners.isEmpty()){
mNumericListeners.remove(0);
}
}
/ **
*设置默认数值,它应如何显示,该值将是否被使用
* {@link #clear}被称为
*参数defaultNumericValue数值
*对于数值@param defaultNumericFormat显示格式
* /
公共无效setDefaultNumericValue(双defaultNumericValue,最后弦乐defaultNumericFormat){
mDefaultText =的String.Format(defaultNumericFormat,defaultNumericValue);
setTextInternal(mDefaultText);
}
/ **
*清晰的文本字段,并将其与集合{@link #setDefaultNumericValue}默认值,如果更换
* 任何
* /
公共无效清除(){
setTextInternal(!?mDefaultText = NULL mDefaultText:);
如果(mDefaultText!= NULL){
handleNumericValueChanged();
}
}
/ **
*返回由文本字段repesented数值
返回:数值或{@link Double.NaN}如果不是数字
* /
公共双getNumericValue(){
。字符串原=的getText()的toString()的replaceAll(mNumberFilterRegex,)。
尝试 {
返回NumberFormat.getInstance()解析(原件).doubleValue()。
}赶上(ParseException的E){
返回Double.NaN;
}
}
/ **
*添加分组分隔符串
* @参数原来原始的字符串,可能已经包含不正确的分组分隔符
* @返回字符串正确的分组分隔符
* /
私人字符串格式(最后弦乐原件){
最终的String []部分= original.split(\\+ DECIMAL_SEPARATOR,-1);
串号=零件[0] //因为我们分裂了与极限-1总是会有至少1份
.replaceAll(mNumberFilterRegex,)
.replaceFirst(LEADING_ZERO_FILTER_REGEX,);
//添加分组分隔符,需要扭转来回,因为Java的正则表达式不支持
//从右到左匹配
数= StringUtils.reverse(
StringUtils.reverse(数).replaceAll(。({3}),$ 1+ GROUPING_SEPARATOR));
//删除前导分组分隔符(如果有)
数= StringUtils.removeStart(号码,将String.valueOf(GROUPING_SEPARATOR));
//添加小数部分如果有的话
如果(parts.length→1){
数+ = DECIMAL_SEPARATOR +部分[1];
}
返回数;
}
/ **
*不触发数值更改显示的文本改变
* @参数文本新文本申请
* /
私人无效setTextInternal(字符串文本){
removeTextChangedListener(mTextWatcher);
的setText(文本);
addTextChangedListener(mTextWatcher);
}
}
例如:
输入10000 这将是10,000瞬间, 输入10000.12 这将是10,000.12
我已经试过:
INT输入2 = 0;
。字符串文本2 = etpersen2.getText()的toString();
如果(text2.length()大于0)
输入2 =的Integer.parseInt(文本2);
串E =将String.valueOf(输入2);
etresult.setText(+ E);
使用 Math.round()
要圆浮到最接近的整数。它返回一个int值,因此,使用类型转换(INT)
是多余的。
公共类测试{
公共静态无效的主要(字符串的args []){
双D = 100.675;
双E = 100.500;
浮动F = 100;
浮G = 90F;
的System.out.println(Math.round(d)条);
的System.out.println(Math.round(e)条);
的System.out.println(Math.round(F));
的System.out.println(Math.round(G));
}
}
I have custom EditText which will convert the input and also able to reverse it. However it will always make the input decimal, with 1 or 2 values behind the input. Right now i am making some calculation app, which need integer. How to make this custom EditText to just take integer input and output?
The code:
@TargetApi(Build.VERSION_CODES.GINGERBREAD)
public class NumericEditText extends EditText {
private final char GROUPING_SEPARATOR = DecimalFormatSymbols.getInstance().getGroupingSeparator();
private final char DECIMAL_SEPARATOR = DecimalFormatSymbols.getInstance().getDecimalSeparator();
private final String LEADING_ZERO_FILTER_REGEX = "^0+(?!$)";
private String mDefaultText = null;
private String mPreviousText = "";
private String mNumberFilterRegex = "[^\\d\\" + DECIMAL_SEPARATOR + "]";
/**
* Interface to notify listeners when numeric value has been changed or cleared
*/
public interface NumericValueWatcher {
/**
* Fired when numeric value has been changed
* @param newValue new numeric value
*/
void onChanged(double newValue);
/**
* Fired when numeric value has been cleared (text field is empty)
*/
void onCleared();
}
private List<NumericValueWatcher> mNumericListeners = new ArrayList<NumericValueWatcher>();
private final TextWatcher mTextWatcher = new TextWatcher() {
private boolean validateLock = false;
@Override
public void afterTextChanged(Editable s) {
if (validateLock) {
return;
}
// valid decimal number should not have more than 2 decimal separators
if (StringUtils.countMatches(s.toString(), String.valueOf(DECIMAL_SEPARATOR)) > 1) {
validateLock = true;
setText(mPreviousText); // cancel change and revert to previous input
setSelection(mPreviousText.length());
validateLock = false;
return;
}
if (s.length() == 0) {
handleNumericValueCleared();
return;
}
setTextInternal(format(s.toString()));
setSelection(getText().length());
handleNumericValueChanged();
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
// do nothing
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
// do nothing
}
};
private void handleNumericValueCleared() {
mPreviousText = "";
for (NumericValueWatcher listener : mNumericListeners) {
listener.onCleared();
}
}
private void handleNumericValueChanged() {
mPreviousText = getText().toString();
for (NumericValueWatcher listener : mNumericListeners) {
listener.onChanged(getNumericValue());
}
}
public NumericEditText(Context context, AttributeSet attrs) {
super(context, attrs);
addTextChangedListener(mTextWatcher);
setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// disable moving cursor
setSelection(getText().length());
}
});
}
/**
* Add listener for numeric value changed events
* @param watcher listener to add
*/
public void addNumericValueChangedListener(NumericValueWatcher watcher) {
mNumericListeners.add(watcher);
}
/**
* Remove all listeners to numeric value changed events
*/
public void removeAllNumericValueChangedListeners() {
while (!mNumericListeners.isEmpty()) {
mNumericListeners.remove(0);
}
}
/**
* Set default numeric value and how it should be displayed, this value will be used if
* {@link #clear} is called
* @param defaultNumericValue numeric value
* @param defaultNumericFormat display format for numeric value
*/
public void setDefaultNumericValue(double defaultNumericValue, final String defaultNumericFormat) {
mDefaultText = String.format(defaultNumericFormat, defaultNumericValue);
setTextInternal(mDefaultText);
}
/**
* Clear text field and replace it with default value set in {@link #setDefaultNumericValue} if
* any
*/
public void clear() {
setTextInternal(mDefaultText != null ? mDefaultText : "");
if (mDefaultText != null) {
handleNumericValueChanged();
}
}
/**
* Return numeric value repesented by the text field
* @return numeric value or {@link Double.NaN} if not a number
*/
public double getNumericValue() {
String original = getText().toString().replaceAll(mNumberFilterRegex, "");
try {
return NumberFormat.getInstance().parse(original).doubleValue();
} catch (ParseException e) {
return Double.NaN;
}
}
/**
* Add grouping separators to string
* @param original original string, may already contains incorrect grouping separators
* @return string with correct grouping separators
*/
private String format(final String original) {
final String[] parts = original.split("\\" + DECIMAL_SEPARATOR, -1);
String number = parts[0] // since we split with limit -1 there will always be at least 1 part
.replaceAll(mNumberFilterRegex, "")
.replaceFirst(LEADING_ZERO_FILTER_REGEX, "");
// add grouping separators, need to reverse back and forth since Java regex does not support
// right to left matching
number = StringUtils.reverse(
StringUtils.reverse(number).replaceAll("(.{3})", "$1" + GROUPING_SEPARATOR));
// remove leading grouping separator if any
number = StringUtils.removeStart(number, String.valueOf(GROUPING_SEPARATOR));
// add fraction part if any
if (parts.length > 1) {
number += DECIMAL_SEPARATOR + parts[1];
}
return number;
}
/**
* Change display text without triggering numeric value changed
* @param text new text to apply
*/
private void setTextInternal(String text) {
removeTextChangedListener(mTextWatcher);
setText(text);
addTextChangedListener(mTextWatcher);
}
}
Example:
input 10000 it will be 10,000 in an instant, input 10000.12 it will be 10,000.12
what i've tried:
int input2 = 0;
String text2 = etpersen2.getText().toString();
if (text2.length() > 0)
input2 = Integer.parseInt(text2);
String e = String.valueOf(input2);
etresult.setText("" + e);
Using Math.round()
should round the float to the nearest whole number. It returns an int value so typecasting using (int)
is redundant.
public class Test{
public static void main(String args[]){
double d = 100.675;
double e = 100.500;
float f = 100;
float g = 90f;
System.out.println(Math.round(d));
System.out.println(Math.round(e));
System.out.println(Math.round(f));
System.out.println(Math.round(g));
}
}
这篇关于安卓定制的EditText(货币格式)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!