机器人的EditText,键盘textWatcher问题机器人、键盘、问题、EditText

2023-09-04 11:30:47 作者:时光与爱终年不遇

我工作的一个Android应用程序,我有一个EditText,其中用户可以输入数字。我想格式化使用不同的货币格式的数字(比如##,##,###),我想要做的飞行,即当用户输入每个数位(不进入的时候是pressed)。我周围的一派,和碰到 TextWatcher 我第一次发现有前途的,但它竟然是一个绝对的痛苦。我调试上的HTC Desire手机,它不仅拥有软键盘我的code。

现在我想获得一个回调,当用户preSS数字(0〜9),删除(退格键)键和回车键。从我的测试中我发现这些(ATLEAST在我的手机)

  

1)EDITTEXT onKeyListener称为   当用户presses删除或回车键。   当用户presses进入,onKey   函数被调用两次,每次进入   (我相信这是对ACTION_UP和   ACTION_DOWN)。当用户presses德尔,   onKey被调用一次(仅适用于   ACTION_DOWN),我不知道为什么。   onKey不会被调用,当用户   presses任何数字(0〜9),这也是我   不能理解。

     

2)TextWatchers 3回调函数   被称为(beforeTextChanged,   onTextChanged,afterTextChanged)   每当用户presses任何数字(0〜   9)键。所以我想用   TextWatcher和onKeyListener在一起   我能得到我所需要的所有回调。

现在我的问题是这些。

  

1)首先在我的HTC软键盘有   是一个键(带有一键盘符号   向下箭头),当我点击它   键盘辞职不给   任何回调。我仍然不能相信   Android的出租用户编辑字段   辞职没有让节目   流程(保存)编辑。现在我的   EDITTEXT正显示出一个值和我   对象有另一个值(我现在的储蓄   在输入和处理回用户编辑   通过对CH375复位键盘preSS   EDITTEXT值与值   反对,但我没有回答这个   键盘上下键)。

     

2)其次,我想格式化数   用户后进入新的数字。说   我已经有123 EDITTEXT和   用户输入pressed 4,我希望我的   EDITTEXT显示1,234。我得到充分的   上onTextChanged号码()和   afterTextChanged(),我可以格式   数并把它带回   EDITTEXT在任何这些回调。   我应该使用哪一个?这是   最好的做法?

     

3)第三一个是最关键   问题。当应用程序开始我把   在EDITTEXT当前对象值。   说我把123 onResume(),而当   用户输入一个数字(比如4)我想它   是1234,但在我的onTextChanged   回调是什么我正为4123.当   我preSS多一个键(比如5)我   越来越45123.所以对于用户输入   EDITTEXT光标指向的结束   文本。但是,当值被设置   另一方面,EDITTEXT光标不要似乎是   更新。我认为我必须做的   一些在textWatcher回调,但   我不知道我应该做的。

