Android-NullPointerException en SearchView en Action Bar
android-actionbar (8)
Tengo un problema al tratar de agregar un widget SearchView a ActionBar en mi actividad: Obtengo un valor nulo cuando llamo a getActionView para obtener mi objeto SearchView.
He seguido la guía para desarrolladores de Android y también he consultado un montón de preguntas sobre SO y algunos otros enlaces en Internet; todo fue en vano. Podría ser algo simple pero no fui capaz de resolverlo, me parece que mi código es básicamente el mismo que el de google (además de cambiar algunos nombres, etc.) pero aún así no funciona.
Cualquier ayuda sería apreciada.
A continuación se incluyen los bits relevantes del código. Por favor, avíseme si no está claro si tiene alguna idea sobre lo que podría estar mal.
Código de actividad:
private ListView workflowListView;
private DrawerLayout drawerLayout;
private ListView drawerList;
private ActionBarDrawerToggle drawerToggle;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().requestFeature(Window.FEATURE_ACTION_BAR);
setContentView(R.layout.activity_workflow_list);
workflowListView = (ListView) findViewById(R.id.workflowListView);
drawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
drawerList = (ListView) findViewById(R.id.drawer_list);
drawerToggle = new ActionBarDrawerToggle(
this, /* host Activity */
drawerLayout, /* DrawerLayout object */
R.drawable.ic_launcher, /* nav drawer icon to replace ''Up'' caret */
R.string.app_name, /* "open drawer" description */
R.string.app_name /* "close drawer" description */
) {
/** Called when a drawer has settled in a completely closed state. */
public void onDrawerClosed(View view) {
// getActionBar().setTitle("Closed drawer");
}
/** Called when a drawer has settled in a completely open state. */
public void onDrawerOpened(View drawerView) {
// getActionBar().setTitle("Open drawer");
}
};
drawerLayout.setDrawerListener(drawerToggle);
ActionBar actionBar = getActionBar();
actionBar.setDisplayShowTitleEnabled(false);
actionBar.setDisplayHomeAsUpEnabled(true);
actionBar.setHomeButtonEnabled(true);
actionBar.setIcon(android.R.color.transparent);
String[] testData = {"a", "b", "c", "d"};
ArrayList<String> workflowList = new ArrayList<String>();
for (String s : testData) {
workflowList.add(s);
}
ArrayAdapter<String> workflowAdapter = new ArrayAdapter<String>(this.getApplicationContext(), R.layout.workflow_list_item, workflowList);
workflowListView.setAdapter(workflowAdapter);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.workflow_list, menu);
inflater.inflate(R.menu.options_menu, menu);
// Associate searchable configuration with the SearchView
SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
// The below line returned null even though it was used in Google sample code
SearchView searchView = (SearchView) menu.findItem(R.id.search).getActionView();
searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));
return super.onCreateOptionsMenu(menu);
}
xml / searchable.xml:
<?xml version="1.0" encoding="utf-8"?>
<searchable xmlns:android="http://schemas.android.com/apk/res/android"
android:label="@string/app_name"
android:hint="@string/search_hint"
android:includeInGlobalSearch="false" />
menu / options_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/search"
android:title="@string/search_title"
android:icon="@drawable/ic_action_search"
android:showAsAction="always|collapseActionView"
android:actionViewClass="android.support.v7.widget.SearchView" />
</menu>
Creo que estás ocupando FragmentActivity , necesitas extender ActionBarActivity
Intenta reemplazar la línea que falla con:
mSearchMenuItem = menu.findItem(R.id.action_search);
mSearchView = (EnglishVerbSearchView) MenuItemCompat.getActionView(mSearchMenuItem);
Donde R.id.action_search es la identificación de su elemento de búsqueda en el menú.
EDITAR
Su manifiesto debe verse así:
<activity
android:name="com.bronzelabs.twc.activities.WorkflowListActivity"
android:label="@string/app_name"
android:theme="@style/Theme.AppCompat.Light" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".activities.SearchResultActivity"
android:theme="@style/Theme.AppCompat.Light"
android:launchMode="singleTop">
<intent-filter>
<action android:name="android.intent.action.SEARCH" />
</intent-filter>
<meta-data android:name="android.app.searchable" android:resource="@xml/searchable"
android:value=".activities.SearchResultActivity" />
</activity>
La forma en que llamas a setSearchableInfo
es:
mSearchView.setSearchableInfo(searchManager.getSearchableInfo(
new ComponentName(getApplicationContext(), SearchResultActivity.class)));
EDIT 2
Asegúrese de que el archivo xml del menú sea así (preste atención a esos 2 atributos con el espacio de nombres yourapp
; esto es necesario cuando usa la biblioteca compat):
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:yourapp="http://schemas.android.com/apk/res-auto" >
<item android:id="@+id/action_search"
android:title="@string/action_search"
android:icon="@drawable/action_search"
yourapp:showAsAction="always|collapseActionView"
yourapp:actionViewClass="android.support.v7.widget.SearchView" />
</menu>
Para cualquiera que todavía esté buscando, seguí todo lo anterior y parecía que no funcionaba. Envolví mi searchView.setSearchableInfo ... en un cheque nulo y listo! Funcionó justo como debería.
if (searchView != null) {
searchView.setSearchableInfo(searchManager.getSearchableInfo(
new ComponentName(getApplicationContext(), SearchActivity.class)));
}
Primero compruebe que está usando el espacio de nombres de la aplicación para actionViewClass .
android:actionViewClass="android.support.v7.widget.SearchView"
-esto lanza NPE
app:actionViewClass="android.support.v7.widget.SearchView"
-use esto
y segundo
Comprueba si estás utilizando la misma searchView
en menu.xml
y en tu Actividad
Tenía un problema muy similar en el que la siguiente línea regresaba nula
SearchView searchView = (android.support.v7.widget.SearchView)MenuItemCompat.getActionView(searchMenuItem);
La solución estaba en mi archivo styles.xml
, cambié el elemento primario de mi AppTheme a Theme.AppCompat.Light
<resources>
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light">
Tuve un similar probablemente que apareció en mis compilaciones de lanzamiento, pero no mis compilaciones de depuración al cambiar a la biblioteca de soporte v21. Resultó ser un problema de ofuscación, y agregar esta línea a mi archivo proguard-rules.txt lo solucionó:
-keep class android.support.v7.widget.SearchView { *; }
Yo tuve el mismo problema. Mi solución es: replace android:actionViewClass="android.support.v7.widget.SearchView"
con
android:actionViewClass="android.widget.SearchView"
para mí, esta es la respuesta correcta: en menu / options_menu.xml, usa esto:
app:actionViewClass="android.support.v7.widget.SearchView"