android EditText ,keyboard textWatcher 问题 [英] android EditText ,keyboard textWatcher problem

查看:14
本文介绍了android EditText ,keyboard textWatcher 问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发一个 android 应用程序,并且我有一个 EditText,用户可以在其中输入数字.我想使用不同的货币格式(比如##、##、###)格式化数字,并且我想即时进行,即当用户输入每个数字时(而不是按下输入时).我四处搜索,发现 TextWatcher 我第一次发现它很有希望,但是事实证明这是一种绝对的痛苦.我正在一台只有软键盘的 HTC Desire 手机上调试我的代码.

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.

现在我想在用户按下数字(0 到 9)、del(退格)键和 enter 键时获得回调.从我的测试中我发现了这些(至少在我的手机上)

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当用户按 del 或 enter 键时.当用户按下回车键时,onKey一次输入调用两次函数(我相信这是 ACTION_UP 和ACTION_DOWN).当用户按下 del 时,onKey 被调用一次(仅适用于ACTION_DOWN) 我不知道为什么.用户时永远不会调用 onKey按下任何数字(0 到 9),这也是我无法理解.

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个回调函数被称为(在TextChanged之前,onTextChanged, afterTextChanged)每当用户按下任何数字(0 到9) 键.所以我想通过使用TextWatcher 和 onKeyListener 在一起我可以得到我需要的所有回调.

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) 首先在我的 HTC 软键盘那里是一个键(带有向下箭头),当我点击它时键盘辞职不给任何回调.我还是不敢相信android让用户编辑字段并辞职不让程序处理(保存)编辑.现在我的editText 显示一个值,而我的对象有另一个值(我正在保存用户在输入时进行编辑,并处理回通过重置按下键盘editText 值与中的值对象,但我对此没有答案键盘向下键).

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) 二、我要格式化数字用户输入新数字后.说我已经有 123 在 editText 和用户输入按下 4,我想要我的editText 显示 1,234.我吃饱了onTextChanged() 和afterTextChanged() 我可以格式化号码并将其放回任何这些回调中的editText.我应该使用哪一个?哪一个是最佳实践?

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) 第三个是最关键的问题.当应用程序启动时,我把editText 中的当前对象值.假设我在 onResume() 上放了 123,当用户输入一个数字(比如 4)我想要它是 1234.但在我的 onTextChanged回调我得到的是4123.当我再按一个键(比如 5) 我是得到 45123.所以对于用户输入editText 光标指向末尾文本.但是当值由手,editText 光标似乎不是更新.我相信我必须做textWatcher 回调中的某些内容,但是我不知道我该怎么办.

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);
    }
}

我知道这是一个大问题,但我正在处理同样的问题 2 天.我是 android 新手,仍然无法相信没有简单的方法可以即时处理 textEdit 数据(我在 iphone 上轻松地做了同样的事情).谢谢大家

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

编辑:使用输入过滤器后

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}); 

当应用启动时,我将 1,234 放在 editText 上

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

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

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

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

我得到:61234 我想要:12346

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;
    }
});

我所做的是在editText的onClick()上,我强制将光标放在当前EditText文本的末尾,当用户按下任何数字时我也做了同样的事情.希望它对某人有所帮助..感谢所有试图提供帮助的人.

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.

这篇关于android EditText ,keyboard textWatcher 问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