Android EditText में दशमलव स्थान सीमित करें


125

मैं एक ऐसा ऐप लिखने की कोशिश कर रहा हूं, जो आपके वित्त को प्रबंधित करने में आपकी मदद करे। मैं एक EditTextफ़ील्ड का उपयोग कर रहा हूँ जहाँ उपयोगकर्ता धन की मात्रा निर्दिष्ट कर सकता है।

मैं सेट inputTypeकरने के लिए numberDecimalजो ठीक काम करता है, सिवाय इसके कि यह लोगों को संख्या के रूप में दर्ज करने के लिए अनुमति देता है 123.122जो पैसे के लिए सही नहीं है।

क्या दशमलव बिंदु दो के बाद वर्णों की संख्या को सीमित करने का एक तरीका है?


जब आप फोकस खोते हैं तो आप एक नियमित अभिव्यक्ति लिख सकते हैं और संपादन पाठ की सामग्री को सत्यापित कर सकते हैं।
अंधी

मुझे InputFilterइंटरफ़ेस मिला , ऐसा लगता है कि मैं क्या चाहता हूं। डेवलपरfilter ।android.com/reference/android/text/ method/…, लेकिन जिस विधि को मुझे लागू करना है वह मेरे लिए भ्रामक है। क्या किसी ने पहले से ही इस तरह के फ़िल्टर को लिखा है और इसका उपयोग करना जानता है?
कॉन्स्टेंटिन वीज़

आरटीएल स्थानों के लिए सुझाए गए समाधानों में से कोई भी काम करते हैं? जहाँ तक मैं बता सकता हूँ वे नहीं ...
निक

जवाबों:


118

अधिक सुरुचिपूर्ण तरीके से एक नियमित अभिव्यक्ति (रेगेक्स) का उपयोग किया जाएगा:

public class DecimalDigitsInputFilter implements InputFilter {

Pattern mPattern;

public DecimalDigitsInputFilter(int digitsBeforeZero,int digitsAfterZero) {
    mPattern=Pattern.compile("[0-9]{0," + (digitsBeforeZero-1) + "}+((\\.[0-9]{0," + (digitsAfterZero-1) + "})?)||(\\.)?");
}

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

}

इसका उपयोग करने के लिए:

editText.setFilters(new InputFilter[] {new DecimalDigitsInputFilter(5,2)});

32
नमस्ते, कुछ किनारे मामले अभी भी अच्छी तरह से संभाले नहीं जा रहे हैं। उदाहरण के लिए, 2.45 टाइप करने के बाद, मैं "कर्सर को टेक्स्ट के सबसे सामने ले जाता हूं"। मैं पाठ का उत्पादन करने की इच्छा 12.45, यह अनुमति नहीं देगा।
चोक यान चेंग सेप

3
यह दशमलव के बाद 2 अंकों में प्रवेश करने के बाद दशमलव से पहले अंकों को बदलने की अनुमति नहीं देता है।
गौरव सिंगला

9
महान समाधान लेकिन यह पूरी तरह से सही नहीं है। मिलानकर्ता को भाग्य की जांच नहीं करनी चाहिए, उसे edittext (dest.subSequence (0, dstart) + source.subSequence (प्रारंभ, अंत) + dest.subSequence (dend, dest.length ()))
Mihaela Romanca

7
मिहाएला सही है, हमें उस स्ट्रिंग के खिलाफ मिलान होना चाहिए जो एडिटेक्स को भरने की कोशिश कर रहा है। मैंने पाया कि इस तरह के एक अन्य प्रश्न पर कैसे समरूपता मिलान किया जा सकता है = TextUtils.concat (dest.subSequence (0, dstart), source.subSequence (start, end), dest .subSequence (dend, dest.length ()))। रेगेक्स बाद में समस्याएं पैदा कर रहा था, हालांकि मैंने इसे "^ \\ d {1," + digitsBeforeZero + "} (\\। \\ d {0," + digitsAfterZero + "}) $" लेकिन तुम 'में बदल दिया? बाद में सत्यापन करना होगा क्योंकि "1." उस रेगेक्स के साथ मान्य है, लेकिन हमें इसकी आवश्यकता है ताकि अवधि टाइप की जा सके।
dt0

6
अल्पविराम (,) के लिए भी आप यह काम कैसे करेंगे? दुनिया के कुछ क्षेत्र कॉमा के साथ दशमलव संख्या टाइप करते हैं (उदा: 123,45)।
एंड्रयू

65

रेगेक्स का उपयोग किए बिना सरल समाधान:

import android.text.InputFilter;
import android.text.Spanned;

/**
 * Input filter that limits the number of decimal digits that are allowed to be
 * entered.
 */
public class DecimalDigitsInputFilter implements InputFilter {

  private final int decimalDigits;

  /**
   * Constructor.
   * 
   * @param decimalDigits maximum decimal digits
   */
  public DecimalDigitsInputFilter(int decimalDigits) {
    this.decimalDigits = decimalDigits;
  }

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


    int dotPos = -1;
    int len = dest.length();
    for (int i = 0; i < len; i++) {
      char c = dest.charAt(i);
      if (c == '.' || c == ',') {
        dotPos = i;
        break;
      }
    }
    if (dotPos >= 0) {

      // protects against many dots
      if (source.equals(".") || source.equals(","))
      {
          return "";
      }
      // if the text is entered before the dot
      if (dend <= dotPos) {
        return null;
      }
      if (len - dotPos > decimalDigits) {
        return "";
      }
    }

    return null;
  }

}

काम में लाना:

editText.setFilters(new InputFilter[] {new DecimalDigitsInputFilter(2)});

मुझे गैर-संख्यात्मक वर्ण स्ट्रिंग जैसे 'a' में डालने से क्या रोक सकता है?
कोन्स्टेंटिन वीट्ज

4
यह: <EditText ... android: inputType = "नंबर" />
11

1
यह होना चाहिए: editText.setFilters (नया इनपुटफिल्टर [] {नया DecimalDigitsInputFilter (2)});
frak

6
यह उस मामले को नहीं संभालता है जहां मैं "999" टाइप करता हूं और फिर पहले 9 के बाद एक दशमलव बिंदु सम्मिलित करता
हूं

1
इस उपयोगी धन्यवाद। हम इस तरह से लंबाई फिल्टर का उपयोग करके दशमलव बिंदु से पहले अंकों को भी सीमित कर सकते हैं। Kotlin: edtAnyAmount.filters = arrayOf <InputFilter> (InputFilter.LengthFilter (7), DecimalDigitsInputFilter (2))
Faldu Jaldeep

