[android : kotlin] 코틀린 EditText 사용 예제( TextWatcher , OnEditorActionListener 입력완료 이벤트 처리)
안드로이드 EditText 뷰를 사용해보자. 사용자가 입력한 데이터를 받을 때 사용된다. 가령, 로그인을 위한 사용자ID를 받을 때 사용된다고 보면 된다. 입력 완료 버튼 혹은 엔터키를 눌렀을 때 또 다른 이벤트를 처리하고 싶은 경우 TextView의 onEditorActionListener()를 사용하여 처리가 가능하다. TextWatcher를 사용하여 실시간으로 입력되는 동작을 확인할 수 있다. addTextChangedListener()메서드를 사용하여 TextWatcher를 설정할 수 있다. beforeTextChanged()메서드는 텍스트가 변경되기 바로 전에 동작한다. onTextChanged()메서드는 텍스타가 변경되는 동시에 동작한다. afterTextChanged()메서드는 텍스트가 변경 된 이후에 동작한다. 3개의 메서드가 거의 동시에 동작하기 때문에 로그를 찍어서 확인하면 이해가 될 것이다. 여러개의 EditText뷰를 사용하여 TextWatcher를 사용하는 경우 무한루프가 발생하기 때문에 반드시 removeTextChangedListener()를 사용하여 제거해 준 후 다음 EditText뷰에 TextWatcher를 설정해야한다. 이런 부분이 번거롭다면, afterTextChanged()메서드에서 null 체크를 해준다.
override fun afterTextChanged(s: Editable?) {
if (s != null && !s.toString().equals("")) {
Log.d("TAG", "afterTextChanged : $s")
}
}
■ EditText뷰를 클릭했을 때 버튼을 클릭한 것과 같은 애니메이션효과 주기
clickable 속성 추가 및 backgroud속성에 ?attr/selectableItemBackground를 추가해준다.
<EditText
android:id="@+id/editText1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ems="10"
android:inputType="text"
android:clickable="true"
android:background="?attr/selectableItemBackground"
android:text="하하하하하"/>
[MainActivity.kt]
package edu.kotlin.study
import android.os.Bundle
import android.text.Editable
import android.text.TextWatcher
import android.util.Log
import android.view.KeyEvent
import android.view.inputmethod.EditorInfo
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
import kotlinx.android.synthetic.main.activity_main.*
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
//문자열 값 세팅
editText1.setText("테스트")
var watcher = MyEditWatcher()
//editText1.addTextChangedListener(watcher)
editText1.setOnEditorActionListener(MyEnterListener())
button1.setOnClickListener {
textView1.text = editText1.text
}
}
inner class MyEditWatcher : TextWatcher {
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
Log.d("TAG", "beforeTextChanged : $s")
}
//문자열이 바뀐 후
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
Log.d("TAG", "onTextChanged : $s")
}
override fun afterTextChanged(s: Editable?) {
//textView1.text = s
if (s != null && !s.toString().equals("")) {
Log.d("TAG", "afterTextChanged : $s")
}
}
}
inner class MyEnterListener : TextView.OnEditorActionListener {
override fun onEditorAction(v: TextView?, actionId: Int, event: KeyEvent?): Boolean {
var handled = false // 키보드 내림
if (actionId == EditorInfo.IME_ACTION_DONE) { //완료버튼 클릭 처리
Log.d("TAG", "IME_ACTION_DONE :" + v?.text)
} else if (actionId == EditorInfo.IME_ACTION_NEXT) {
Log.d("TAG", "IME_ACTION_NEXT :" + v?.text)
handled = true // 키보드 유지
}
return handled
}
}
}
[activity_main.xml]
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:id="@+id/textView1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="텍스트뷰"
android:textAppearance="@style/TextAppearance.AppCompat.Display2" />
<EditText
android:id="@+id/editText1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ems="10"
android:inputType="textPersonName"
android:text="Name" />
<Button
android:id="@+id/button1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Button"/>
</LinearLayout>
[build.gradle(:app)]
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
android {
compileSdkVersion 29
defaultConfig {
applicationId "edu.kotlin.study"
minSdkVersion 22
targetSdkVersion 29
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
implementation fileTree(dir: "libs", include: ["*.jar"])
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
implementation 'androidx.core:core-ktx:1.3.1'
implementation 'androidx.appcompat:appcompat:1.2.0'
implementation 'androidx.constraintlayout:constraintlayout:2.0.1'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test.ext:junit:1.1.2'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
}