Как реализовать форматирование EditText в реальном времени? - PullRequest
1 голос
/ 20 июня 2019

Я хочу иметь EditText, который автоматически форматирует пользовательский ввод в режиме реального времени, например, он преобразует 1000000 в 1 000 000

Я пытался Ввод денег Android с фиксированным десятичным значением , но когда я установил текст, приложение зависало

EditText etMoney;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    etMoney = (EditText)findViewById(R.id.etMoney);
    etMoney.addTextChangedListener(new TextWatcher() {
        @Override
        public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
        }

        @Override
        public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
            etMoney.setText(currencyFormat(etMoney.getText().toString()));
        }

        @Override
        public void afterTextChanged(Editable editable) {
        }
    });
}
public static String currencyFormat(String amount) {
    DecimalFormat formatter = new DecimalFormat("###,###,###");
    return formatter.format(Double.parseDouble(amount));
}

Требуемый вывод - это преобразование в реальном времени непосредственно в EditText, но как только я что-то наберу в EditText, приложение вылетает.

Журнал аварий:

06-20 15:19:57.453 1699-1715/system_process E/ActivityManager: ANR in com.hassilproject.myapplication (com.hassilproject.myapplication/.MainActivity)
                                                               PID: 2521
                                                               Reason: Input dispatching timed out (Waiting to send key event because the focused window has not finished processing all of the input events that were previously delivered to it.  Outbound queue length: 0.  Wait queue length: 1.)

Ответы [ 5 ]

0 голосов
/ 20 июня 2019

Каждый раз, когда вы изменяете текст EditText, вызывается метод TextWatcher. Таким образом, вы должны установить флаг, чтобы указать, что источник изменений. И метод обратного вызова TextWatcher. отметьте флажок, чтобы избежать бесконечного цикла.

etMoney.addTextChangedListener(new TextWatcher() {
    private boolean changedByFormatText = false;
    @Override
    public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
    }

    @Override
    public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {

    }

    @Override
    public void afterTextChanged(Editable editable) {
        if(changedByFormatText) {
            changedByFormatText = false;
            return;
        } else {
           changedByFormatText = true;
           etMoney.setText(currencyFormat(etMoney.getText().toString()));
        }

    }
});
0 голосов
/ 20 июня 2019

// Создать метод

private TextWatcher onTextChangedListener() {
        return new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {

            }

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {

            }

            @Override
            public void afterTextChanged(Editable s) {
                editText.removeTextChangedListener(this);

                try {
                    String originalString = s.toString();

                    Long longval;
                    if (originalString.contains(",")) {
                        originalString = originalString.replaceAll(",", "");
                    }
                    longval = Long.parseLong(originalString);

                    DecimalFormat formatter = (DecimalFormat) NumberFormat.getInstance(Locale.US);
                    formatter.applyPattern("#,###,###,###");
                    String formattedString = formatter.format(longval);

                    //setting text after format to EditText
                    editText.setText(formattedString);
                    editText.setSelection(editText.getText().length());
                } catch (NumberFormatException nfe) {
                    nfe.printStackTrace();
                }

                editText.addTextChangedListener(this);
            }
        };
    }

// Вызов метода

editText.addTextChangedListener(onTextChangedListener());
0 голосов
/ 20 июня 2019

Попробуйте, я создал собственное представление для ввода валюты. Используйте метод currency() для получения значения в EditText.

class CurrencyInput(context: Context, attributeSet: AttributeSet) : TextInputEditText(context, attributeSet) {

    private val currencyTextWatcher = CurrencyWatcher()

    override fun onFocusChanged(focused: Boolean, direction: Int, previouslyFocusedRect: Rect?) {
        super.onFocusChanged(focused, direction, previouslyFocusedRect)
        if (focused) addTextChangedListener(currencyTextWatcher) else removeTextChangedListener(currencyTextWatcher)
    }

    fun currency(): Long = currencyTextWatcher.amount
    private fun Long.toDecimalStr(): String = decimalFormatter().format(this)

    inner class CurrencyWatcher : TextWatcher {
        var amount = 0L
        var amountDecimal = ""
        override fun afterTextChanged(editable: Editable?) {
            editable?.toString()?.run {
                when {
                    equals("") -> {
                        amount = 0
                        amountDecimal = "0"
                    }
                    else -> {
                        amount = replace(",", "").replace(".", "").toLong()
                        amountDecimal = if (amount >= 1000) amount.toDecimalStr() else amount.toString()
                    }
                }
                this@CurrencyInput.apply {
                    removeTextChangedListener(this@CurrencyWatcher)
                    amount.let {
                        setText(amountDecimal)
                        setSelection(amountDecimal.length)
                    }
                    addTextChangedListener(this@CurrencyWatcher)
                }
            }
        }
        override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) { }
        override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) { }
    }

}

Замените на имя вашего пакета при использовании CurrencyInput в макете

<com.google.android.material.textfield.TextInputLayout
            style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginBottom="7dp"
            android:hint="Currency"
            app:endIconMode="clear_text">
            <com.package.CurrencyInput
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:inputType="number"/>
        </com.google.android.material.textfield.TextInputLayout>
0 голосов
/ 20 июня 2019

Надеюсь, это сработает для вас.

 etMoney.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {

            }

            @Override
            public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {

            }

            @Override
            public void afterTextChanged(Editable editable) {
                etMoney.removeTextChangedListener(this);
                new Handler().postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        try {
                            if (!editable.toString().equalsIgnoreCase("")) {
                                etMoney.setText("" + currencyFormat(editable.toString()));
                            }
                        } catch (NumberFormatException e) {
                            e.printStackTrace();
                        }
                    }
                }, 4000); //after 4 second it will update to UI.
               etMoney.addTextChangedListener(this);
            }
        });

Метод денежного формата приведен ниже

 public String currencyFormat(String amount) {
        return new DecimalFormat("###,###,###").format(Double.parseDouble(amount));
    }
0 голосов
/ 20 июня 2019

изменить этот код

 etMoney.addTextChangedListener(new TextWatcher() {
    @Override
    public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
    }

    @Override
    public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {

    }

    @Override
    public void afterTextChanged(Editable editable) {
        etMoney.setText(currencyFormat(editable.toString()));
    }
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...