37

यह InputFilterसमस्या के समाधान को कार्यान्वित करता है।

import android.text.SpannableStringBuilder;
import android.text.Spanned;
import android.text.method.DigitsKeyListener;

public class MoneyValueFilter extends DigitsKeyListener {
    public MoneyValueFilter() {
        super(false, true);
    }

    private int digits = 2;

    public void setDigits(int d) {
        digits = d;
    }

    @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 changed, replace the source
        if (out != null) {
            source = out;
            start = 0;
            end = out.length();
        }

        int len = end - start;

        // if deleting, source is empty
        // and deleting can't break anything
        if (len == 0) {
            return source;
        }

        int dlen = dest.length();

        // Find the position of the decimal .
        for (int i = 0; i < dstart; i++) {
            if (dest.charAt(i) == '.') {
                // being here means, that a number has
                // been inserted after the dot
                // check if the amount of digits is right
                return (dlen-(i+1) + len > digits) ? 
                    "" :
                    new SpannableStringBuilder(source, start, end);
            }
        }

        for (int i = start; i < end; ++i) {
            if (source.charAt(i) == '.') {
                // being here means, dot has been inserted
                // check if the amount of digits is right
                if ((dlen-dend) + (end-(i + 1)) > digits)
                    return "";
                else
                    break;  // return new SpannableStringBuilder(source, start, end);
            }
        }

        // if the dot is after the inserted part,
        // nothing can break
        return new SpannableStringBuilder(source, start, end);
    }
}

क्या मुझे पता है कि कोई कारण है कि हमें अशक्त के बजाय SpannableStringBuilder को वापस करने की आवश्यकता है? मैं इसे अशक्त के साथ परीक्षण करता हूं, यह अच्छी तरह से भी काम करता है। इसके अलावा, क्या हमारे लिए डिजिट्सकेलिस्टनर से विरासत की कोई आवश्यकता है? Android का उपयोग करते हुए: inputType = "numberDecimal" सभी "0123456789" प्रदर्शन करेगा। अक्षर प्रवर्तन।
चोक यान चेंग सेप

1
ठीक काम करता है। आपका बहुत बहुत धन्यवाद।
आंद्रेई औलास्का

34

यहाँ एक नमूना InputFilter है जो केवल दशमलव बिंदु से पहले अधिकतम 4 अंक और उसके बाद अधिकतम 1 अंक की अनुमति देता है।

मान जो संपादन की अनुमति देता है: 555.2 , 555 , .2

मान जो संपादित करते हैं ब्लॉक: 55555.2 , 055.2 , 555.42

        InputFilter filter = new InputFilter() {
        final int maxDigitsBeforeDecimalPoint=4;
        final int maxDigitsAfterDecimalPoint=1;

        @Override
        public CharSequence filter(CharSequence source, int start, int end,
                Spanned dest, int dstart, int dend) {
                StringBuilder builder = new StringBuilder(dest);
                builder.replace(dstart, dend, source
                        .subSequence(start, end).toString());
                if (!builder.toString().matches(
                        "(([1-9]{1})([0-9]{0,"+(maxDigitsBeforeDecimalPoint-1)+"})?)?(\\.[0-9]{0,"+maxDigitsAfterDecimalPoint+"})?"

                        )) {
                    if(source.length()==0)
                        return dest.subSequence(dstart, dend);
                    return "";
                }

            return null;

        }
    };

    mEdittext.setFilters(new InputFilter[] { filter });

नहीं होने देता। टाइप करने के लिए
AmiNadimi

22

मैंने @Pinhassi समाधान के लिए कुछ सुधार किए हैं। यह कुछ मामलों को संभालता है:

1.आप कहीं भी कर्सर ले जा सकते हैं

2.मिनस साइन हैंडलिंग

3.digitsbefore = 2 और digitsafter = 4 और आप 12.4545 दर्ज करें। फिर यदि आप "" को हटाना चाहते हैं, तो यह अनुमति नहीं देगा।

public class DecimalDigitsInputFilter implements InputFilter {
    private int mDigitsBeforeZero;
    private int mDigitsAfterZero;
    private Pattern mPattern;

    private static final int DIGITS_BEFORE_ZERO_DEFAULT = 100;
    private static final int DIGITS_AFTER_ZERO_DEFAULT = 100;

    public DecimalDigitsInputFilter(Integer digitsBeforeZero, Integer digitsAfterZero) {
    this.mDigitsBeforeZero = (digitsBeforeZero != null ? digitsBeforeZero : DIGITS_BEFORE_ZERO_DEFAULT);
    this.mDigitsAfterZero = (digitsAfterZero != null ? digitsAfterZero : DIGITS_AFTER_ZERO_DEFAULT);
    mPattern = Pattern.compile("-?[0-9]{0," + (mDigitsBeforeZero) + "}+((\\.[0-9]{0," + (mDigitsAfterZero)
        + "})?)||(\\.)?");
    }

    @Override
    public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
    String replacement = source.subSequence(start, end).toString();
    String newVal = dest.subSequence(0, dstart).toString() + replacement
        + dest.subSequence(dend, dest.length()).toString();
    Matcher matcher = mPattern.matcher(newVal);
    if (matcher.matches())
        return null;

    if (TextUtils.isEmpty(source))
        return dest.subSequence(dstart, dend);
    else
        return "";
    }
}

मुझे लगता है कि यह सही समाधान होना चाहिए, मेरा दिन बना। धन्यवाद।
प्रतीक बुटानी ३१'१६ को ik

1
@ ओंकार यह गलत है। यह स्थिति हमेशा सच होगी भले ही लंबाई> 0, dest.length () == 0 हमेशा सच हो, भले ही आप संपूर्ण पाठ को 0 से अधिक
संपादित करें

@ ओंकार आपकी टिप्पणी को दूर करें pls
user924

@android_dev मैं नकारात्मक मान (ऋण) क्यों नहीं लिख सकता?
user924

यदि आप सेट करते हैं android:inputType="number"या android:inputType="numberDecimal"यह माइनस टाइप करने की अनुमति नहीं देगा, तो यह android:digits="0123456789.-"मदद नहीं करता
user924

18

मुझे दूसरा समाधान पसंद नहीं है और मैंने अपना खुद का बनाया है। इस समाधान के साथ आप बिंदु से पहले MAX_BEFORE_POINT से अधिक अंक दर्ज नहीं कर सकते हैं और दशमलव MAX_DECIMAL से अधिक नहीं हो सकते।

