Android에서 EditText의 최소 및 최대 값을 정의하는 방법이 있습니까?


133

에 대한 최소값과 최대 값을 정의하고 싶습니다 EditText.

예를 들어, 한 사람이 월 값을 입력하려고하면 1-12 사이 여야합니다.

나는 그것을 사용하여 그것을 할 수 TextWatcher있지만 레이아웃 파일이나 다른 곳에서 다른 방법이 있는지 알고 싶다.

편집 : 문자 수를 제한하고 싶지 않습니다. 값을 제한하고 싶습니다. 예를 들어 EditText12를 입력 할 때 월 w 문자를 제한 하면 12를 입력하지만 22를 입력하면 입력하는 동안 허용해서는 안됩니다.


누군가는 이러한 모든 유형의 입력 필터를 라이브러리 / 컬렉션으로 만들어야합니다. 그런 다음 모두가 함께 작업하고 테스트 할 수 있습니다. 각 사람이 자신의 일을하는 것이 아닙니다.
Zapnologica 2016 년

이 편집 텍스트 필터를 사용하여 문제를 해결하십시오. 필터
Taras Smakula

답변:


286

먼저이 수업을 만드십시오 :

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

그런 다음 활동에서 이것을 사용하십시오.

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

이를 통해 사용자 는 1에서 12 사이의 값만 입력 할 수 있습니다 .

편집하다 :

로 편집 텍스트를 설정하십시오 android:inputType="number".

자세한 내용은 https://www.techcompose.com/how-to-set-minimum-and-maximum-value-in-edittext-in-android-app-development/ 에서 확인할 수 있습니다 .

감사.


1
트윗 담아 가기 시도해보고 도움이 필요하면 알려주십시오. 감사.
Pratik Sharma

12
아 도움이 필요해 1930과 1999 사이의 값을 쓰는 동안 문제가 있습니다. 1을 쓸 때 값을 제어하고 1은 1930과 1999 사이가 아니므로 받아들이지 않습니다.
mertaydin

1
@mertaydin 이봐 미안하지만 내 작품에 약간 바빠서 불을 붙였다. 방금 시간을 들여서 필터 클래스에 적용된 알고리즘을 수정해야한다고 생각합니다. 내가 그 일을 마치면 당신을 업데이트 할 것입니다.
Pratik Sharma

1
의 일부 문자는의 일부 문자를 source대체합니다 dest. 교체품을 시뮬레이션하고 최종 결과를 얻은 다음 확인해야한다고 생각합니다.
SD

3
@Pratik Sharma, 1900 년에서 2000 년까지 범위에 들어가면 작동하지 않습니다. 제안 할 수 있습니까
EminenT

89

Pratik의 코드에 작은 오류가 있습니다. 예를 들어, 값이 10이고 처음에 1을 추가하여 110을 만들면 필터 함수는 새 값을 101로 처리합니다.

이에 대한 수정 사항은 아래를 참조하십시오.

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

고마워이게 많은 도움이되었습니다!
joschplusa

4
나는이 명확 생각 이럴 :String replacement = source.subSequence(start, end).toString(); String newVal = dest.subSequence(0, dstart).toString() + replacement + dest.subSequence(dend, dest.length()).toString();
스벤 제이콥스에게

1
+1. 이 솔루션은 허용 된 것보다 더 정확합니다. 이를 확인하려면 예를 들어 selectAllOnFocus 옵션이 활성화 된 상태에서 InputFilterMinMax 를 사용하고 결과를 비교하십시오.
Sash0k

1
String newVal= dest.toString().substring(0, dstart) + source.toString().substring(start, end) + dest.toString().substring(dend, dest.toString().length());더 깨끗하고 깨끗하게 보입니다.
Shishir Gupta

5
OP @mertaydin이 @Patrick의 답변에 대한 의견에서 언급 했듯이이 솔루션에는 여전히 큰 결함이 있지만 왜보고되지 않은지 궁금합니다 min==3.1 또는 2로 시작하는 숫자를 입력 할 수 없습니다 (예 : 15, 23)
Guerneen4

