Android'de EditText için bir minimum ve maksimum değer tanımlamanın bir yolu var mı?


133

Bir için minimum ve maksimum değer tanımlamak istiyorum EditText.

Örneğin: herhangi bir kişi ay değeri girmeye çalışırsa, değer 1-12 arasında olmalıdır.

Kullanarak yapabilirim, TextWatcherancak bunu düzen dosyasında veya başka bir yerde yapmanın başka bir yolu olup olmadığını bilmek istiyorum.

Düzenleme: Karakter sayısını sınırlamak istemiyorum. Değeri sınırlamak istiyorum. Örneğin, EditText12 girdiğimde ay w karakterlerini sınırlarsam kabul eder, ancak 22 girersem girerken kabul etmemesi gerekir.


Birisi tüm bu tür girdi filtrelerinden bir kitaplık / koleksiyon oluşturmalıdır. Sonra herkes birlikte çalışıp test edebilir. Herkesin kendi işini yapması yerine.
Zapnologica

Sorununuzu çözmek için bu metin düzenleme filtresini kullanın. filter
Taras Smakula

Yanıtlar:


286

Önce bu sınıfı yapın:

package com.test;

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

public class InputFilterMinMax implements InputFilter {

    private int min, max;

    public InputFilterMinMax(int min, int max) {
        this.min = min;
        this.max = max;
    }

    public InputFilterMinMax(String min, String max) {
        this.min = Integer.parseInt(min);
        this.max = Integer.parseInt(max);
    }

    @Override
    public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {   
        try {
            int input = Integer.parseInt(dest.toString() + source.toString());
            if (isInRange(min, max, input))
                return null;
        } catch (NumberFormatException nfe) { }     
        return "";
    }

    private boolean isInRange(int a, int b, int c) {
        return b > a ? c >= a && c <= b : c >= b && c <= a;
    }
}

Ardından bunu Faaliyetinizden kullanın:

EditText et = (EditText) findViewById(R.id.myEditText);
et.setFilters(new InputFilter[]{ new InputFilterMinMax("1", "12")});

Bu, kullanıcının yalnızca 1'den 12'ye kadar değerler girmesine izin verecektir .

DÜZENLE :

Edittext'nizi ile ayarlayın android:inputType="number".

Daha fazla bilgiyi https://www.techcompose.com/how-to-set-minimum-and-maximum-value-in-edittext-in-android-app-development/ adresinde bulabilirsiniz. .

Teşekkürler.


1
@mertaydin tabii. bir deneyin, sonra yardımıma ihtiyacınız olursa bana bildirin. Teşekkürler.
Pratik Sharma

12
Aah, yardıma ihtiyacım var. 1930 ile 1999 arasında yazma değerinde sorun yaşıyorum. 1 yazdığımda değeri kontrol ediyor ve 1 1930 ile 1999 arasında değil bu yüzden kabul etmiyor.
mertaydin

1
@mertaydin Özür dilerim ama işimle biraz meşguldüm. Buna bakmak için biraz zamanım var, sanırım filtre sınıfında uygulanan algoritmada değişiklikler yapmam gerekiyor. Bunu bitirdiğimde sizi güncelleyeceğim.
Pratik Sharma

1
Bazı karakterler sourcebazı karakterlerin yerini alacak dest. Sanırım değişimin simülasyonunu yapmalı ve nihai sonucu almalı, sonra doğrulamalısınız.
SD

3
@Pratik Sharma, 1900-2000 aralığına girdiğimde bu çalışmıyor, bir şey önerebilir misin
EminenT

89

Pratik'in kodunda küçük bir hata var. Örneğin, bir değer 10 ise ve 110 yapmak için başlangıca 1 eklerseniz, filtre işlevi yeni değeri 101 olarak değerlendirir.

Bunun düzeltmesi için aşağıya bakın:

@Override
public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
    try {
        // Remove the string out of destination that is to be replaced
        String newVal = dest.toString().substring(0, dstart) + dest.toString().substring(dend, dest.toString().length());
        // Add the new string in
        newVal = newVal.substring(0, dstart) + source.toString() + newVal.substring(dstart, newVal.length());
        int input = Integer.parseInt(newVal);
        if (isInRange(min, max, input))
            return null;
    } catch (NumberFormatException nfe) { }
    return "";
}

Teşekkürler bu bana çok yardımcı oldu!
joschplusa

4
Sanırım bu daha açık bir imho :String replacement = source.subSequence(start, end).toString(); String newVal = dest.subSequence(0, dstart).toString() + replacement + dest.subSequence(dend, dest.length()).toString();
Sven Jacobs

1
+1. bu çözüm kabul edilenden daha doğru. O kullanmayı deneyin örneğin kontrol etmek InputFilterMinMax ile selectAllOnFocus seçeneği etkin ve sonucu karşılaştırın.
Sash0k

1
Neden olmasın String newVal= dest.toString().substring(0, dstart) + source.toString().substring(start, end) + dest.toString().substring(dend, dest.toString().length());, daha temiz ve net görünüyor.
Shishir Gupta

5
OP @ mertaydin tarafından @Patrick'in cevabına yapılan bir yorumda belirtildiği gibi, bu çözümün hala büyük bir kusuru var, neden rapor edilmediğini merak ediyorum: min==3O zaman 1 veya 2 ile başlayan herhangi bir sayıyı yazmak imkansızsa (örn: 15, 23)
Guerneen4