आप अधिक मात्रा में अंक टाइप नहीं कर सकते, कोई अन्य प्रभाव नहीं! अतिरिक्त में अगर आप लिखते हैं "।" यह "0." प्रकार का है

  1. EditText को लेआउट में सेट करें:

    एंड्रॉयड: inputType = "numberDecimal"

  2. अपने onCreate में श्रोता को शामिल करें। यदि आप बिंदु से पहले और बाद में अंकों की संख्या को PerfectDecimal को संपादित करना चाहते हैं (str, NUMBER_BEFORE_POINT, NUMBER_DECIMALS), यहां 3 और 2 पर सेट है

    EditText targetEditText = (EditText)findViewById(R.id.targetEditTextLayoutId);
    
    targetEditText.addTextChangedListener(new TextWatcher() {
      public void onTextChanged(CharSequence arg0, int arg1, int arg2, int arg3) {}
    
      public void beforeTextChanged(CharSequence arg0, int arg1, int arg2, int arg3) {}
    
      public void afterTextChanged(Editable arg0) {
        String str = targetEditText.getText().toString();
        if (str.isEmpty()) return;
        String str2 = PerfectDecimal(str, 3, 2);
    
        if (!str2.equals(str)) {
            targetEditText.setText(str2);
            int pos = targetEditText.getText().length();
            targetEditText.setSelection(pos);
        }
      }
    });
  3. इस फनकोन को शामिल करें:

    public String PerfectDecimal(String str, int MAX_BEFORE_POINT, int MAX_DECIMAL){
      if(str.charAt(0) == '.') str = "0"+str;
      int max = str.length();
    
      String rFinal = "";
      boolean after = false;
      int i = 0, up = 0, decimal = 0; char t;
      while(i < max){
        t = str.charAt(i);
        if(t != '.' && after == false){
            up++;
            if(up > MAX_BEFORE_POINT) return rFinal;
        }else if(t == '.'){
            after = true;
        }else{
            decimal++;
            if(decimal > MAX_DECIMAL)
                return rFinal;
        }
        rFinal = rFinal + t;
        i++;
      }return rFinal;
    }

और हो गया!


1
चीयर्स। बहुत अच्छी तरह से काम करें जब दूसरे ने मेरे लिए काम नहीं किया
भालू

1
यह स्वीकृत उत्तर होना चाहिए .. यह सही है .. सभी शर्तें यहाँ संतुष्ट हैं।
नयन

1
सभी अत्यधिक मतदान के जवाबों में, इस जवाब ने वास्तव में मेरे लिए काम किया है।
रोहित मंडीवाल

बहुत बढ़िया! मैंने सभी संयोजनों की कोशिश की और ऐसा लगता है कि यह बहुत अच्छा काम करता है। धन्यवाद।
दोपहर

मुझे पता नहीं है कि यह कैसे काम करता है, लेकिन यह सिर्फ एक आकर्षण की तरह काम करता है।
दोपहर

17

मैंने TextWatcherनिम्नलिखित तरीके से इसकी मदद से इसे हासिल किया

final EditText et = (EditText) findViewById(R.id.EditText1);
int count = -1;
et.addTextChangedListener(new TextWatcher() {
    public void onTextChanged(CharSequence arg0, int arg1, int arg2,int arg3) {             

    }
    public void beforeTextChanged(CharSequence arg0, int arg1,int arg2, int arg3) {             

    }

    public void afterTextChanged(Editable arg0) {
        if (arg0.length() > 0) {
            String str = et.getText().toString();
            et.setOnKeyListener(new OnKeyListener() {
                public boolean onKey(View v, int keyCode, KeyEvent event) {
                    if (keyCode == KeyEvent.KEYCODE_DEL) {
                        count--;
                        InputFilter[] fArray = new InputFilter[1];
                        fArray[0] = new InputFilter.LengthFilter(100);
                        et.setFilters(fArray);
                        //change the edittext's maximum length to 100. 
                        //If we didn't change this the edittext's maximum length will
                        //be number of digits we previously entered.
                    }
                    return false;
                }
            });
            char t = str.charAt(arg0.length() - 1);
            if (t == '.') {
                count = 0;
            }
            if (count >= 0) {
                if (count == 2) {                        
                    InputFilter[] fArray = new InputFilter[1];
                    fArray[0] = new InputFilter.LengthFilter(arg0.length());
                    et.setFilters(fArray);
                    //prevent the edittext from accessing digits 
                    //by setting maximum length as total number of digits we typed till now.
                }
                count++;
            }
        }
    }
});

यह समाधान उपयोगकर्ता को दशमलव बिंदु के बाद दो अंकों से अधिक दर्ज करने की अनुमति नहीं देगा। इसके अलावा आप दशमलव बिंदु से पहले किसी भी अंक को दर्ज कर सकते हैं। इस ब्लॉग को देखें http://v4all123.blogspot.com/2013/05/set-limit-for-fraction-in-decimal.html कई EditText के लिए फ़िल्टर सेट करने के लिए। मुझे उम्मीद है कि इससे सहायता मिलेगी। धन्यवाद।


देर से जानकारी के लिए क्षमा करें। के countसाथ आरंभ करने के लिए मत भूलना -1। तब केवल यह सही ढंग से काम करेगा। int count = -1;
गुनासेलन

Gunaseelan - मैंने उपरोक्त कोड और इसके अच्छे काम की कोशिश की। लेकिन जब मैं टाइप किए गए टेक्स्ट को हटाता हूं और फिर से टाइपिंग शुरू करता हूं तो केवल एक अंक टाइप करता हूं, इसके लिए कोई समाधान .....
Siva K

@ शिवक कोई रास्ता नहीं दोस्त। यदि आप हटाते हैं और फिर टाइप करते हैं तो यह न्यूनतम 100 अंकों को स्वीकार करेगा। मैं नहीं जानता कि आप इसे कैसे एक्सेस कर रहे हैं listener। किसी भी तरह से एक नज़र कृपया मेरे ब्लॉग पोस्ट । आपको अंदाजा हो सकता है। यदि आप कृपया मुझे बता नहीं सकते। मैं इस मुद्दे के संबंध में आपकी मदद करूंगा।
गुनसेलेन

मैंने सत्यापित किया है कि @ शिव ने क्या कहा है। यह किसी भी मामले में चतुर है, लेकिन मैं इसे कुछ संपादन करने जा रहा हूं ताकि यह पूरी तरह कार्यात्मक हो (मेरी राय में)
MrTristan