10

@Patrik의 솔루션과 @Zac의 추가에서 본 것 중에서 제공된 코드는 여전히 큰 문제가 있습니다.

그렇다면 min==31 또는 2로 시작하는 숫자를 입력 할 수 없습니다 (예 : 15, 23)
그렇다면 min>=10모든 숫자가 1,2,3으로 시작해야하므로 아무것도 입력 할 수 없습니다 ...

내 이해로는 사용자가 양수를 입력하면 값이 커지고 쉽게 수행 할 수 있기 때문에 최소한 min 값이 아닌 EditText클래스를 간단히 사용하여 값 의 최소-최대 제한을 달성 할 수 없습니다 InputFilterMinMax. 즉시 테스트를 통해 한계에 도달했는지 또는 범위를 벗어 났는지 확인하고 준수하지 않는 항목을 차단합니다. 사용자가 입력을 완료했는지 여부를 확신 할 수 없으므로 차단해야하는지 여부를 결정할 수 없으므로 최소값 테스트는 다른 이야기입니다.

그것은 OP가 요청한 것이 아니라 검증 목적으로 InputFilter최대 값을 테스트 하기 위해 솔루션에 결합했으며 사용자가 입력을 마치고 포커스를 잃을 OnFocusChangeListener때 최소 값을 다시 테스트하기 위해 EditText다음과 같이했습니다.

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

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
            }

        }
    }
}
}

그런 활동의 설정 InputFilterMax과를 OnFocusChangeListenerMinEditText 참고 : 수있는이 두 분, 맥스 onFocusChangeListener.

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

OnFocusChangeListenerMin이 작동하지 않습니다. 모든 값을 0에서 시작합니다.
EminenT

1
좀 더 자세히 설명해 주시겠습니까? 모든 값을 0에서 무엇을 의미 합니까?
Guerneen4

코드에서 OnFocusChangeListenerMin은 문제 부에서 논의했듯이 20 이상으로 작동해야합니다. 0, 1, 2, ------ 19 등 20 미만의 모든 값을 허용합니다.
EminenT

해결책을 찾았습니까?
EminenT

유효성 검사의 목적으로 OnFoncusChangeListener를 사용했습니다. 제 경우에는 EditText에 오류를 표시합니다. 토스트로 사용자에게 값이 좋지 않다고 if(Integer.valueOf(val)<min){ //Notify user that the value is not good } 알리고 새 값을 입력하도록 초대 합니다. 원하는 것을 수행 할 수 있습니다. 사용자 및 EditText를 공백으로 설정하면 이것이 귀하의 질문에 대한 답변인지 알 수 없습니다.
Guerneen4 2016 년

9

Pratik과 Zac의 답변 확장. Zac는 그의 답변에서 Pratik의 작은 버그를 수정했습니다. 그러나 코드가 음수 값을 지원하지 않으면 NumberFormatException이 발생합니다. 이를 수정하고 MIN을 음수로 만들려면 다음 코드를 사용하십시오.

다른 두 줄 사이에이 줄을 굵게 표시하십시오.

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

if (newVal.equalsIgnoreCase ( "-") && min <0) null을 반환합니다.

int 입력 = 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과 같은 음수 범위를 필요로하는 경우이 솔루션을 사용할 수 있습니다.

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 코드를 확장하여 int 대신 BigDecimal 객체를 사용하여 더 큰 숫자를 허용하고 숫자가 아닌 EditText의 형식 (예 : 공백, 쉼표 및 마침표)

편집 :이 구현은 통화에 사용했을 때 BigDecimal (MIN_SIG_FIG 상수 참조)에 설정된 최소 유효 숫자로 2를 가지고 있으므로 소수점 앞에 항상 2 개의 선행 숫자가 있습니다. 자체 구현에 필요한대로 MIN_SIG_FIG 상수를 변경하십시오.

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

내 대답을 찾았습니다. 지금은 늦었지만 당신과 공유하고 싶습니다. 이 인터페이스를 구현합니다.

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

}