10

@ Patrik'in çözümü ve @ Zac'in eklenmesiyle ilgili gördüklerim arasında, sağlanan kodun hala büyük bir sorunu var:

Eğer min==3o zaman herhangi bir sayı 1 ya da 2 ile başlayan yazmak için imkansız (ex: 15, 23)
ise min>=10o zaman her sayı 1,2,3 başlamak zorunda kalacak gibi herhangi bir şey yazmak imkansız ...

Anladığım kadarıyla EditText, sınıfın basit kullanımıyla bir değerinin min-maks sınırlamasına ulaşamayız.InputFilterMinMax , en azından minimum Değer için değil, çünkü kullanıcı pozitif bir sayı yazarken, değer büyür ve kolayca bir Sınıra ulaşıp ulaşmadığını veya aralığın dışına çıkıp çıkmadığını kontrol etmek ve uymayan girişleri engellemek için anında test. Min değerini test etmek farklı bir hikaye çünkü kullanıcının yazmayı bitirip bitirmediğinden emin olamıyoruz ve bu nedenle engelleyip engellemememiz gerektiğine karar veremiyoruz.

Tam olarak OP'nin istediği şey bu değil, ancak doğrulama amacıyla InputFilter, çözümümde maksimum değerleri OnFocusChangeListenertest etmek için birleştirdim EditText, kullanıcının yazmayı bitirdiğini varsayarak odağı kaybettiğinde minimum değeri yeniden test etmek için ve bunun gibi bir şey:

package test;


import android.text.InputFilter;

import android.text.Spanned;

public class InputFilterMax implements InputFilter {

private int max;

public InputFilterMax(int max) {
    this.max = max;
}

public InputFilterMax(String max) {
    this.max = Integer.parseInt(max);
}

@Override
public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {   
    try {
        String replacement = source.subSequence(start, end).toString(); 

        String newVal = dest.toString().substring(0, dstart) + replacement +dest.toString().substring(dend, dest.toString().length());

        int input = Integer.parseInt(newVal);

        if (input<=max)
            return null;
    } catch (NumberFormatException nfe) { }   
//Maybe notify user that the value is not good      
return "";
}
}

Ve OnFocusChangeListenerMin

package test;

import android.text.TextUtils;
import android.view.View;
import android.view.View.OnFocusChangeListener;

public class OnFocusChangeListenerMin implements OnFocusChangeListener {

private int min;

public OnFocusChangeListenerMin(int min) {
    this.min = min;
}

public OnFocusChangeListenerMin(String min) {
    this.min = Integer.parseInt(min);
}


@Override
public void onFocusChange(View v, boolean hasFocus) {
    if(!hasFocus) {
        String val = ((EditText)v).getText().toString();
        if(!TextUtils.isEmpty(val)){
            if(Integer.valueOf(val)<min){
                //Notify user that the value is not good
            }

        }
    }
}
}

Sonra Aktivite ayarlanır InputFilterMaxve OnFocusChangeListenerMinhiç EditText not: Artık 2 hem minimum ve maksimum de onFocusChangeListener.

mQteEditText.setOnFocusChangeListener( new OnFocusChangeListenerMin('20');
mQteEditText.setFilters(new InputFilter[]{new InputFilterMax(getActivity(),'50')});

OnFocusChangeListenerMin çalışmıyor, tüm değerleri sıfırdan koydu
EminenT

1
Biraz daha detaylandırır mısın? sıfırdan tüm değerleri koymak ne demek ?
Guerneen 4

Koddan OnFocusChangeListenerMin, problemde tartışıldığı gibi 20'nin üzerinde çalışıyor olmalı ama 20'den küçük 0, 1, 2, ------ 19 vb. gibi tüm değerleri kabul ediyor
EminenT

herhangi bir çözüm buldun mu?
EminenT

OnFoncusChangeListener'ı doğrulama amacıyla kullandım, benim durumumda EditText'te bir hata görüntülüyorum, kullanıcıya bir Toast ile değerin iyi olmadığını bildirin ve onu yeni bir değer girmeye davet edin if(Integer.valueOf(val)<min){ //Notify user that the value is not good } Orada istediğinizi yapabilirsiniz, kullanıcısı ve EditText'i boş olarak ayarlayın, bunun sorunuzu yanıtlayıp yanıtlamadığını bilmiyorum
Guerneen4

9

Pratik ve Zac'in cevabının uzantısı. Zac, Pratik'in cevabındaki küçük bir hatayı düzeltti. Ancak kodun negatif değerleri desteklemediğini fark ettim, bir NumberFormatException oluşturacak. Bunu düzeltmek ve MIN’ın negatif olmasına izin vermek için aşağıdaki kodu kullanın.

Bu satırı (kalın) diğer iki satır arasına ekleyin:

newVal = newVal.substring (0, dstart) + source.toString () + newVal.substring (dstart, newVal.length ());

eğer (newVal.equalsIgnoreCase ("-") && min <0) null döndür;

int input = Integer.parseInt (newVal);

public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
    try {
        // Remove the string out of destination that is to be replaced
        String newVal = dest.toString().substring(0, dstart) + dest.toString().substring(dend, dest.toString().length());
        // Add the new string in
        newVal = newVal.substring(0, dstart) + source.toString() + newVal.substring(dstart, newVal.length());
        //****Add this line (below) to allow Negative values***// 
        if(newVal.equalsIgnoreCase("-") && min < 0)return null;
        int input = Integer.parseInt(newVal);
        if (isInRange(min, max, input))
            return null;
    } catch (NumberFormatException nfe) {
        nfe.printStackTrace();
    }
    return "";
}

5

-90: 90 gibi negatif sayılara sahip aralığa ihtiyacınız varsa, bu çözümü kullanabilirsiniz.

public class InputFilterMinMax implements InputFilter {

private int min, max;

public InputFilterMinMax(int min, int max) {
    this.min = min;
    this.max = max;
}

public InputFilterMinMax(String min, String max) {
    this.min = Integer.parseInt(min);
    this.max = Integer.parseInt(max);
}

@Override
public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
    try {
        String stringInput = dest.toString() + source.toString();
        int value;
        if (stringInput.length() == 1 && stringInput.charAt(0) == '-') {
            value = -1;
        } else {
            value = Integer.parseInt(stringInput);
        }
        if (isInRange(min, max, value))
            return null;
    } catch (NumberFormatException nfe) {
    }
    return "";
}

private boolean isInRange(int min, int max, int value) {
    return max > min ? value >= min && value <= max : value >= max && value <= min;
}
}

