web-dev-qa-db-fra.com

MenuItemCompat.getActionView renvoie toujours la valeur null

Je viens de mettre en œuvre le v7 AppCompat bibliothèque de support mais le MenuItemCompat.getActionView retourne toujours null dans chaque Android que j'ai testée (4.2.2, 2.3.4 ....)

Le SearchView est affiché dans la barre d’action, mais il ne répond pas aux actions tactiles et ne se développe pas pour afficher son EditText et se présente comme une simple icône.

@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>
141
Mohsen Afshin

Finalement j'ai trouvé la solution.

  1. Changer l’espace de noms de actionViewClass de Android:actionViewClass à app:actionViewClass

  2. Implémentation Android.support.v7.widget.SearchView.OnQueryTextListener interface pour l'activité en cours.

  3. Utilisez directement setOnQueryTextListener au lieu 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);
    }
    
296
Mohsen Afshin

Dans mon cas, c'était un fichier ProGuard. Vous devez ajouter cette ligne:

-keep class Android.support.v7.widget.SearchView { *; }
85
Ivan Vazhnov

Pour moi, une importation d'espace de nom menu.xml Incorrecte a été à l'origine de ce problème.

Mon original menu.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>

Il semble que le xmlns:app="http://schemas.Android.com/tools" Ait amené MenuItemCompat.getActionView() à renvoyer null. Changer cette importation en xmlns:app="http://schemas.Android.com/apk/res-auto" A résolu le problème.

Nouveau travail 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>
42
Sean Barbeau

Je pense que le problème est que vous utilisez SearchView à partir du package Support V7 et peut-être que votre niveau d'API est défini sur ..... 22 ??.

Changer votre code à la suivante pour résoudre le problème:

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> 
5
Michele Caggiano

J'étais avec la même erreur, ma méthode getActionView() retournait toujours null. Donc, j'ai fait les choses suivantes:

<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"/>

J'ai vu dans certains messages que les gens utilisent app: ou yourapp, mais j'ai utilisé normalement Android:ActionVewClass.

Sur ma méthode 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;
}

Et n'oubliez pas de mettre dans la méthode onCreate:

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

Cela fonctionne très bien pour mon activité "extension" pour FragmentActivity et ActionBarActivity.

4
Franzé Jr.

La réponse de Mohsen Afshin ci-dessus était mon point de départ et j'ai fait quelques ajustements pour le faire fonctionner avec ma configuration:

@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>
2
kasiahayden

J'ai eu le même code, mais au lieu d'utiliser l'importation Android.support.v7.widget.SearchView; J'utilisais import Android.widget.SearchView;. Cela a résolu mon problème avec la valeur null. Il suffit donc de modifier ce code dans votre activité de recherche et cela fonctionnera, ainsi que de modifier l’espace de noms au format XML.

1
marcelocolombo

J'ai eu un problème très similaire avec la différence que je tentais d'utiliser une classe qui a étendu Android.widget.ImageView

Si vous utilisez ProGuard, vous devez spécifier d'autoriser les méthodes impliquées dans cette classe.

-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

Cela dit, "Autoriser tous les constructeurs nécessaires pouvant être appelés à partir du xml et autoriser tous les configurateurs personnalisés utilisés (ajouter davantage si nécessaire)"

0
ElliotM

Voici un extrait de la procédure à suivre pour gérer searchView à partir de la bibliothèque de support 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;
  }

De plus, si vous utilisez Proguard, ajoutez ceci à sa configuration:

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