그런 다음 활동 내에서 다음과 같이 구현하십시오.

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();
            }
        }
    });
}

더 좋은 말이 있으면 알려주세요.


int n = 0; 중복됩니다. N의 기본값은 0이기 때문에
케니 Dabiri

1
왜 int n = 0이 중복입니까? 여기서는 로컬 변수이며 인스턴스 변수는 아닙니다.
User12111111

4

허용 된 답변에 문제가 있습니다.

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

커서를 텍스트 중간으로 옮기고 무언가를 입력하면 위의 문장이 잘못된 결과를 생성합니다. 예를 들어, 먼저 "12"를 입력 한 다음 1과 2 사이에 "0"을 입력하면 위에서 언급 한 명령문은 102 대신 "120"을 생성합니다.이 명령문을 아래 명령문으로 수정했습니다.

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

4

필요한 경우 Kotlin (유틸리티 사용)

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

그런 다음 Kotlin 클래스에서 이것을 사용하십시오.

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

이 EditText는 1에서 100까지 허용합니다.

그런 다음 XML에서 이것을 사용하십시오.

android:inputType="number"

리턴 소스를 사용하고 나를 위해 일합니다 ==> if (isInRange (min, max, input)) 리턴 소스
Muzafferus

3

최소 / 최대를 편집 텍스트로 설정하는 더 간단한 방법을 만들었습니다. 산술 키패드를 사용 하고이 방법으로 작업합니다.

 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());
    }
 }

이 방법은 모든 값을 허용하지만 사용자 값이 한계를 준수하지 않으면 자동으로 최소 / 최대 한계로 설정됩니다. 예를 들어. limit limin = 10, limax = 80 사용자가 8을 설정하면 자동으로 10이 변수에 저장되고 EditText가 10으로 설정됩니다.


3

나는 이것에 이미 백만 개의 답변이 있으며, 하나는 받아 들였다. 그러나 허용 된 답변에는 수많은 버그가 있으며 나머지 대부분은 가능한 모든 사용 사례로 확장하지 않고 단순히 하나 또는 두 개를 수정합니다.

따라서 기본적으로 지원 답변에서 제안 된 대부분의 버그 수정을 컴파일하고 범위를 벗어난 숫자를 0 방향 (범위가 0에서 시작하지 않는 경우)으로 연속 입력 할 수있는 방법을 추가했습니다. 더 이상 범위 내에 있지 않아야합니다. 분명히하기 위해, 지금이 다른 많은 솔루션에 실제로 문제를 일으키는 유일한 시간입니다.

수정 사항은 다음과 같습니다.

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("");
        }
    }

}

일부 입력 사례는 "활성 적으로"처리 할 수 ​​없으므로 (즉, 사용자가 입력 한대로)이를 무시하고 사용자가 텍스트 편집을 마친 후에 처리해야합니다.

사용 방법은 다음과 같습니다.

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);

이제 사용자가 허용되는 범위보다 0에 가까운 숫자를 입력하려고하면 다음 두 가지 중 하나가 발생합니다.

  1. 경우 minmax동일한 자릿수의 그들이 마지막 자리에 도착하면, 그들은 모두에서 입력을 허용하지 않습니다.

  2. 텍스트가 포커스를 잃을 때 범위를 벗어난 숫자가 필드에 남아 있으면 가장 가까운 경계로 자동 조정됩니다.

물론, 사용자는 허용되는 범위보다 0에서 더 멀리 떨어진 값을 입력 할 수 없으며 이와 같은 숫자로 인해 텍스트 필드에 "실수로"있을 수도 없습니다.

알려진 문제

  1. EditText사용자가 작업을 마쳤을 때 포커스를 잃는 경우에만 작동 합니다.

다른 옵션은 사용자가 "완료"/ 반환 키를 눌렀을 때 살균하는 것이지만, 대부분 또는 대부분의 경우 어쨌든 초점이 손실됩니다.

