Homayoun Behzadian
Homayoun Behzadian

Reputation: 1163

How to implement android.text.InputType

I just develoed below class:

    class LocalizedNumberInputFilter implements InputFilter
    {

        @Override
        public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
            String destText = dest.toString();
            String destPrefix = dstart > 0 ? destText.substring(0, dstart) : "";
            String destSuffix = dend > 0 ? destText.substring(dend) : destText;

            String srcText = source.toString().substring(start, end);

            String result = destPrefix + srcText + destSuffix;

            Double parsed = FarayanUtility.TryParseDouble(result);
            if (parsed == null) {
                return "";
            }

            String grouped = NumberFormat.getInstance().format(parsed);
            String localized = localNumberProvider.Localize(grouped);

            return localized;
        }
    }

and set EditText filters as

setFilters(new InputFilter[]{new LocalizedNumberInputFilter()});

to group and localize user entered text. like below table:

User entry ----> Displaying text

1 ----> ۱

12 ----> ۱۲

123 ----> ۱۲۳

1234 ----> ۱,۲۳۴

and so on.

But nothing will be displayed after user types

Upvotes: 0

Views: 40

Answers (1)

Ali Behzadian Nejad
Ali Behzadian Nejad

Reputation: 9044

If you want to have Persian/Arabic numbers in your application text inputs, you have two options:

  • Use fonts with modified numbers
  • Use a TextWatcher class to format your input

For second option:

public class NumberTextWatcher implements TextWatcher {

    private DecimalFormat df;   // With fraction
    private DecimalFormat dfnd; // without fraction
    private boolean hasFractionalPart;
    private Number number;

    private EditText et;

    public NumberTextWatcher(EditText et)
    {
        df = new DecimalFormat("#,###.##");
        df.setDecimalSeparatorAlwaysShown(true);
        dfnd = new DecimalFormat("#,###");
        this.et = et;
        hasFractionalPart = false;
    }

    @Override
    public void afterTextChanged(Editable s)
    {
        // VERY IMPORTANT
        et.removeTextChangedListener(this);

        try {
            int inilen, endlen;
            inilen = et.getText().length();

            String v = s.toString().replace(String.valueOf(df.getDecimalFormatSymbols().getGroupingSeparator()), "");
            number = df.parse(v);
            int cp = et.getSelectionStart();
            if (hasFractionalPart) {
                et.setText(df.format(number));
            } else {
                et.setText(dfnd.format(number));
            }
            endlen = et.getText().length();
            int sel = (cp + (endlen - inilen));
            if (sel > 0 && sel <= et.getText().length()) {
                et.setSelection(sel);
            } else {
                // place cursor at the end?
                et.setSelection(et.getText().length() - 1);
            }
        } catch (NumberFormatException nfe) {
            // do nothing?
        } catch (ParseException e) {
            // do nothing?
        }

        // VERY IMPORTANT
        et.addTextChangedListener(this);
    }

    @Override
    public void beforeTextChanged(CharSequence s, int start, int count, int after)
    {
    }

    @Override
    public void onTextChanged(CharSequence s, int start, int before, int count)
    {
        if (s.toString().contains(String.valueOf(df.getDecimalFormatSymbols().getDecimalSeparator())))
        {
            hasFractionalPart = true;
        } else {
            hasFractionalPart = false;
        }
    }

    public Long getLongNumber() {
        return number.longValue();
    }

}

Upvotes: 1

Related Questions