5

@Pratik Sharmas kodunu, daha büyük sayıları kabul edebilmesi ve EditText'te sayı olmayan herhangi bir biçimlendirmeyi hesaba katabilmesi için tam sayılar yerine BigDecimal nesnelerini kullanacak şekilde genişlettim (para birimi biçimlendirmesi, örneğin boşluklar, virgüller ve noktalar gibi)

DÜZENLEME: Bu uygulamanın, para birimi için kullandığım için BigDecimal'de ayarlanan minimum anlamlı rakamlar olarak 2'ye sahip olduğuna dikkat edin (MIN_SIG_FIG sabitine bakın), bu nedenle ondalık noktadan önce her zaman 2 önde gelen sayı vardı. MIN_SIG_FIG sabitini kendi uygulamanız için gerektiği gibi değiştirin.

public class InputFilterMinMax implements InputFilter {
private static final int MIN_SIG_FIG = 2;
private BigDecimal min, max;

public InputFilterMinMax(BigDecimal min, BigDecimal max) {
    this.min = min;
    this.max = max;
}

public InputFilterMinMax(String min, String max) {
    this.min = new BigDecimal(min);
    this.max = new BigDecimal(max);
}

@Override
public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart,
        int dend) {
    try {
        BigDecimal input = formatStringToBigDecimal(dest.toString()
                + source.toString());

        if (isInRange(min, max, input)) {

            return null;
        }
    } catch (NumberFormatException nfe) {

    }
    return "";
}

private boolean isInRange(BigDecimal a, BigDecimal b, BigDecimal c) {
    return b.compareTo(a) > 0 ? c.compareTo(a) >= 0 && c.compareTo(b) <= 0
            : c.compareTo(b) >= 0 && c.compareTo(a) <= 0;
}

public static BigDecimal formatStringToBigDecimal(String n) {

    Number number = null;
    try {
        number = getDefaultNumberFormat().parse(n.replaceAll("[^\\d]", ""));

        BigDecimal parsed = new BigDecimal(number.doubleValue()).divide(new BigDecimal(100), 2,
                BigDecimal.ROUND_UNNECESSARY);
        return parsed;
    } catch (ParseException e) {
        return new BigDecimal(0);
    }
}

private static NumberFormat getDefaultNumberFormat() {
    NumberFormat nf = NumberFormat.getInstance(Locale.getDefault());
    nf.setMinimumFractionDigits(MIN_SIG_FIG);
    return nf;
}

4

Kendi cevabımı buldum. Artık çok geç ama sizinle paylaşmak istiyorum. Bu arayüzü uyguluyorum:

import android.text.TextWatcher;


public abstract class MinMaxTextWatcher implements TextWatcher {
    int min, max;
    public MinMaxTextWatcher(int min, int max) {
        super();
        this.min = min;
        this.max = max;
    }

}

Ve sonra bunu aktivitenizin içinde şu şekilde uygulayın:

private void limitEditText(final EditText ed, int min, int max) {
    ed.addTextChangedListener(new MinMaxTextWatcher(min, max) {
        @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 str = s.toString();
            int n = 0;
            try {
                n = Integer.parseInt(str);
                if(n < min) {
                    ed.setText(min);
                    Toast.makeText(getApplicationContext(), "Minimum allowed is " + min, Toast.LENGTH_SHORT).show();
                }
                else if(n > max) {
                    ed.setText("" + max);
                    Toast.makeText(getApplicationContext(), "Maximum allowed is " + max, Toast.LENGTH_SHORT).show();
                }
            }
            catch(NumberFormatException nfe) {
                ed.setText("" + min);
                Toast.makeText(getApplicationContext(), "Bad format for number!" + max, Toast.LENGTH_SHORT).show();
            }
        }
    });
}

Bu çok basit bir cevap, eğer daha iyisi varsa lütfen söyleyin.


int n = 0; gereksizdir. N'nin varsayılan değeri 0 olduğu için
Kenny Dabiri

