wake-up-neo.com

Der OnCloseListener von SearchView funktioniert nicht

Ich versuche, Unterstützung für die SearchView in der Android 3.0+ ActionBar hinzuzufügen, aber ich kann die OnCloseListener nicht dazu bringen, zu funktionieren.

Hier ist mein Code:

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.menu, menu);
    searchView = (SearchView) menu.findItem(R.id.search_textbox).getActionView();
    searchView.setOnQueryTextListener(new OnQueryTextListener() {
        @Override
        public boolean onQueryTextChange(String newText) {
            searchLibrary(newText);
            return false;
        }
        @Override
        public boolean onQueryTextSubmit(String query) { return false; }
    });
    searchView.setOnCloseListener(new OnCloseListener() {
        @Override
        public boolean onClose() {
            System.out.println("Testing. 1, 2, 3...");
            return false;
        }
    });
    return true;
}

Die Suche funktioniert großartig und bis auf die Variable OnCloseListener funktioniert alles. Es wird nichts an Logcat gedruckt. Hier ist der Logcat für das Klicken auf die Schaltfläche "Schließen":

02-17 13:01:52.914: I/TextType(446): TextType = 0x0
02-17 13:01:57.344: I/TextType(446): TextType = 0x0
02-17 13:02:02.944: I/TextType(446): TextType = 0x0

Ich habe die Dokumentation und Beispiele durchgesehen, aber es schien nichts zu ändern. Ich lasse es auf einem Asus Transformer Prime und einem Galaxy Nexus laufen, beide auf Eiscremesandwich. Irgendwelche Ideen?

Update:

Ja System.out.println()funktioniert. Hier ist der Beweis:

   @Override
 public boolean onQueryTextChange(String newText) {
    System.out.println(newText + "hello");
    searchLibrary(newText);
    return false;
 }

Ergebnisse in diesem Logcat:

02-17 13:04:20.094: I/System.out(21152): hello
02-17 13:04:24.914: I/System.out(21152): thello
02-17 13:04:25.394: I/System.out(21152): tehello
02-17 13:04:25.784: I/System.out(21152): teshello
02-17 13:04:26.064: I/System.out(21152): testhello
91
Michell Bak

Ich treffe auch dieses Problem, und ich habe keine andere Wahl, als auf "Oncloselistener" zu verzichten. Stattdessen erhalten Sie Ihr menuItem und dann setOnActionExpandListener. Überschreiben Sie dann unimplents Methoden. 

@Override
public boolean onMenuItemActionExpand(MenuItem item) {
    // TODO Auto-generated method stub
    Log.d("*******","onMenuItemActionExpand");
    return true;
}

@Override
public boolean onMenuItemActionCollapse(MenuItem item) {
    //do what you want to when close the sesarchview
    //remember to return true;
    Log.d("*******","onMenuItemActionCollapse");
    return true;
}
135
niki huang

Für Android API 14+ (ICS und höher) verwenden Sie diesen Code:

// When using the support library, the setOnActionExpandListener() method is
// static and accepts the MenuItem object as an argument
MenuItemCompat.setOnActionExpandListener(menuItem, new OnActionExpandListener() {
    @Override
    public boolean onMenuItemActionCollapse(MenuItem item) {
        // Do something when collapsed
        return true;  // Return true to collapse action view
    }

    @Override
    public boolean onMenuItemActionExpand(MenuItem item) {
        // Do something when expanded
        return true;  // Return true to expand action view
    }
});

Weitere Informationen: http://developer.Android.com/guide/topics/ui/actionbar.html#ActionView

Ref: onActionCollapse/onActionExpand

59
lomza

Für dieses Problem habe ich mir so etwas ausgedacht,

private SearchView mSearchView;