我张贴下面我code。

 公共类APPHOME扩展AppBaseActivity {
    私人的EditText ED = NULL;
    私人的NumberFormat amountFormatter = NULL;
    私人布尔isUserInput = TRUE;

    @覆盖
    公共无效的onCreate(包savedInstanceState){
        super.onCreate(savedInstanceState);
        的setContentView(R.layout.app_home_screen);

        ED =(EditText上)findViewById(R.id.main_amount_textfield);
        amountFormatter =新的DecimalFormat(##,##,###);


        ed.setOnKeyListener(新View.OnKeyListener(){
            @覆盖
            公共布尔onKey(视图V,INT关键code,KeyEvent的事件){
                如果(event.getAction()== KeyEvent.ACTION_DOWN)
                    返回true;
                字符串strippedAmount = ed.getText()的toString()代替(,);
                如果(键code == KeyEvent.KEY code_DEL){
                    //删除pressed,昏迷的条数,然后删除至少显著数字。
                    strippedAmount = strippedAmount.substring(0,strippedAmount.length() -  1);
                    INT amountNumeral = 0;
                    尝试{
                        amountNumeral =的Integer.parseInt(strippedAmount);
                    }赶上(NumberFormatException异常E){
                    }
                    myObject.amount = amountNumeral;
                    isUserInput = FALSE;
                    setFormattedAmount(amountNumeral,ed.getId());
                }否则,如果(键code == KeyEvent.KEY code_ENTER){
                    //输入pressed,保存编辑辞职键盘
                    INT amountNumeral = 0;
                    尝试{
                        amountNumeral =的Integer.parseInt(strippedAmount);
                    }赶上(NumberFormatException异常E){
                    }
                    myObject.amount = amountNumeral;
                    isUserInput = FALSE;
                    setFormattedAmount(myObject.amount,ed.getId());
                    //保存编辑
                    保存();
                    //辞职键盘..
                    InputMethodManager在=(InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
                    in.hideSoftInputFromWindow(AppHome.this.getCurrentFocus().getWindowToken(),InputMethodManager.HIDE_NOT_ALWAYS);
                }
                返回true;
            }
        });

        TextWatcher inputTextWatcher =新TextWatcher(){
            公共无效afterTextChanged(编辑S){
                如果(isUserInput == FALSE){
                    // textWatcher是递归的。当EDITTEXT值从code textWatcher回调改变被调用。因此,这个变量作为一个标志告诉是否更改用户生成或not..Possibly马车code .. :(
                    isUserInput = TRUE;
                    返回;
                }
                字符串strippedAmount = ed.getText()的toString()代替(,);
                INT amountNumeral = 0;
                尝试{
                    amountNumeral =的Integer.parseInt(strippedAmount);
                }赶上(NumberFormatException异常E){
                }
                isUserInput = FALSE;
                setFormattedAmount(amountNumeral,ed.getId());
            }

            公共无效beforeTextChanged(CharSequence中,诠释开始,诠释计数,之后INT){
            }
            公共无效onTextChanged(CharSequence中,诠释开始,诠释之前,诠释计数){
            }
        };

        ed.addTextChangedListener(inputTextWatcher);
    } //的onCreate结束...

    公共无效setFormattedAmount(整数金额,整数inputBoxId){
        双amountValue = 0;
        字符串textString = NULL;
        TextView的amountInputBox =(TextView中)findViewById(inputBoxId);

        amountValue = Double.parseDouble(Integer.toString(量));
        textString = amountFormatter.format(amountValue)的ToString();
        amountInputBox.setText(textString);
    }
}
 
外刊阅读 机器人该拥有自己的 脸 吗

我知道这是一个很大的问题,但我工作的这个相同的问题2天。我是新来的Andr​​oid和仍然无法相信,有没有简单的方法来处理动态数据的TextEdit(我做在iPhone上轻松相同)。感谢所有

修改:使用输入滤波器后

 输入过滤器过滤器=新的输入过滤器(){
    公共CharSequence的过滤器(CharSequence的来源,诠释开始,诠释年底,跨区DEST,INT DSTART,诠释DEND){
            字符串strippedAmount = dest.toString()+源;
            strippedAmount = strippedAmount.replace(,,);

        INT amountNumeral = 0;
        尝试{
            amountNumeral =的Integer.parseInt(strippedAmount);
        }赶上(NumberFormatException异常E){
        }
            返回amountFormatter.format(amountNumeral)的ToString();
    }
};

ed.setFilters(新输入过滤器[] {滤});
 

当应用程序启动时我就EDITTEXT投入1,234

  myObject.amount = 1234;
ed.setText(amountFormatter.format(myObject.amount)的ToString());
 

然后,当用户点击EDITTEXT,键盘弹出,并说用户输入数字6

  

我越来越:61234我想:   12346

解决方案

好了,经过多次撞头,我发现了一个变通的光标位置problem..I不知道它是否是正确的做法,但我把它工作..

  TextWatcher inputTextWatcher =新TextWatcher(){
        公共无效afterTextChanged(编辑S){
            如果(isUserInput == FALSE){
                // textWatcher是递归的。当EDITTEXT值从code textWatcher回调改变被调用。因此,这个变量作为一个标志告诉是否更改用户生成或not..Possibly马车code .. :(
                isUserInput = TRUE;
                ed.setSelection(ed.getText()长度());
                返回;
            }
            字符串strippedAmount = ed.getText()的toString()代替(,);
            INT amountNumeral = 0;
            尝试{
                amountNumeral =的Integer.parseInt(strippedAmount);
            }赶上(NumberFormatException异常E){
            }
            isUserInput = FALSE;
            setFormattedAmount(amountNumeral,ed.getId());
        }

        公共无效beforeTextChanged(CharSequence中,诠释开始,诠释计数,之后INT){
        }
        公共无效onTextChanged(CharSequence中,诠释开始,诠释之前,诠释计数){
        }
    };
ed.addTextChangedListener(inputTextWatcher);


ed.setOnClickListener(新View.OnClickListener(){
        @覆盖
        公共无效的onClick(视图v){
            INT长度= ed.getText()长度()。
            ed.setCursorVisible(真正的);
            ed.setSelection(长);
        }
    });

ed.setOnKeyListener(新View.OnKeyListener(){
    @覆盖
    公共布尔onKey(视图V,INT关键code,KeyEvent的事件){
            如果(event.getAction()== KeyEvent.ACTION_UP)
                返回true;
            字符串strippedAmount = ed.getText()的toString()代替(,);
            如果(键code == KeyEvent.KEY code_DEL){
                //删除pressed,昏迷的条数,然后删除至少显著数字。
                strippedAmount = strippedAmount.substring(0,strippedAmount.length() -  1);
                INT amountNumeral = 0;
                尝试{
                    amountNumeral =的Integer.parseInt(strippedAmount);
                }赶上(NumberFormatException异常E){
                }
                isUserInput = FALSE;
                setFormattedAmount(amountNumeral,ed.getId());
                返回true;
            }否则,如果(键code == KeyEvent.KEY code_ENTER){
                //输入pressed,保存编辑辞职键盘
                INT amountNumeral = 0;
                尝试{
                    amountNumeral =的Integer.parseInt(strippedAmount);
                }赶上(NumberFormatException异常E){
                }
                isUserInput = FALSE;
                setFormattedAmount(amountNumeral,ed.getId());
                //保存编辑
                //辞职键盘..
                InputMethodManager在=(InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
                in.hideSoftInputFromWindow(AppHome.this.getCurrentFocus().getWindowToken(),InputMethodManager.HIDE_NOT_ALWAYS);
                返回true;
            }
            返回false;
    }
});
 

我所做的是EDITTEXT的的onClick(),我用力把光标在当前的EditText文本的末尾,我也做了同样的,当用户pressed任何数字。希望它可以帮助someone..Thanks大家谁试图帮助。

I am working on a android app and I have an EditText where user can input numbers. I want to format the number using different currency formats (say ##,##,###) and I want to do it on the fly, ie when user enter each digit(not when enter is pressed). I googled around, and came across TextWatcher which I first found promising, but it turned out to be an absolute pain. I am debugging my code on a HTC Desire phone which only has a soft keyboard.

Now I want to get a callback when user press numbers (0 to 9) , del (backspace) key and enter key. From my testing I found these (atleast on my phone)

1) editText onKeyListener is called when user presses del or enter key. When user presses enter, onKey function is called twice for one enter (which I believe is for ACTION_UP and ACTION_DOWN). When user presses del, onKey is called once (only for ACTION_DOWN) which I dont know why. onKey is never called when user presses any digits(0 to 9) which too I cant understand.

2) TextWatchers 3 callback functions are called (beforeTextChanged, onTextChanged, afterTextChanged) whenever user presses any number (0 to 9) key . So I thought by using TextWatcher and onKeyListener together I can get all callbacks I need.

Now my questions are these..

1) First in my HTC soft keyboard there is a key (a keyboard symbol with a down arrow) and when I click on it keyboard is resigned without giving any callback. I still cant believe android letting user to edit a field and resign without letting program to process (save) the edit. Now my editText is showing one value and my object has another value (I am saving user edits on enter, and handling back press on keyboard by reseting editText value with the value in the object , but I have no answer to this keyboard down key).

2) Second, I want to format the number after user entered the new digit. Say I already have 123 on editText and user entered pressed 4, I want my editText to display 1,234. I get full number on onTextChanged() and afterTextChanged() and I can format the number and put it back to editText in any of these callback. Which one should I use? Which is the best practice?