1
İnt n = 0 neden burada gereksizdir? yerel bir değişkendir ve burada örnek değişkeni değildir.
User12111111

4

Kabul edilen cevapta bir yanlışlık var.

int input = Integer.parseInt(dest.toString() + source.toString());

İmleci metnin ortasına götürürsem, sonra bir şey yazarsam, yukarıdaki ifade yanlış sonuç verecektir. Örneğin, önce "12" yazın, ardından 1 ile 2 arasında "0" yazın, ardından yukarıda belirtilen ifade 102 yerine "120" üretecektir. Bu ifadeyi aşağıdaki ifadelere değiştirdim:

String destString = dest.toString();
  String inputString = destString.substring(0, dstart) + source.toString() + destString.substring(dstart);
  int input = Integer.parseInt(inputString);

4

İhtiyaç varsa Kotlin (Yardımcı Programları Kullanın)

class InputFilterMinMax: InputFilter {
    private var min:Int = 0
    private var max:Int = 0
    constructor(min:Int, max:Int) {
        this.min = min
        this.max = max
    }
    constructor(min:String, max:String) {
        this.min = Integer.parseInt(min)
        this.max = Integer.parseInt(max)
    }
    override fun filter(source:CharSequence, start:Int, end:Int, dest: Spanned, dstart:Int, dend:Int): CharSequence? {
        try
        {
            val input = Integer.parseInt(dest.toString() + source.toString())
            if (isInRange(min, max, input))
                return null
        }
        catch (nfe:NumberFormatException) {}
        return ""
    }
    private fun isInRange(a:Int, b:Int, c:Int):Boolean {
        return if (b > a) c in a..b else c in b..a
    }
}

Sonra bunu Kotlin sınıfınızdan kullanın

percentage_edit_text.filters = arrayOf(Utilities.InputFilterMinMax(1, 100))

Bu EditText 1'den 100'e kadar izin verir.

Sonra bunu XML'nizden kullanın

android:inputType="number"

Dönüş kaynağı kullanıyorum ve benim için çalışıyorum ==> if (isInRange (min, max, input)) dönüş kaynağı
Muzafferus

3

Edittext için bir min / maks ayarlamanın daha basit bir yolunu yaptım. Aritmetik tuş takımı kullanıyorum ve şu yöntemle çalışıyorum:

 private int limit(EditText x,int z,int limin,int limax){

    if( x.getText().toString()==null || x.getText().toString().length()==0){
        x.setText(Integer.toString(limin));
        return z=0;
    }
    else{
        z = Integer.parseInt(x.getText().toString());
         if(z <limin || z>limax){
             if(z<10){
                 x.setText(Integer.toString(limin));
                return  z=0;
             }
            else{
                x.setText(Integer.toString(limax));
                return z=limax;
            }

         }
         else
            return z = Integer.parseInt(x.getText().toString());
    }
 }

Yöntem, tüm değerlerinizi kabul eder, ancak bir kullanıcı değeri sınırlarınıza uymazsa, otomatik olarak min / maks sınırına ayarlanır. Örn. limit limin = 10, limax = 80 eğer kullanıcı 8'i ayarlarsa, otomatik olarak 10 bir değişkene kaydedilir ve Metni Düzenle 10 olarak ayarlanır.


3

Buna zaten bir milyon cevap olduğunu biliyorum ve biri kabul edildi. Bununla birlikte, kabul edilen yanıtta çok sayıda hata vardır ve geri kalanların çoğu, olası tüm kullanım durumlarını genişletmeden bunlardan birini (veya belki ikisini) giderir.

Bu yüzden, temelde destek yanıtlarında önerilen hata düzeltmelerinin çoğunu derledim ve aynı zamanda aralık dışındaki sayıların 0 yönünde sürekli girişine izin veren bir yöntem ekledim (aralık 0'dan başlamazsa), en azından başlayana kadar artık aralıkta olamayacağından emin. Çünkü açık olmak gerekirse, bu, diğer çözümlerin çoğunda gerçekten sorun yaratan tek zamandır.

İşte düzeltme:

public class InputFilterIntRange implements InputFilter, View.OnFocusChangeListener {

    private final int min, max;

    public InputFilterIntRange(int min, int max) {
        if (min > max) {
            // Input sanitation for the filter itself
            int mid = max;
            max = min;
            min = mid;
        }
        this.min = min;
        this.max = max;
    }

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

        // Determine the final string that will result from the attempted input
        String destString = dest.toString();
        String inputString = destString.substring(0, dstart) + source.toString() + destString.substring(dstart);

        // Don't prevent - sign from being entered first if min is negative
        if (inputString.equalsIgnoreCase("-") && min < 0) return null;

        try {
            int input = Integer.parseInt(inputString);
            if (mightBeInRange(input))
                return null;
        } catch (NumberFormatException nfe) {}

        return "";
    }

    @Override
    public void onFocusChange(View v, boolean hasFocus) {

        // Since we can't actively filter all values
        // (ex: range 25 -> 350, input "15" - could be working on typing "150"),
        // lock values to range after text loses focus
        if (!hasFocus) {
            if (v instanceof EditText) sanitizeValues((EditText) v);
        }
    }

    private boolean mightBeInRange(int value) {
        // Quick "fail"
        if (value >= 0 && value > max) return false;
        if (value >= 0 && value >= min) return true;
        if (value < 0 && value < min) return false;
        if (value < 0 && value <= max) return true;

        boolean negativeInput = value < 0;

        // If min and max have the same number of digits, we can actively filter
        if (numberOfDigits(min) == numberOfDigits(max)) {
            if (!negativeInput) {
                if (numberOfDigits(value) >= numberOfDigits(min) && value < min) return false;
            } else {
                if (numberOfDigits(value) >= numberOfDigits(max) && value > max) return false;
            }
        }

        return true;
    }

    private int numberOfDigits(int n) {
        return String.valueOf(n).replace("-", "").length();
    }

    private void sanitizeValues(EditText valueText) {
        try {
            int value = Integer.parseInt(valueText.getText().toString());
            // If value is outside the range, bring it up/down to the endpoint
            if (value < min) {
                value = min;
                valueText.setText(String.valueOf(value));
            } else if (value > max) {
                value = max;
                valueText.setText(String.valueOf(value));
            }
        } catch (NumberFormatException nfe) {
            valueText.setText("");
        }
    }

}

