概要
- android.support.v7.widget.SearchViewで音声検索まわりでハマったことなどをメモ代わりに書きます
通常の検索
- まずは音声検索抜きで検索ボックスを表示します
- 例として、MainActivityに設置していきます
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="labeneko.com.searchtest" >
<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<!-- launchMode="singleTop"を指定し、MainActivityを再利用して新しいintentを作成。
MainActivity#onNewIntentが呼ばれる。 -->
<activity
android:name=".MainActivity"
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>
<!-- Search Intentを受け取れるようにする -->
<action android:name="android.intent.action.SEARCH" />
</intent-filter>
<!-- 入力した文字列を受け取るActivityのnameを設定する -->
<meta-data android:name="android.app.default_searchable"
android:value=".MainActivity" />
<meta-data android:name="android.app.searchable"
android:resource="@xml/searchable"/>
</activity>
</application>
</manifest>
MainActivity.java
public class MainActivity extends ActionBarActivity {
private SearchView searchView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
searchView = (SearchView) findViewById(R.id.search_view);
searchView.setIconified(false);
searchView.setIconifiedByDefault(false);
SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
searchView.setSearchableInfo(searchManager
.getSearchableInfo(getComponentName()));
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String query) {
// queryを用いて処理を行う
return false;
}
@Override
public boolean onQueryTextChange(String s) {
return false;
}
});
}
@Override
protected void onNewIntent(Intent intent) {
setIntent(intent);
if (Intent.ACTION_SEARCH.equals(intent.getAction())) {
String query = intent.getStringExtra(SearchManager.QUERY);
boolean submit = false;
searchView.setQuery(query, submit);
}
}
}
activity_main.xml
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/darker_gray">
<android.support.v7.widget.SearchView
android:id="@+id/search_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@android:color/white"
android:layout_margin="16dp"/>
</RelativeLayout>
searchable.xml
<?xml version="1.0" encoding="utf-8"?>
<!-- label,hintは直接文字列で指定すると正常な挙動をしないようです -->
<searchable
xmlns:android="http://schemas.android.com/apk/res/android"
android:label="@string/app_name"
android:hint="@string/search_hint" />
strings.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">SearchTest</string>
<string name="hello_world">Hello world!</string>
<string name="search_hint">入力してください</string>
</resources>
- これで通常の検索ができるようになります
音声検索ができるようにする
- 音声検索を有効にするには下記のようにコードを修正します
searchable.xml
<?xml version="1.0" encoding="utf-8"?>
<!-- 末尾にvoiceSearchModeを追加 -->
<searchable
xmlns:android="http://schemas.android.com/apk/res/android"
android:label="@string/app_name"
android:hint="@string/search_hint"
android:voiceSearchMode="showVoiceSearchButton|launchRecognizer" />
MainActivity.java
...
@Override
protected void onNewIntent(Intent intent) {
setIntent(intent);
if (Intent.ACTION_SEARCH.equals(intent.getAction())) {
String query = intent.getStringExtra(SearchManager.QUERY);
// searchViewに音声入力の結果を入れる
// 音声入力後にそのまま別のActivityに飛ばす等する際はここで処理をする
boolean submit = false;
searchView.setQuery(query, submit);
}
}
- 以上の変更で音声検索ができるようになります
下線が邪魔だと感じだら
- 前に音声検索無し版の記事を書きましたのでご参考にしてください(android.support.v7.widget.SearchViewで下線を消す)
- http://qiita.com/labeneko/items/8b163df905624d4c40a9
- SearchViewに背景色を設定しても、下線は消えません。また、SearchView自体には下線の表示を制御するxmlの指定等存在しません。
- この線はSearchViewの内部を構成している要素の一つである
search_plate
とsubmit_area
に背景色を追加することで消すことができます。背景色はtransparentでも可です。
MainActivity.java
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
...
// 以下のコードを追加
// テキスト入力欄
searchView.findViewById(android.support.v7.appcompat.R.id.search_plate)
.setBackgroundColor(getResources().getColor(android.R.color.transparent));
// 音声検索ボタンが属するボックス
searchView.findViewById(android.support.v7.appcompat.R.id.submit_area)
.setBackgroundColor(getResources().getColor(android.R.color.transparent));
}
- これで下線も消せました
- 音声検索には他の方法やライブラリ等あるようなので、適宜調べていきたいと思います