@TargetApi(14)
@Override
public boolean onCreateOptionsMenu(Menu menu)
{

    MenuInflater inflater = getMenuInflater();
    inflater.inflate(R.menu.conversation_index_activity_menu, menu);

    mSearchView = (SearchView) menu.findItem(R.id.itemSearch).getActionView();

    MenuItem menuItem = menu.findItem(R.id.itemSearch);

    int currentapiVersion = Android.os.Build.VERSION.SDK_INT;
    if (currentapiVersion >= Android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH)
    {
        menuItem.setOnActionExpandListener(new OnActionExpandListener()
        {

            @Override
            public boolean onMenuItemActionCollapse(MenuItem item)
            {
                // Do something when collapsed
                Log.i(TAG, "onMenuItemActionCollapse " + item.getItemId());
                return true; // Return true to collapse action view
            }

            @Override
            public boolean onMenuItemActionExpand(MenuItem item)
            {
                // TODO Auto-generated method stub
                Log.i(TAG, "onMenuItemActionExpand " + item.getItemId());
                return true;
            }
        });
    } else
    {
        // do something for phones running an SDK before froyo
        mSearchView.setOnCloseListener(new OnCloseListener()
        {

            @Override
            public boolean onClose()
            {
                Log.i(TAG, "mSearchView on close ");
                // TODO Auto-generated method stub
                return false;
            }
        });
    }


    return super.onCreateOptionsMenu(menu);

}
27
Ben Benson

Ich bin in Android 4.1.1 auf dasselbe Problem gestoßen. Sieht aus, als wäre es ein bekannter Fehler: https://code.google.com/p/Android/issues/detail?id=25758

Als Workaround habe ich jedoch den Zustandsänderungslistener verwendet (wenn SearchView von der Aktionsleiste getrennt wird, wird es offensichtlich geschlossen).

view.addOnAttachStateChangeListener(new OnAttachStateChangeListener() {

    @Override
    public void onViewDetachedFromWindow(View arg0) {
        // search was detached/closed
    }

    @Override
    public void onViewAttachedToWindow(View arg0) {
        // search was opened
    }
});

Der obige Code hat in meinem Fall gut funktioniert.


Ich poste dieselbe Antwort hier: https://stackoverflow.com/a/24573266/2162924

17
Dario

Am Ende habe ich einen kleinen Hack benutzt, der für meinen Zweck gut funktioniert - ich bin mir nicht sicher, ob er für alle Zwecke geeignet ist. Auf jeden Fall überprüfe ich, ob die Suchanfrage leer ist. Dies hängt jedoch nicht wirklich mit dem SearchView des OnCloseListener zusammen - das funktioniert immer noch nicht!

searchView.setOnQueryTextListener(new OnQueryTextListener() {
            @Override
            public boolean onQueryTextChange(String newText) {
                if (newText.length() > 0) {
                    // Search
                } else {
                    // Do something when there's no input
                }
                return false;
            }
            @Override
            public boolean onQueryTextSubmit(String query) { return false; }
        });
10
Michell Bak

Nun, das hat mein Problem gelöst:

Menüpunkt mit showAsAction="always"

<item
    Android:id="@+id/action_search"
    Android:icon="@drawable/ic_action_search"
    Android:title="Search"
    app:actionViewClass="Android.support.v7.widget.SearchView"
    app:showAsAction="always"/>

und in Aktivität

searchView.setOnCloseListener(new OnCloseListener() {

        @Override
        public boolean onClose() {

            Log.i("SearchView:", "onClose");
            searchView.onActionViewCollapsed();
            return false;
        }
    });
6
Sushant

Damit OnCloseListener funktioniert, stellen Sie sicher, dass showAsAction im Suchmenüelement auf always gesetzt ist.

<menu xmlns:Android="http://schemas.Android.com/apk/res/Android"
      xmlns:app="http://schemas.Android.com/apk/res-auto"
      xmlns:tools="http://schemas.Android.com/tools"
      tools:context=".SearchActivity">

    <item
        Android:id="@+id/search"
        Android:title="@string/search"
        Android:icon="@drawable/ic_search_toolbar"
        app:showAsAction="always"
        app:actionViewClass="Android.support.v7.widget.SearchView"/>
</menu>
2
Julio Betta

Ich bin mit dem gleichen Problem konfrontiert, dass onCloseListener das SearchView nicht aufgerufen hat . Verstehen Sie aus dem in 25758 aufgetretenen Fehler und einigen von mir gelesenen Postings, um onCloseListener aufzurufen.

searchView.setIconifiedByDefault(true);

Aber für meinen Fall wollte ich, dass die Suchansicht geöffnet wurde und nicht die ganze Zeit ikonifiziert wurde. Ich kann dieses Problem beheben, indem ich unten eine weitere Zeile hinzufüge:

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    MenuInflater inflater = getMenuInflater();
    inflater.inflate(R.menu.search_bar, menu);
    SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
    searchView = (SearchView) menu.findItem(R.id.search).getActionView();
    searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));
    searchView.setOnQueryTextListener(queryTextListener);
    searchView.setIconifiedByDefault(true);
    searchView.setIconified(false);
    return true;
}

