दशमलव विभाजक अल्पविराम (',') के साथ NumberDecimal inputType में EditText


133

inputType numberDecimalमें EditTextडॉट का उपयोग करता है '।' दशमलव विभाजक के रूप में। यूरोप में इसके बजाय कॉमा ',' का उपयोग करना आम है। भले ही मेरा स्थान जर्मन के रूप में सेट किया गया हो, दशमलव विभाजक अभी भी 'है।'

क्या दशमलव विभाजक के रूप में अल्पविराम प्राप्त करने का एक तरीका है?



1
: इस बग अंत में एंड्रॉयड हे में तय किया गया है issuetracker.google.com/issues/36907764
Lovis

वे कहते हैं कि यह निश्चित है लेकिन मैं इसे निश्चित नहीं कर सकता हूँ? क्या आप?
सेबस्टियन

5
मैं यह पुष्टि कर सकता हूं कि यह तय नहीं है, कम से कम मेरे नेक्सस 4 पर एंड्रॉइड 8.1 (उर्फ वंशावली 15.1) चल रहा है। सेटिंग के साथ-> फ्रेंच (फ्रांस) के लिए भाषा सेट, Android के साथ एक EditText: inputType = "numberDecimal" ',' (अल्पविराम) विभाजक प्रदान करता है, लेकिन फिर भी अल्पविराम को स्वीकार करने से इनकार करता है। की पेशकश की। ' (दशमलव बिंदु) स्वीकार किया जाता है। इस बग को पहली बार रिपोर्ट किए हुए 9 साल से ज्यादा का समय हो चुका है। क्या यह किसी प्रकार का रिकॉर्ड है? लंगड़ा।
पीट

जवाबों:


105

एक वर्कअराउंड (जब तक Google इस बग को ठीक नहीं करता) एक EditTextसाथ android:inputType="numberDecimal"और का उपयोग करना है android:digits="0123456789.,"

इसके बाद निम्न टेक्स्ट के साथ EditText में एक TextChangedListener जोड़ें

public void afterTextChanged(Editable s) {
    double doubleValue = 0;
    if (s != null) {
        try {
            doubleValue = Double.parseDouble(s.toString().replace(',', '.'));
        } catch (NumberFormatException e) {
            //Error
        }
    }
    //Do something with doubleValue
}

1
अपने कीबोर्ड पर दिखाने के लिए कॉमा (,) के लिए @ ज़ोंबी आपके डिवाइस पर निर्धारित भाषा पर निर्भर करता है। यदि आपके इनपुट में नंबरडेसिमल है और आपकी भाषा अंग्रेजी (संयुक्त राज्य) है, तो यह नेक्सस डिवाइस (संदर्भ) पर दिखाई देगा। यह संभव है कि गैर नेक्सस डिवाइस इसका सम्मान न करें
hcpl

11
यह काम करता है, लेकिन ध्यान रखें कि यह "24,22.55" जैसे पाठ को प्राप्त करने देता है। इसे ठीक करने के लिए आपको कुछ अतिरिक्त सत्यापन जोड़ने की आवश्यकता हो सकती है!
19

8
क्या यह अभी भी जाने का रास्ता है?
विली मेंजेल

इससे भी बेहतर, चार स्थानीयकरण का उपयोग करेंसएपेरेटर = डेसीमलफोर्मसिमबोलसगेटइनस्टेंस ()। getDecimalSeparator (); localizedFloatString = localizedFloatString.replace ('।', localizedSeparator);
सूपरटोन

4
ऐसा लगता है कि यह सिर्फ एक बग को दूसरे के लिए व्यापार कर रहा है। जैसा कि ऊपर लागू किया गया है, यह उन स्थानों के लिए काम करेगा जो इसके बजाय उपयोग करते हैं। रिवर्स की कीमत पर जो दुनिया भर में अधिक आम है। @ सुथर्टन के ट्वीक से मदद मिलती है, हालांकि जब वे हिट करते हैं तो आपके उपयोगकर्ता आश्चर्यचकित हो सकते हैं। और एक है, इनपुट में दिखाई देते हैं।
निक

