검색 인터페이스 설정

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에 전달하여 아키텍처의 다른 레이어에서 이 검색어를 사용하여 표시할 검색결과를 가져올 수 있습니다.