그러나 소프트 키보드를 닫아도 요소 초점이 자동으로 해제되지 는 않습니다 . 나는 안드로이드 개발자의 99.99 %가 그것을 원한다고 확신하지만 (그리고 EditText요소에 대한 초점 처리 는 일반적으로 큰 문제가 아니 었습니다), 그러나 현재로서는 내장 기능이 없습니다. 이 문제를 해결하는 가장 쉬운 방법은 EditText다음과 같이 확장하는 것입니다.

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

뷰가 실제로 포커스를 잃지 않았더라도 입력을 살균하기 위해 필터를 "트릭"합니다 . 보기가 나중에 자체적으로 초점을 잃으면 입력 위생이 다시 트리거되지만 이미 수정되었으므로 아무것도 변경되지 않습니다.

폐쇄

아휴. 그것은 많았다. 처음에는 꽤 쉬운 문제인 것처럼 보였지만 바닐라 안드로이드의 작은 조각을 발견했습니다 (적어도 Java에서는). 다시 한 번, 리스너를 추가하고 EditText범위에 0이 포함되지 않은 경우 확장 하면됩니다. (실제로 범위에 0이 포함되어 있지 않지만 1 또는 -1에서 시작하면 문제가 발생하지 않습니다.)

마지막으로, 이것은 int 에서만 작동합니다 . 확실히 십진수 ( double, float) 로 작동하도록 구현할 수있는 방법이 있지만, 나나 원래의 요구자는 그것을 필요로하지 않기 때문에 특별히 깊이 들어가고 싶지는 않습니다. 완료 후 필터링을 다음 행과 함께 사용하는 것이 매우 쉽습니다.

// 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;

당신은에서 변경해야 할 것입니다 intfloat(또는 double), 하나의 삽입을 허용 .(또는 ,, 국가에 따라?), 그리고 대신의 진수 유형 중 하나로서 구문 분석 int.

어쨌든 대부분의 작업을 처리하므로 매우 유사하게 작동합니다.


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에 대한 매우 간단한 예 :

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

이 코드를 확인하십시오

    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 
  }

텍스트 감시자와 함께 편집 텍스트 및 편집 텍스트 필터에 대한 자세한 내용을 보려면 아래 링크를 사용하십시오.

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


OP는 값을 입력 할 때이를 확인하려고합니다. 가치를 입력 한 후 시나리오에 대한 솔루션을 제공했다고 생각합니다
MysticMagicϡ

나는 질문자가 아닙니다. 나는 당신의 대답에 대해 의문을 가지고 있었기 때문에 그것을 명확히하고있었습니다.
MysticMagicϡ

문자 수를 확인하고 싶지 않습니다. 이 코드에서 카운트를 확인하려고한다고 생각합니다. 1-12는 13,14 등이 아닙니다. 따라서 99가 2 자 길이가 될 때까지 12,13,14입니다.
mertaydin

안녕 @ mertaydin 당신이 제공 한 링크로 시도 했습니까 .. 그 예를 참조하십시오 .. 당신이 원하는 것일 수 있습니다. 그것은 당신이 입력하는 동안 텍스트를 볼 수 있습니다 ..
itsrajesh4uguys

감사합니다. 귀하의 답변과 @Pratik Sharma의 답변을 시도하겠습니다.
mertaydin

1

최대 한도에만 관심이 있다면 아래 줄을 추가하십시오.

android:maxLength="10" 

최소 제한을 추가 해야하는 경우이 방법으로 최소 제한은 7입니다. 사용자는 최소 제한과 최대 제한 사이에 문자를 입력하도록 제한됩니다 (8 ~ 10 사이)

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();
        }
    }

시작시 사용자가 01을 입력하도록 제한 해야하는 경우 다음과 같이 if 조건을 수정하십시오.

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

최종 통화 방법에서

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

2
vlaue, 길이는 아닙니다
포트폴리오

1

@Pratik Sharma