30

यहां दिए गए 'अंक' समाधान पर एक बदलाव:

char separator = DecimalFormatSymbols.getInstance().getDecimalSeparator();
input.setKeyListener(DigitsKeyListener.getInstance("0123456789" + separator));

स्थानीय विभाजक को ध्यान में रखते हुए।


यह मूल प्रश्न का सबसे स्वच्छ उत्तर है। धन्यवाद
पीटर

इसे ऑनक्रिएट () में रखें, यह जाने का रास्ता है, IMHO।
टेकनिक्विस्ट

6
मुझे यह पसंद है, लेकिन केयरफुल ,रहें ... ऐसे कीबोर्ड हैं जो उपयोगकर्ता के लोकेल की परवाह नहीं करते हैं, इसलिए उपयोगकर्ता के पास उनके कीबोर्ड में कुंजी नहीं है । उदाहरण: सैमसंग कीबोर्ड (किटकैट)।
ब्रिस गाबिन

2
यह डुप्लिकेट दशमलव विभाजकों की अनुमति देगा। इसे संभालने के लिए नीचे उत्तर देखें: stackoverflow.com/a/45384821/6138589
एस्ड्रास लोपेज़

19

EditText के लिए कोड मुद्रा मास्क के बाद ($ 123,125.155)

Xml लेआउट

  <EditText
    android:inputType="numberDecimal"
    android:layout_height="wrap_content"
    android:layout_width="200dp"
    android:digits="0123456789.,$" />

कोड

EditText testFilter=...
testFilter.addTextChangedListener( new TextWatcher() {
        boolean isEdiging;
        @Override public void onTextChanged(CharSequence s, int start, int before, int count) { }
        @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { }

        @Override public void afterTextChanged(Editable s) {
            if(isEdiging) return;
            isEdiging = true;

            String str = s.toString().replaceAll( "[^\\d]", "" );
            double s1 = Double.parseDouble(str);

            NumberFormat nf2 = NumberFormat.getInstance(Locale.ENGLISH);
            ((DecimalFormat)nf2).applyPattern("$ ###,###.###");
            s.replace(0, s.length(), nf2.format(s1));

            isEdiging = false;
        }
    });

16

यह एंड्रॉइड एसडीके में एक ज्ञात बग है। केवल वर्कअराउंड अपने खुद के सॉफ्ट कीबोर्ड बनाना है। आप यहां कार्यान्वयन का एक उदाहरण पा सकते हैं ।


15
क्या चार साल बाद कोई खबर है?
एंटोनियो सेस्टो

Xamarin में इसका अनुभव करते हैं। साथ ही साथ। संस्कृति {se-SV} है और सुन्नत bot को दर्शाती है "," (दशमलव विभाजक) और "।" (हजार समूह विभाजक) लेकिन "दबाने पर", पाठ क्षेत्र में कुछ भी दर्ज नहीं किया जाता है और कोई भी घटना नहीं
उठती है

मैं पुष्टि कर सकता हूं कि बग अभी भी मौजूद है।
लैंसफ्लरे

Android O डेवलपर प्रीव्यू में तय किया गया
R00We

6

अगर आप एडिटटेक्स्ट को प्रोग्रामिक रूप से इंस्टेंट कर रहे हैं तो मार्टिंस का जवाब काम नहीं करेगा। मैं आगे बढ़ा और DigitsKeyListenerएपीआई 14 से शामिल वर्ग को अल्पविराम और अवधि दोनों के लिए दशमलव विभाजक के रूप में संशोधित किया ।

इसका उपयोग करने के लिए, setKeyListener()पर कॉल करें EditText, जैसे

// Don't allow for signed input (minus), but allow for decimal points
editText.setKeyListener( new MyDigitsKeyListener( false, true ) );

हालाँकि, आपको अभी भी मार्टिन चाल का उपयोग करना है TextChangedListenerजहाँ आप पीरियड्स के साथ कॉमा की जगह लेते हैं

