Android 无法让操作栏中的搜索视图工作
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/11699206/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Cannot get searchview in actionbar to work
提问by Jonathan Andersson
I am pretty new to java and android development; and I have been working on an app in which I want an action bar with a SearchView
. I have looked at the google examples but I can not get it to work. I must be doing something wrong and I'm about to give up on app-development :D I have searched but I have not found anything helpful. Maybe you guys can help me :)
我对 java 和 android 开发很陌生;我一直在开发一个应用程序,我想要一个带有SearchView
. 我看过谷歌的例子,但我无法让它工作。我一定是做错了什么,我即将放弃应用程序开发:DI 已经搜索过,但我没有找到任何有用的东西。也许你们可以帮助我:)
The problem: I get the search view to open as it should, but after that nothing happens at all, I've noticed that my searchManager.getSearchableInfo(getComponentName())returns null. Also my hint that I've given is not displayed in my search box which leads me to believing that maybe the app can't find my searchable.xml? Enough talk :)
问题:我让搜索视图按原样打开,但之后什么也没发生,我注意到我的searchManager.getSearchableInfo(getComponentName())返回 null。此外,我给出的提示没有显示在我的搜索框中,这使我相信该应用程序可能找不到我的 searchable.xml?够了:)
MainActivity.java
主活动.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
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);
}
}
And here is a link to the referred project, I would be eternally grateful if someone was to help me with this!
这是指向所引用项目的链接,如果有人能帮助我解决这个问题,我将永远感激不尽!
回答by Sloy
Your problem is in your AndroidManifest. I had it almost exactly as you do, because that is what I get following the documentation. But it is unclear or mistaken.
您的问题出在您的 AndroidManifest 中。我几乎和你一样,因为这是我按照文档得到的。但不清楚或错误。
Watching at the API Demos source I found that the "android.app.searchable" metadata must go in your "results" activity, and in the main activity (or the activity where you place the SearchView) you point to the other one with "android.app.default_searchable".
在观看 API Demos 源时,我发现“android.app.searchable”元数据必须在您的“结果”活动中,并且在主活动(或放置 SearchView 的活动)中,您用“指向另一个活动” android.app.default_searchable”。
You can see it in the following file, which is the Manifest from my test project:
您可以在以下文件中看到它,该文件是我的测试项目中的 Manifest:
<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>
It is also important that the hint and label in the searchable.xml are references, and not hardcoded strings.
searchable.xml 中的提示和标签是引用而不是硬编码字符串也很重要。
I hope it solves your problem. It took me all day to figure it out :(
我希望它能解决你的问题。我花了一整天才弄明白:(
回答by bakua
Android guides explicitly says:
Android 指南明确指出:
// Assumes current activity is the searchable activity
searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));
Which is in your case NOT TRUE. Because you don't want to search in MainActivity but in SearchableActivity. That means you should use this ComponentName instead of getComponentName() method:
在你的情况下,这是不正确的。因为您不想在 MainActivity 中搜索,而是在 SearchableActivity 中搜索。这意味着你应该使用这个 ComponentName 而不是 getComponentName() 方法:
ComponentName cn = new ComponentName(this, SearchableActivity.class);
searchView.setSearchableInfo(searchManager.getSearchableInfo(cn));
回答by NPike
Also it seems that both the android:hint and android:label attributes MUSTbe references to strings in strings.xml. Being lazy and hardcoding the string values doesn't seem to work at all :)
此外,android:hint 和 android:label 属性似乎都必须是对 strings.xml 中字符串的引用。懒惰和硬编码字符串值似乎根本不起作用:)
i.e. Don't do:
即不要这样做:
<?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>
But definitely do (as the OP correctly did):
但一定要这样做(正如 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>
回答by togikan
If you are using Android Studio,
如果您使用的是 Android Studio,
<meta-data
android:name="android.app.default_searchable"
android:value=".SearchActivity" />
part may not work.
部分可能不起作用。
write full package name like
写完整的包名,如
<meta-data
android:name="android.app.default_searchable"
android:value="com.example.test.SearchActivity" />
回答by Son Nguyen Thanh
be careful with "xml/searchable.xml".
If you made HARD CODE with android:hint
and android:label
.It will not work. Haha
Should be :
小心“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"/>
回答by ban-geoengineering
Make sure your searchables.xml
file is in the correct location (i.e, in your res/xml/
folder) and that the same file does not contain any errors - otherwise you will find that (SearchManager)getSystemService(Context.SEARCH_SERVICE).getSearchableInfo(componentName)
will return null, breaking your search functionality.
确保您的searchables.xml
文件位于正确的位置(即,在您的res/xml/
文件夹中)并且同一文件不包含任何错误 - 否则您会发现(SearchManager)getSystemService(Context.SEARCH_SERVICE).getSearchableInfo(componentName)
它将返回 null,从而破坏您的搜索功能。
(Also, ensure you set componentName
in the appropriate manner, because the example shown in the Android guide is for only when you are making searches and displaying searches in the same Activity.)
(此外,请确保componentName
以适当的方式进行设置,因为 Android 指南中显示的示例仅适用于在同一 Activity 中进行搜索和显示搜索的情况。)
回答by Kedar Paranjape
There's actually no need use the "missing part" as described in the answers above. This method(using a SearchView
) works exactly as the official docs say till Using the Search widget. Here a slight modification needs to made as follows:
实际上没有必要使用上面答案中描述的“缺失部分”。这种方法(使用 a SearchView
)与官方文档所说的完全一样,直到使用搜索小部件。这里需要稍作修改如下:
Properties in a SearchableInfo
are used to display labels, hints, suggestions, create intents for launching search results screens and controlling other affordances such as a voice button(docs).
aSearchableInfo
中的属性用于显示标签、提示、建议、创建用于启动搜索结果屏幕和控制其他功能的意图,例如语音按钮 ( docs)。
Thus, the SearchableInfo
object we pass to the SearchView.setSearchableInfo(SearchableInfo s)
must contain proper references to the target activity which should be displayed to show the search results. This is done by manually passing the ComponentName
of our target activity. One constructor for creating a ComponentName
is
因此,SearchableInfo
我们传递给的对象SearchView.setSearchableInfo(SearchableInfo s)
必须包含对应该显示以显示搜索结果的目标活动的正确引用。这是通过手动传递ComponentName
目标活动的 来完成的。用于创建 a 的一个构造函数ComponentName
是
public ComponentName (String pkg, String cls)
pkg
and cls
are package names and class names of the target activity to be launched for displaying search results. Note that:
pkg
和cls
是要启动以显示搜索结果的目标活动的包名和类名。注意:
pkg
must point to the root package name of your project and,
pkg
必须指向项目的根包名称,并且,
cls
must be a fully qualified name of the class(i.e. the entire thing)
cls
必须是类的完全限定名称(即整个事物)
e.g.:
例如:
@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;
}
Depending on your requirements take a look at the other ComponentName
constructors.
根据您的要求,查看其他ComponentName
构造函数。
回答by Usama Saeed US
i was facing same issue adding search intent filter like this to searchable activity:
我遇到了同样的问题,将这样的搜索意图过滤器添加到可搜索活动中:
<activity
android:launchMode="singleTop"
android:name=".ui.activities.MainActivity"
android:label="@string/app_name"
android:theme="@style/AppTheme.NoActionBar">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.SEARCH" />
</intent-filter>
<meta-data
android:name="android.app.searchable"
android:resource="@xml/searchable" />
</activity>
回答by randomness
Double check if the corresponding entry(ie search_hint and app_label) is present in values/strings.xml
仔细检查 values/strings.xml 中是否存在相应的条目(即 search_hint 和 app_label)
eg
例如
<string name="app_label">FunApp</string>
<string name="search_hint">Caps Off</string>