http://developer.Android.com/guide/topics/search/search-dialog.html で説明されている手順に従って、メモ帳アプリケーションに検索機能を実装しました。
私の問題は、検索を終了すると、新しいアクティビティが開き、検索クエリをキャプチャすることです。しかし、本当に欲しいのは、新しいアクティビティを開始するのではなく、現在のアクティビティに返されるクエリです。
これは可能ですか?
更新:
AndroidManifest.xml
<activity Android:name="MyNotepad"
Android:label="@string/app_name">
<intent-filter>
<action Android:name="Android.intent.action.MAIN" />
<category Android:name="Android.intent.category.LAUNCHER" />
<action Android:name="Android.intent.action.SEARCH"></action>
</intent-filter>
<meta-data Android:resource="@xml/searchable" Android:name="Android.app.searchable"></meta-data>
</activity><activity Android:name="Preferences" Android:label="Preferences" >
</activity>
searchable.xml
<?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">
</searchable>
Javaコード
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_pad);
Intent intent = getIntent();
if (Intent.ACTION_SEARCH.equals(intent.getAction())) {
String query = intent.getStringExtra(SearchManager.QUERY);
Toast.makeText(getApplicationContext(), query, Toast.LENGTH_LONG).show();
}
}
@Override
public boolean onOptionsItemSelected(MenuItem item)
{
switch(item.getItemId())
{
case R.id.menuItemSearch:
startSearch("", false, null, false);
break;
}
return true;
}
電話で検索ボタンを使用しても機能しません。そのため、問題はAndroidManifest.xmlにあると考えています
アプリケーションマニフェストで、現在のアクティビティを検索可能なアクティビティとして定義する必要があります。
<activity Android:name="BrowseItems" Android:label="@string/browseitems"
Android:launchMode="singleTop">
<intent-filter>
<action Android:name="Android.intent.action.SEARCH" />
</intent-filter>
<meta-data Android:name="Android.app.searchable"
Android:resource="@xml/itemsearchable" />
</activity>
次に、次のコードを使用します。これは http://developer.Android.com/guide/topics/search/search-dialog.html#LifeCycle
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.search);
handleIntent(getIntent());
}
@Override
protected void onNewIntent(Intent intent) {
setIntent(intent);
handleIntent(intent);
}
private void handleIntent(Intent intent) {
if (Intent.ACTION_SEARCH.equals(intent.getAction())) {
String query = intent.getStringExtra(SearchManager.QUERY);
// Do work using string
}
}
その後、文字列を使用してアクティビティをリロードできます。リストアクティビティの場合は、データをロードしてその中の文字列を使用するために使用するコードを呼び出すことができます。
検索可能なアクティビティでAndroidManifest.xmlに追加します。
Android:launchMode="singleTop"
そのため、AndroidManifest.xmlは次のようになります。
<activity Android:name="MyNotepad"
Android:label="@string/app_name"
Android:launchMode="singleTop">
<intent-filter>
<action Android:name="Android.intent.action.MAIN" />
<category Android:name="Android.intent.category.LAUNCHER" />
<action Android:name="Android.intent.action.SEARCH"></action>
</intent-filter>
<meta-data Android:resource="@xml/searchable" Android:name="Android.app.searchable"></meta-data>
</activity><activity Android:name="Preferences" Android:label="Preferences" >
理由:
この投稿 から:
アクティビティ起動モードには、次の4つの有効な値があります。
「標準」「singleTop」「singleTask」「singleInstance」
「標準」がデフォルト値です。 4つの値は2つのグループに分類されます。
'standard'および 'singleTop'は複数のアクティビティインスタンスをインスタンス化でき、インスタンスは同じタスクにとどまります。 「singleTask」または「singleInstance」の場合、アクティビティクラスはシングルトンパターンを使用し、そのインスタンスは新しいタスクのルートアクティビティになります。各値を調べてみましょう: "標準":
アクティビティクラスの複数のインスタンスをインスタンス化し、複数のインスタンスを同じタスクまたは異なるタスクに追加できます。これは、ほとんどのアクティビティの共通モードです。
「singleTop」:
「標準」との違いは、アクティビティのインスタンスが現在のタスクの最上部に既に存在し、システムがこのアクティビティにインテントをルーティングする場合、新しいインスタンスは作成されず、onNewIntent()メソッドを起動するためです。新しいオブジェクト。
私はこれを単に使用します:-
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String s) {
//on submit
return false;
}
@Override
public boolean onQueryTextChange(String s) {
//get all text changes
return false;
}
});
これは、リストビュー全体を検索し、アイテムを除外する必要がある場合に最適です。マニフェストファイルを使用して検索機能を実装することはありません。 2つの方法はすべての仕事をします。
私も同じ問題に直面していたので、このコードを書いて問題を解決しました。
これをアクティビティに実装する
**implements SearchView.OnQueryTextListener, SearchView.OnCloseListener**
この関数をクラスに追加:
private void setupSearchView()
{
searchView.setIconifiedByDefault(true);
SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
if (searchManager != null)
{
List<SearchableInfo> searchables = searchManager.getSearchablesInGlobalSearch();
// Try to use the "applications" global search provider
SearchableInfo info = searchManager.getSearchableInfo(getComponentName());
for (SearchableInfo inf : searchables)
{
if (inf.getSuggestAuthority() != null && inf.getSuggestAuthority().startsWith("applications"))
{
info = inf;
}
}
searchView.setSearchableInfo(info);
}
searchView.setOnQueryTextListener(this);
searchView.setOnCloseListener(this);
}
onCreateOptionsMenu(メニューメニュー)で関数を呼び出します
@Override
public boolean onCreateOptionsMenu(Menu menu)
{
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.menu, menu);
//restoreActionBar();
// Associate searchable configuration with the SearchView
//SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
searchView = (SearchView) menu.findItem(R.id.action_search).getActionView();
//searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));
setupSearchView();
return super.onCreateOptionsMenu(menu);
}
これで問題が完全に解決します。
ハッピーコーディング!!
簡単に:
Android:launchMode="singleTop"
のsearchable activity
定義にAndroidManifest.xml
を追加しますsearchable activity
にonNewIntent
を実装し、そこで検索を処理します。私は Lachlanの手がかり の「その後、文字列を使用してアクティビティをリロードできます」に従って、最終的にこれを解決しました。そのため、最初にラクランの投稿を読んでから、「アクティビティをリロードする」ために次の3つの手順を実行してください。
リストアクティビティのコード:
private void handleIntent(Intent intent) {
if (Intent.ACTION_SEARCH.equals(intent.getAction())) {
String searchText = intent.getStringExtra(SearchManager.QUERY);
((MyApp)this.getApplicationContext()).setSearchText(searchText);
this.finish();
}
}
protected void onResume() {
super.onResume();
String searchText = ((MyApp)this.getApplicationContext()).getSearchText();
//refresh your list here...
}
MyAppクラス:(この元のアイデアはここからです: Android:グローバル変数の宣言方法? )
public class MyApp extends Application {
private String mSearchText;
public String getSearchText() {
return mSearchText;
}
public void setSearchText(String searchText) {
this.mSearchText = searchText;
}
}
マニフェストファイルでアプリケーションにプロパティAndroid:name=".MyApp"
を追加することを忘れないでください。幸運を!
マニフェストファイルで、次を追加します。
Android:launchMode="singleTop"
検索アクティビティに。次に、検索アクティビティに実装させます SearchView.OnSuggestionListener 最後に:
mSearchView.setOnSuggestListener(this)
これにより、検索アクティビティの新しいインスタンスを作成せずに、提案クリックイベントを処理できます。
SearchViewの_SearchView.OnSuggestionListener
_が設定され、オーバーライドされたメソッドがtrueを返す場合、新しいアクティビティは表示されません( デフォルトの動作をオーバーライドする )。次のように、onCreateOptionsMenu()
実装でそれを行うことができます。
_ searchView.setOnSuggestionListener(new SearchView.OnSuggestionListener() {
@Override
public boolean onSuggestionSelect(int position) {
return true;
}
@Override
public boolean onSuggestionClick(int position) {
CursorAdapter selectedView = searchView.getSuggestionsAdapter();
Cursor cursor = (Cursor) selectedView.getItem(position);
int index = cursor.getColumnIndexOrThrow(SearchManager.SUGGEST_COLUMN_TEXT_1);
searchView.setQuery(cursor.getString(index), true);
return true;
}
});
_
アクティビティを強制的にsingleTopまたはその他のハッキングする必要はありません。