Bazı girdi durumlarının "aktif olarak" (yani, kullanıcı onu girerken) ele alınmasının imkansız olduğuna dikkat edin, bu yüzden onları yok saymalıyız ve kullanıcı metni düzenlemeyi bitirdikten sonra bunları ele almalıyız.

İşte bunu nasıl kullanabileceğiniz:

EditText myEditText = findViewById(R.id.my_edit_text);
InputFilterIntRange rangeFilter = new InputFilterIntRange(25, 350);
myEditText.setFilters(new InputFilter[]{rangeFilter});

// Following line is only necessary if your range is like [25, 350] or [-350, -25].
// If your range has 0 as an endpoint or allows some negative AND positive numbers, 
// all cases will be handled pre-emptively.
myEditText.setOnFocusChangeListener(rangeFilter);

Şimdi, kullanıcı aralığın izin verdiğinden 0'a yakın bir sayı yazmaya çalıştığında, iki şeyden biri gerçekleşecek:

  1. Eğer minve maxbasamak aynı sayıda onlar nihai rakam aldıktan sonra, hepsi de girdi bunu izin verilmez.

  2. Metin odağı kaybettiğinde alanda aralığın dışında bir sayı bırakılırsa, otomatik olarak en yakın sınıra ayarlanacaktır.

Ve tabii ki, kullanıcının 0'dan aralığın izin verdiğinden daha uzak bir değer girmesine asla izin verilmeyecektir ve böyle bir sayının bu nedenle "kazara" metin alanına girmesi mümkün değildir.

Bilinen Sorunlar?)

  1. Bu, yalnızca EditTextkullanıcının işini bitirdiğinde odağı kaybederse çalışır .

Diğer seçenek, kullanıcı "bitti" / dönüş tuşuna bastığında sterilize etmektir, ancak çoğu veya hatta çoğu durumda, bu yine de odak kaybına neden olur.

Ancak, yumuşak klavye kapanış olacak değil otomatik elemanı un-odaklanır. Eminim Android geliştiricilerinin% 99,99'u bunu isterdi (ve EditTextöğelere odaklanma genel olarak bir bataklık değildi), ancak henüz bunun için yerleşik bir işlevsellik yok. Bunu aşmak için bulduğum en kolay yöntem, gerekirse,EditText şunun gibi bir şeyi :

public class EditTextCloseEvent extends AppCompatEditText {

    public EditTextCloseEvent(Context context) {
        super(context);
    }

