Как добавить SearchWidget в ActionBar?
Я пытаюсь добавить Search-ActionView в свое приложение (как описано здесь http://developer.android.com/guide/topics/search/search-dialog.html#UsingSearchWidget). К сожалению, я продолжаю получать исключение NullPointerException, и мне сложно определить, что на самом деле происходит не так.
Я создал поисковую конфигурацию и операцию поиска, как показано на странице android. Мое меню .xml файла выглядит следующим образом:
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
...
<item
android:id="@+id/menu_item_search"
android:actionViewClass="android.widget.SearchView"
android:icon="@drawable/icon_search"
android:showAsAction="always"
android:title="@string/action_bar_button_search">
</item>
</menu>
Это метод, в котором выбрано исключение:
public boolean onCreateOptionsMenu( Menu menu )
{
MenuInflater menuInflater = getMenuInflater();
menuInflater.inflate( R.menu.action_bar, menu );
SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
SearchView searchView = (SearchView) menu.findItem(R.id.menu_item_search).getActionView();
// NullPointerException thrown here; searchView is null.
searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));
searchView.setIconifiedByDefault(false);
return super.onCreateOptionsMenu( menu );
}
Полная трассировка стека:
FATAL EXCEPTION: main
java.lang.NullPointerException
at com.example.activities.Test.onCreateOptionsMenu(Test.java:41)
at android.app.Activity.onCreatePanelMenu(Activity.java:2444)
at com.android.internal.policy.impl.PhoneWindow.preparePanel(PhoneWindow.java:408)
at com.android.internal.policy.impl.PhoneWindow.invalidatePanelMenu(PhoneWindow.java:759)
at com.android.internal.policy.impl.PhoneWindow$1.run(PhoneWindow.java:2997)
at android.os.Handler.handleCallback(Handler.java:605)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4507)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:790)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:557)
at dalvik.system.NativeStart.main(Native Method)
Ответы
Ответ 1
используйте этот способ, как в ссылка
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.action_bar, menu);
MenuItem searchItem = menu.findItem(R.id.menu_item_search);
SearchView searchView = (SearchView) searchItem.getActionView();
SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
if(null!=searchManager ) {
searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));
}
searchView.setIconifiedByDefault(false);
return true;
}
Ответ 2
Поскольку этот вопрос просматривается довольно часто, и я снова и снова наткнулся на ту же проблему, и здесь мы немного следим за тем, чтобы отслеживать все необходимые шаги для создания SearchWidget.
В SearchWidget есть одна сложная часть: Если вы используете жестко закодированные строки в файле searchable.xml вместо ресурсов, приложение будет разбиваться с запутанным сообщением об ошибке. Мне потребовалось слишком много часов моей жизни...
-
Создайте действие для обработки результатов поиска
public class Search extends Activity {}
-
Добавьте файл "searchable.xml" в каталог res/xml (используйте ресурсы для подсказки и метки!)
<searchable xmlns:android="http://schemas.android.com/apk/res/android"
android:hint="@string/search_hint"
android:includeInGlobalSearch="false"
android:label="@string/search_label"
android:searchSettingsDescription="@string/search_global_description" />
-
Создайте правильный пункт меню "main.xml" в каталоге res/menu
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:id="@+id/options_menu_main_search"
android:actionViewClass="android.widget.SearchView"
android:icon="@drawable/icon_magnifier"
android:showAsAction="always"
android:title="Search"/>
</menu>
-
Обновите свой Manifest.xml: добавьте активность поиска и укажите, какие действия могут получать поисковые запросы. Добавление <meta-data android:name="android.app.default_searchable" android:value=".app.Search" />
в activity
node делает его доступным для поиска. Добавление его в application
node делает все действия доступными для поиска.
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<application>
<meta-data
android:name="android.app.default_searchable"
android:value=".app.Search" />
<activity android:name=".activities.Search" >
<intent-filter>
<action android:name="android.intent.action.SEARCH" />
</intent-filter>
<meta-data
android:name="android.app.searchable"
android:resource="@xml/searchable" />
</activity>
</application>
-
Добавьте SearchManager в ActionView в каждое действие, которое должно предоставить SearchWidget
public class Activity extends android.app.Activity
{
@Override
public boolean onCreateOptionsMenu( Menu menu )
{
getMenuInflater().inflate( R.menu.main, menu );
// Add SearchWidget.
SearchManager searchManager = (SearchManager) getSystemService( Context.SEARCH_SERVICE );
SearchView searchView = (SearchView) menu.findItem( R.id.options_menu_main_search ).getActionView();
searchView.setSearchableInfo( searchManager.getSearchableInfo( getComponentName() ) );
return super.onCreateOptionsMenu( menu );
}
}
Ответ 3
Если вы используете таргетинг Android 2.x и используете android.support.v7.widget.SearchView
убедитесь, что ваш файл menu.xml выглядит так (обратите внимание на пространство имен yourapp)
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:yourapp="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/search"
android:title="@string/search"
android:icon="@drawable/ic_search"
yourapp:showAsAction="always"
yourapp:actionViewClass="android.support.v7.widget.SearchView" />
</menu>
И в Управлении, где вы раздуваете меню, используйте:
android.support.v7.widget.SearchView searchView = (android.support.v7.widget.SearchView)
MenuItemCompat.getActionView(menu.findItem(R.id.search));
Ответ 4
SearchView getActionView возвращает null
Как в ссылке, откройте файл xml вашего меню и измените
android:actionViewClass="android.widget.SearchView"
в
app:actionViewClass="android.widget.SearchView"
это сработало для меня
Ответ 5
У меня тоже такая же проблема. В моем случае изменение android:actionViewClass
до app:actionViewClass
решило проблему
(с тегом xmlns:app="http://schemas.android.com/apk/res-auto"
в теге <menu>
).
Ответ 6
Эта проблема запускается отсутствующим фильтром цели:
<intent-filter>
<action android:name="android.intent.action.SEARCH" />
</intent-filter>
Ответ 7
Прежде всего, создайте XML файл, содержащий SearchWidget, в папку макета
<?xml version="1.0" encoding="utf-8"?>
<SearchView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/edit_query"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:inputType="textFilter"
>
</SearchView>
Затем, в своей деятельности, откройте панель действий
android.support.v7.app.ActionBar actionBar = getSupportActionBar();
Затем добавьте ссылку на ваш поиск
actionBar.setCustomView(R.layout.custom_action_bar);
search = (EditText) actionBar.getCustomView().findViewById(
R.id.edit_query);
Затем установите параметр отображения для панели действий
actionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM | ActionBar.DISPLAY_HOME_AS_UP);
Что это.
Btw, вы также можете использовать мой виджет поиска, который берет список строк в виде списка массивов и отображает их в соответствии с введенным запросом, Когда пользователь выбирает конкретный результат, возвращается выбранный результат, который может быть получен в onActivityResult родительской активности.