List에 들어있는 (혹은 Array 등..) 데이터를 검색하기 위해 SearchBar를 만들어 작업합니다.
그 중 하나의 방법으로 AutoCompleteTextView를 사용하면, 특별한 알고리즘 구현없이 간편하게 검색을 할 수 있는 기능이 얻어집니다!
AutoCompleteTextView는 다음과 같은 특징을 지닙니다.
completionThreshold
속성을 통해 자동완성 검색이 시작되는 문자의 수를 결정할 수 있습니다. 첫 번째 특징의 경우에는 어떻게 조작하면 중간 문자부터 검색 가능하도록 할 수 있는 것 같습니다만.. 다른분들 코드를 봐도 이해가 안돼서 후에 새롭게 포스팅 하도록 하겠습니다 ㅠㅠ 어쨌든 default로 부여되는 특징은 맞습니다!
<AutoCompleteTextView
android:id="@+id/auto_tv"
android:layout_width="0dp"
android:layout_height="40dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toStartOf="@id/search_image"
app:layout_constraintTop_toTopOf="parent"
android:maxLines="3"
android:background="@android:color/transparent"
android:hint="검색할 단어를 입력해주세요." />
위의 코드를 이용하여 뷰를 하나 구성합니다.
android:completionHint="hint"
android:completionThreshold="2"
위와 같은 대표적인 속성 역시 사용할 수 있습니다.
completionHint
은 자동으로 펼쳐지는 검색어 리스트에 보여지는 문구를 설정합니다.
completionThreshold
는 몇 개의 문자를 입력해야 검색이 시작되는지를 설정합니다.
검색이 될 항목들의 리스트를 만들어줍니다.
val wordList = mutableListOf<String>()
enroll_btn.setOnClickListener {
wordList.add(enroll_input.text.toString())
}
저는 단어를 직접 입력해서 List에 저장하는 꼴로 예제를 구성했습니다.
enroll_input
에 저장할 단어를 입력하고 enroll_btn
을 클릭하여 wordList
에 저장하는 식으로 말입니다!
AutoCompleteTextView에 사용하려면 리스트의 데이터를 뿌려줄 어댑터가 필요합니다.
자체적으로 setAdapter
를 제공하므로 이를 사용합니다.
val adapter = ArrayAdapter<String>(this, android.R.layout.simple_dropdown_item_1line, wordList)
search_bar.auto_tv.setAdapter(adapter)
이렇게 하면 사용 설정이 끝납니다.
View에 문자를 입력하면 threshold
의 설정 값에 따라 일치하는 데이터들이 나열되는 것을 볼 수 있습니다.
<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="8dp"
android:layout_gravity="center">
<AutoCompleteTextView
android:id="@+id/auto_tv"
android:layout_width="0dp"
android:layout_height="40dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toStartOf="@id/search_image"
app:layout_constraintTop_toTopOf="parent"
android:maxLines="3"
android:background="@android:color/transparent"
android:hint="검색할 단어를 입력해주세요." />
<ImageView
android:id="@+id/search_image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@id/auto_tv"
app:layout_constraintBottom_toBottomOf="@id/auto_tv"
android:src="@android:drawable/ic_menu_search"/>
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.cardview.widget.CardView>
<?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">
<include
android:id="@+id/search_bar"
layout="@layout/search_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/enroll_text"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="단어 등록"
android:textSize="24sp"
app:layout_constraintTop_toBottomOf="@id/search_bar"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:layout_marginTop="128dp"/>
<EditText
android:id="@+id/enroll_input"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintStart_toStartOf="@id/enroll_text"
app:layout_constraintTop_toBottomOf="@id/enroll_text"
app:layout_constraintEnd_toStartOf="@id/enroll_btn"/>
<Button
android:id="@+id/enroll_btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/enroll_text"
android:text="단어 등록하기"
android:paddingHorizontal="8dp"/>
<TextView
android:id="@+id/result_text"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="선택된 단어 정보"
android:textSize="24sp"
app:layout_constraintTop_toBottomOf="@id/enroll_btn"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:layout_marginTop="64dp"/>
<TextView
android:id="@+id/result"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="선택된 단어는 xx이며, yy글자로 이루어져 있습니다."
android:textSize="18sp"
app:layout_constraintTop_toBottomOf="@id/result_text"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:layout_marginTop="16dp"
android:maxLines="3" />
</androidx.constraintlayout.widget.ConstraintLayout>
package com.dongldh.autocompletetextviewex
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.ArrayAdapter
import kotlinx.android.synthetic.main.activity_main.*
import kotlinx.android.synthetic.main.search_bar.*
import kotlinx.android.synthetic.main.search_bar.view.*
class MainActivity : AppCompatActivity() {
val wordList = mutableListOf<String>()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
search_bar.auto_tv.threshold = 1
enroll_btn.setOnClickListener {
wordList.add(enroll_input.text.toString())
val adapter = ArrayAdapter<String>(this, android.R.layout.simple_dropdown_item_1line, wordList)
search_bar.auto_tv.setAdapter(adapter)
enroll_input.setText("")
}
// search_image를 클릭했을 때
search_bar.search_image.setOnClickListener {
result.text = "선택된 단어는 ${search_bar.auto_tv.text}이며,\n${search_bar.auto_tv.text.length}글자로 이루어져 있습니다."
search_bar.auto_tv.setText("")
}
// AutoCompleteTextView에 나열된 항목을 클릭했을 경우 바로 적용 되도록
search_bar.auto_tv.setOnItemClickListener { parent, view, position, id ->
result.text = "선택된 단어는 ${search_bar.auto_tv.text}이며,\n${search_bar.auto_tv.text.length}글자로 이루어져 있습니다."
search_bar.auto_tv.setText("")
}
}
}