import android.text.InputType;
import android.text.SpannableStringBuilder;
import android.text.Spanned;
import android.text.method.NumberKeyListener;
import android.view.KeyEvent;

class MyDigitsKeyListener extends NumberKeyListener {

    /**
     * The characters that are used.
     *
     * @see KeyEvent#getMatch
     * @see #getAcceptedChars
     */
    private static final char[][] CHARACTERS = new char[][] {
        new char[] { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' },
        new char[] { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '-' },
        new char[] { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '.', ',' },
        new char[] { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '-', '.', ',' },
    };

    private char[] mAccepted;
    private boolean mSign;
    private boolean mDecimal;

    private static final int SIGN = 1;
    private static final int DECIMAL = 2;

    private static MyDigitsKeyListener[] sInstance = new MyDigitsKeyListener[4];

    @Override
    protected char[] getAcceptedChars() {
        return mAccepted;
    }

    /**
     * Allocates a DigitsKeyListener that accepts the digits 0 through 9.
     */
    public MyDigitsKeyListener() {
        this(false, false);
    }

    /**
     * Allocates a DigitsKeyListener that accepts the digits 0 through 9,
     * plus the minus sign (only at the beginning) and/or decimal point
     * (only one per field) if specified.
     */
    public MyDigitsKeyListener(boolean sign, boolean decimal) {
        mSign = sign;
        mDecimal = decimal;

        int kind = (sign ? SIGN : 0) | (decimal ? DECIMAL : 0);
        mAccepted = CHARACTERS[kind];
    }

    /**
     * Returns a DigitsKeyListener that accepts the digits 0 through 9.
     */
    public static MyDigitsKeyListener getInstance() {
        return getInstance(false, false);
    }

    /**
     * Returns a DigitsKeyListener that accepts the digits 0 through 9,
     * plus the minus sign (only at the beginning) and/or decimal point
     * (only one per field) if specified.
     */
    public static MyDigitsKeyListener getInstance(boolean sign, boolean decimal) {
        int kind = (sign ? SIGN : 0) | (decimal ? DECIMAL : 0);

        if (sInstance[kind] != null)
            return sInstance[kind];

        sInstance[kind] = new MyDigitsKeyListener(sign, decimal);
        return sInstance[kind];
    }

    /**
     * Returns a DigitsKeyListener that accepts only the characters
     * that appear in the specified String.  Note that not all characters
     * may be available on every keyboard.
     */
    public static MyDigitsKeyListener getInstance(String accepted) {
        // TODO: do we need a cache of these to avoid allocating?

        MyDigitsKeyListener dim = new MyDigitsKeyListener();

        dim.mAccepted = new char[accepted.length()];
        accepted.getChars(0, accepted.length(), dim.mAccepted, 0);

        return dim;
    }

    public int getInputType() {
        int contentType = InputType.TYPE_CLASS_NUMBER;
        if (mSign) {
            contentType |= InputType.TYPE_NUMBER_FLAG_SIGNED;
        }
        if (mDecimal) {
            contentType |= InputType.TYPE_NUMBER_FLAG_DECIMAL;
        }
        return contentType;
    }

    @Override
    public CharSequence filter(CharSequence source, int start, int end,
                               Spanned dest, int dstart, int dend) {
        CharSequence out = super.filter(source, start, end, dest, dstart, dend);

        if (mSign == false && mDecimal == false) {
            return out;
        }

        if (out != null) {
            source = out;
            start = 0;
            end = out.length();
        }

        int sign = -1;
        int decimal = -1;
        int dlen = dest.length();

        /*
         * Find out if the existing text has '-' or '.' characters.
         */

        for (int i = 0; i < dstart; i++) {
            char c = dest.charAt(i);

            if (c == '-') {
                sign = i;
            } else if (c == '.' || c == ',') {
                decimal = i;
            }
        }
        for (int i = dend; i < dlen; i++) {
            char c = dest.charAt(i);

            if (c == '-') {
                return "";    // Nothing can be inserted in front of a '-'.
            } else if (c == '.' ||  c == ',') {
                decimal = i;
            }
        }

        /*
         * If it does, we must strip them out from the source.
         * In addition, '-' must be the very first character,
         * and nothing can be inserted before an existing '-'.
         * Go in reverse order so the offsets are stable.
         */

        SpannableStringBuilder stripped = null;

        for (int i = end - 1; i >= start; i--) {
            char c = source.charAt(i);
            boolean strip = false;

            if (c == '-') {
                if (i != start || dstart != 0) {
                    strip = true;
                } else if (sign >= 0) {
                    strip = true;
                } else {
                    sign = i;
                }
            } else if (c == '.' || c == ',') {
                if (decimal >= 0) {
                    strip = true;
                } else {
                    decimal = i;
                }
            }

            if (strip) {
                if (end == start + 1) {
                    return "";  // Only one character, and it was stripped.
                }

                if (stripped == null) {
                    stripped = new SpannableStringBuilder(source, start, end);
                }

                stripped.delete(i - start, i + 1 - start);
            }
        }

        if (stripped != null) {
            return stripped;
        } else if (out != null) {
            return out;
        } else {
            return null;
        }
    }
}

doc से: KeyListener का उपयोग केवल उन मामलों के लिए किया जाना चाहिए, जहां किसी एप्लिकेशन का अपना ऑन-स्क्रीन कीपैड होता है और इसे मिलान करने के लिए हार्ड कीबोर्ड ईवेंट को संसाधित करना चाहता है। डेवलपर
.android.com

6

आप विभिन्न स्थानों के लिए निम्नलिखित का उपयोग कर सकते हैं

private void localeDecimalInput(final EditText editText){

    DecimalFormat decFormat = (DecimalFormat) DecimalFormat.getInstance(Locale.getDefault());
    DecimalFormatSymbols symbols=decFormat.getDecimalFormatSymbols();
    final String defaultSeperator=Character.toString(symbols.getDecimalSeparator());

    editText.addTextChangedListener(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 editable) {
            if(editable.toString().contains(defaultSeperator))
                editText.setKeyListener(DigitsKeyListener.getInstance("0123456789"));
            else
                editText.setKeyListener(DigitsKeyListener.getInstance("0123456789" + defaultSeperator));
        }
    });
}

