Android:将搜索查询返回到当前活动

Android: Return search query to current activity

我按照http://developer.android.com/guide/topics/search/search-dialog.html中描述的步骤在我的记事本应用程序中实现搜索功能。

我的问题是,当我完成搜索时,一个新的活动将打开,捕获我的搜索查询。但我真正想要的是返回到当前活动的查询,而不是启动新的查询。

这有可能吗?

更新:

androidmanifest.xml文件

1
2
3
4
5
6
7
8
9
10
11
12
<wyn>
<activity android:name="MyNotepad"
                  android:label="@string/app_name">
            <intent-filter>
               
                <category android:name="android.intent.category.LAUNCHER" />
                </action>
            </intent-filter>
            <meta-data android:resource="@xml/searchable" android:name="android.app.searchable"></meta-data>
        </activity>
</activity>
</wyn>

搜索XML

1
2
3
4
5
6
7
8
<wyn>
<?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>
</wyn>

Java代码

1
2
3
4
5
6
7
8
9
10
11
12
<wyn>
@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();
    }
}
</wyn>
1
2
3
4
5
6
7
8
9
10
11
12
13
<wyn>
@Override
public boolean onOptionsItemSelected(MenuItem item)
{
    switch(item.getItemId())
    {
        case R.id.menuItemSearch:
            startSearch("", false, null, false);
    break;
    }
    return true;
}
</wyn>

即使我用手机上的搜索按钮也不行。因此,我认为问题出在androidmanifest.xml中。


在应用程序清单中,需要将当前活动定义为可搜索的活动。

1
2
3
4
5
6
7
8
<activity android:name="BrowseItems" android:label="@string/browseitems"
            android:launchMode="singleTop">
            <intent-filter>
               
            </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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
@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:

1
android:launchMode="singleTop"

因此,您的androidmanifest.xml看起来如下:

1
2
3
4
5
6
7
8
9
10
<activity android:name="MyNotepad"
              android:label="@string/app_name"
              android:launchMode="singleTop">
        <intent-filter>
           
            <category android:name="android.intent.category.LAUNCHER" />
            </action>
        </intent-filter>
        <meta-data android:resource="@xml/searchable" android:name="android.app.searchable"></meta-data>
    </activity>

原因:

从这个帖子:

活动启动模式有四个有效值:

"标准""独角戏""单选""单实例"

"标准"是默认值。这四个值分为两组:

"standard"和"singletop"可以实例化多个活动实例,实例将保留在同一任务中。对于"singletask"或"singleinstance",activity类使用singleton模式,该实例将成为新任务的根Activity。让我们检查每个值:"标准":

可以实例化活动类的多个实例,并且可以将多个实例添加到同一个任务或不同的任务中。这是大多数活动的通用模式。

"独角戏":

与"标准"的区别在于,如果当前任务的顶部已经存在活动的实例,并且系统将意向路由到此活动,则不会创建新实例,因为它将触发onNewIntent()方法而不是创建新对象。


我只是用这个:

1
2
3
4
5
6
7
8
9
10
11
12
13
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;
        }
});

当必须在ListView中搜索并筛选出项时,最好使用此选项。我从不使用清单文件实现搜索函数。这两种方法完成了所有的工作。


我也面临同样的问题,然后我写了这个代码,它解决了我的问题。

在您的活动中实现这一点

1
**implements SearchView.OnQueryTextListener, SearchView.OnCloseListener**

在类中添加此函数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
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);
        }

调用onCreateOptions菜单(菜单菜单)中的函数

1
2
3
4
5
6
7
8
9
10
11
12
13
@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"添加到AndroidManifest.xml中的searchable activity定义中。
  • searchable activity中实现onNewIntent并在那里进行搜索。

  • 在清单文件中,添加:

    1
    android:launchMode="singleTop"

    搜索活动。然后,让搜索活动实现searchview.onsuggestionListener最后:

    1
    mSearchView.setOnSuggestListener(this)

    通过这种方式,您可以在不创建搜索活动的新实例的情况下处理建议单击事件。


    我按照拉克兰的提示"你可以用这个字符串重新加载你的活动",最后解决了这个问题。因此,请先阅读Lachlan的帖子,然后采取以下3个步骤"重新加载您的活动":

  • 在ApplicationContext中保存查询字符串。
  • 完成新打开的搜索活动。
  • 重写onresume,获取刚刚保存的查询字符串,然后刷新列表。
  • 列表活动中的代码:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    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:如何声明全局变量?)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    public class MyApp extends Application {

        private String mSearchText;

        public String getSearchText() {
            return mSearchText;
        }

        public void setSearchText(String searchText) {
            this.mSearchText = searchText;
        }
    }

    不要忘记将属性android:name=".MyApp"添加到清单文件中的应用程序中。祝你好运!


    如果SearchView上的SearchView.OnSuggestionListener已设置,并且被重写的方法返回true(覆盖默认行为),则不会显示新的活动。在onCreateOptionsMenu()实现中可以这样做,如下所示:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
        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;
            }
        });

    无需强制将活动设置为单顶或其他黑客。


    只要添加

    1
    2
    3
    4
    5
    6
    7
      <meta-data
         android:name="android.app.default_searchable"
         android:value="#Activity_Name" />

       <!-- All your activities, service, etc. -->

    </application>

    在android的manifest.xml文件中,activity name是处理搜索的活动的名称。