2011年5月18日水曜日

Android Search dialogを使ってみる

検索ダイアログを使って見たのでメモ。上から出てくる例のアレ。
詳しくはAndroid Developersで。Creating a Search Interface | Android Developers

サンプルとして、ページ内を検索して、対象文字を赤字にするような簡単なものを作る。

1.検索ダイアログを定義する

searchable.xmlを用意する。名前は何でも良いが、Android Developersに合わせておく。
<?xml version="1.0" encoding="utf-8"?>
<searchable xmlns:android="http://schemas.android.com/apk/res/android"
    android:label="@string/search_label"
    android:hint="@string/search_hint"
    android:searchMode="showSearchLabelAsBadge"
    android:imeOptions="actionSearch"
    android:inputType="text" />
labelはそのまま文字列を書いたら動かないのでstringを定義してやる必要あるので注意。
searchModeはラベルも表示するためにshowSearchLabelAsBadge。imeOptionsをactionSearchにするのは、imeの決定ボタンを検索アイコンにするため。エミュレータではならなかったけど。。

2.AndroidManifest.xml

サンプルでは、検索ダイアログの呼び出しと検索後が同じAcitivityなので下記の用に定義。
        <activity android:name=".SearchableActivity" android:label="@string/app_name"
            android:launchMode="singleTop">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>

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

            <meta-data android:name="android.app.searchable"
                android:resource="@xml/searchable" />
        </activity>
分ける場合はこんな感じらしい。
<application ... >
    <!-- 検索ダイアログ呼び出し元 -->
    <activity android:name=".SearchableActivity" >
        <intent-filter>
            <action android:name="android.intent.action.SEARCH" />
        </intent-filter>
        <meta-data android:name="android.app.searchable"
                   android:resource="@xml/searchable"/>
    </activity>

    <!-- 検索後 -->
    <activity android:name=".OtherActivity" ... >
        <!-- enable the search dialog to send searches to SearchableActivity -->
        <meta-data android:name="android.app.default_searchable"
                   android:value=".SearchableActivity" />
    </activity>
    ...
</application>

これで検索キーを押せばダイアログが出るようにはなる。

ただ、この検索キーだかボタンだかは実機のどこにあるのかわからない。Galaxy SだとMenuの長押しで検索ダイアログが出てきたが、Xperia arcだとMenuの長押しでは出てこない。
エミュレータは虫眼鏡アイコンあるのでわかりやすい。ちなみにF5でも良い。

分かりにくいので、メニューに検索を追加する。onSearchRequestedを呼んだれば、検索窓がでる。
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        super.onCreateOptionsMenu(menu);
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.menu, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
        case R.id.search:
            onSearchRequested();
            return true;
        }
        return false;
    }

3.検索処理

intentからクエリーを取り出して処理をさせる。同じActivityに渡す場合にはonNewIntentが呼び出される。
    @Override
    protected void onNewIntent(Intent intent) {
        if (Intent.ACTION_SEARCH.equals(intent.getAction())) {
            String query = intent.getStringExtra(SearchManager.QUERY);
            mText.setText(Html.fromHtml(mText.getText().toString().replaceAll(
                    "(" + query + ")", "<font color=\"red\">$1</font>")));
        }
    }
このサンプルではクエリーを赤字にしてるだけ。