यह मेरे लिए सबसे अच्छा समाधान है, लेकिन कुछ फोन, जैसे सैमसंग के साथ समस्या है, जो कीबोर्ड में "," कोमा नहीं दिखा रहे हैं। इसलिए मैंने इसे कोमा और डॉट दोनों की अनुमति देने के लिए बदल दिया, लेकिन फिर लोकेल के अनुसार जगह ले ली
Riccardo Casatta

5

आप निम्न इनपुट का उपयोग करके मान्य इनपुट के रूप में अल्पविराम को भी शामिल कर सकते हैं: -

XML के माध्यम से:

<EditText
    android:inputType="number"
    android:digits="0123456789.," />

प्रोग्राम के रूप में:

EditText input = new EditText(THE_CONTEXT);
input.setKeyListener(DigitsKeyListener.getInstance("0123456789.,"));

इस तरह एंड्रॉइड सिस्टम नंबर के कीबोर्ड को दिखाएगा और कॉमा के इनपुट की अनुमति देगा। उम्मीद है कि इस सवाल का जवाब :)


इस समाधान के साथ जब आप ",", लेकिन संपादित पाठ शो "" पर टैप करते हैं।
मारा जिमेनेज़

2

मोनो (Droid) समाधानों के लिए:

decimal decimalValue = decimal.Parse(input.Text.Replace(",", ".") , CultureInfo.InvariantCulture);

1

आप निम्नलिखित कर सकते हैं:

DecimalFormatSymbols d = DecimalFormatSymbols.getInstance(Locale.getDefault());
input.setFilters(new InputFilter[] { new DecimalDigitsInputFilter(5, 2) });
input.setKeyListener(DigitsKeyListener.getInstance("0123456789" + d.getDecimalSeparator()));

