android - sgoliver - ¿Cómo agregar un SearchWidget a la barra de acción?
personalizar toolbar android studio (7)
Dado que esta pregunta se consulta con bastante frecuencia y me encontré con el mismo problema una y otra vez, aquí hay un pequeño seguimiento que realiza un seguimiento de todos los pasos necesarios para crear un SearchWidget.
Sin embargo, hay una parte difícil sobre SearchWidget: si usa cadenas codificadas en el archivo searchable.xml en lugar de recursos, la aplicación se bloqueará con un mensaje de error confuso. Esto me tomó demasiadas horas de mi vida ...
Crear una actividad para manejar los resultados de búsqueda.
public class Search extends Activity {}
Agregue un archivo "searchable.xml" a su directorio res / xml ( use los recursos para la sugerencia y la etiqueta )
<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" />
Cree el elemento de menú adecuado "main.xml" en su directorio 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>
Actualice su Manifest.xml: agregue la actividad de búsqueda y especifique qué actividades pueden recibir intentos de búsqueda. Agregar
<meta-data android:name="android.app.default_searchable" android:value=".app.Search" />
a un nodo deactivity
hace que se pueda buscar. Al agregarlo al nodo de laapplication
todas las actividades se pueden buscar.<?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>
Agregue el SearchManager a su ActionView en cada actividad que debe proporcionar el 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 ); } }
Estoy tratando de agregar un Search-ActionView a mi aplicación (como se explica aquí http://developer.android.com/guide/topics/search/search-dialog.html#UsingSearchWidget ). Desafortunadamente, sigo recibiendo una NullPointerException y me cuesta mucho detectar qué es lo que realmente está mal.
Creé una configuración de búsqueda y una actividad de búsqueda como se muestra en la página de Android. Mi archivo .xml del menú se ve así:
<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>
Este es el método donde se lanza la excepción:
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 );
}
Rastreo de pila completa:
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)
En primer lugar, cree un archivo XML que contenga SearchWidget en su carpeta de diseño
<?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>
Luego, en tu actividad, recupera la barra de acción.
android.support.v7.app.ActionBar actionBar = getSupportActionBar();
Luego agregue una referencia a su vista de búsqueda
actionBar.setCustomView(R.layout.custom_action_bar);
search = (EditText) actionBar.getCustomView().findViewById(
R.id.edit_query);
Luego, configura la opción de visualización para la barra de acción
actionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM | ActionBar.DISPLAY_HOME_AS_UP);
Eso es.
Por cierto, también puede usar mi widget de búsqueda, que toma una lista de cadenas como una lista de matrices y las muestra, de acuerdo con la consulta ingresada. Una vez que el usuario selecciona un resultado particular, se devuelve el resultado seleccionado que puede recuperarse en el resultado de actividad de la actividad principal.
Este problema se desencadena por un filtro de intento faltante:
<intent-filter>
<action android:name="android.intent.action.SEARCH" />
</intent-filter>
Si está utilizando la orientación a Android 2.x y está utilizando android.support.v7.widget.SearchView, verifique que su menu.xml tenga este aspecto (tenga en cuenta el espacio de nombres de su aplicación)
<?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>
Y en la Actividad donde infla el menú utilice:
android.support.v7.widget.SearchView searchView = (android.support.v7.widget.SearchView)
MenuItemCompat.getActionView(menu.findItem(R.id.search));
También tengo el mismo problema. En mi caso, cambie android:actionViewClass
a app:actionViewClass
resolvió el problema (con xmlns:app="http://schemas.android.com/apk/res-auto"
en la etiqueta <menu>
).
usar de esta manera como en el link
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;
}
SearchView getActionView regresa nulo
Al igual que en el enlace, abra su archivo xml de menú y cambie
android:actionViewClass="android.widget.SearchView"
dentro
app:actionViewClass="android.widget.SearchView"
esto me funcionó