@Gunaseelan आपके समाधान के लिए धन्यवाद। लेकिन इसमें कुछ कीड़े हैं। उदाहरण के लिए, जब मैं दूसरा दशमलव हटाता हूं, तो यह फिर से टाइप करना असंभव है (मुझे इसे फिर से टाइप करने में सक्षम होने के लिए सभी दशमलव को हटाना होगा)। इसके अलावा, पूरी प्रविष्टि को हटाने के बाद, जब फिर से टाइप किया जाता है, तो कुछ अजीब सीमाएं होती हैं।
आकील

14

इनपुटफिल्टर I के साथ आया था जिससे आप दशमलव स्थान से पहले और बाद में अंकों की संख्या को कॉन्फ़िगर कर सकते हैं। इसके अतिरिक्त, यह अग्रणी शून्य को अस्वीकार करता है।

public class DecimalDigitsInputFilter implements InputFilter
{
    Pattern pattern;

    public DecimalDigitsInputFilter(int digitsBeforeDecimal, int digitsAfterDecimal)
    {
        pattern = Pattern.compile("(([1-9]{1}[0-9]{0," + (digitsBeforeDecimal - 1) + "})?||[0]{1})((\\.[0-9]{0," + digitsAfterDecimal + "})?)||(\\.)?");
    }

    @Override public CharSequence filter(CharSequence source, int sourceStart, int sourceEnd, Spanned destination, int destinationStart, int destinationEnd)
    {
        // Remove the string out of destination that is to be replaced.
        String newString = destination.toString().substring(0, destinationStart) + destination.toString().substring(destinationEnd, destination.toString().length());

        // Add the new string in.
        newString = newString.substring(0, destinationStart) + source.toString() + newString.substring(destinationStart, newString.length());

        // Now check if the new string is valid.
        Matcher matcher = pattern.matcher(newString);

        if(matcher.matches())
        {
            // Returning null indicates that the input is valid.
            return null;
        }

        // Returning the empty string indicates the input is invalid.
        return "";
    }
}

// To use this InputFilter, attach it to your EditText like so:
final EditText editText = (EditText) findViewById(R.id.editText);

EditText.setFilters(new InputFilter[]{new DecimalDigitsInputFilter(4, 4)});

अच्छा समाधान! यह मेरे लिए काम करता है, लेकिन मैं अग्रणी अवधि (डॉट) को अस्वीकार करना चाहता हूं। उदाहरण के लिए, ".123" अनुक्रम की अनुमति नहीं है। इसे कैसे प्राप्त किया जाए?
ibogolyubskiy

13

दशमलव के बाद आवश्यकता 2 अंकों की होती है दशमलव बिंदु से पहले अंकों की कोई सीमा नहीं होनी चाहिए । तो, समाधान होना चाहिए,

public class DecimalDigitsInputFilter implements InputFilter {

    Pattern mPattern;

    public DecimalDigitsInputFilter() {
        mPattern = Pattern.compile("[0-9]*+((\\.[0-9]?)?)||(\\.)?");
    }

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

और इसका उपयोग करें,

mEditText.setFilters(new InputFilter[]{new DecimalDigitsInputFilter()});

प्रेरणा के लिए @Pinhassi को धन्यवाद।


अच्छा ... वर्किंग फाइन
जोजो

12

मेरा समाधान सरल है और सही काम करता है!

public class DecimalInputTextWatcher implements TextWatcher {

private String mPreviousValue;
private int mCursorPosition;
private boolean mRestoringPreviousValueFlag;
private int mDigitsAfterZero;
private EditText mEditText;

public DecimalInputTextWatcher(EditText editText, int digitsAfterZero) {
    mDigitsAfterZero = digitsAfterZero;
    mEditText = editText;
    mPreviousValue = "";
    mRestoringPreviousValueFlag = false;
}

@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
    if (!mRestoringPreviousValueFlag) {
        mPreviousValue = s.toString();
        mCursorPosition = mEditText.getSelectionStart();
    }
}

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

@Override
public void afterTextChanged(Editable s) {
    if (!mRestoringPreviousValueFlag) {

        if (!isValid(s.toString())) {
            mRestoringPreviousValueFlag = true;
            restorePreviousValue();
        }

    } else {
        mRestoringPreviousValueFlag = false;
    }
}

private void restorePreviousValue() {
    mEditText.setText(mPreviousValue);
    mEditText.setSelection(mCursorPosition);
}

private boolean isValid(String s) {
    Pattern patternWithDot = Pattern.compile("[0-9]*((\\.[0-9]{0," + mDigitsAfterZero + "})?)||(\\.)?");
    Pattern patternWithComma = Pattern.compile("[0-9]*((,[0-9]{0," + mDigitsAfterZero + "})?)||(,)?");

    Matcher matcherDot = patternWithDot.matcher(s);
    Matcher matcherComa = patternWithComma.matcher(s);

    return matcherDot.matches() || matcherComa.matches();
}
}

उपयोग:

myTextEdit.addTextChangedListener(new DecimalInputTextWatcher(myTextEdit, 2));

isValid()प्रत्येक isValid()कॉल पर पैटर्न को फिर से बनाने से बचने के लिए कंस्ट्रक्टर से पैटर्न को स्थानांतरित करें।
हेमंत कौशिक

6

एक TextView में डालने से पहले अपने स्ट्रिंग को फॉर्मेट करने के लिए NumberFormat.getCurrencyInstance () का उपयोग करने का प्रयास करें ।

कुछ इस तरह:

NumberFormat currency = NumberFormat.getCurrencyInstance();
myTextView.setText(currency.format(dollars));

संपादित करें - मुद्रा के लिए कोई इनपुट टाइप नहीं है जो मुझे डॉक्स में मिल सकता है। मैं इसकी कल्पना करता हूं क्योंकि कुछ मुद्राएं हैं जो दशमलव स्थानों के लिए समान नियम का पालन नहीं करती हैं, जैसे कि जापानी येन।

जैसा कि LeffelMania ने उल्लेख किया है, आप उपर्युक्त कोड का उपयोग करके उपयोगकर्ता इनपुट को सही कर सकते हैं TextWatcherजो आपके सेट पर है EditText


6

थोड़ा बेहतर @Pinhassi समाधान।

बहुत अच्छा काम करता है। यह समसामयिक तार को मान्य करता है।

public class DecimalDigitsInputFilter implements InputFilter {

Pattern mPattern;

public DecimalDigitsInputFilter() {
    mPattern = Pattern.compile("([1-9]{1}[0-9]{0,2}([0-9]{3})*(\\.[0-9]{0,2})?|[1-9]{1}[0-9]{0,}(\\.[0-9]{0,2})?|0(\\.[0-9]{0,2})?|(\\.[0-9]{1,2})?)");

}

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