और फिर आप एक इनपुट फ़िल्टर का उपयोग कर सकते हैं:

    public class DecimalDigitsInputFilter implements InputFilter {

Pattern mPattern;

public DecimalDigitsInputFilter(int digitsBeforeZero, int digitsAfterZero) {
    DecimalFormatSymbols d = new DecimalFormatSymbols(Locale.getDefault());
    String s = "\\" + d.getDecimalSeparator();
    mPattern = Pattern.compile("[0-9]{0," + (digitsBeforeZero - 1) + "}+((" + s + "[0-9]{0," + (digitsAfterZero - 1) + "})?)||(" + s + ")?");
}

@Override
public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {

    Matcher matcher = mPattern.matcher(dest);
    if (!matcher.matches())
        return "";
    return null;
}

}


हजार और सौ के बीच एक स्थान हो सकता है, यह पैटर्न स्वरूपित इनपुट को मना कर देगा
एरिक झाओ

1

IMHO इस समस्या के लिए सबसे अच्छा तरीका सिर्फ इनपुटफिल्टर का उपयोग करना है। एक अच्छी बात यहाँ DecimalDigitsInputFilter है । तो आप बस कर सकते हैं:

editText.setInputType(TYPE_NUMBER_FLAG_DECIMAL | TYPE_NUMBER_FLAG_SIGNED | TYPE_CLASS_NUMBER)
editText.setKeyListener(DigitsKeyListener.getInstance("0123456789,.-"))
editText.setFilters(new InputFilter[] {new DecimalDigitsInputFilter(5,2)});

यह एक आकर्षण की तरह काम किया है, धन्यवाद! (ऊपर इतने सारे गलत समाधान के बाद ... :() लेकिन मेरा एक सवाल है: मैं उस कॉमा को कैसे प्राप्त कर सकता हूं (",") स्क्रीन पर प्रदर्शित नहीं डॉट डॉट ("।") क्योंकि हंगरी में हम दशमलव विभाजक के रूप में कॉमा का उपयोग कर रहे हैं। ।
अबीगैल ल’फय

1
Android: अंक = "0123456789," सेटिंग को EditText में जोड़ा जा सकता है। इसके अलावा, DecimalDigitsInputFilter में अशक्त लौटने के बजाय, आप उत्तर stackoverflow.com/a/40020731/1510222 के अनुसार source.replace ("।", ",") वापस कर सकते हैं। एक मानक कीबोर्ड में डॉट को छिपाने का कोई तरीका नहीं है
अर्काडियस सेइलीस्की

1

अपने इनपुट उपयोग को स्थानीय बनाने के लिए:

char sep = DecimalFormatSymbols.getInstance().getDecimalSeparator();

और फिर जोड़ें:

textEdit.setKeyListener(DigitsKeyListener.getInstance("0123456789" + sep));

"," के साथ "को बदलना न भूलें।" इसलिए फ्लोट या डबल इसे त्रुटियों के बिना पार्स कर सकते हैं।


1
यह समाधान कई कॉमा में प्रवेश करने देता है
लियो डायरोडोडर

1

यहां अन्य सभी पदों में प्रमुख छेद थे, इसलिए यहां एक समाधान है:

  • क्षेत्र के आधार पर अल्पविराम या अवधि लागू करें, आपको इसके विपरीत टाइप नहीं करने देगा।
  • यदि EditText कुछ मान से शुरू होता है, तो यह सही विभाजक को आवश्यकतानुसार बदल देता है।

XML में:

<EditText
    ...
    android:inputType="numberDecimal" 
    ... />

वर्ग चर:

private boolean isDecimalSeparatorComma = false;

ऑनक्रिएट में, वर्तमान लोकेल में उपयोग किए गए विभाजक को खोजें:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
    NumberFormat nf = NumberFormat.getInstance();
    if (nf instanceof DecimalFormat) {
        DecimalFormatSymbols sym = ((DecimalFormat) nf).getDecimalFormatSymbols();
        char decSeparator = sym.getDecimalSeparator();
        isDecimalSeparatorComma = Character.toString(decSeparator).equals(",");
    }
}

