Невозможно заставить searchview работать в панели действий
Я довольно новичок в разработке Java и Android; и я работал над приложением, в котором я хочу панель действий с SearchView
, Я посмотрел на примеры Google, но я не могу заставить его работать. Я, должно быть, что-то делаю не так, и я собираюсь отказаться от разработки приложений: я искал, но я не нашел ничего полезного. Может быть, вы, ребята, можете мне помочь:)
Проблема: я открываю представление поиска, как и должно, но после этого ничего не происходит, я заметил, что мой searchManager.getSearchableInfo(getComponentName()) возвращает ноль. Также мой подсказка, которую я дал, не отображается в окне поиска, что наводит меня на мысль, что, возможно, приложение не может найти мой 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);
}
}
А вот ссылка на упомянутый проект, буду вечно признателен, если кто-то мне поможет в этом!
8 ответов
Ваша проблема в вашем AndroidManifest. У меня было почти так же, как и у вас, потому что это то, что я получаю, следуя документации. Но это неясно или ошибочно.
Просматривая исходный код API Demos, я обнаружил, что метаданные "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. Это означает, что вы должны использовать это ComponentName вместо метода getComponentName():
ComponentName cn = new ComponentName(this, SearchableActivity.class);
searchView.setSearchableInfo(searchManager.getSearchableInfo(cn));
Также кажется, что атрибуты android: hint и android: label ДОЛЖНЫ быть ссылками на строки в 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>
Но определенно сделайте (как правильно сделал ОП):
<?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>
Будьте осторожны с "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"/>
Если вы используете 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" />
На самом деле нет необходимости использовать "недостающую часть", как описано в ответах выше. Этот метод (с использованием SearchView
) работает точно так, как говорят официальные документы, до использования виджета поиска. Здесь небольшая модификация должна быть сделана следующим образом:
Недвижимость в SearchableInfo
используются для отображения меток, подсказок, предложений, создания намерений для запуска экранов результатов поиска и управления другими возможностями, такими как голосовая кнопка ( документы).
Таким образом SearchableInfo
объект, который мы передаем SearchView.setSearchableInfo(SearchableInfo s)
должен содержать правильные ссылки на целевую деятельность, которая должна отображаться для отображения результатов поиска. Это делается путем ручной передачи ComponentName
нашей целевой деятельности. Один конструктор для создания ComponentName
является
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
Конструкторы.
Убедитесь, что ваш searchables.xml
файл находится в правильном месте (т.е. в вашем res/xml/
папку) и тот же файл не содержит ошибок - в противном случае вы обнаружите, что (SearchManager)getSystemService(Context.SEARCH_SERVICE).getSearchableInfo(componentName)
вернет ноль, нарушая вашу функциональность поиска.
(Также убедитесь, что вы установили componentName
соответствующим образом, потому что пример, показанный в руководстве по Android, предназначен только для тех случаев, когда вы выполняете поиск и отображаете результаты поиска в одной и той же операции.)
Я столкнулся с той же проблемой, добавляя фильтр намерения поиска, подобный этому, к активности с возможностью поиска:
<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>
Дважды проверьте, присутствует ли соответствующая запись (т.е. search_hint и app_label) в values /strings.xml
например
<string name="app_label">FunApp</string>
<string name="search_hint">Caps Off</string>