    String formatedSource = source.subSequence(start, end).toString();

    String destPrefix = dest.subSequence(0, dstart).toString();

    String destSuffix = dest.subSequence(dend, dest.length()).toString();

    String result = destPrefix + formatedSource + destSuffix;

    result = result.replace(",", ".");

    Matcher matcher = mPattern.matcher(result);

    if (matcher.matches()) {
        return null;
    }

    return "";
}

 }

6

मैंने उपरोक्त समाधानों को संशोधित किया है और एक के बाद एक बनाया है। आप दशमलव बिंदु से पहले और बाद में अंकों की संख्या निर्धारित कर सकते हैं।

public class DecimalDigitsInputFilter implements InputFilter {

private final Pattern mPattern;

public DecimalDigitsInputFilter(int digitsBeforeZero, int digitsAfterZero) {
    mPattern = Pattern.compile(String.format("[0-9]{0,%d}(\\.[0-9]{0,%d})?", digitsBeforeZero, digitsAfterZero));
}

@Override
public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
    Matcher matcher = mPattern.matcher(createResultString(source, start, end, dest, dstart, dend));
    if (!matcher.matches())
        return "";
    return null;
}

private String createResultString(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
    String sourceString = source.toString();
    String destString = dest.toString();
    return destString.substring(0, dstart) + sourceString.substring(start, end) + destString.substring(dend);
}

}


यह लगभग वही है जो 2014 में इसी सवाल पर दिया गया था।
मेहुल जोसर

5
DecimalFormat form = new DecimalFormat("#.##", new DecimalFormatSymbols(Locale.US));
    EditText et; 
    et.setOnEditorActionListener(new TextView.OnEditorActionListener() {
        @Override
        public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {

        if (actionId == EditorInfo.IME_ACTION_DONE) {
            double a = Double.parseDouble(et.getText().toString());
            et.setText(form.format(a));
        }
        return false;
    }
});

यह क्या करता है जब आप संपादन चरण से बाहर निकलते हैं तो यह फ़ील्ड को सही प्रारूप में प्रारूपित करता है। उनके पास इस समय केवल 2 दशमलव चरखे हैं। मुझे लगता है कि यह करने के लिए यह बहुत आसान तरीका है।


4

यहाँ सभी उत्तर बहुत जटिल हैं मैंने इसे बहुत सरल बनाने की कोशिश की। अपने कोड पर देखें और अपने लिए निर्णय लें -

int temp  = 0;
int check = 0;

editText.addTextChangedListener(new TextWatcher() {

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

        if(editText.getText().toString().length()<temp)
        {
            if(!editText.getText().toString().contains("."))
                editText.setFilters(new InputFilter[] { new InputFilter.LengthFilter(editText.getText().toString().length()-1) });
            else
                editText.setFilters(new InputFilter[] { new InputFilter.LengthFilter(editText.getText().toString().length()+1) });

        }

        if(!editText.getText().toString().contains("."))
        {
            editText.setFilters(new InputFilter[] { new InputFilter.LengthFilter(editText.getText().toString().length()+1) });
            check=0;
        }


        else if(check==0)
        {
            check=1;
            editText.setFilters(new InputFilter[] { new InputFilter.LengthFilter(editText.getText().toString().length()+2) });
        }
    }

    @Override
    public void beforeTextChanged(CharSequence s, int start, int count,
            int after) {
        temp = editText.getText().toString().length();


    }

    @Override
    public void afterTextChanged(Editable s) {
        // TODO Auto-generated method stub

    }
});

यह मेरे लिए एकदम सही काम कर रहा है। मैंने सभी परिदृश्यों की जाँच की। धन्यवाद।
अमरनाथ बैठा

मान लीजिए कि मैंने 1234.56 दर्ज किया है, अब मैं इसे इस तरह से संपादित करना चाहता हूं 12378.56, मैं दशमलव को हटाए बिना ऐसा नहीं कर सकता।
अमन वर्मा

4

मुझे वास्तव में पिंहासी का जवाब पसंद आया, लेकिन ध्यान दिया गया कि दशमलव बिंदु के बाद उपयोगकर्ता द्वारा निर्दिष्ट संख्या अंकों में प्रवेश करने के बाद आप दशमलव बिंदु के बाईं ओर पाठ में प्रवेश नहीं कर सकते। समस्या यह थी कि समाधान केवल पिछले पाठ का परीक्षण करता था जो दर्ज किया गया था, वर्तमान पाठ दर्ज नहीं किया गया था। तो यहाँ मेरा समाधान है जो नए वर्ण को मूल पाठ में सत्यापन के लिए सम्मिलित करता है।

package com.test.test;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import android.text.InputFilter;
import android.text.Spanned;
import android.util.Log;

public class InputFilterCurrency implements InputFilter {
    Pattern moPattern;

    public InputFilterCurrency(int aiMinorUnits) {
        // http://www.regexplanet.com/advanced/java/index.html
        moPattern=Pattern.compile("[0-9]*+((\\.[0-9]{0,"+ aiMinorUnits + "})?)||(\\.)?");

    } // InputFilterCurrency

    @Override
    public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
        String lsStart  = "";
        String lsInsert = "";
        String lsEnd    = "";
        String lsText   = "";

        Log.d("debug", moPattern.toString());
        Log.d("debug", "source: " + source + ", start: " + start + ", end:" + end + ", dest: " + dest + ", dstart: " + dstart + ", dend: " + dend );

        lsText = dest.toString();

        // If the length is greater then 0, then insert the new character
        // into the original text for validation
        if (lsText.length() > 0) {

            lsStart = lsText.substring(0, dstart);
            Log.d("debug", "lsStart : " + lsStart);
            // Check to see if they have deleted a character
            if (source != "") {
                lsInsert = source.toString();
                Log.d("debug", "lsInsert: " + lsInsert);
            } // if
            lsEnd = lsText.substring(dend);
            Log.d("debug", "lsEnd   : " + lsEnd);
            lsText = lsStart + lsInsert + lsEnd;
            Log.d("debug", "lsText  : " + lsText);

        } // if

        Matcher loMatcher = moPattern.matcher(lsText);
        Log.d("debug", "loMatcher.matches(): " + loMatcher.matches() + ", lsText: " + lsText);
        if(!loMatcher.matches()) {
            return "";
        }
        return null;

    } // CharSequence

} // InputFilterCurrency

और EditText फ़िल्टर सेट करने के लिए कॉल

editText.setFilters(new InputFilter[] {new InputFilterCurrency(2)});

