私はJavaおよびAndroid開発;に初めて、そしてSearchView
のアクションバーが必要なアプリに取り組んでいます。 Googleの例を見てきましたが、うまくいかないので、何か間違ったことをしているので、アプリ開発をあきらめようとしています:私を助けることができます:)
問題:必要に応じて検索ビューを開くことができますが、その後何も起こらず、自分のsearchManager.getSearchableInfo(getComponentName())はnullを返します。また、指定したというヒントが検索ボックスに表示されないため、アプリがsearchable.xmlを見つけられない可能性があります。十分な話:)
MainActivity.Java
public class MainActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_main, menu);
// Get the SearchView and set the searchable configuration
SearchManager searchManager =
(SearchManager) getSystemService(Context.SEARCH_SERVICE);
SearchView searchView =
(SearchView) menu.findItem(R.id.menu_search).getActionView();
searchView.setSearchableInfo(
searchManager.getSearchableInfo(getComponentName()));
return true;
}
}
searchable.xml
<?xml version="1.0" encoding="utf-8"?>
<searchable xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:hint="@string/search_hint"
Android:label="@string/app_label">
</searchable>
Androidmanifest
<manifest xmlns:Android="http://schemas.Android.com/apk/res/Android"
package="com.example.searchapp"
Android:versionCode="1"
Android:versionName="1.0" >
<uses-sdk
Android:minSdkVersion="14"
Android:targetSdkVersion="15" />
<application
Android:icon="@drawable/ic_launcher"
Android:label="@string/app_name"
Android:theme="@style/AppTheme" >
<activity Android:name=".SearchableActivity" >
<intent-filter>
<action Android:name="Android.intent.action.SEARCH" />
</intent-filter>
</activity>
<activity
Android:name=".MainActivity"
Android:label="@string/title_activity_main" >
<intent-filter>
<action Android:name="Android.intent.action.MAIN" />
<category Android:name="Android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<meta-data Android:name="Android.app.searchable"
Android:resource="@xml/searchable"/>
</application>
</manifest>
SearchableActivity.Java
package com.example.searchapp;
import Android.app.ListActivity;
import Android.app.SearchManager;
import Android.content.Intent;
import Android.os.Bundle;
import Android.util.Log;
public class SearchableActivity extends ListActivity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.search);
// Get the intent, verify the action and get the query
Intent intent = getIntent();
if (Intent.ACTION_SEARCH.equals(intent.getAction())) {
String query = intent.getStringExtra(SearchManager.QUERY);
doMySearch(query);
}
}
private void doMySearch(String query) {
Log.d("Event",query);
}
}
そして、ここに紹介されたプロジェクトへのリンクがあります、誰かがこれで私を助けてくれたら永遠に感謝します!
問題はAndroidManifestにあります。それはドキュメントに従っているので、私はあなたと同じように持っていました。しかし、それは不明瞭または間違っています。
APIデモのソースを見ると、「Android.app.searchable」メタデータが「results」アクティビティに含まれている必要があり、メインアクティビティ(またはSearchViewを配置するアクティビティ)で「 Android.app.default_searchable」。
私のテストプロジェクトからのマニフェストである次のファイルでそれを見ることができます:
<manifest xmlns:Android="http://schemas.Android.com/apk/res/Android"
package="com.example.test"
Android:versionCode="1"
Android:versionName="1.0" >
<uses-sdk
Android:minSdkVersion="8"
Android:targetSdkVersion="15" />
<application
Android:icon="@drawable/ic_launcher"
Android:label="@string/app_name"
Android:theme="@style/AppTheme" >
<activity
Android:name=".MainActivity"
Android:label="@string/title_activity_main" >
<intent-filter>
<action Android:name="Android.intent.action.MAIN" />
<category Android:name="Android.intent.category.LAUNCHER" />
</intent-filter>
<meta-data
Android:name="Android.app.default_searchable"
Android:value=".SearchActivity" />
</activity>
<activity
Android:name=".SearchActivity"
Android:label="@string/app_name" >
<!-- This intent-filter identifies this activity as "searchable" -->
<intent-filter>
<action Android:name="Android.intent.action.SEARCH" />
<category Android:name="Android.intent.category.DEFAULT" />
</intent-filter>
<!-- This metadata entry provides further configuration details for searches -->
<!-- that are handled by this activity. -->
<meta-data
Android:name="Android.app.searchable"
Android:resource="@xml/searchable" />
</activity>
</application>
Searchable.xmlのヒントとラベルが参照であり、ハードコーディングされた文字列ではないことも重要です。
それがあなたの問題を解決することを願っています。それを理解するのに一日中かかった:(
Androidガイドは次のように明示しています:
// Assumes current activity is the searchable activity
searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));
あなたの場合、これは真実ではありません。 MainActivityではなくSearchableActivityで検索するためです。つまり、getComponentName()メソッドの代わりにこのComponentNameを使用する必要があります。
ComponentName cn = new ComponentName(this, SearchableActivity.class);
searchView.setSearchableInfo(searchManager.getSearchableInfo(cn));
また、Android:hint属性とAndroid:label属性の両方[〜#〜] must [〜#〜]は、strings.xmlの文字列への参照であるようです。文字列値を遅延させてハードコーディングすると、まったく機能しないようです:)
つまり、しないでください:
<?xml version="1.0" encoding="utf-8"?>
<searchable xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:hint="Search for something..."
Android:label="My App">
</searchable>
しかし、間違いなく(OPが正しくしたように):
<?xml version="1.0" encoding="utf-8"?>
<searchable xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:hint="@string/search_hint"
Android:label="@string/app_label">
</searchable>
Android Studioを使用している場合、
<meta-data
Android:name="Android.app.default_searchable"
Android:value=".SearchActivity" />
一部が機能しない場合があります。
のような完全なパッケージ名を書く
<meta-data
Android:name="Android.app.default_searchable"
Android:value="com.example.test.SearchActivity" />
「xml/searchable.xml」に注意してください。 Android:hint
およびAndroid:label
でハードコードを作成した場合、機能しません。ハハは:
<searchable xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:hint="@string/app_name"
Android:label="@string/search_lb"
Android:voiceSearchMode="showVoiceSearchButton|launchRecognizer"/>
searchables.xml
ファイルが正しい場所にあります(つまり、res/xml/
フォルダー)および同じファイルにエラーが含まれていない-そうでない場合は(SearchManager)getSystemService(Context.SEARCH_SERVICE).getSearchableInfo(componentName)
はnullを返し、検索機能を破壊します。
(また、Androidガイドに示されている例は、同じアクティビティで検索を行って検索を表示している場合にのみ使用されるため、componentName
を適切な方法で設定してください。 )
上記の回答で説明したように、実際には「欠落部分」を使用する必要はありません。このメソッド(SearchView
を使用)は、公式ドキュメントが Searchウィジェットの使用 までのように機能します。ここでは、次のように少し変更する必要があります。
SearchableInfo
のプロパティは、ラベル、ヒント、提案の表示、検索結果画面の起動および音声ボタンなどの他のアフォーダンスの制御のためのインテントの作成に使用されます( docs )。
したがって、SearchView.setSearchableInfo(SearchableInfo s)
に渡すSearchableInfo
オブジェクトには、検索結果を表示するために表示されるターゲットアクティビティへの適切な参照が含まれている必要があります。これは、ターゲットアクティビティのComponentName
を手動で渡すことで実行されます。 ComponentName
を作成するための1つのコンストラクターは
public ComponentName (String pkg, String cls)
pkg
とcls
は、検索結果を表示するために起動されるターゲットアクティビティのパッケージ名とクラス名です。ご了承ください:
pkg
はプロジェクトのルートパッケージ名を指している必要があり、
cls
はクラスの完全修飾名でなければなりません(つまり、全体)
例えば。:
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_main, menu);
// Get the SearchView and set the searchable configuration
String pkg = "com.example.musicapp"
String cls = "com.example.musicapp.search.SearchActivity"
ComponentName mycomponent = new ComponentName(pkg,cls);
SearchManager searchManager =(SearchManager)getSystemService(Context.SEARCH_SERVICE);
SearchView searchView = (SearchView) menu.findItem(R.id.menu_search).getActionView();
searchView.setSearchableInfo(searchManager.getSearchableInfo(mycomponent));
searchView.setIconifiedByDefault(false); //if using on actionbar
return true;
}
要件に応じて、他のComponentName
コンストラクターを見てください。