इसके अलावा onCreate, यदि आप वर्तमान मूल्य में लोड कर रहे हैं तो इसे अपडेट करने के लिए इसका उपयोग करें:

// Replace editText with commas or periods as needed for viewing
String editTextValue = getEditTextValue(); // load your current value
if (editTextValue.contains(".") && isDecimalSeparatorComma) {
    editTextValue = editTextValue.replaceAll("\\.",",");
} else if (editTextValue.contains(",") && !isDecimalSeparatorComma) {
    editTextValue = editTextValue.replaceAll(",",".");
}
setEditTextValue(editTextValue); // override your current value

इसके अलावा, श्रोताओं को जोड़ें

editText.addTextChangedListener(editTextWatcher);

if (isDecimalSeparatorComma) {
    editText.setKeyListener(DigitsKeyListener.getInstance("0123456789,"));
} else {
    editText.setKeyListener(DigitsKeyListener.getInstance("0123456789."));
}

editTextWatcher

TextWatcher editTextWatcher = 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) {
        String editTextValue = s.toString();

        // Count up the number of commas and periods
        Pattern pattern = Pattern.compile("[,.]");
        Matcher matcher = pattern.matcher(editTextValue);
        int count = 0;
        while (matcher.find()) {
            count++;
        }

        // Don't let it put more than one comma or period
        if (count > 1) {
            s.delete(s.length()-1, s.length());
        } else {
            // If there is a comma or period at the end the value hasn't changed so don't update
            if (!editTextValue.endsWith(",") && !editTextValue.endsWith(".")) {
                doSomething()
            }
        }
    }
};

doSomething () उदाहरण, डेटा हेरफेर के लिए मानक अवधि में परिवर्तित

private void doSomething() {
    try {
        String editTextStr = editText.getText().toString();
        if (isDecimalSeparatorComma) {
            editTextStr = editTextStr.replaceAll(",",".");
        }
        float editTextFloatValue = editTextStr.isEmpty() ?
                0.0f :
                Float.valueOf(editTextStr);

        ... use editTextFloatValue
    } catch (NumberFormatException e) {
        Log.e(TAG, "Error converting String to Double");
    }
}

0

एंड्रॉइड में बिल्ट इन नंबर फॉर्मेटर होता है।

EditTextदशमलव और अल्पविराम की अनुमति देने के लिए आप इसे जोड़ सकते हैं : android:inputType="numberDecimal"औरandroid:digits="0123456789.,"

तब कहीं आपके कोड में, या तो जब उपयोगकर्ता क्लिक करता है तो सहेजने के बाद या पाठ दर्ज करने के बाद (एक श्रोता का उपयोग करें)।

// Format the number to the appropriate double
try { 
    Number formatted = NumberFormat.getInstance().parse(editText.getText().toString());
    cost = formatted.doubleValue();
} catch (ParseException e) {
    System.out.println("Error parsing cost string " + editText.getText().toString());
    cost = 0.0;
}

0

मैंने एडिटिंग के दौरान ही कॉमा को डॉट में बदलने का फैसला किया। यहाँ मेरा मुश्किल और सापेक्ष सरल समाधान है:

    editText.setOnFocusChangeListener(new View.OnFocusChangeListener() {
        @Override
        public void onFocusChange(View v, boolean hasFocus) {
            EditText editText = (EditText) v; 
            String text = editText.getText().toString();
            if (hasFocus) {
                editText.setText(text.replace(",", "."));
            } else {
                if (!text.isEmpty()) {
                    Double doubleValue = Double.valueOf(text.replace(",", "."));
                    editText.setText(someDecimalFormatter.format(doubleValue));
                }
            }
        }
    });

someDecimalFormatter कॉमा का उपयोग करेगा या डॉट लोकेल पर निर्भर करता है


