검색 인터페이스 설정

Android 3.0부터 앱 바에서 SearchView 위젯을 항목으로 사용하는 것이 앱에서 검색 기능을 제공하는 기본 방법입니다. 앱 바의 모든 항목과 마찬가지로 SearchView를 정의하여 항상 표시하거나 공간이 있을 때만 표시하거나 축소 가능한 작업으로 표시할 수 있습니다. 축소 가능한 작업의 경우 SearchView를 처음에는 아이콘으로 표시한 다음 사용자가 아이콘을 클릭하면 전체 앱 바를 검색 입력란으로 표시합니다.

참고: 이 과정의 뒷부분에서는 SearchView를 지원하지 않는 기기의 경우 Android 2.1(API 수준 7)과 앱이 호환되도록 하는 방법을 알아봅니다.

앱 바에 검색 뷰 추가

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="android.widget.SearchView" />
    </menu>
    

참고: 메뉴 항목에 이미 기존 XML 파일이 있다면 대신 <item> 요소를 파일에 추가할 수 있습니다.

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

Kotlin

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

        return true
    }
    

자바

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.options_menu, menu);

        return true;
    }
    

지금 앱을 실행하면 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 ... >
        ...
        <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)

        // Associate searchable configuration with the SearchView
        val searchManager = getSystemService(Context.SEARCH_SERVICE) as SearchManager
        (menu.findItem(R.id.search).actionView as SearchView).apply {
            setSearchableInfo(searchManager.getSearchableInfo(componentName))
        }

        return true
    }
    

자바

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.options_menu, menu);

        // Associate searchable configuration with the SearchView
        SearchManager searchManager =
               (SearchManager) getSystemService(Context.SEARCH_SERVICE);
        SearchView searchView =
                (SearchView) menu.findItem(R.id.search).getActionView();
        searchView.setSearchableInfo(
                searchManager.getSearchableInfo(getComponentName()));

        return true;
    }
    

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

검색 가능한 활동 만들기

사용자가 검색어를 제출하면 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 인텐트가 있는지 확인하여 처리합니다.

참고: 검색 가능한 활동이 단일 최상위 모드(android:launchMode="singleTop")에서 실행되는 경우 onNewIntent() 메서드에서도 ACTION_SEARCH 인텐트를 처리합니다. 단일 최상위 모드에서는 활동 인스턴스가 하나만 만들어지며 이후에는 활동을 시작하기 위해 호출해도 스택에서 새 활동이 만들어지지 않습니다. 이 실행 모드는 사용자가 매번 새 활동 인스턴스를 만들지 않고 동일한 활동에서 검색을 실행할 수 있으므로 유용합니다.

Kotlin

    class SearchResultsActivity : Activity() {

        override fun onCreate(savedInstanceState: Bundle?) {
            ...
            handleIntent(intent)
        }

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

        private fun handleIntent(intent: Intent) {

            if (Intent.ACTION_SEARCH == intent.action) {
                val query = intent.getStringExtra(SearchManager.QUERY)
                //use the query to search your data somehow
            }
        }
        ...
    }
    

자바

    public class SearchResultsActivity extends Activity {

        @Override
        public void onCreate(Bundle savedInstanceState) {
            ...
            handleIntent(getIntent());
        }

        @Override
        protected void onNewIntent(Intent intent) {
            ...
            handleIntent(intent);
        }

        private void handleIntent(Intent intent) {

            if (Intent.ACTION_SEARCH.equals(intent.getAction())) {
                String query = intent.getStringExtra(SearchManager.QUERY);
                //use the query to search your data somehow
            }
        }
        ...
    }
    

지금 앱을 실행하면 SearchView에서 사용자의 검색어를 수락하고 ACTION_SEARCH 인텐트로 검색 가능한 활동을 시작할 수 있습니다. 이제 검색어를 통해 데이터를 저장하고 검색하는 방법을 찾는 것은 개발자의 책임입니다.