web-dev-qa-db-fra.com

Android - NullPointerException sur SearchView dans la barre d'action

J'ai un problème en essayant d'ajouter un widget SearchView à la barre d'action dans mon activité. J'obtiens une valeur null lorsque j'appelle getActionView pour obtenir mon objet SearchView.

J'ai suivi le guide du développeur Android et ai également abordé une tonne de SO ainsi que d'autres liens sur Internet; Tout en rien. Cela pourrait être quelque chose de simple mais je n’étais pas capable de le comprendre - il me semble que mon code est fondamentalement le même que celui de Google (à part changer certains noms, etc.) mais cela ne fonctionnera toujours pas.

Toute aide serait appréciée.

Inclus ci-dessous sont des bits pertinents du code. S'il vous plaît laissez-moi savoir si quelque chose n'est pas clair ou si vous avez une idée de ce qui pourrait éventuellement être faux.

Code d'activité:

    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>
46
JakeP

Essayez de remplacer la ligne défaillante par:

mSearchMenuItem = menu.findItem(R.id.action_search);
mSearchView = (EnglishVerbSearchView) MenuItemCompat.getActionView(mSearchMenuItem);

Où R.id.action_search est l'id de votre élément de recherche dans le menu.

MODIFIER

Votre manifeste devrait ressembler à ça:

<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 façon dont vous appelez setSearchableInfo est la suivante:

mSearchView.setSearchableInfo(searchManager.getSearchableInfo(
            new ComponentName(getApplicationContext(), SearchResultActivity.class)));

EDIT 2

Assurez-vous que votre fichier xml de menu est comme ça (faites attention à ces 2 attributs avec l'espace de noms yourapp - c'est nécessaire lorsque vous utilisez la bibliothèque 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>
106
Szymon

Commencez par vérifier que vous utilisez app namespace pour actionViewClass .

Android:actionViewClass="Android.support.v7.widget.SearchView"- cela jette NPE

app:actionViewClass="Android.support.v7.widget.SearchView"- utilisez ceci

et deuxieme 

Vérifiez si vous utilisez same searchView dans menu.xml et dans votre Activity

25
Ketan Keshri

J'ai eu un semblable similaire probablement apparu sur mes versions de publication, mais pas mes versions de débogage lors du basculement vers la bibliothèque de support v21. Il s’est avéré qu’il s’agissait d’un problème d’obscurcissement, et l’ajout de cette ligne à mon fichier proguard-rules.txt a corrigé le problème:

-keep class Android.support.v7.widget.SearchView { *; }
25
waynesford

J'ai eu un problème très similaire où la ligne suivante retournait null

SearchView searchView = (Android.support.v7.widget.SearchView)MenuItemCompat.getActionView(searchMenuItem);

Le correctif était dans mon fichier styles.xml, j'ai changé le parent de mon AppTheme en Theme.AppCompat.Light

<resources>
    <!-- Base application theme. -->
    <style name="AppTheme" parent="Theme.AppCompat.Light">
1
Parampal Pooni

pour moi, c’est la bonne réponse: Dans menu/options_menu.xml, utilisez ceci:

app:actionViewClass="Android.support.v7.widget.SearchView"
0
liang

Pour tous ceux qui cherchaient encore, je suivais tout ce qui était écrit ci-dessus et ne parvenais pas à faire avancer les choses. J'ai enveloppé mon searchView.setSearchableInfo ... dans un chèque nul et le tour est joué! Il a fonctionné comme il se doit.

if (searchView != null) {
    searchView.setSearchableInfo(searchManager.getSearchableInfo(
                    new ComponentName(getApplicationContext(), SearchActivity.class)));
}
0
Jacob

Je pense que vous occupez FragmentActivity, vous devez prolonger de ActionBarActivity 

0
steving21