3) Third one is the most crucial problem. When app start I put the current object value in the editText. Say I put 123 on onResume(), and when user enter a digit (say 4) I want it to be 1234. But on my onTextChanged callback what I am getting is 4123. When I press one more key (say 5) I am getting 45123. So for user inputs editText cursor are pointing to end of the text. But when value is set by hand, editText cursor dont seems to be updating. I believe I have to do something in textWatcher callbacks but I dont know what I should do.

I am posting my code below.

public class AppHome extends AppBaseActivity {
    private EditText ed = null;
    private NumberFormat amountFormatter = null;
    private boolean  isUserInput = true;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.app_home_screen);

        ed = (EditText)findViewById(R.id.main_amount_textfield);
        amountFormatter = new DecimalFormat("##,##,###");


        ed.setOnKeyListener(new View.OnKeyListener() {
            @Override
            public boolean onKey(View v, int keyCode, KeyEvent event) {
                if(event.getAction() == KeyEvent.ACTION_DOWN) 
                    return true;
                String strippedAmount = ed.getText().toString().replace(",", "");
                if(keyCode == KeyEvent.KEYCODE_DEL){
                    //delete pressed, strip number of comas and then delete least significant digit.
                    strippedAmount = strippedAmount.substring(0, strippedAmount.length() - 1);
                    int amountNumeral = 0;
                    try{
                        amountNumeral = Integer.parseInt(strippedAmount);
                    } catch(NumberFormatException e){
                    }
                    myObject.amount = amountNumeral;
                    isUserInput = false;
                    setFormattedAmount(amountNumeral,ed.getId());
                }else if(keyCode == KeyEvent.KEYCODE_ENTER){
                    //enter pressed, save edits and resign keyboard
                    int amountNumeral = 0;
                    try{
                        amountNumeral = Integer.parseInt(strippedAmount);
                    } catch(NumberFormatException e){
                    }
                    myObject.amount = amountNumeral;
                    isUserInput = false;
                    setFormattedAmount(myObject.amount,ed.getId());
                    //save edits
                    save();
                    //resign keyboard..
                    InputMethodManager in = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
                    in.hideSoftInputFromWindow(AppHome.this.getCurrentFocus().getWindowToken(),InputMethodManager.HIDE_NOT_ALWAYS);
                }
                return true;
            }
        });

        TextWatcher inputTextWatcher = new TextWatcher() {
            public void afterTextChanged(Editable s) { 
                if(isUserInput == false){
                    //textWatcher is recursive. When editText value is changed from code textWatcher callback gets called. So this variable acts as a flag which tells whether change is user generated or not..Possibly buggy code..:(
                    isUserInput = true;
                    return;
                }
                String strippedAmount = ed.getText().toString().replace(",", "");
                int amountNumeral = 0;
                try{
                    amountNumeral = Integer.parseInt(strippedAmount);
                } catch(NumberFormatException e){
                }
                isUserInput = false;
                setFormattedAmount(amountNumeral,ed.getId());
            }

            public void beforeTextChanged(CharSequence s, int start, int count, int after){
            }
            public void onTextChanged(CharSequence s, int start, int before, int count) {
            }
        };

        ed.addTextChangedListener(inputTextWatcher);
    }//end of onCreate...

    public void setFormattedAmount(Integer amount, Integer inputBoxId){
        double amountValue = 0;
        String textString =null;
        TextView amountInputBox = (TextView) findViewById(inputBoxId);

        amountValue = Double.parseDouble(Integer.toString(amount));
        textString = amountFormatter.format(amountValue).toString();
        amountInputBox.setText(textString);
    }
}

