검색 인터페이스 설정

Compose 사용해 보기
Jetpack Compose는 Android에 권장되는 UI 도구 키트입니다. Compose에서 검색 기능을 추가하는 방법을 알아보세요.

앱에서 검색 기능을 제공하려면 SearchView 위젯을 앱 바의 항목으로 사용하는 것이 좋습니다. 앱 바의 모든 항목과 마찬가지로 SearchView를 항상 표시하도록 정의하거나 공간이 있을 때만 표시하도록 정의할 수 있습니다. 접을 수 있는 작업으로 정의할 수도 있습니다. 이 작업은 처음에는 SearchView를 아이콘으로 표시한 다음 사용자가 아이콘을 탭하면 전체 앱 바를 검색창으로 표시합니다.

앱 바에 SearchView 추가

SearchView 위젯을 앱 바에 추가하려면 프로젝트에 res/menu/options_menu.xml 파일을 만들고 다음 코드를 파일에 추가하세요. 이 코드는 사용할 아이콘, 항목 제목 등 검색 항목을 만드는 방법을 정의합니다. collapseActionView 속성을 사용하면 SearchView가 확장되어 전체 앱 바를 차지하고 사용하지 않을 때는 일반 앱 바 항목으로 다시 축소될 수 있습니다. 핸드셋 기기에서는 앱 바 공간이 제한되므로 collapsibleActionView 속성을 사용하여 더 나은 사용자 환경을 제공하는 것이 좋습니다.

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@+id/search"
        android:title="@string/search_title"
        android:icon="@drawable/ic_search"
        android:showAsAction="collapseActionView|ifRoom"
        android:actionViewClass="androidx.appcompat.widget.SearchView" />
</menu>

액세스가 더 쉬운 검색 아이콘을 사용하려면 /res/drawable 폴더에 ic_search.xml 파일을 만들고 다음 코드를 포함합니다.

<vector
    android:height="24dp"
    android:tint="#000000"
    android:viewportHeight="24"
    android:viewportWidth="24"
    android:width="24dp"
    xmlns:android="http://schemas.android.com/apk/res/android">
        <path android:fillColor="@android:color/white" android:pathData="M15.5,14h-0.79l-0.28,-0.27C15.41,12.59 16,11.11 16,9.5 16,5.91 13.09,3 9.5,3S3,5.91 3,9.5 5.91,16 9.5,16c1.61,0 3.09,-0.59 4.23,-1.57l0.27,0.28v0.79l5,4.99L20.49,19l-4.99,-5zM9.5,14C7.01,14 5,11.99 5,9.5S7.01,5 9.5,5 14,7.01 14,9.5 11.99,14 9.5,14z"/>
</vector>

앱 바에 SearchView를 표시하려면 활동의 onCreateOptionsMenu() 메서드에서 XML 메뉴 리소스 res/menu/options_menu.xml를 확장하세요.

Kotlin

override fun onCreateOptionsMenu(menu: Menu): Boolean {
    menuInflater.inflate(R.menu.options_menu, menu)

    return true
}

앱을 실행하면 다음과 같은 결과가 생성됩니다.

앱 상단 바에 검색 아이콘이 있는 빈 화면을 보여주는 이미지
그림 1. 앱 상단 바의 검색 아이콘

SearchView가 앱의 앱 바에 표시되지만 작동하지 않습니다. 검색 아이콘을 탭하면 다음과 같이 표시됩니다.

검색 뷰가 작동하는 모습을 보여주는 이미지
그림 2. SearchView 작업

SearchView를 작동하도록 하려면 SearchView가 작동하는 방식을 정의해야 합니다.

검색 구성 만들기

검색 구성SearchView의 작동 방식을 지정하고 res/xml/searchable.xml 파일에 정의됩니다. 검색 구성에는 최소한 Android 매니페스트의 <application> 또는 <activity> 요소의 android:label 속성과 값이 동일한 android:label 속성이 포함되어야 합니다. 그러나 android:hint 속성을 추가하여 사용자에게 검색창에 입력할 내용을 알려주는 것도 좋습니다.

<?xml version="1.0" encoding="utf-8"?>

<searchable xmlns:android="http://schemas.android.com/apk/res/android"
        android:label="@string/app_name"
        android:hint="@string/search_hint" />

앱의 매니페스트 파일에서 res/xml/searchable.xml 파일을 가리키는 <meta-data> 요소를 선언합니다. SearchView를 표시하려는 <activity>의 요소를 선언합니다.

<activity
android:name=".SearchResultsActivity"
android:exported="false"
android:label="@string/title_activity_search_results"
android:launchMode="singleTop"
android:theme="@style/Theme.AppCompat.Light">
    <intent-filter>
        <action android:name="android.intent.action.SEARCH" />
    </intent-filter>
    <meta-data
        android:name="android.app.searchable"
        android:resource="@xml/searchable" />
</activity>

만든 onCreateOptionsMenu() 메서드에서 setSearchableInfo(SearchableInfo)를 호출하여 검색 구성을 SearchView와 연결합니다.

Kotlin

override fun onCreateOptionsMenu(menu: Menu): Boolean {
    menuInflater.inflate(R.menu.options_menu, menu)

    val searchManager = getSystemService(Context.SEARCH_SERVICE) as SearchManager
    val searchView = menu.findItem(R.id.search).actionView as SearchView
    val component = ComponentName(this, SearchResultsActivity::class.java)
    val searchableInfo = searchManager.getSearchableInfo(component)
    searchView.setSearchableInfo(searchableInfo)
    return true
}

getSearchableInfo()를 호출하면 검색 구성 XML 파일에서 만든 SearchableInfo 객체를 가져옵니다. 검색 구성이 SearchView와 올바르게 연결되고 사용자가 쿼리를 제출하면 SearchViewACTION_SEARCH 인텐트로 활동을 시작합니다. 그런 다음 이 인텐트를 필터링하고 검색어를 처리할 수 있는 활동이 필요합니다.

검색 가능한 활동 만들기

검색 가능한 활동은 ACTION_SEARCH 인텐트를 필터링하고 데이터 세트에서 검색어를 검색합니다. 검색 가능한 활동을 만들려면 ACTION_SEARCH 인텐트를 필터링할 활동을 선언하세요.

<activity android:name=".SearchResultsActivity" ... >
    ...
    <intent-filter>
        <action android:name="android.intent.action.SEARCH" />
    </intent-filter>
    ...
</activity>

검색 가능한 활동에서 onCreate() 메서드에 ACTION_SEARCH 인텐트가 있는지 확인하여 처리합니다.

Kotlin

class SearchResultsActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_search_results)
        handleIntent(intent)
    }

    override fun onNewIntent(intent: Intent) {
        super.onNewIntent(intent)
        handleIntent(intent)
    }

    private fun handleIntent(intent: Intent) {
        if (Intent.ACTION_SEARCH == intent.action) {
            val query = intent.getStringExtra(SearchManager.QUERY)
            Log.d("SEARCH", "Search query was: $query")
        }
    }
}

이제 SearchView에서 사용자의 검색어를 수락하고 ACTION_SEARCH 인텐트로 검색 가능한 활동을 시작할 수 있습니다.

검색어를 가져온 후 ViewModel에 전달하면 아키텍처의 다른 레이어에서 이를 사용하여 표시할 검색 결과를 가져올 수 있습니다.