음수 를 지원 하려면 필터 메소드 내에 다음 코드를 추가하십시오 .

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

}

그런 다음 활동에서 이것을 사용하십시오.

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

다음을 사용하여 편집 텍스트를 설정하십시오.

android:inputType="number|numberSigned"

0

// 여전히 문제가 있지만 여기에서 어떤 범위에서든 양, 최대를 사용할 수 있습니다 (양수 또는 음수)

// 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의 답변에 추가하기 위해 다음은 사용자가 최소 2 자리를 입력 할 수있는 수정 된 버전입니다 (예 : 15-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;
    }}

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

도움이 되었기를 바랍니다. 이유없이 친절하게 공감하지 마십시오.


0

여기 내가 사용한 방식이 있습니다. 음수로 작동합니다.

먼저 다음 코드를 사용하여 MinMaxFIlter.java 클래스를 작성하십시오.

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

그런 다음 필터를 작성하고 다음과 같이 편집 텍스트로 설정하십시오.

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

이것은 내 코드입니다 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" />

자바

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

InputFilter로이를 수행 할 수 있습니다. 분명히이 입력 필터 인터페이스 만 사용할 수 있습니다. 입력 필터를 확장하는 새로운 클래스를 만드는 성가신 방법을 수행하기 전에 내부 클래스 인터페이스 인스턴스화와 함께이 바로 가기를 사용할 수 있습니다.

따라서 당신은 이것을 이렇게합니다 :

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+"";

                    }
                }
        });

이 예제에서는 EditText의 값이 8보다 큰지 확인합니다. 그렇지 않으면 8로 설정해야합니다. 따라서 최소한 max 또는 다른 필터 로직을 스스로 구성해야합니다. 그러나 적어도 u는 필터 로직을 EditText에 직접 깔끔하고 짧게 쓸 수 있습니다.

도움이 되었기를 바랍니다


0

EditText의 최소값을 정의하기 위해 다음을 사용했습니다.

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

0

@Patrik의 코드에는 좋은 아이디어가 있지만 많은 버그가 있습니다. @Zac 및 @Anthony B (음수 솔루션)는 그중 일부를 해결했지만 @Zac의 코드에는 여전히 3 개의 시장 버그가 있습니다.

1. 사용자가 EditText의 모든 항목을 삭제하면 숫자를 다시 입력 할 수 없습니다. 물론 각 필드에서 EditText 변경 리스너를 사용하여 제어 할 수는 있지만 각 필드에 대해 공통 InputFilter 클래스를 사용하는 것의 아름다움을 없애줍니다. 앱의 EditText

2. @ Guernee4에 따르면, 예를 들어 min = 3이면 1부터 시작하는 숫자를 입력 할 수 없습니다.

3. 예를 들어 min = 0 인 경우 원하는 0을 많이 입력하면 결과가 우아하지 않을 수 있습니다. 또는 최소값이 무엇이든간에 사용자는 커서를 첫 번째 숫자의 왼쪽 크기, 왼쪽의 선행 0을 왼쪽으로 배치 할 수 있으며 우아하지도 않습니다.

이 3 가지 버그를 해결하기 위해 @Zac 코드의 작은 변경 사항을 알려 드리겠습니다. 버그 # 3에 관해서는 여전히 왼쪽의 모든 선행 0을 완전히 제거 할 수 없었습니다. 항상 하나 일 수 있지만 그 경우 00, 01, 0100 등은 000000, 001, 000100 등보다 더 우아합니다. 기타.

코드는 다음과 같습니다.

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

좋은 하루 보내세요!


-1

여기 Pratik 샤르마의 대답에 내 걸릴위한거야 KotlinDouble하나가 그것을 필요로하는 경우

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

이 입력 필터가 잘못되어 텍스트의 시작, 종료, dstart, 덴드 인덱스를 무시하므로 중간에 문자를 삽입하여 편집 텍스트를 변경하면 올바르게 작동하지 않습니다.
Radu
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.