    public EditTextCloseEvent(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public EditTextCloseEvent(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    @Override
    public boolean onKeyPreIme(int keyCode, KeyEvent event) {
        if (event.getKeyCode() == KeyEvent.KEYCODE_BACK) {
            for (InputFilter filter : this.getFilters()) {
                if (filter instanceof InputFilterIntRange)
                    ((InputFilterIntRange) filter).onFocusChange(this, false);
            }
        }
        return super.dispatchKeyEvent(event);
    }
}

Bu, görünümde olmasa bile, filtreyi girişi temizlemesi için "kandırır". aslında odağı kaybetmemiş . Görünüm daha sonra kendi kendine odak kaybederse, girdi temizliği tekrar tetiklenir, ancak zaten düzeltildiği için hiçbir şey değişmez.

Kapanış

Whew. Bu çok fazlaydı. Başlangıçta oldukça basit bir problem gibi görünen şey, pek çok çirkin vanilya Android parçasını (en azından Java'da) ortaya çıkarmakla sonuçlandı. Ve bir kez daha, aralığınız bir şekilde 0'ı içermiyorsa dinleyiciyi eklemeniz ve genişletmeniz yeterlidir EditText.(Ve gerçekçi olarak, aralığınız 0 içermiyor ancak 1 veya -1 ile başlıyorsa, sorun yaşamazsınız.)

Son bir not olarak, bu yalnızca ints için işe yarar . Ondalık sayılarla ( double, float) çalışmak için onu uygulamanın kesinlikle bir yolu var , ancak ne benim ne de asıl soranın buna ihtiyacı olmadığından, özellikle bu kadar derinlere inmek istemiyorum. Aşağıdaki satırlarla birlikte tamamlama sonrası filtrelemeyi kullanmak çok kolay olacaktır:

// Quick "fail"
if (value >= 0 && value > max) return false;
if (value >= 0 && value >= min) return true;
if (value < 0 && value < min) return false;
if (value < 0 && value <= max) return true;

Yalnızca intyerine float(veya double) arasında değişiklik yapmanız , tek bir .(veya ,ülkeye bağlı olarak?) Eklenmesine izin vermeniz ve ondalık türlerden biri olarak ayrıştırmanız gerekir int.

Bu, işin çoğunu zaten halleder, bu yüzden çok benzer şekilde çalışır.


2
@Override
public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
    try {
        String prefix = dest.toString().substring(0, dstart);
        String insert = source.toString();
        String suffix = dest.toString().substring(dend);
        String input_string = prefix + insert + suffix;
        int input = Integer.parseInt(input_string);

        if (isInRange(min, max, input) || input_string.length() < String.valueOf(min).length())
            return null;
    } catch (NumberFormatException nfe) { }
    return "";
}

private boolean isInRange(int a, int b, int c) {
    return b > a ? c >= a && c <= b : c >= b && c <= a;
}

2

Kotlin hakkında çok basit bir örnek:

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

class InputFilterRange(private var range: IntRange) : InputFilter {

    override fun filter(source: CharSequence, start: Int, end: Int, dest: Spanned, dstart: Int, dend: Int) = try {
        val input = Integer.parseInt(dest.toString() + source.toString())
        if (range.contains(input)) null else ""
    } catch (nfe: NumberFormatException) {
        ""
    }
}

1

lütfen bu kodu kontrol edin

    String pass = EditText.getText().toString(); 
    if(TextUtils.isEmpty(pass) || pass.length < [YOUR MIN LENGTH]) 
    { 
       EditText.setError("You must have x characters in your txt"); 
        return; 
    }

    //continue processing



edittext.setOnFocusChangeListener( new OnFocusChangeListener() {

       @Override
       public void onFocusChange(View v, boolean hasFocus) {
          if(hasFocus) {
           // USE your code here 
  }

Edittext ve metin izleyicili edittext filtreleri hakkında daha fazla ayrıntı için aşağıdaki bağlantıyı kullanın.

http://www.mobisoftinfotech.com/blog/android/android-edittext-setfilters-example-numeric-text-field-patterns-and-length-restriction/


OP, değer girilirken bunu doğrulamak ister. Değer girildikten sonra senaryo için çözüm sağladığınızı düşünüyorum
MysticMagicϡ

Soru soran ben değilim. Cevabınızdan şüphe duyduğum için açıklığa kavuşturuyordum.
MysticMagicϡ

Karakter sayısını kontrol etmek istemiyorum. Sanırım bu koddaki sayımı kontrol etmeye çalışıyorsunuz: if (TextUtils.isEmpty (pass) || pass.length <[YOUR MIN LENGTH]) Ben sadece değeri sınırlıyorum, örneğin kullanıcının aradaki değeri yazması gereken ay değeri için 1-12 değil 13,14, vb. Yani, 12,13,14, ta ki 99 2 karakter uzunluğunda.
mertaydin

merhaba @mertaydin size verdiğim link ile denediniz mi .. o örneğe bakın .. istediğiniz bu olabilir. siz girerken metni izleyecek ..
itsrajesh4uguys

Tamam teşekkürler, cevabını ve @ Pratik Sharma'nın cevabını deneyeceğim.
mertaydin

1

Yalnızca maksimum limit konusunda endişeleriniz varsa, sadece aşağıdaki satıra ekleyin

android:maxLength="10" 

Minimum limit eklemeniz gerekiyorsa, bu şekilde yapabilirsiniz minimum limit 7'dir. Kullanıcı minimum ve maksimum limit arasında (8 ile 10 arasında) karakter girebilir

public final static boolean isValidCellPhone(String number){
        if (number.length() < 8 || number.length() >10 ) {
            return false;
        } else {

           return android.util.Patterns.PHONE.matcher(number).matches();
        }
    }

Kullanıcıyı başlangıçta 01 girmesi için de kısıtlamanız gerekiyorsa, koşulu bu şekilde değiştirin

if (!(number.startsWith("01")) || number.length() < 8 || number.length() >10 ) {  
.
.
.
}

Sonunda çağrı yöntemi gibi

   ....else if (!(Helper.isValidMobilePhone(textMobileNo))){
                        Helper.setEditTextError(etMobileNo,"Invalid Mobile Number");
                    }......

2
Bu vlaue değil, uzunluk
portfoliobuilder

1

@Hayalhanemersin

Negatif sayıları desteklemek için aşağıdaki kodu filtre yöntemine ekleyin :

package ir.aboy.electronicarsenal;

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

public class InputFilterMinMax implements InputFilter {

  private int min, max;
  int input;

  InputFilterMinMax(int min, int max) {
    this.min = min;
    this.max = max;
  }

  public InputFilterMinMax(String min, String max) {
    this.min = Integer.parseInt(min);
    this.max = Integer.parseInt(max);
  }

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

      if ((dest.toString() + source.toString()).equals("-")) {
        source = "-1";
      }

      input = Integer.parseInt(dest.toString() + source.toString());
      if (isInRange(min, max, input))
        return null;

    } catch (NumberFormatException ignored) {
    }
    return "";
  }

  private boolean isInRange(int a, int b, int c) {
    return b > a ? c >= a && c <= b : c >= b && c <= a;
  }

}

Ardından bunu Faaliyetinizden kullanın:

findViewById(R.id.myEditText).setFilters(new InputFilter[]{ new InputFilterMinMax(1, 12)});

Edittext'nizi şununla ayarlayın:

android:inputType="number|numberSigned"

0

// hala bazı problemler var ama burada min, max değerlerini herhangi bir aralıkta kullanabilirsiniz (pozitif veya negatif)

// in filter calss
 @Override
 public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
        try {
            // Remove the string out of destination that is to be replaced
            int input;
            String newVal = dest.toString() + source.toString();
            if (newVal.length() == 1 && newVal.charAt(0) == '-') {
                input = min; //allow
            }
            else {
                newVal = dest.toString().substring(0, dstart) + dest.toString().substring(dend, dest.toString().length());
                // Add the new string in
                newVal = newVal.substring(0, dstart) + source.toString() + newVal.substring(dstart, newVal.length());
                input = Integer.parseInt(newVal);
            }

            //int input = Integer.parseInt(dest.toString() + source.toString());

            if (isInRange(min, max, input))
                return null;
        } catch (NumberFormatException nfe) {
        }
        return "";
    }

//also the filler must set as below: in the edit createview
// to allow enter number and backspace.
et.setFilters(new InputFilter[]{new InputFilterMinMax(min >= 10 ?  "0" : String.valueOf(min), max >-10 ? String.valueOf(max) :"0" )});



//and at same time must check range in the TextWatcher()
et.addTextChangedListener(new
 TextWatcher() {

      @Override
      public void afterTextChanged (Editable editable)
      {
         String tmpstr = et.getText().toString();
         if (!tmpstr.isEmpty() && !tmpstr.equals("-") ) {
             int datavalue = Integer.parseInt(tmpstr);
             if ( datavalue >= min || datavalue <= max) {
               // accept data ...     
             }
         }
      }
 });

0

Pratik'in cevabına eklemek için, işte kullanıcının en az 2 hane de girebileceği değiştirilmiş bir sürüm, örneğin, 15 ila 100:

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

public class InputFilterMinMax implements InputFilter {

    private int min, max;

    public InputFilterMinMax(int min, int max) {
        this.min = min;
        this.max = max;
    }

    public InputFilterMinMax(String min, String max) {
        this.min = Integer.parseInt(min);
        this.max = Integer.parseInt(max);
    }

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

        try {
            if(end==1)
                min=Integer.parseInt(source.toString());
            int input = Integer.parseInt(dest.toString() + source.toString());
            if (isInRange(min, max, input))
                return null;
        } catch (NumberFormatException nfe) {
        }
        return "";
    }

    private boolean isInRange(int a, int b, int c) {

        return b > a ? c >= a && c <= b : c >= b && c <= a;
    }}

eklendi: if (end == 1) min = Integer.parseInt (source.toString ());

Bu yardımcı olur umarım. lütfen sebepsiz yere olumsuz oy vermeyin.


0

İşte kullandığım yol, negatif sayı için çalışıyor

İlk olarak, aşağıdaki kodla MinMaxFIlter.java sınıfını oluşturun:

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

/**
* Created by 21 on 4/5/2016.
*/
public class MinMaxFilter implements InputFilter {

private double mIntMin, mIntMax;

public MinMaxFilter(double minValue, double maxValue) {
    this.mIntMin = minValue;
    this.mIntMax = maxValue;
}

public MinMaxFilter(String minValue, String maxValue) {
    this.mIntMin = Double.parseDouble(minValue);
    this.mIntMax = Double.parseDouble(maxValue);
}

@Override
public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
    try {
        Boolean isNeg = false;
        String provi = dest.toString() + source.toString();
        if("-".equals(provi.substring(0,1))){
            if(provi.length()>1) {
                provi = provi.substring(1, provi.length());
                isNeg = true;
            }
            else{
                if("".equals(source)){
                    return null;
                }
                return "-";
            }
        }

        double input = Double.parseDouble(provi); 
        if(isNeg){input = input * (-1);}

        if (isInRange(mIntMin, mIntMax, input)) {
            return null;
        }
    } catch (Exception nfe) {}
    return "";
}

private boolean isInRange(double a, double b, double c) {
    if((c>=a && c<=b)){
        return true;
    }
    else{
        return false;
    }
}
}

