android EditText, проблема с клавиатурой textWatcher

Я работаю над приложением для Android, и у меня есть EditText, где пользователь может вводить числа. Я хочу отформатировать число, используя разные валютные форматы (например, ##, ##, ###), и я хочу сделать это на лету, то есть когда пользователь вводит каждую цифру (а не при нажатии клавиши ввода). Я погуглил и наткнулся на TextWatcher , который я сначала нашел многообещающим, но он оказался абсолютной болью. Я отлаживаю свой код на телефоне HTC Desire, у которого есть только программная клавиатура.

Теперь я хочу получать обратный вызов, когда пользователь нажимает цифры (от 0 до 9), клавишу del (backspace) и клавишу ввода. В ходе тестирования я обнаружил (по крайней мере, на моем телефоне)

1) вызывается editText onKeyListener Я погуглил и наткнулся на TextWatcher , который я сначала нашел многообещающим, но он оказался абсолютной болью. Я отлаживаю свой код на телефоне HTC Desire, у которого есть только программная клавиатура.

Теперь я хочу получать обратный вызов, когда пользователь нажимает цифры (от 0 до 9), клавишу del (backspace) и клавишу ввода. В ходе тестирования я обнаружил (по крайней мере, на моем телефоне)

1) вызывается editText onKeyListener Я погуглил и наткнулся на TextWatcher , который сначала показался мне многообещающим, но он оказался абсолютной проблемой. Я отлаживаю свой код на телефоне HTC Desire, у которого есть только программная клавиатура.

Теперь я хочу получать обратный вызов, когда пользователь нажимает цифры (от 0 до 9), клавишу del (backspace) и клавишу ввода. В ходе тестирования я обнаружил (по крайней мере, на своем телефоне)

1) вызывается editText onKeyListener 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 и уйти в отставку, не давая программе обработать (сохранить) правку. Теперь мой editText показывает одно значение, а мой объект имеет другое значение (я сохраняю пользовательские правки при входе и обратная обработка нажмите на клавиатуре, сбросив editText значение со значением в объект, но у меня нет ответа на это клавиша вниз на клавиатуре).

2) Во-вторых, я хочу отформатировать число после того, как пользователь ввел новую цифру. Сказать У меня уже есть 123 на editText и пользователь нажал 4, я хочу editText для отображения 1,234. Я сыт число onTextChanged () и afterTextChanged () и я могу форматировать номер и верните его на editText в любом из этих обратных вызовов. Какой мне использовать? Какой передовой опыт?

3) Третий - самый важный проблема. При запуске приложения я ставлю текущее значение объекта в editText. Скажем, я поставил 123 на onResume (), а когда пользователь вводит цифру (скажем, 4) я хочу это должно быть 1234. Но на моем onTextChanged обратный вызов я получаю 4123. Когда Я нажимаю еще одну клавишу (скажем 5) Я получение 45123. Итак, для пользовательского ввода editText курсор указывает на конец текст. Но когда значение установлено рука, курсор editText не кажется обновление. Я считаю, что должен сделать что-то в обратных вызовах textWatcher, но Я не знаю, что мне делать.

Я публикую свой код ниже.

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). Спасибо всем

РЕДАКТИРОВАТЬ : после использования входного фильтра

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

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

Затем, когда пользователь щелкает editText, появляется клавиатура и говорит, что пользователь вводит цифру 6

Я получаю: 61234 Хочу: 12346

14
задан Krishnabhadra 13 April 2011 в 08:57
поделиться