0

मुझे नहीं पता कि आपके उत्तर इतने जटिल क्यों हैं। यदि SDK में कोई बग है तो आपको इसे ओवरराइड करना चाहिए या चारों ओर जाना चाहिए।

मैंने उस समस्या को हल करने के लिए दूसरा रास्ता चुना है। यदि आप अपनी स्ट्रिंग को प्रारूपित करते हैं Locale.ENGLISHऔर फिर इसे EditText(यहां तक ​​कि एक रिक्त स्ट्रिंग के रूप में भी) डालते हैं । उदाहरण:

String.format(Locale.ENGLISH,"%.6f", yourFloatNumber);

उस समाधान का पीछा करते हुए आपका परिणाम दिखाए गए कीबोर्ड के साथ संगत है। फिर फ्लोट और डबल नंबर, कॉमा के बजाय डॉट के साथ प्रोग्रामिंग भाषाओं के लिए विशिष्ट रूप से काम करते हैं।


0

मेरा समाधान है:

  • मुख्य गतिविधि में:

    char separator =DecimalFormatSymbols.getInstance().getDecimalSeparator(); textViewPitchDeadZone.setKeyListener(DigitsKeyListener.getInstance("0123456789" + separator));

  • Xml फ़ाइल में: android:imeOptions="flagNoFullscreen" android:inputType="numberDecimal"

और मैंने एक स्ट्रिंग के रूप में EditText में डबल लिया।


0

मैं यह पुष्टि कर सकता हूं कि प्रस्तावित सुधार सैमसंग IME (कम से कम S6 और S9 पर) और शायद एलजी पर काम नहीं करते हैं। वे अभी भी लोकेल की परवाह किए बिना दशमलव विभाजक के रूप में एक डॉट दिखाते हैं। Google के IME पर स्विच करना इसे ठीक करता है लेकिन अधिकांश डेवलपर्स के लिए शायद ही कोई विकल्प हो।

यह इन कीबोर्ड के लिए ओरियो में भी तय नहीं किया गया है क्योंकि यह एक फिक्स है जो सैमसंग और / या एलजी को करना है और फिर अपने प्राचीन हैंडसेट तक भी धकेलना है।

मैंने इसके बजाय नंबर-कीबोर्ड प्रोजेक्ट को कांटा और एक मोड जोड़ा जहां यह IME: फोर्क की तरह व्यवहार करता है । विवरण के लिए परियोजना का नमूना देखें। इसने मेरे लिए काफी अच्छा काम किया है और यह उन कई "पिन एंट्री" नकली आईएमई के समान है जो आप बैंकिंग ऐप्स में देखते हैं।

नमूना एप्लिकेशन स्क्रीनशॉट


0

यह 8 साल से अधिक समय बीत चुका है और मुझे आश्चर्य है, यह मुद्दा अभी तक तय नहीं हुआ है ...
मैं इस सरल मुद्दे से जूझ रहा हूं क्योंकि @ मार्टिन द्वारा सबसे अधिक उत्तर दिए गए उत्तर से कई विभाजकों को टाइप करने की सुविधा मिलती है, अर्थात उपयोगकर्ता "12 ,,," टाइप कर सकता है। ,,, 12,1, 21,2, "
इसके अलावा, दूसरी चिंता यह है कि कुछ उपकरणों पर संख्यात्मक कीबोर्ड पर अल्पविराम नहीं दिखाया गया है (या एक डॉट बटन के कई दबाव की आवश्यकता है)

यहाँ मेरा समाधान समाधान है, जो उल्लिखित समस्याओं को हल करता है और उपयोगकर्ता को टाइप करने देता है '।' और ',', लेकिन EditText में वह एकमात्र दशमलव विभाजक देखेंगे जो वर्तमान स्थान से मेल खाता है:

editText.apply { addTextChangedListener(DoubleTextChangedListener(this)) }

