Android/UI(XML)

InputFilter로 입력값을 제어해보자! (feat. 이모지만 입력받기)

MJ핫산 2022. 11. 10. 00:48

사이드 프로젝트를 진행하던 중 한 가지 문제가 생겼다.

테마별 지도를 주제로 하는 앱이어서 지도를 생성할 때 그 지도의 테마를 잘 나타낼 수 있는 이모지를 등록해야 하는데 만약 사용자가 이모지가 아닌 다른 텍스트를 입력할 경우 앱의 의도와 디자인이 와장창 깨지기 때문에 이모지만 입력할 수 있도록 제재가 필요했다.

🥸 이모지 키보드만 보여주고 싶었지만..

그래서 inputType=“number” 같은 속성을 사용해서 숫자 키보드만 보여주고, 입력도 숫자만 받을 수 있는 것처럼 이모지 키보드만 보여주고 싶었는데... 인생은 절대 호락호락하지 않지. EditText의 속성 중에 이모지만 보여주거나 입력할 수 있는 속성은 없었다.. ㅇ<-<

 

✨ 그럼 일단 입력받고 이모지인지 확인하자!

바로 이모지 키보드를 열어서 보여줄 수 있는 방법은 없지만 차선책을 생각해보았고, 일단 입력을 받은 후 이모지인지 확인하기로 했다.

가장 먼저 생각난 방법은 TextChangedListener를 달아서 텍스트가 변경될 때마다 이모지를 확인하는 것이었다.

binding.editText.addTextChangedListener {
    if (it.toString() !is 이모지) {
        // TODO : 이모지만 입력해주세요!
    }
}

하지만 이미 텍스트를 입력받은 후 체크하기 때문에 동작이 어색했다.

 

그래서 다음으로 찾은 방법이 바로 InputFilter 이다! ✨

💐 InputFilter가 머에용

안드로이드 공식 문서에는 이렇게 적혀있다.

 InputFilters can be attached to `Editable`s to constrain the changes that can be made to them.

대충 해석하면 Editable한 것들에 InputFilter를 연결해서 변경사항을 제한할 수 있다. 즉 문자 입력을 제한할 수 있다는 것 같다. ^^;

아, 그리고 갑자기 생각나서 확인해봤는데 android:inputType="textFilter" 랑은 다른 거더라..

🏋️‍♀️ 사용해보자!

우선 CustomInputFilter를 만들어준다.

class CustomInputFilter : InputFilter {
    override fun filter(
        source: CharSequence?,
        start: Int,
        end: Int,
        dest: Spanned?,
        dstart: Int,
        dend: Int
    ): CharSequence? {
        // source or null을 리턴하면 입력한 값이 그래도 입력됨.
        // ""를 리턴하면 ""가 입력되기 때문에 입력되지 않는 것 처럼 보임.
        // "(마음대로)"를 리턴하면 "(마음대로)"가 입력됨.
        return source
    }
}

그리고 필터를 적용하고 싶은 EditTextView(Editable)에 적용하면 끝!

// 방법 1
binding.editText.filters = arrayOf(CustomInputFilter())

// 방법 2
binding.editText.filters = arrayOf(InputFilter { source, _, _, _, _, _ ->
    return@InputFilter source
})

이제 InputFilter를 이용해서 이모지만 입력할 수 있도록 할 차례!

 

아래 글을 참고했는데, 이 글은 어떻게 하면 이모지를 입력할 수 없게 할 수 있냐는 질문이었어서 난 이걸 반대로 사용했다.

https://stackoverflow.com/questions/22990870/how-to-disable-emoji-from-being-entered-in-android-edittext

class EmojiFilter : InputFilter {
    override fun filter(
        source: CharSequence?,
        start: Int,
        end: Int,
        dest: Spanned?,
        dstart: Int,
        dend: Int
    ): CharSequence? {
        for (i in start until end) {
            val type = Character.getType(source[i]).toByte()
            if (type != Character.SURROGATE && type != Character.OTHER_SYMBOL) {
                return ""
            }
        }

        return source
    }
}

완성한 EmojiFilter를 앱에 적용해보면 이렇게 된다. ><

이모지가 아닌 텍스트를 입력할 때는 아예 입력되지 않고, 이모지를 입력했을 때만 입력되는 것을 볼 수 있다.

👋 마무리

이상 Emoji만 입력받는 등 텍스트 입력을 제한하기 위해서 InputFilter에 대해 알아보았는데요~

혹시 이런 방법 말고도 이모지만 입력받을 수 있는 다른 방법이나, 조건문이나, 아이디어 등이 있으시면 언제든 제보받습니다~

다들 파이팅. 🐜

🔗 참고

- https://developer.android.com/reference/android/text/InputFilter

- https://stackoverflow.com/questions/22990870/how-to-disable-emoji-from-being-entered-in-android-edittext

- https://stackoverflow.com/questions/26024096/is-there-a-way-to-make-android-open-the-emoji-keyboard?noredirect=1&lq=1%EF%BB%BF

- https://latte-is-horse.tistory.com/285

- https://jung-story.tistory.com/61

'Android > UI(XML)' 카테고리의 다른 글

Android 그림자 살펴보기  (2) 2022.10.13