programing

Android에서 EditText의 문자를 제한하려면 InputFilter를 어떻게 사용합니까?

newstyles 2023. 8. 12. 10:04

Android에서 EditText의 문자를 제한하려면 InputFilter를 어떻게 사용합니까?

문자를 0-9, a-z, A-Z 및 스페이스바로만 제한하고 싶습니다.입력 유형을 설정하면 숫자로 제한할 수 있지만 입력 필터가 문서를 보는 방법을 알 수 없습니다.

저는 이것을 다른 포럼에서 찾았습니다.아주 잘 작동합니다.

InputFilter filter = new InputFilter() {
    public CharSequence filter(CharSequence source, int start, int end,
            Spanned dest, int dstart, int dend) {
        for (int i = start; i < end; i++) {
            if (!Character.isLetterOrDigit(source.charAt(i))) {
                return "";
            }
        }
        return null;
    }
};
edit.setFilters(new InputFilter[] { filter });

InputFilter사전 제안을 표시하는 Android 버전에서는 s가 약간 복잡합니다.당신은 가끔 한가지.SpannableStringBuilder은 평범한String에 시대에source 명령어

은 다과같것들.InputFilter작동해야 합니다.이 코드를 자유롭게 개선하십시오!

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

        if (source instanceof SpannableStringBuilder) {
            SpannableStringBuilder sourceAsSpannableBuilder = (SpannableStringBuilder)source;
            for (int i = end - 1; i >= start; i--) { 
                char currentChar = source.charAt(i);
                 if (!Character.isLetterOrDigit(currentChar) && !Character.isSpaceChar(currentChar)) {    
                     sourceAsSpannableBuilder.delete(i, i+1);
                 }     
            }
            return source;
        } else {
            StringBuilder filteredStringBuilder = new StringBuilder();
            for (int i = start; i < end; i++) { 
                char currentChar = source.charAt(i);
                if (Character.isLetterOrDigit(currentChar) || Character.isSpaceChar(currentChar)) {    
                    filteredStringBuilder.append(currentChar);
                }     
            }
            return filteredStringBuilder.toString();
        }
    }
}

훨씬 쉽습니다.

<EditText
    android:inputType="text"
    android:digits="0,1,2,3,4,5,6,7,8,9,*,qwertzuiopasdfghjklyxcvbnm" />

게시된 답변 중 어떤 것도 저에게 효과가 없었습니다.저는 제 나름의 해결책을 가지고 왔습니다.

InputFilter filter = new InputFilter() {
    @Override
    public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
        boolean keepOriginal = true;
        StringBuilder sb = new StringBuilder(end - start);
        for (int i = start; i < end; i++) {
            char c = source.charAt(i);
            if (isCharAllowed(c)) // put your condition here
                sb.append(c);
            else
                keepOriginal = false;
        }
        if (keepOriginal)
            return null;
        else {
            if (source instanceof Spanned) {
                SpannableString sp = new SpannableString(sb);
                TextUtils.copySpansFrom((Spanned) source, start, sb.length(), null, sp, 0);
                return sp;
            } else {
                return sb;
            }           
        }
    }

    private boolean isCharAllowed(char c) {
        return Character.isLetterOrDigit(c) || Character.isSpaceChar(c);
    }
}
editText.setFilters(new InputFilter[] { filter });

이 작업을 100% 필요하고 매우 단순하게 사용하십시오.

<EditText
android:inputType="textFilter"
android:digits="@string/myAlphaNumeric" />

strings.xml에서

<string name="myAlphaNumeric">abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789</string>

입력 유형에서 특수 문자를 피하려면

public static InputFilter filter = new InputFilter() {
    @Override
    public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
        String blockCharacterSet = "~#^|$%*!@/()-'\":;,?{}=!$^';,?×÷<>{}€£¥₩%~`¤♡♥_|《》¡¿°•○●□■◇◆♧♣▲▼▶◀↑↓←→☆★▪:-);-):-D:-(:'(:O 1234567890";
        if (source != null && blockCharacterSet.contains(("" + source))) {
            return "";
        }
        return null;
    }
};

아래와 같이 편집 텍스트에 필터를 설정할 수 있습니다.

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

단순화하기 위해 다음과 같은 작업을 수행했습니다.