Ardından, filtrenizi aşağıdaki gibi oluşturup edittext'inize ayarlayın:

EditText edittext = new EditText(context);
editext.setInputType(InputType.TYPE_CLASS_NUMBER | InputType.TYPE_NUMBER_FLAG_SIGNED);
eInt.setFilters(new InputFilter[]{new MinMaxFilter(min, max)});

0

bu benim kodum max = 100, min = 0

xml

<TextView
                    android:id="@+id/txt_Mass_smallWork"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:textColor="#000"
                    android:textSize="20sp"
                    android:textStyle="bold" />

java

EditText ed = findViewById(R.id.txt_Mass_smallWork);
    ed.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) {
            if(!charSequence.equals("")) {
                int massValue = Integer.parseInt(charSequence.toString());
                if (massValue > 10) {
                    ed.setFilters(new InputFilter[]{new InputFilter.LengthFilter(2)});
                } else {
                    ed.setFilters(new InputFilter[]{new InputFilter.LengthFilter(3)});
                }
            }
        }

        @Override
        public void afterTextChanged(Editable editable) {

        }
    });

0

Bunu bir InputFilter ile yapabilirsiniz. Görünüşe göre, kullanabileceğiniz bu Giriş Filtresi Arayüzü var. Sinir bozucu bir şekilde yapmadan önce, Giriş filtresini genişleten yeni bir Sınıf oluşturmadan önce, bu kısayolu bir sınıf içi arabirim somutlaştırması ile kullanabilirsiniz.