Durch searchView.setIconified (false) wird die searchView geöffnet, obwohl der Standardwert in der vorherigen Zeile auf true gesetzt ist. Auf diese Weise ist es mir gelungen, sowohl eine SearchView Zu haben, die sich ständig öffnet, als auch den onCloseListener aufzurufen.

2
gkl

Für MenuItemCompat-Problem habe ich ViewTreeObserver hinzugefügt, um den Sichtbarkeitsstatus zu verfolgen. Sie können meine Antwort hier überprüfen: https://stackoverflow.com/a/28762632/1633609

Erstellen Sie den Menüeintrag, wobei app:showAsAction auf immer festgelegt ist. 

<item   
 Android:id="@+id/action_search"  
 Android:title="..."  
 Android:icon="..."  
 app:actionViewClass="Android.support.v7.widget.SearchView"  
 app:showAsAction="always"/>

Wenn Sie die Variable SearchView in der Methode onCreateOptionsMenu erstellen, machen Sie etwas Ähnliches

inflater.inflate(R.menu.menu_search, menu);
final MenuItem item = menu.findItem(R.id.action_search);
final SearchView search = (SearchView) item.getActionView();
search.setQueryHint(getString(R.string.search_brand_item));
search.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
  @Override
  public boolean onQueryTextSubmit(String query) {
    // add your code
    return false;
  }

  @Override
  public boolean onQueryTextChange(String newText) {
    // add your code 
    return false;
  }
});
search.setOnCloseListener(new SearchView.OnCloseListener() {
  @Override
  public boolean onClose() {
    // add your code here
    return false;
  }
});
search.setIconifiedByDefault(true); // make sure to set this to true

search.setIconifiedByDefault(true) muss auf true gesetzt sein, um die onClose()-Methode für die oben erstellte SearchView.OnCloseListener() aufzurufen.

1
Ray Hunter

Es ist ein Workaround, hat aber für mich funktioniert

  searchView.setOnQueryTextListener(new Android.widget.SearchView.OnQueryTextListener() {

                String lastText;

                @Override
                public boolean onQueryTextChange(final String newText) {
                    if (lastText != null && lastText.length() > 1 && newText.isEmpty()) {
                        // close ctn clicked

                        return true;
                    }
}
0
Nativ

es scheint schon ein alter Thread zu sein, aber ich dachte, ich habe das gleiche Problem API 18 am Anfang. Nach dem googeln fand ich diesen Thread, eine weitere Stunde las der Javadoc für etwas ausprobiert, das ich in Javadoc nicht so ganz verstehe, die folgende Arbeit für mich jetzt:

searchView.setIconifiedByDefault(true);

   // OnQueryTextListener
   @Override
   public boolean onQueryTextSubmit(String query) {
      Log.d(tag, "onQueryTextSubmit: " + query);
      return true;
   }

   @Override
   public boolean onQueryTextChange(String query) {
      Log.d(tag, "onQueryTextChange: " + query);
      return true;
   }

   // OnCloseListener
   @Override
   public boolean onClose() {
      Log.w(tag, "onClose: ");
      return false;
   }

Ich habe ein bisschen mit true/false gespielt, das macht irgendwie den Unterschied und es funktioniert jetzt für mich. Hoffentlich kann es jemandem Zeit sparen.

0
Sean

Die OnCloseListener wird nicht aufgerufen, weil der Android-Code einen Fehler enthält. Der Listener wird nur aufgerufen, wenn Sie auch setIconifiedByDefault(true) aufrufen.

0
Joseph Earl
    searchView.setOnCloseListener {
        d("click", "close clicked")
        [email protected] false
    }

wenn Sie auf close searchView -> klicken

D/Klick: Klicken Sie auf Schließen

0

Ich bin auf dieses Problem gestoßen, als ich versucht habe, das Anzeigen/Schließen von SearchView zu erkennen. Am Ende habe ich einen anderen Listener verwendet und es hat funktioniert für das, was ich brauche:

        setOnQueryTextFocusChangeListener { _, hasFocus ->
            if (hasFocus) {
                // SearchView is being shown
            } else {
                // SearchView was dismissed
            }
        }
0
Psylocke