Ouput with two decimal places
05-22 15:25:33.434: D/debug(30524): [0-9]*+((\.[0-9]{0,2})?)||(\.)?
05-22 15:25:33.434: D/debug(30524): source: 5, start: 0, end:1, dest: 123.4, dstart: 5, dend: 5
05-22 15:25:33.434: D/debug(30524): lsStart : 123.4
05-22 15:25:33.434: D/debug(30524): lsInsert: 5
05-22 15:25:33.434: D/debug(30524): lsEnd   : 
05-22 15:25:33.434: D/debug(30524): lsText  : 123.45
05-22 15:25:33.434: D/debug(30524): loMatcher.matches(): true, lsText: 123.45

Ouput inserting a 5 in the middle
05-22 15:26:17.624: D/debug(30524): [0-9]*+((\.[0-9]{0,2})?)||(\.)?
05-22 15:26:17.624: D/debug(30524): source: 5, start: 0, end:1, dest: 123.45, dstart: 2, dend: 2
05-22 15:26:17.624: D/debug(30524): lsStart : 12
05-22 15:26:17.624: D/debug(30524): lsInsert: 5
05-22 15:26:17.624: D/debug(30524): lsEnd   : 3.45
05-22 15:26:17.624: D/debug(30524): lsText  : 1253.45
05-22 15:26:17.624: D/debug(30524): loMatcher.matches(): true, lsText: 1253.45

4

मैंने उस समाधान पर सुधार किया जो पिनहासी द्वारा रेगेक्स का उपयोग करता है इसलिए यह किनारे के मामलों को भी सही ढंग से संभालता है। इनपुट सही है या नहीं, यह जांचने से पहले, एंड्रॉइड डॉक्स द्वारा बताए अनुसार पहले स्ट्रिंग का निर्माण किया जाता है।

public class DecimalDigitsInputFilter implements InputFilter {

    private Pattern mPattern;

    private static final Pattern mFormatPattern = Pattern.compile("\\d+\\.\\d+");

    public DecimalDigitsInputFilter(int digitsBeforeDecimal, int digitsAfterDecimal) {
        mPattern = Pattern.compile(
            "^\\d{0," + digitsBeforeDecimal + "}([\\.,](\\d{0," + digitsAfterDecimal +
                "})?)?$");
    }

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

        String newString =
            dest.toString().substring(0, dstart) + source.toString().substring(start, end) 
            + dest.toString().substring(dend, dest.toString().length());

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

उपयोग:

editText.setFilters(new InputFilter[] {new DecimalDigitsInputFilter(5,2)});

4

दशमलव के बाद 2 से अधिक अंकों में प्रवेश करने वाले उपयोगकर्ता को रोकने के लिए सरल सहायक वर्ग यहां है:

public class CostFormatter  implements TextWatcher {

private final EditText costEditText;

public CostFormatter(EditText costEditText) {
    this.costEditText = costEditText;
}

@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 synchronized void afterTextChanged(final Editable text) {
    String cost = text.toString().trim();

    if(!cost.endsWith(".") && cost.contains(".")){
        String numberBeforeDecimal = cost.split("\\.")[0];
        String numberAfterDecimal = cost.split("\\.")[1];

        if(numberAfterDecimal.length() > 2){
            numberAfterDecimal = numberAfterDecimal.substring(0, 2);
        }
        cost = numberBeforeDecimal + "." + numberAfterDecimal;
    }
    costEditText.removeTextChangedListener(this);
    costEditText.setText(cost);
    costEditText.setSelection(costEditText.getText().toString().trim().length());
    costEditText.addTextChangedListener(this);
}
}

4

मैंने उत्तर बदल दिया है av6 (फेवास केवी द्वारा) क्योंकि वहां आप पहले स्थान पर सिर्फ एक बिंदु रख सकते हैं।

final InputFilter [] filter = { new InputFilter() {

    @Override
    public CharSequence filter(CharSequence source, int start, int end,
                               Spanned dest, int dstart, int dend) {
        StringBuilder builder = new StringBuilder(dest);
        builder.replace(dstart, dend, source
                .subSequence(start, end).toString());
        if (!builder.toString().matches(
                "(([1-9]{1})([0-9]{0,4})?(\\.)?)?([0-9]{0,2})?"

        )) {
            if(source.length()==0)
                return dest.subSequence(dstart, dend);
            return "";
        }
        return null;
    }
}};

3

जैसा कि अन्य लोगों ने कहा, मैंने अपनी परियोजना में इस वर्ग को जोड़ा और फ़िल्टर को EditTextमेरी इच्छा के अनुसार सेट किया ।

फ़िल्टर को @ Pixel के उत्तर से कॉपी किया गया है। मैं बस यह सब एक साथ रख रहा हूँ।

public class DecimalDigitsInputFilter implements InputFilter {

    Pattern mPattern;

    public DecimalDigitsInputFilter() {
        mPattern = Pattern.compile("([1-9]{1}[0-9]{0,2}([0-9]{3})*(\\.[0-9]{0,2})?|[1-9]{1}[0-9]{0,}(\\.[0-9]{0,2})?|0(\\.[0-9]{0,2})?|(\\.[0-9]{1,2})?)");

    }

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

        String formatedSource = source.subSequence(start, end).toString();

        String destPrefix = dest.subSequence(0, dstart).toString();

        String destSuffix = dest.subSequence(dend, dest.length()).toString();

        String result = destPrefix + formatedSource + destSuffix;

        result = result.replace(",", ".");

        Matcher matcher = mPattern.matcher(result);

        if (matcher.matches()) {
            return null;
        }

        return "";
    }
}

अब अपने EditTextइस तरह से फ़िल्टर सेट करें।

mEditText.setFilters(new InputFilter[]{new DecimalDigitsInputFilter()});

यहाँ एक महत्वपूर्ण बात यह है कि इसमें दशमलव बिंदु के बाद दो से अधिक अंक नहीं दिखाने की मेरी समस्या को हल करता है, EditTextलेकिन समस्या यह getText()है कि जब मैं इससे होता हूं EditText, तो यह मेरे द्वारा टाइप किए गए पूरे इनपुट को वापस कर देता है।

उदाहरण के लिए, फ़िल्टर को लागू करने के बाद EditText, मैंने इनपुट 1.5699856987 सेट करने का प्रयास किया। तो स्क्रीन में यह 1.56 दिखाता है जो एकदम सही है।

