tutorial studio ejemplo bar android searchview android-actionbar-compat android-search

studio - searchview android ejemplo



MenuItemCompat.getActionView siempre devuelve null (10)

Acabo de implementar la biblioteca de soporte de v7 AppCompat pero el MenuItemCompat.getActionView siempre devuelve null en cada versión de Android que probé (4.2.2, 2.3.4 ....)

SearchView se muestra en la barra de acciones, pero no responde a las acciones táctiles y no se expande para mostrar su EditText y es como un simple icono.

@Override public boolean onCreateOptionsMenu(Menu menu) { MenuInflater inflater = getMenuInflater(); inflater.inflate(R.menu.menu, menu); MenuItem searchItem = menu.findItem(R.id.action_search); SearchView searchView = (SearchView) MenuItemCompat.getActionView(searchItem); if (searchView != null) { SearchViewCompat.setOnQueryTextListener(searchView, mOnQueryTextListener); searchView.setIconifiedByDefault(false); Log.d(TAG,"SearchView not null"); } else Log.d(TAG, "SearchView is null"); } return super.onCreateOptionsMenu(menu); }

Menu.xml

<?xml version="1.0" encoding="utf-8"?> <menu xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto"> <item android:id="@+id/action_search" app:showAsAction="always|collapseActionView" android:icon="@drawable/abc_ic_search" android:title="@string/action_bar_search" android:actionViewClass="android.support.v7.widget.SearchView"/> <item android:id="@+id/action_refresh" android:icon="@drawable/refresh" android:title="@string/action_bar_refresh" app:showAsAction="ifRoom"/> </menu>


Aquí hay un fragmento de cómo manejar el searchView de la biblioteca de soporte v7:

@Override public void onCreateOptionsMenu(final Menu menu,final MenuInflater inflater) { menu.clear(); getActivity().getMenuInflater().inflate(...,menu); _searchView=(SearchView)MenuItemCompat.getActionView(_searchMenuItem); _searchView.setQueryHint(...); if(VERSION.SDK_INT<VERSION_CODES.HONEYCOMB) { final EditText searchTextView=(EditText)searchView.findViewById(R.id.search_src_text); if(searchTextView!=null) { searchTextView.setScroller(new Scroller(_context)); searchTextView.setMaxLines(1); searchTextView.setVerticalScrollBarEnabled(true); searchTextView.setMovementMethod(new ScrollingMovementMethod()); searchTextView.setTextColor(_context.getResources().getColor(App.getResIdFromAttribute(_context,android.R.attr.textColorPrimary))); } } _searchView.setOnQueryTextListener(new android.support.v7.widget.SearchView.OnQueryTextListener() { ... }); MenuItemCompat.setActionView(_searchMenuItem,_searchView); MenuItemCompat.setOnActionExpandListener(_searchMenuItem,new OnActionExpandListener() { ... }); super.onCreateOptionsMenu(menu,inflater); } public static int getResIdFromAttribute(final Activity activity,final int attr) { if(attr==0) return 0; final TypedValue typedvalueattr=new TypedValue(); activity.getTheme().resolveAttribute(attr,typedvalueattr,true); return typedvalueattr.resourceId; }

Además, si usa Proguard, agréguelo a su configuración:

-keep class android.support.v4.app.** { *; } -keep interface android.support.v4.app.** { *; } -keep class android.support.v7.widget.SearchView { *; } -keepattributes *Annotation*


Creo que el problema es que utilizas SearchView desde el paquete Support V7 y tal vez tu nivel de API está establecido en ... 22 ??.

Cambiando tu código a lo siguiente para solucionar el problema:

menu.xml

<?xml version="1.0" encoding="UTF-8" ?> <menu xmlns:android="http://schemas.android.com/apk/res/android" > <item android:id="@+id/action_search" android:icon="@drawable/actionbar_button_search" android:title="Search" android:showAsAction="always" android:actionViewClass="android.widget.SearchView" /> </menu>


Eliminar código: public class DemoActivity extends ActionBarActivity

Reemplazar por: public class DemoActivity extends Activity


En mi caso, era un archivo ProGuard. Necesita agregar esta línea:

-keep class android.support.v7.widget.SearchView { *; }


Estaba con el mismo error, mi método getActionView() siempre devolvía nulo. Entonces, hice las siguientes cosas:

<item android:id="@+id/action_search" android:icon="@drawable/abc_ic_search" android:title="@string/search_title" android:showAsAction="always" android:actionViewClass="android.widget.SearchView"/>

