¿Cómo agregar un widget de búsqueda a la barra de acción?

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 detectar lo que realmente está saliendo 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 de menú .xml 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 completo de la pila:

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)

preguntado el 30 de junio de 12 a las 18:06

¿Puedes publicar el código completo? ¿Ha implementado la configuración de búsqueda y la actividad de búsqueda como se describe en el documento? -

Como se escribió anteriormente: el xml de búsqueda y la actividad de búsqueda se configuran y agregan al Manifiesto. La línea 41 es la que comenté con "NullPointerException lanzado aquí; searchView es nulo". -

Así que el problema es en realidad que menu.findItem(R.id.menu_item_search).getActionView() sigue volviendo nulo. -

¿Cuál es el nombre del archivo de menú, según el código R.menu.action_bar, y según la descripción Mi menu .xml el archivo se parece a esto -

solo confirmando que todo lo demás se ve bien..... -

7 Respuestas

Dado que esta pregunta se busca con bastante frecuencia y me topé 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 complicada 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...

  1. Crear una actividad para manejar los resultados de búsqueda

    public class Search extends Activity {}
    
  2. Agregue un archivo "buscable.xml" a su directorio res/xml (¡Usa recursos para sugerencias y etiquetas!)

    <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" />
    
  3. 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>
    
  4. Actualice su Manifest.xml: agregue la actividad de búsqueda y especifique qué actividades pueden recibir intentos de búsqueda. agregando <meta-data android:name="android.app.default_searchable" android:value=".app.Search" /> a una activity node hace que se pueda buscar. Agregándolo a la application node hace que todas las actividades se puedan 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>
    

  5. Agregue el SearchManager a su ActionView en cada actividad que debería 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 );
        }
    }
    

Respondido el 22 de junio de 13 a las 13:06

¡Gracias! Respuesta realmente útil - blaganesh101

El ejemplo más claro que he visto - tom kincaid

Me ayudaría si se elaborara el paso 1; esa es la parte con la que estoy teniendo problemas. - Rock Lee

Si está utilizando la orientación Android 2.x y utilizando android.support.v7.widget.SearchView verifique que su menu.xml se vea así (tenga en cuenta el tuaplicacion espacio de nombres)

<?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 inflas el menú usa:

android.support.v7.widget.SearchView searchView = (android.support.v7.widget.SearchView) 
MenuItemCompat.getActionView(menu.findItem(R.id.search));

respondido 13 mar '14, 16:03

Esto debe marcarse como la respuesta correcta, la primera respuesta no tiene sentido, es el searchView que es nulo, no el searchManager. - Saher Ahwal

Gracias por el consejo. Reparaste mi temperamento actual. - bmeulmeester

usar de esta manera como en aquí

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;
    }

Respondido el 24 de diciembre de 14 a las 02:12

ok, simplemente cambie la identificación a menu_item_search_1 para ambos lugares, luego limpie y construya el proyecto y ejecute eso ... - Dheeresh Singh

No descubrí qué estaba fallando exactamente, pero algunos intentos más de cambiar el nombre, construir y limpiar resolvieron el problema de alguna manera. Probablemente tuve algunos deslices estúpidos en alguna parte... - Taig

He probado esta solución, pero aún así la vista de búsqueda en la línea searchView.setSearchableInfo(searchManager... es nulo. ¿Cómo puedo llegar al SearchView real como se define en el archivo menu.xml? - david miler

Esto no parece resolver el problema, y ​​el formato del código es extraño... - aubtin samai

SearchView getActionView devuelve nulo

Como en el enlace, abra su archivo xml de menú y cambie

android:actionViewClass="android.widget.SearchView"

dentro

app:actionViewClass="android.widget.SearchView" 

esto funcionó para mí

contestado el 23 de mayo de 17 a las 13:05

También tengo el mismo problema. en mi caso cambio android:actionViewClass a app:actionViewClass resolvió el problema (con xmlns:app="http://schemas.android.com/apk/res-auto" in <menu> etiqueta).

Respondido el 03 de junio de 16 a las 10:06

En primer lugar, cree un archivo XML que contenga el 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, configure 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 podrías usar mi widget de búsqueda que toma una lista de cadenas como una lista de matriz y las muestra, de acuerdo con la consulta ingresada. Una vez que el usuario selecciona un resultado en particular, se devuelve el resultado seleccionado que se puede recuperar en onActivityResult de la actividad principal.

Respondido el 03 de Septiembre de 16 a las 10:09

Este problema se desencadena por la falta de un filtro de intenciones:

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

Respondido el 27 de enero de 14 a las 16:01

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.