I know it is a big question, but I am working on this same problem for 2 days. I am new to android and still cant believe that there is no easy way to process textEdit data on the fly (I done the same on iphone with ease). Thanks all

EDIT: after using input filter

InputFilter filter = new InputFilter() { 
    public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) { 
            String strippedAmount = dest.toString() + source;
            strippedAmount = strippedAmount.replace(",", "");

        int amountNumeral = 0;
        try{
            amountNumeral = Integer.parseInt(strippedAmount);
        } catch(NumberFormatException e){
        }           
            return amountFormatter.format(amountNumeral).toString(); 
    } 
}; 

ed.setFilters(new InputFilter[]{filter}); 

When app starts I am putting 1,234 on the editText

myObject.amount = 1234;
ed.setText(amountFormatter.format(myObject.amount).toString());

Then when user clicks the editText, keyboard pops up, and say user enters digit 6

I am getting : 61234 I want : 12346

解决方案

Well, after much head banging, I found a work around for cursor position problem..I dont know whether it is the correct way, But I got it working..

    TextWatcher inputTextWatcher = new TextWatcher() {
        public void afterTextChanged(Editable s) { 
            if(isUserInput == false){
                //textWatcher is recursive. When editText value is changed from code textWatcher callback gets called. So this variable acts as a flag which tells whether change is user generated or not..Possibly buggy code..:(
                isUserInput = true;
                ed.setSelection(ed.getText().length());
                return;
            }
            String strippedAmount = ed.getText().toString().replace(",", "");
            int amountNumeral = 0;
            try{
                amountNumeral = Integer.parseInt(strippedAmount);
            } catch(NumberFormatException e){
            }
            isUserInput = false;
            setFormattedAmount(amountNumeral,ed.getId());
        }

        public void beforeTextChanged(CharSequence s, int start, int count, int after){
        }
        public void onTextChanged(CharSequence s, int start, int before, int count) {
        }
    };