और पाठ देखने वाला:

  open class DoubleTextChangedListener(private val et: EditText) : TextWatcher {

    init {
        et.inputType = InputType.TYPE_CLASS_NUMBER or InputType.TYPE_NUMBER_FLAG_DECIMAL
        et.keyListener = DigitsKeyListener.getInstance("0123456789.,")
    }

    private val separator = DecimalFormatSymbols.getInstance().decimalSeparator

    override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
        //empty
    }

    @CallSuper
    override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {
        et.run {
            removeTextChangedListener(this@DoubleTextChangedListener)
            val formatted = toLocalizedDecimal(s.toString(), separator)
            setText(formatted)
            setSelection(formatted.length)
            addTextChangedListener(this@DoubleTextChangedListener)
        }
    }

    override fun afterTextChanged(s: Editable?) {
        // empty
    }

    /**
     * Formats input to a decimal. Leaves the only separator (or none), which matches [separator].
     * Examples:
     * 1. [s]="12.12", [separator]=',' -> result= "12,12"
     * 2. [s]="12.12", [separator]='.' -> result= "12.12"
     * 4. [s]="12,12", [separator]='.' -> result= "12.12"
     * 5. [s]="12,12,,..,,,,,34..,", [separator]=',' -> result= "12,1234"
     * 6. [s]="12.12,,..,,,,,34..,", [separator]='.' -> result= "12.1234"
     * 7. [s]="5" -> result= "5"
     */
    private fun toLocalizedDecimal(s: String, separator: Char): String {
        val cleared = s.replace(",", ".")
        val splitted = cleared.split('.').filter { it.isNotBlank() }
        return when (splitted.size) {
            0 -> s
            1 -> cleared.replace('.', separator).replaceAfter(separator, "")
            2 -> splitted.joinToString(separator.toString())
            else -> splitted[0]
                    .plus(separator)
                    .plus(splitted.subList(1, splitted.size - 1).joinToString(""))
        }
    }
}

0

सरल समाधान, एक कस्टम नियंत्रण करें। (यह Xamarin Android में बनाया गया है लेकिन जावा को आसानी से पोर्ट करना चाहिए)

public class EditTextDecimalNumber:EditText
{
    readonly string _numberFormatDecimalSeparator;

    public EditTextDecimalNumber(Context context, IAttributeSet attrs) : base(context, attrs)
    {
        InputType = InputTypes.NumberFlagDecimal;
        TextChanged += EditTextDecimalNumber_TextChanged;
        _numberFormatDecimalSeparator = System.Threading.Thread.CurrentThread.CurrentUICulture.NumberFormat.NumberDecimalSeparator;

        KeyListener = DigitsKeyListener.GetInstance($"0123456789{_numberFormatDecimalSeparator}");
    }

    private void EditTextDecimalNumber_TextChanged(object sender, TextChangedEventArgs e)
    {
        int noOfOccurence = this.Text.Count(x => x.ToString() == _numberFormatDecimalSeparator);
        if (noOfOccurence >=2)
        {
            int lastIndexOf = this.Text.LastIndexOf(_numberFormatDecimalSeparator,StringComparison.CurrentCulture);
            if (lastIndexOf!=-1)
            {
                this.Text = this.Text.Substring(0, lastIndexOf);
                this.SetSelection(this.Text.Length);
            }

        }
    }
}

0

आप उपयोग कर सकते हैं inputType="phone", हालांकि उस स्थिति में आपको कई ,या .वर्तमान में काम करना होगा, इसलिए अतिरिक्त सत्यापन आवश्यक होगा।


-1

मुझे लगता है कि यह समाधान यहां लिखे गए अन्य की तुलना में कम जटिल है:

<EditText
    android:inputType="numberDecimal"
    android:digits="0123456789," />

इस तरह जब आप 'दबाते हैं।' सॉफ्ट कीबोर्ड में कुछ नहीं होता है; केवल संख्या और अल्पविराम की अनुमति है।


4
यदि आप ऐसा करते हैं तो आप बस उन सभी स्थानों को तोड़ देंगे जो उपयोग करते हैं। '' बजाय।
निक
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.