Vi en algunos mensajes que las personas están usando la aplicación: o yourapp, pero usé normalmente android:ActionVewClass .

En mi método onCreateOptionsMenu :

@Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.feed, menu); // Associate searchable configuration with the SearchView SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE); SearchView searchView = (SearchView) menu.findItem(R.id.action_search) .getActionView(); searchView.setSearchableInfo(searchManager .getSearchableInfo(getComponentName())); return true; }

Y no te olvides de poner en el método onCreate :

// enabling action bar app icon and behaving it as toggle button getActionBar().setDisplayHomeAsUpEnabled(true); getActionBar().setHomeButtonEnabled(true);

Esto funciona muy bien para mi actividad de "extender" para FragmentActivity y ActionBarActivity .


Finalmente encontré la solución.

  1. Cambiar el espacio de nombre de actionViewClass desde android:actionViewClass a la app:actionViewClass

  2. Implementando la interfaz android.support.v7.widget.SearchView.OnQueryTextListener para la actividad actual.

  3. Utilice directamente setOnQueryTextListener lugar de SearchViewCompat.setOnQueryTextListener

    @Override public boolean onCreateOptionsMenu(Menu menu) { MenuInflater inflater = getMenuInflater(); inflater.inflate(R.menu.menu, menu); MenuItem searchItem = menu.findItem(R.id.action_search); SearchView searchView = (SearchView) MenuItemCompat.getActionView(searchItem); if (searchView != null) { searchView.setOnQueryTextListener(this); } return super.onCreateOptionsMenu(menu); }


La respuesta anterior de Mohsen Afshin fue mi punto de partida y realicé algunas modificaciones para que funcione con mi configuración:

@Override public boolean onCreateOptionsMenu(Menu menu) { MenuInflater inflater = getMenuInflater(); inflater.inflate(R.menu.menu, menu); MenuItem searchItem = menu.findItem(R.id.action_search); // SearchView searchView = (SearchView) MenuItemCompat // .getActionView(searchItem); SearchView searchView = (SearchView) searchItem.getActionView(); if (searchView != null) { searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() { @Override public boolean onQueryTextSubmit(String s) { // do something with s, the entered string query = s; Toast.makeText(getApplicationContext(), "String entered is " + s, Toast.LENGTH_SHORT).show(); return true; } @Override public boolean onQueryTextChange(String s) { return false; } }); } return super.onCreateOptionsMenu(menu); }

menu.xml

<menu xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" tools:context=".MainActivity" > <item android:id="@+id/action_search" android:orderInCategory="5" android:title="Search" android:icon="@drawable/ic_action_search" android:showAsAction="ifRoom|collapseActionView" android:actionViewClass="android.widget.SearchView" /> </menu>


Para mí, una importación incorrecta del espacio de nombres menu.xml causó este problema.

Mi menu.xml original.xml:

<menu xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/tools"> <item android:id="@+id/action_search" android:title="@string/map_option_search" android:icon="@drawable/ic_action_search" app:showAsAction="collapseActionView|ifRoom" app:actionViewClass="android.support.v7.widget.SearchView"/> </menu>

Parece que xmlns:app="http://schemas.android.com/tools" estaba causando que MenuItemCompat.getActionView() devuelva null . Al cambiar esta importación a xmlns:app="http://schemas.android.com/apk/res-auto" solucionó el problema.

Nuevo menu.xml :

<menu xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto"> <item android:id="@+id/action_search" android:title="@string/map_option_search" android:icon="@drawable/ic_action_search" app:showAsAction="collapseActionView|ifRoom" app:actionViewClass="android.support.v7.widget.SearchView"/> </menu>


Tenía el mismo código, pero en lugar de usar la importación android.support.v7.widget.SearchView; Estaba usando import android.widget.SearchView; . Esto solucionó mi problema con el valor null . Así que simplemente cambie este código en su actividad de búsqueda y funcionará y también cambiará el espacio de nombres en el archivo xml.


Tuve un problema muy similar con la diferencia de que estaba intentando usar una clase que extendía android.widget.ImageView

Si usa ProGuard, debe especificar para permitir los métodos involucrados en esta clase.

-keep public class * extends android.widget.ImageView{ public <init>(android.content.Context); public <init>(android.content.Context, android.util.AttributeSet); public <init>(android.content.Context, android.util.AttributeSet, int); public void set*(...); }

http://proguard.sourceforge.net/manual/examples.html

Esto dice, "Permitir todos los constructores necesarios que puedan llamarse desde xml y permitir cualquier setter personalizado que use también (agregar más según sea necesario)"