ed.addTextChangedListener(inputTextWatcher);


ed.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            int length          =   ed.getText().length();
            ed.setCursorVisible(true);
            ed.setSelection(length);
        }
    });

ed.setOnKeyListener(new View.OnKeyListener() {
    @Override
    public boolean onKey(View v, int keyCode, KeyEvent event) {
            if(event.getAction() == KeyEvent.ACTION_UP) 
                return true;
            String strippedAmount = ed.getText().toString().replace(",", "");
            if(keyCode == KeyEvent.KEYCODE_DEL){
                //delete pressed, strip number of comas and then delete least significant digit.
                strippedAmount = strippedAmount.substring(0, strippedAmount.length() - 1);
                int amountNumeral = 0;
                try{
                    amountNumeral = Integer.parseInt(strippedAmount);
                } catch(NumberFormatException e){
                }
                isUserInput = false;
                setFormattedAmount(amountNumeral,ed.getId());
                return true;
            }else if(keyCode == KeyEvent.KEYCODE_ENTER){
                //enter pressed, save edits and resign keyboard
                int amountNumeral = 0;
                try{
                    amountNumeral = Integer.parseInt(strippedAmount);
                } catch(NumberFormatException e){
                }
                isUserInput = false;
                setFormattedAmount(amountNumeral,ed.getId());
                //save edits
                //resign keyboard..
                InputMethodManager in = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
                in.hideSoftInputFromWindow(AppHome.this.getCurrentFocus().getWindowToken(),InputMethodManager.HIDE_NOT_ALWAYS);
                return true;
            }
            return false;
    }
});

What I have done is on onClick() of editText, I forcefully put the cursor at the end of the current EditText text, and I have done the same when user pressed any digit. Hope it helps someone..Thanks for everyone who tried to help.

 
精彩推荐
图片推荐