반응형

위로 프로젝트를 진행하면서 게시글이 적힐 때 글자수 제한과 입력받은 글자수를 표시하고 싶어서..! 기능을 구현해보았습니다.

요런식으로 입력 받은 글자수 6/2000를 표시하고 2000자가 넘어가면 더이상 입력되지 않도록.

 

간단하게 레이아웃 구성

최대 40글자/ 최대 4줄 까지 입력될 수 있도록 만들어 보겠습니다.

요런식으로 간단하게 레이아웃 구성을 해주었습니다. 소스 코드는 아래와 같습니다.

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <EditText
        android:id="@+id/editText"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:hint="여기에 입력해주세요."
        android:layout_marginTop="20dp"
        android:layout_marginBottom="70dp"
        android:layout_marginLeft="20dp"
        android:layout_marginRight="20dp"
        android:gravity="top|left"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <TextView
        android:id="@+id/txtCnt"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginEnd="16dp"
        android:text="0 / 40\n 글자"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/editText"
        app:layout_goneMarginEnd="20dp"
        android:layout_marginBottom="20dp"/>

</androidx.constraintlayout.widget.ConstraintLayout>

TextWatcher

 

우선 EditText에 입력되는 텍스트의 변화를 감지하기위해 TextWathcer 객체를 생성하여줍니다.

 아래는 공식문서의 TextWathcer에대한 설명입니다.

When an object of this type is attached to an Editable, its methods will be called when the text is changed.

with(binding){
        editText.addTextChangedListener(object : TextWatcher {
            override fun beforeTextChanged(pos: CharSequence?, p1: Int, p2: Int, p3: Int) {
                TODO("Not yet implemented")
            }

            override fun onTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {
                TODO("Not yet implemented")
            }

            override fun afterTextChanged(p0: Editable?) {
                TODO("Not yet implemented")
            }
        })
    }

TextWatcher 인터페이스의 메서드를 모두 오버라이드 해줍니다. 윈도우 : ctrl + i / 맥 : command + i 

 글자수, 문장수 제한을 넘지 않으면 입력 받은 문자열을 그대로 출력하기 위해 입력받은 문자열이 담길 maxText 변수를 만들어주고

 텍스트가 대체되기 전에 대체됨을 알리기위해 호출되는 함수인 beforeTextChanged에서

maxText = pos.toString()

 

을 처리해줍니다. maxText에는 입력된 값의 마지막 값이 하나 빠진 값이 들어가게 되는데 ex) 1234입력일 경우 maxText = "123"

 나중에 글자수, 문자수 제한을 초과하면 maxText값을 나타낼 것입니다.

 

텍스트가 대체된 것을 알려주기 위해 호출되는 함수인 onTextChanged안에 글자수, 문장수 제한관련 코드를 모두 작성하여줍니다.

코드를 먼저보면 아래와 같습니다.

with(binding){
        editText.addTextChangedListener(object : TextWatcher {
            var maxText = ""
            override fun beforeTextChanged(pos: CharSequence?, p1: Int, p2: Int, p3: Int) {
                maxText = pos.toString()
            }
            override fun onTextChanged(pos: CharSequence?, p1: Int, p2: Int, p3: Int) {

                if(editText.lineCount > 4){
                    Toast.makeText(this@MainActivity, "최대 4줄까지 입력 가능합니다.",
                    Toast.LENGTH_SHORT).show()

                    editText.setText(maxText)
                    editText.setSelection(editText.length())
                    countText.setText("${editText.length()} / 40")
                } else if(editText.length() > 40){
                    Toast.makeText(this@MainActivity, "최대 40자까지 입력 가능합니다.",
                    Toast.LENGTH_SHORT).show()

                    editText.setText(maxText)
                    editText.setSelection(editText.length())
                    countText.setText("${editText.length()} / 40")
                } else {
                    countText.setText("${editText.length()} / 40")
                }
            }
            override fun afterTextChanged(p0: Editable?) {

            }
        })
    }

유저가 입력한 텍스트값을 그대로 저장할 변수인 userInput을 선언해줍니다.

 글자수가 40글자가 넘지 않고 문장수가 4줄을 넘지 않으면 텍스트는 그대로 보여주고 레이아웃 하단의 글자수 세는 부분

(0 / 40) 을 입력받은 글자수에 비례하여 갱신해줍니다. 

else {
    countText.setText("${editText.length()} / 40")
}

만약 문장수가 4문장이 넘게된다면 우선 Toast로 경고창을 띄워줍니다.

보여질 텍스트인 editText의 텍스트를 위에서 선언한 maxText로 설정하여줍니다.

editText.setText(maxText)

글자가 입력되는 부분을 알려주는 커서는 setSelection 함수로 정해줄 수 있습니다.

입력된 텍스트의 끝부분으로 설정해주어 커서가 맨 마지막에 올 수 있도록 합니다.

editText.setSelection(editText.length())

마지막으로 글자수를 갱신하여 줍니다.

countText.setText("${editText.length()} / 40")

글자수가 40글자가 넘었을 때도 마찬가지로 코드를 작성해주면 됩니다.

 

완성된 메인엑티비티 코드는 아래와 같습니다.

package com.example.edittext

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.text.Editable
import android.text.TextWatcher
import android.widget.Toast
import com.example.edittext.databinding.ActivityMainBinding
import kotlin.math.max

class MainActivity : AppCompatActivity() {

    val binding by lazy {ActivityMainBinding.inflate(layoutInflater)}

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(binding.root)

        with(binding){
            editText.addTextChangedListener(object : TextWatcher {
                var maxText = ""
                override fun beforeTextChanged(pos: CharSequence?, p1: Int, p2: Int, p3: Int) {
                    maxText = pos.toString()
                }
                override fun onTextChanged(pos: CharSequence?, p1: Int, p2: Int, p3: Int) {

                    if(editText.lineCount > 4){
                        Toast.makeText(this@MainActivity,
                            "최대 4줄까지 입력 가능합니다.",
                            Toast.LENGTH_SHORT).show()

                        editText.setText(maxText)
                        editText.setSelection(editText.length())
                        countText.setText("${editText.length()} / 40")
                    } else if(editText.length() > 40){
                        Toast.makeText(this@MainActivity, "최대 40자까지 입력 가능합니다.",
                            Toast.LENGTH_SHORT).show()

                        editText.setText(maxText)
                        editText.setSelection(editText.length())
                        countText.setText("${editText.length()} / 40")
                    } else {
                        countText.setText("${editText.length()} / 40")
                    }
                }
                override fun afterTextChanged(p0: Editable?) {

                }
            })
        }
    }
}

예제 코드

https://github.com/soopeach/LimitedEditText

 

GitHub - soopeach/LimitedEditText

Contribute to soopeach/LimitedEditText development by creating an account on GitHub.

github.com

간단한 소스코드이지만 깃허브에 올려놓았습니다.

반응형
  • 네이버 블러그 공유하기
  • 네이버 밴드에 공유하기
  • 페이스북 공유하기
  • 카카오스토리 공유하기