[Android] AutoCompleteTextView를 이용하여 검색기능 구현하기

이동현·2020년 7월 11일
0

List에 들어있는 (혹은 Array 등..) 데이터를 검색하기 위해 SearchBar를 만들어 작업합니다.
그 중 하나의 방법으로 AutoCompleteTextView를 사용하면, 특별한 알고리즘 구현없이 간편하게 검색을 할 수 있는 기능이 얻어집니다!

특징

AutoCompleteTextView는 다음과 같은 특징을 지닙니다.

  • 첫 단어부터 일치해야 검색이 가능합니다. (단어의 중간부터 검색되는 방식이 아닙니다)
    예를 들어, "대한민국"을 검색하려면 "대한"으로 검색해야 자동완성어로 제시됩니다. 중간 글자인 "민국"을 입력했을 경우 검색되지 않습니다.
  • layout단의 completionThreshold 속성을 통해 자동완성 검색이 시작되는 문자의 수를 결정할 수 있습니다.

첫 번째 특징의 경우에는 어떻게 조작하면 중간 문자부터 검색 가능하도록 할 수 있는 것 같습니다만.. 다른분들 코드를 봐도 이해가 안돼서 후에 새롭게 포스팅 하도록 하겠습니다 ㅠㅠ 어쨌든 default로 부여되는 특징은 맞습니다!

사용방법

View 만들기

<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의 설정 값에 따라 일치하는 데이터들이 나열되는 것을 볼 수 있습니다.

예제

  1. search_bar.xml
    AutoCompleteTextView 라고 크게 다를 건 없어 보입니다.
    저는 그러한 뷰 하나와 검색기능을 수행 할 ImageView를 하나 넣었습니다.
<?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>

  1. activity_main.xml
    include 태그를 이용하여 앞서 만들었던 search_bar.xml을 넣었습니다.
    또한, 단어 데이터를 넣어줄 EditText부분과 Button부분도 추가했습니다.
    여기서 입력하는 단어는 검색어 리스트에 저장됩니다.
    최종적으로 선택된 단어의 정보를 나타내는 TextView가 하나 존재합니다.
<?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>

  1. MainActivity.kt
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("")
        }
    }

}
profile
영차영차

0개의 댓글