Android SearchView.OnQueryTextListener()意外启动意图

时间:2016-04-26 18:55:13

标签: java android android-intent

我在我的应用程序中实现了一个Searchview,并遇到了一个奇怪的问题。基本上,用户能够输入要搜索的字符串并正确提交。但是,我的应用程序将根据搜索查询过滤ListView,然后将启动一个Intent,导致活动再次启动并返回到它显示所有结果的原始状态。

以下是相关代码。

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    ...
    searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
        @Override
        public boolean onQueryTextSubmit(String query) {
            updateEntriesView(dbHelper.queryByName(query));
            Toast.makeText(getApplicationContext(), "Searching for " + query, Toast.LENGTH_LONG).show();
            return true;
        }

        @Override
        public boolean onQueryTextChange(String newText) {
            return false;
        }
    });
}

private void updateEntriesView(ArrayList<Entry> response) {
    mListView = (ListView) findViewById(R.id.listview_entries);
    if (adapter == null) {
        adapter = new EntryListAdapter(EntriesActivity.this, R.layout.row_entry_layout, response);
        mListView.setAdapter(adapter);
    } else {
        adapter.clear();
        adapter.addAll(response);
        adapter.notifyDataSetChanged();
    }
    adapter.setNotifyOnChange(true);
}

我无法想出改变这种行为,我找不到任何有关它在线实施的文档。有没有办法可以覆盖此功能并阻止它启动意图并将活动重新启动到原来的未过滤状态?

修改
我自己能够解决这个问题。对于任何可能遇到同样问题的人来说,我的解决方案就是。

所以我的AndroidManifest.xml中有一个intent-filter,它会在搜索操作上启动意图。这是导致它启动一个意图并启动我的活动的新实例的原因。

我的解决方案是将此活动转换为单个顶级活动,并添加代码以处理意图。通过使活动单个顶部,它允许活动处理传入的意图而无需启动意图的新实例。有关普通活动和单个活动之间差异的更详细说明,这是一篇关于该主题的好文章https://www.mobomo.com/2011/06/android-understanding-activity-launchmode/

现在,因为我的活动是单顶,我可以覆盖onNewIntent()方法并添加我的代码来处理这个意图,而无需启动新实例。解决我的问题的相关代码如下。

AndroidManifest.xml

<activity android:name=".EntriesActivity"
    android:launchMode="singleTop">
    <intent-filter>
        <action android:name="android.intent.action.SEARCH" />
    </intent-filter>
    <meta-data
        android:name="android.app.searchable"
        android:resource="@xml/searchable"></meta-data>
</activity>

EntriesActivity.java

public class EntriesActivity extends AppCompatActivity {
    ...
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        ...
        searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
            @Override
            public boolean onQueryTextSubmit(String query) {
                updateEntriesView(dbHelper.queryByName(query));
                Toast.makeText(getApplicationContext(), "Searching for " + query, Toast.LENGTH_LONG).show();
                return true;
            }

            @Override
            public boolean onQueryTextChange(String newText) {
                return false;
            }
        });
    }

    @Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
        handleIntent(intent);
    }

    private void handleIntent(Intent intent) {
        if (Intent.ACTION_SEARCH.equals(intent.getAction())) {
            String query = intent.getStringExtra(SearchManager.QUERY);
            updateEntriesView(dbHelper.queryEntriesByName(query));
        }
    }

    private void updateEntriesView(ArrayList<Entry> response) {
        if (adapter == null) {
             adapter = new EntryListAdapter(EntriesActivity.this, R.layout.row_entry_layout, response);
            mEntriesList.setAdapter(adapter);
        } else {
            adapter.clear();
            adapter.addAll(response);
            adapter.notifyDataSetChanged();
        }
        adapter.setNotifyOnChange(true);
    }
}

我希望这会有所帮助。

2 个答案:

答案 0 :(得分:0)

您需要使用searchView.clearFocus();清除文本视图的焦点 请参阅此答案:https://stackoverflow.com/a/15127252/7710739

答案 1 :(得分:0)

我知道这很旧,但是如果您搜索并导致相同的活动,请尝试删除

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

我不相信它不应该尝试发起一项新活动。