तब मैं इस इनपुट का उपयोग कुछ अन्य गणनाओं के लिए करना चाहता था इसलिए मैं उस इनपुट फ़ील्ड से पाठ प्राप्त करना चाहता था ( EditText)। जब मैंने फोन किया तो mEditText.getText().toString()यह 1.5699856987 था जो मेरे मामले में स्वीकार्य नहीं था।

इसलिए मुझे इसे प्राप्त करने के बाद फिर से मूल्य को पार्स करना पड़ा EditText

BigDecimal amount = new BigDecimal(Double.parseDouble(mEditText.getText().toString().trim()))
    .setScale(2, RoundingMode.HALF_UP);

setScaleसे पूरा पाठ प्राप्त करने के बाद यहाँ चाल है EditText


हैलो, मैं कैसे सुनिश्चित कर सकता हूं कि यदि उपयोगकर्ता दशमलव (?) का इनपुट नहीं करता है तो उसे 2 अंकों से अधिक दर्ज करने में सक्षम नहीं होना चाहिए?
मनीषनेगी

2

मुझे भी इस समस्या का सामना करना पड़ा है। मैं कई EditTexts में कोड का पुन: उपयोग करने में सक्षम होना चाहता था। यह मेरा समाधान है:

उपयोग:

CurrencyFormat watcher = new CurrencyFormat();
priceEditText.addTextChangedListener(watcher);

वर्ग:

public static class CurrencyFormat implements TextWatcher {

    public void onTextChanged(CharSequence arg0, int start, int arg2,int arg3) {}

    public void beforeTextChanged(CharSequence arg0, int start,int arg2, int arg3) {}

    public void afterTextChanged(Editable arg0) {
        int length = arg0.length();
        if(length>0){
            if(nrOfDecimal(arg0.toString())>2)
                    arg0.delete(length-1, length);
        }

    }


    private int nrOfDecimal(String nr){
        int len = nr.length();
        int pos = len;
        for(int i=0 ; i<len; i++){
            if(nr.charAt(i)=='.'){
                pos=i+1;
                    break;
            }
        }
        return len-pos;
    }
}

2

@ मेरे लिए यू ..

txtlist.setFilters(new InputFilter[] { new DigitsKeyListener( Boolean.FALSE,Boolean.TRUE) {

        int beforeDecimal = 7;
        int afterDecimal = 2;

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

            String etText = txtlist.getText().toString();
            String temp = txtlist.getText() + source.toString();
            if (temp.equals(".")) {
                return "0.";
            } else if (temp.toString().indexOf(".") == -1) {
                // no decimal point placed yet
                 if (temp.length() > beforeDecimal) {
                    return "";
                }
            } else {
                int dotPosition ;
                int cursorPositon = txtlistprice.getSelectionStart();
                if (etText.indexOf(".") == -1) {
                    dotPosition = temp.indexOf(".");
                }else{
                    dotPosition = etText.indexOf(".");
                }
                if(cursorPositon <= dotPosition){
                    String beforeDot = etText.substring(0, dotPosition);
                    if(beforeDot.length()<beforeDecimal){
                        return source;
                    }else{
                        if(source.toString().equalsIgnoreCase(".")){
                            return source;
                        }else{
                            return "";
                        }
                    }
                }else{
                    temp = temp.substring(temp.indexOf(".") + 1);
                    if (temp.length() > afterDecimal) {
                        return "";
                    }
                }
            }
            return super.filter(source, start, end, dest, dstart, dend);
        }
    } });

2

एक बहुत देर से प्रतिक्रिया: हम इसे बस इस तरह से कर सकते हैं:

etv.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) {
            if (s.toString().length() > 3 && s.toString().contains(".")) {
                if (s.toString().length() - s.toString().indexOf(".") > 3) {
                    etv.setText(s.toString().substring(0, s.length() - 1));
                    etv.setSelection(edtSendMoney.getText().length());
                }
            }
        }

        @Override
        public void afterTextChanged(Editable arg0) {
        }
}

2

यहाँ दशमलव बिंदु के बाद TextWatcherकेवल n अंक की अनुमति है ।

TextWatcher

private static boolean flag;
public static TextWatcher getTextWatcherAllowAfterDeci(final int allowAfterDecimal){

    TextWatcher watcher = new TextWatcher() {

        @Override
        public void onTextChanged(CharSequence s, int start, int before, int count) {
            // TODO Auto-generated method stub

        }

        @Override
        public void beforeTextChanged(CharSequence s, int start, int count,
                int after) {
            // TODO Auto-generated method stub

        }

        @Override
        public void afterTextChanged(Editable s) {
            // TODO Auto-generated method stub
            String str = s.toString();
            int index = str.indexOf ( "." );
            if(index>=0){
                if((index+1)<str.length()){
                    String numberD = str.substring(index+1);
                    if (numberD.length()!=allowAfterDecimal) {
                        flag=true;
                    }else{
                        flag=false;
                    }   
                }else{
                    flag = false;
                }                   
            }else{
                flag=false;
            }
            if(flag)
                s.delete(s.length() - 1,
                        s.length());
        }
    };
    return watcher;
}

कैसे इस्तेमाल करे

yourEditText.addTextChangedListener(getTextWatcherAllowAfterDeci(1));

एक जादू की तरह काम करता है!!। धन्यवाद
हीरन

2

इसे प्राप्त करने का सबसे सरल तरीका है:

et.addTextChangedListener(new TextWatcher() {
    public void onTextChanged(CharSequence arg0, int arg1, int arg2, int arg3) {
        String text = arg0.toString();
        if (text.contains(".") && text.substring(text.indexOf(".") + 1).length() > 2) {
            et.setText(text.substring(0, text.length() - 1));
            et.setSelection(et.getText().length());
        }
    }

    public void beforeTextChanged(CharSequence arg0, int arg1, int arg2, int arg3) {

    }

    public void afterTextChanged(Editable arg0) {
    }
});

सरल और पर्फेक्ट उत्तर
लोगो

1

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

     yourEditText.addTextChangedListener(new TextWatcher() {
        @Override
        public void onTextChanged(CharSequence s, int start, int before, int count) {
            NumberFormat formatter = new DecimalFormat("#.##");
            double doubleVal = Double.parseDouble(s.toString());
            yourEditText.setText(formatter.format(doubleVal));
        }

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

        @Override
        public void afterTextChanged(Editable s) {}
    });

यदि उपयोगकर्ता दशमलव बिंदु के बाद दो से अधिक संख्याओं के साथ एक संख्या में प्रवेश करता है, तो यह स्वचालित रूप से सही हो जाएगा।

मुझे आशा है कि मैंने मदद की होगी!