Bu nedenle, sadece şunu yaparsınız:

EditText subTargetTime = (EditText) findViewById(R.id.my_time);
subTargetTime.setFilters( new InputFilter[] {
                new InputFilter() {
                    @Override
                    public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
                        int t = Integer.parseInt(source.toString());
                        if(t <8) { t = 8; }
                        return t+"";

                    }
                }
        });

Bu örnekte, EditText değerinin 8'den büyük olup olmadığını kontrol ediyorum. Değilse, 8'e ayarlanacaktır. Bu yüzden, min max veya herhangi bir filtre mantığına kendi kendinize gelmeniz gerekir. Ama en azından filtre mantığını oldukça düzgün ve kısa olarak doğrudan EditText'e yazabilirsiniz.

Bu yardımcı olur umarım


0

EditText'in minimum değerini tanımlamak için şunu kullandım:

if (message.trim().length() >= 1 && message.trim().length() <= 12) {
  // do stuf
} else {
  // Too short or too long
}

0

@ Patrik'in kodunun güzel bir fikri var ama pek çok hata var. @Zac ve @Anthony B (negatif sayı çözümleri) bazılarını çözdü, ancak @ Zac'in kodunda hala 3 belediye başkanı hatası var:

1. Kullanıcı EditText'teki tüm girişleri silerse, herhangi bir sayıyı tekrar yazmak imkansızdır .. Elbette bu, her alanda bir EditText değiştirilmiş dinleyici kullanılarak kontrol edilebilir, ancak her biri için ortak bir InputFilter sınıfı kullanmanın güzelliğini ortadan kaldıracaktır. Uygulamanızda EditText.

2. @ Guernee4, örneğin min = 3 ise, 1 ile başlayan herhangi bir sayının yazılmasının imkansız olduğunu söylüyor.

3. Örneğin min = 0 ise, istediğiniz çok sayıda sıfır varsa, sonucun zarif olmadığını yazabilirsiniz. Veya ayrıca, minimum değer ne olursa olsun, kullanıcı imleci ilk sayının sol boyutuna yerleştirebilir, bu da zarif olmayan bir dizi sıfırları sola yerleştirebilir.

Bu 3 hatayı çözmek için @ Zac'in kodundaki bu küçük değişikliklerle geldim. Hata # 3 ile ilgili olarak, sol taraftaki tüm önde gelen sıfırları hala tam olarak silemedim; Her zaman bir olabilir, ancak bu durumda 00, 01, 0100 vb. Daha zariftir ve 000000, 001, 000100 vb. Vb.

İşte kod:

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

            // Using @Zac's initial solution
            String lastVal = dest.toString().substring(0, dstart) + dest.toString().substring(dend);
            String newVal = lastVal.substring(0, dstart) + source.toString() + lastVal.substring(dstart);
            int input = Integer.parseInt(newVal);

            // To avoid deleting all numbers and avoid @Guerneen4's case
            if (input < min && lastVal.equals("")) return String.valueOf(min);

            // Normal min, max check
            if (isInRange(min, max, input)) {

                // To avoid more than two leading zeros to the left
                String lastDest = dest.toString();
                String checkStr = lastDest.replaceFirst("^0+(?!$)", "");
                if (checkStr.length() < lastDest.length()) return "";

                return null;
            }
        } catch (NumberFormatException ignored) {}
        return "";
    }

İyi günler!


-1

İşte Pratik Sharma'nın cevabını Kotlinve Doubleherhangi birinin buna ihtiyacı varsa

class InputFilterMinMax : InputFilter {

private var min: Double = MIN_LIMIT
private var max: Double = MIN_LIMIT

constructor(min: Int, max: Int) {
    this.min = min.toDouble()
    this.max = max.toDouble()
}

constructor(min: String, max: String) {
    this.min = min.toDouble()
    this.max = max.toDouble()
}

constructor(min: Double, max: Double) {
    this.min = min
    this.max = max
}

override fun filter(
    source: CharSequence,
    start: Int,
    end: Int,
    dest: Spanned,
    dstart: Int,
    dend: Int
): CharSequence? {
    try {
        val input = (dest.toString() + source.toString()).toDouble()
        if (isInRange(min, max, input))
            return null
    } catch (nfe: NumberFormatException) {
        Timber.e(nfe)
    }

    return ""
}

private fun isInRange(a: Double, b: Double, c: Double): Boolean {
    return if (b > a) c in a..b else c in b..a
}
}

Bu giriş filtresi yanlıştır, metnin başlangıç, bitiş, dstart, dend indislerini göz ardı eder, bu nedenle ortada bir karakter ekleyerek düzenleme metnini değiştirirseniz doğru çalışmayacaktır
Radu
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.