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.
Cambiar el espacio de nombre de
actionViewClass
desdeandroid:actionViewClass
a laapp:actionViewClass
Implementando la interfaz
android.support.v7.widget.SearchView.OnQueryTextListener
para la actividad actual.Utilice directamente
setOnQueryTextListener
lugar deSearchViewCompat.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)"