क्या आपने इस कोड का परीक्षण किया? यह वास्तव में काम नहीं कर सकता, क्योंकि जब भी आप सेटटैक्स कहते हैं () टेक्स्टवॉकर फिर से आग लगाता है => अनंत लूप।
मुएटज़ेनफ्लो

06-07 08: 01: 35.006: ई / AndroidRuntime (30230): java.lang.StackOverflowError काम नहीं कर रही
अंजुला

1

यह मेरे लिए ठीक काम करता है। यह फ़ोकस परिवर्तित और वापस प्राप्त होने के बाद भी मान दर्ज करने की अनुमति देता है। उदाहरण के लिए: 123.00, 12.12, 0.01, आदि ..

1. फ़ाइल से एक्सेस किए Integer.parseInt(getString(R.string.valuelength)) गए इनपुट की लंबाई निर्दिष्ट करता है । यह मूल्यों को बदलने के लिए आसान है। 2. , यह दशमलव स्थानों के लिए अधिकतम सीमा है।digits.Valuesstring.xmlInteger.parseInt(getString(R.string.valuedecimal))

private InputFilter[] valDecimalPlaces;
private ArrayList<EditText> edittextArray;

valDecimalPlaces = new InputFilter[] { new DecimalDigitsInputFilterNew(
    Integer.parseInt(getString(R.string.valuelength)),
    Integer.parseInt(getString(R.string.valuedecimal))) 
};

EditTextमानों की सरणी जो कार्रवाई करने की अनुमति देती है।

for (EditText etDecimalPlace : edittextArray) {
            etDecimalPlace.setFilters(valDecimalPlaces);

मैंने केवल उन मानों के सरणी का उपयोग किया है, जिनमें एकाधिक edittext अगला DecimalDigitsInputFilterNew.classफ़ाइल है।

import android.text.InputFilter;
import android.text.Spanned;

public class DecimalDigitsInputFilterNew implements InputFilter {

    private final int decimalDigits;
    private final int before;

    public DecimalDigitsInputFilterNew(int before ,int decimalDigits) {
        this.decimalDigits = decimalDigits;
        this.before = before;
    }

    @Override
    public CharSequence filter(CharSequence source, int start, int end,
        Spanned dest, int dstart, int dend) {
        StringBuilder builder = new StringBuilder(dest);
        builder.replace(dstart, dend, source
              .subSequence(start, end).toString());
        if (!builder.toString().matches("(([0-9]{1})([0-9]{0,"+(before-1)+"})?)?(\\.[0-9]{0,"+decimalDigits+"})?")) {
             if(source.length()==0)
                  return dest.subSequence(dstart, dend);
             return "";
        }
        return null;
    }
}

1

यह pinhassi के उत्तर पर बनाना है - यह मुद्दा कि मैं आया था कि दशमलव सीमा तक पहुँच जाने के बाद आप दशमलव से पहले मान नहीं जोड़ सकते। समस्या को ठीक करने के लिए, हमें पैटर्न मिलान करने से पहले अंतिम स्ट्रिंग का निर्माण करना होगा।

import java.util.regex.Matcher;
import java.util.regex.Pattern;

import android.text.InputFilter;
import android.text.Spanned;

public class DecimalLimiter implements InputFilter
{
    Pattern mPattern;

    public DecimalLimiter(int digitsBeforeZero,int digitsAfterZero) 
    {
        mPattern=Pattern.compile("[0-9]{0," + (digitsBeforeZero) + "}+((\\.[0-9]{0," + (digitsAfterZero) + "})?)||(\\.)?");
    }

    @Override
    public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) 
    {
        StringBuilder sb = new StringBuilder(dest);
        sb.insert(dstart, source, start, end);

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

1
et = (EditText) vw.findViewById(R.id.tx_edittext);

et.setFilters(new InputFilter[] {
        new DigitsKeyListener(Boolean.FALSE, Boolean.TRUE) {
            int beforeDecimal = 5, afterDecimal = 2;

            @Override
            public CharSequence filter(CharSequence source, int start, int end,
                    Spanned dest, int dstart, int dend) {
                String temp = et.getText() + source.toString();

                if (temp.equals(".")) {
                    return "0.";
                }
                else if (temp.toString().indexOf(".") == -1) {
                    // no decimal point placed yet
                    if (temp.length() > beforeDecimal) {
                        return "";
                    }
                } else {
                    temp = temp.substring(temp.indexOf(".") + 1);
                    if (temp.length() > afterDecimal) {
                        return "";
                    }
                }

                return super.filter(source, start, end, dest, dstart, dend);
            }
        }
});

आपके उत्तर समय से लगभग 2 वर्ष। मैंने आपके कोड का उपयोग करने की कोशिश की, तब मैंने पाया कि आपके समाधान के बारे में समस्या यह है कि आप इसके sourceबाद क्या करेंगे et.getText()। यह हमेशा समझ में आता है कि लोग बॉक्स की शुरुआत के बजाय बॉक्स के अंत में टाइप करते हैं। StringBuilder stringBuilder = new StringBuilder(text.getText().toString()); stringBuilder.replace(dstart, dend, source.toString()); String temp = stringBuilder.toString();कार्य करना चाहिए। फिर भी धन्यवाद।
Truong Hieu

1

DecimalDigitsInputFilter नाम के साथ एंड्रॉइड कोटलिन में एक नया वर्ग बनाएं

class DecimalDigitsInputFilter(digitsBeforeZero: Int, digitsAfterZero: Int) : InputFilter {
lateinit var mPattern: Pattern
init {
    mPattern =
        Pattern.compile("[0-9]{0," + (digitsBeforeZero) + "}+((\\.[0-9]{0," + (digitsAfterZero) + "})?)||(\\.)?")
}
override fun filter(
    source: CharSequence?,
    start: Int,
    end: Int,
    dest: Spanned?,
    dstart: Int,
    dend: Int
): CharSequence? {
    val matcher: Matcher = mPattern.matcher(dest?.subSequence(0, dstart).toString() + source?.subSequence(start, end).toString() + dest?.subSequence(dend, dest?.length!!).toString())
    if (!matcher.matches())
        return ""
    else
        return null
}

इस वर्ग को निम्न पंक्ति के साथ बुलाओ

 et_buy_amount.filters = (arrayOf<InputFilter>(DecimalDigitsInputFilter(8,2)))

उसी के लिए बहुत सारे उत्तर हैं, लेकिन यह आपको दशमलव से पहले 8 अंक और दशमलव के बाद 2 अंक दर्ज करने की अनुमति देगा

अन्य उत्तर केवल 8 अंकों को स्वीकार कर रहे हैं

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