edit_text.filters = arrayOf(object : InputFilter {
    override fun filter(
        source: CharSequence?,
        start: Int,
        end: Int,
        dest: Spanned?,
        dstart: Int,
        dend: Int
    ): CharSequence? {
        return source?.subSequence(start, end)
            ?.replace(Regex("[^A-Za-z0-9 ]"), "")
    }
})

이렇게 하면 원본 문자열의 새 부분에 있는 원하지 않는 모든 문자를 빈 문자열로 바꿉니다.

edit_text는 수는입니다.EditText개체를 참조합니다.

는 코는다음같다습니과드다로 쓰여 .kotlin.

첫번추 대가상에 먼저 합니다.strings.xml:

<string name="vin_code_mask">0123456789abcdefghjklmnprstuvwxyz</string>

XML:

android:digits="@string/vin_code_mask"

코틀린의 코드:

edit_text.filters += InputFilter { source, start, end, _, _, _ ->
    val mask = getString(R.string.vin_code_mask)
    for (i in start until end) {
        if (!mask.contains(source[i])) {
            return@InputFilter ""
        }
    }
    null
}

이상하지만 에뮬레이터의 소프트 키보드에서 이상하게 작동합니다.

경고!다음 코드는 소프트웨어 키보드의 숫자를 제외한 모든 문자 및 기타 기호를 필터링합니다.스마트폰에는 디지털 키보드만 나타납니다.

edit_text.keyListener = DigitsKeyListener.getInstance(context.getString(R.string.vin_code_mask))

저도 주로 설정합니다.maxLength,filters,inputType.

승인된 답변 외에도 다음과 같은 방법을 사용할 수 있습니다.android:inputType="textCapCharacters"<EditText>대문자(및 숫자)만 사용할 수 있습니다.

맞습니다. XML 레이아웃 자체에서 다음을 사용하여 수정하는 가장 좋은 방법입니다.

<EditText
android:inputType="text"
android:digits="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" />

Florian Frölich가 올바르게 지적했듯이, 텍스트 보기에도 잘 작동합니다.

<TextView
android:inputType="text"
android:digits="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" />

주의할 점은, 영화에 언급된 등장인물들입니다.android:digits 주의하십시오. :) :) 시만되므문집놓않주의도록하시십오표지치합을자로▁:)▁will오시십. :)

정규식에 원하는 문자를 지정하여 입력 필터에서 사용할 수 있습니다.

val regex = Regex("[a-zA-Z\\d ]")
    
editText.filters = arrayOf(InputFilter { source, _, _, _, _, _ ->
    source.filter { regex.matches(it.toString()) }
})

주의, 나는 사용하지 않았습니다.\w는 언더스코어 클스래밑줄, 있때다니문기입어를 포함하기 입니다._

어떤 이유에서인지 Android.text.LoginFilter 클래스의 생성자는 패키지 범위이므로 이 코드와 동일하더라도 직접 확장할 수 없습니다.그러나 LoginFilter를 확장할 수 있습니다.사용자 이름 필터일반!그러면 다음과 같이 됩니다.

class ABCFilter extends LoginFilter.UsernameFilterGeneric {
    public UsernameFilter() {
        super(false); // false prevents not-allowed characters from being appended
    }

    @Override
    public boolean isAllowed(char c) {
        if ('A' <= c && c <= 'C')
            return true;
        if ('a' <= c && c <= 'c')
            return true;

        return false;
    }
}

이것은 실제로 문서화되지는 않았지만 코어 lib의 일부이며 소스는 간단합니다.저는 지금까지 그것을 한동안 사용해왔지만, 아직까지는 문제가 없습니다. 스패너블과 관련된 복잡한 것을 시도해 본 적이 없다는 것은 인정합니다.

사용자가 텍스트 편집에 빈 문자열을 입력하지 못하도록 해야 할 때 이 간단한 해결책이 도움이 되었습니다.물론 문자를 더 추가할 수 있습니다.

InputFilter textFilter = new InputFilter() {

@Override

public CharSequence filter(CharSequence c, int arg1, int arg2,

    Spanned arg3, int arg4, int arg5) {

    StringBuilder sbText = new StringBuilder(c);

    String text = sbText.toString();

    if (text.contains(" ")) {    
        return "";   
    }    
    return c;   
    }   
};

private void setTextFilter(EditText editText) {

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

}

이 스레드는 오래된 스레드이지만 특정 솔루션에는 모두 문제가 있습니다(장치/Android 버전/키보드에 따라 다름).

다른 접근 방식

