'InputFilter'에 해당되는 글 1건

  1. 2010.12.01 [안드로이드] 바이트 길이로 사용자 입력을 제한하는 InputFilter (11)
android.text.InputFilter를 이용해서 사용자의 텍스트입력을 다양한 방식으로 필터링할 수 있습니다. 
입력문자를 모두 대문자로 바꾸거나(InputFilter.AllCaps 이용), 문자열의 길이를 제한(InputFilter.LengthFilter 이용)할 수 있죠. 그밖에 다양한 필터를 만들 수 있을 겁니다. (정규식을 적용한 필터 예제 : http://flysky.thoth.kr/blog/4208673)

그런데 안드로이드가 기본으로 제공하는 InputFilter.LengthFilter는, 글자수(캐릭터 수)로 문자열의 길이를 계산하기 때문에 바이트 수로 길이를 제한하고 싶은 경우에는 사용할 수 없습니다. (한글처럼 문자열에 non-ascii 글자가 포함되면 글자 수 < 바이트 수).

아래 ByteLengthFilter는 바이트 길이로 입력을 제한해주는 필터입니다.

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

/**
 * EditText 등의 필드에 텍스트 입력/수정시 
 * 입력문자열의 바이트 길이를 체크하여 입력을 제한하는 필터.
 *
 */
public class ByteLengthFilter implements InputFilter {

    private String mCharset; //인코딩 문자셋

    protected int mMaxByte; // 입력가능한 최대 바이트 길이

    public ByteLengthFilter(int maxbyte, String charset) {
        this.mMaxByte = maxbyte;
        this.mCharset = charset;
    }

    /**
     * 이 메소드는 입력/삭제 및 붙여넣기/잘라내기할 때마다 실행된다.
     *
     * - source : 새로 입력/붙여넣기 되는 문자열(삭제/잘라내기 시에는 "")
     * - dest : 변경 전 원래 문자열
     */
    public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart,
            int dend) {

        // 변경 후 예상되는 문자열
        String expected = new String();
        expected += dest.subSequence(0, dstart);
        expected += source.subSequence(start, end);
        expected += dest.subSequence(dend, dest.length());

        int keep = calculateMaxLength(expected) - (dest.length() - (dend - dstart));

        if (keep <= 0) {
            return ""; // source 입력 불가(원래 문자열 변경 없음)
        } else if (keep >= end - start) {
            return null; // keep original. source 그대로 허용
        } else {
            return source.subSequence(start, start + keep); // source중 일부만 입력 허용
        }
    }

    /**
     * 입력가능한 최대 문자 길이(최대 바이트 길이와 다름!).
     */
    protected int calculateMaxLength(String expected) {
        return mMaxByte - (getByteLength(expected) - expected.length());
    }    
    
    /**
     * 문자열의 바이트 길이.
     * 인코딩 문자셋에 따라 바이트 길이 달라짐.
     * @param str
     * @return
     */
    private int getByteLength(String str) {
        try {
            return str.getBytes(mCharset).length;
        } catch (UnsupportedEncodingException e) {
            //e.printStackTrace();
        }
        return 0;
    }
}    

EditText에는 이렇게 적용하면 됩니다.

int maxByte = ...;
EditText editText = ...;

InputFilter[] filters = new InputFilter[] {new ByteLengthFilter(maxByte, "KSC5601")};
editText.setFilters(filters);

신고
크리에이티브 커먼즈 라이선스
Creative Commons License
Posted by 에코지오

댓글을 달아 주세요

  1. BlogIcon 휴우 2010.12.02 20:20 신고  댓글주소  수정/삭제  댓글쓰기

    좋은 내용 감사합니다. 그렇지 않아도 한글 입력관련에서 바이트 제한이 필요했는데 정말 큰 도움이 되었습니다.

  2. 프리티나 2010.12.14 22:19 신고  댓글주소  수정/삭제  댓글쓰기

    입력 제한이 있어서 찾고 있었는데 너무 감사드립니다.

  3. 님짱 2011.11.29 10:29 신고  댓글주소  수정/삭제  댓글쓰기

    정말 감사합니다. 하나 배워가네요 ㅠㅠ!!

  4. 달군 2011.12.06 16:49 신고  댓글주소  수정/삭제  댓글쓰기

    좋은 내용 감사합니다!
    한가지 더 궁금한게 있는데요, 제가 아직 안드로이드와 Java 문법을 잘 몰라서 그러는데
    코드 거의 마지막 부분에
    return str.getBytes(mCharset).length;
    라고 쓰셧잔아요? .length가 그냥 사용가능한건가요? byte[]에 대해 쓸수있는거같은데 다른 primitive type 배열에도 .length 를 그냥 쓸수있는건지.. 왜 사용가능한건가요?
    너무 기초적인 질문이라서 죄송합니다.^^

  5. 강석렬 2012.08.29 17:52 신고  댓글주소  수정/삭제  댓글쓰기

    감사합니다 덕분에 UTF-8 글자 수 입력 제한도 수월하게 적용할 수 있었습니다~~^^

  6. k 2012.10.25 19:03 신고  댓글주소  수정/삭제  댓글쓰기

    calculateMaxLength 메소드에서

    mMaxByte - (getByteLength(expected) - expected.length());

    문자열의 Byte 길이에서 문자열의 길이를 빼는 이유가 뭐죠?

  7. BlogIcon MFamStory 2013.01.09 10:54 신고  댓글주소  수정/삭제  댓글쓰기

    감사합니다.
    글자수 입력 제한 Byte 방법을 찾고 있었는데좋은 내용 잘 배워갑니다. ㅎㅎ
    출처와 저작권 표시를 명시하고 퍼갈께요.

  8. rgjoon 2016.07.08 11:47 신고  댓글주소  수정/삭제  댓글쓰기

    filter에서 빈 문자열("")을 리턴하면 원래 문자열에 변경이 없는 것이 아니라 dstart - dend 까지의 내용이 없어져 버립니다. 키패드를 통해 입력하는 경우에는 원래 문자열의 뒤에 추가되는 형식이라 변경이 없는 것처럼 보이지만, 원래 문자열의 일부분을 선택한 상태에서 입력하면 해당 부분이 없어집니다. 그게 원래 의도된 동작인지는 모르겠지만, 주석 부분은 수정을 하셔야 될거 같네요.



티스토리 툴바