그래서 결국 저는 다른 접근 방식을 사용했습니다.InputFilter가 있는 저는 문가있는구현나, 사있다습니고하용는제다를 사용하고 .TextWatcher 리고그고.TextChangedListener의 시대의EditText.

전체 코드(예)

editText.addTextChangedListener(new TextWatcher() {

    @Override
    public void afterTextChanged(Editable editable) {
        super.afterTextChanged(editable);

        String originalText = editable.toString();
        int originalTextLength = originalText.length();
        int currentSelection = editText.getSelectionStart();

        // Create the filtered text
        StringBuilder sb = new StringBuilder();
        boolean hasChanged = false;
        for (int i = 0; i < originalTextLength; i++) {
            char currentChar = originalText.charAt(i);
            if (isAllowed(currentChar)) {
                sb.append(currentChar);
            } else {
                hasChanged = true;
                if (currentSelection >= i) {
                    currentSelection--;
                }
            }
        }

        // If we filtered something, update the text and the cursor location
        if (hasChanged) {
            String newText = sb.toString();
            editText.setText(newText);
            editText.setSelection(currentSelection);
        }
    }

    private boolean isAllowed(char c) {
        // TODO: Add the filter logic here
        return Character.isLetter(c) || Character.isSpaceChar(c);
    }
    @Override
    public void beforeTextChanged(CharSequence s, int start, int count, int after) {
        // Do Nothing
    }

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

ㅠㅠInputFilter키보드 구현에 따라 다르기 때문에 Android에서는 좋은 솔루션이 아닙니다.은 입키력다전로달전중기다입니로 되기 .EditText그러나 일부 키보드는 다른 구현을 가지고 있기 때문에InputFilter.filter()호출, 이것은 문제가 있습니다.

에 ㅠㅠㅠTextWatcher키보드 구현에는 관심이 없으며, 간단한 솔루션을 만들고 모든 장치에서 작동할 수 있도록 합니다.

InputFilter를 하위 분류하면 영숫자가 아닌 문자를 필터링하는 자체 InputFilter를 만들 수 있습니다.

한방법이 있습니다.filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend)또한 할당된 텍스트 편집에 어떤 문자가 입력되었는지 알아야 하는 모든 정보를 제공합니다.

고유한 입력 필터를 만든 후 setFilters(...)를 호출하여 텍스트 편집에 할당할 수 있습니다.

http://developer.android.com/reference/android/text/InputFilter.html#filter(java.lang .CharSequence, int, int, android.text.스판, int, int)

다른 사람들이 다뤄온 범위의 내용을 무시하고 사전 제안을 적절하게 처리하기 위해 다음과 같은 코드가 작동한다는 것을 알게 되었습니다.

제안이 증가함에 따라 소스가 증가하므로 반환하기 전에 실제로 대체할 문자 수를 확인해야 합니다.

잘못된 문자가 없으면 null을 반환하여 기본 대체를 수행합니다.

그렇지 않으면 편집 텍스트에 실제로 배치될 하위 문자열에서 유효한 문자를 추출해야 합니다.

InputFilter filter = new InputFilter() { 
    public CharSequence filter(CharSequence source, int start, int end, 
    Spanned dest, int dstart, int dend) { 

        boolean includesInvalidCharacter = false;
        StringBuilder stringBuilder = new StringBuilder();

        int destLength = dend - dstart + 1;
        int adjustStart = source.length() - destLength;
        for(int i=start ; i<end ; i++) {
            char sourceChar = source.charAt(i);
            if(Character.isLetterOrDigit(sourceChar)) {
                if(i >= adjustStart)
                     stringBuilder.append(sourceChar);
            } else
                includesInvalidCharacter = true;
        }
        return includesInvalidCharacter ? stringBuilder : null;
    } 
}; 

편집 텍스트의 단어를 방지합니다.언제든지 사용할 수 있는 클래스를 만듭니다.

public class Wordfilter implements InputFilter
{
    @Override
    public CharSequence filter(CharSequence source, int start, int end,Spanned dest, int dstart, int dend) {
        // TODO Auto-generated method stub
        boolean append = false;
        String text = source.toString().substring(start, end);
        StringBuilder str = new StringBuilder(dest.toString());
        if(dstart == str.length())
        {
            append = true;
            str.append(text);
        }
        else
            str.replace(dstart, dend, text);
        if(str.toString().contains("aaaaaaaaaaaa/*the word here*/aaaaaaaa"))
        {
            if(append==true)
                return "";
            else
                return dest.subSequence(dstart, dend);
        }
        return null;
    }
}

사용할 수 있습니다.setOnKeyListener이 방법으로 입력을 사용자 정의할 수 있습니다.edittext!

이렇게 텍스트 편집의 이름 필드에 대한 필터를 작성했습니다.(첫 문자는 CAPS이며, 각 단어 뒤에는 공백을 하나만 사용할 수 있습니다.

public void setNameFilter() {
    InputFilter filter = new InputFilter() {
        @RequiresApi(api = Build.VERSION_CODES.KITKAT)
        public CharSequence filter(CharSequence source, int start, int end,
                                   Spanned dest, int dstart, int dend) {
            for (int i = start; i < end; i++) {
                if (dend == 0) {
                    if (Character.isSpaceChar(source.charAt(i)) ||
                            !Character.isAlphabetic(source.charAt(i))) {
                        return Constants.Delimiter.BLANK;
                    } else {
                        return String.valueOf(source.charAt(i)).toUpperCase();
                    }
                } else if (Character.isSpaceChar(source.charAt(i)) &&
                        String.valueOf(dest).endsWith(Constants.Delimiter.ONE_SPACE)) {
                    return Constants.Delimiter.BLANK;
                } else if ((!Character.isSpaceChar(source.charAt(i)) &&
                        !Character.isAlphabetic(source.charAt(i)))) {
                    return Constants.Delimiter.BLANK;
                }
            }
            return null;
        }
    };
    editText.setFilters(new InputFilter[]{filter, new InputFilter.LengthFilter(Constants.Length.NAME_LENGTH)});
}

나도 코틀린에서 같은 대답을 합니다.

/**
 * Returns the filter of the editText'es CharSequence value when [filterType] is:
 * 1 -> letters; 2 -> letters and digits; 3 -> digits;
 * 4 -> digits and dots
 */
class InputFilterAlphanumeric(private val filterType: Int): InputFilter {
    override fun filter(source: CharSequence?, start: Int, end: Int, dest: Spanned?, dstart: Int, dend: Int): CharSequence {
        (source as? SpannableStringBuilder)?.let {sourceAsSpannableBuilder  ->
            for (i in (end - 1) downTo start) {
                val currentChar = source[i]
                when(filterType) {
                    1 -> {
                        if (!currentChar.isLetter() && !currentChar.isWhitespace()) {
                            sourceAsSpannableBuilder.delete(i, i + 1)
                        }
                    }
                    2 -> {
                        if (!currentChar.isLetterOrDigit() && !currentChar.isWhitespace()) {
                            sourceAsSpannableBuilder.delete(i, i + 1)
                        }
                    }
                    3 -> {
                        if (!currentChar.isDigit()) {
                            sourceAsSpannableBuilder.delete(i, i + 1)
                        }
                    }
                    4 -> {
                        if (!currentChar.isDigit() || !currentChar.toString().contains(".")) {
                            sourceAsSpannableBuilder.delete(i, i + 1)
                        }
                    }
                }
            }
            return source
        } ?: run {
            val filteredStringBuilder = StringBuilder()
            for (i in start until end) {
                val currentChar = source?.get(i)
                when(filterType) {
                    1 -> {
                        if (currentChar?.isLetter()!! || currentChar.isWhitespace()) {
                            filteredStringBuilder.append(currentChar)
                        }
                    }
                    2 -> {
                        if (currentChar?.isLetterOrDigit()!! || currentChar.isWhitespace()) {
                            filteredStringBuilder.append(currentChar)
                        }
                    }
                    3 -> {
                        if (currentChar?.isDigit()!!) {
                            filteredStringBuilder.append(currentChar)
                        }
                    }
                    4 -> {
                        if (currentChar?.isDigit()!! || currentChar.toString().contains(".")) {
                            filteredStringBuilder.append(currentChar)
                        }
                    }
                }
            }
            return filteredStringBuilder
        }
    }
}

확장 기능이 있는 클래스를 가져옵니다.

fun EditText.filterByDataType(filterType: Int) {
    this.filters = arrayOf<InputFilter>(InputFilterAlphanumeric(filterType))
}

언급URL : https://stackoverflow.com/questions/3349121/how-do-i-use-inputfilter-to-limit-characters-in-an-edittext-in-android