SearchView in ActionBar – problemi con il button * Up *

Sto utilizzando il SearchView ActionBar del ListView . La lente di ingrandimento può essere toccata, il SearchView mostra la relativa casella di modifica e l'utente può inserire il text per filtrare il contenuto dell'elenco. Funziona quasi. Tuttavia, quando l'utente preme il button Su , il SearchView crollerà all'icona, il text all'interno del widget viene eliminato e il filter viene ripristinato. L'effetto (nel mio caso) è che l'elenco può essere filtrato solo quando il SearchView non è iconificato. Il comportmento voluto è mantenere il text del filter anche dopo che la SearchView stata crollata.

Attenzione: il comportmento è probabilmente cambiato in Android 4.3. Con 4.2.2 ha funzionato come voluto. Vedere le osservazioni di seguito.

  • Attività traslucida per riempire l'integer schermo
  • Distriggers il button di ricerca in Android
  • Come catturare "Spiacente, questo video non può essere riprodotto" errore su VideoView
  • Distriggers lo scorrimento in webview?
  • Integrazione YouTube di YouTube, rimozione del logo di YouTube
  • Come get la window di dialogo di crash con il button report
  • Dettagli: Per essere più specifici, il menu contiene il seguente elemento:

     <item android:id="@+id/menu_search_customers" android:title="@string/menu_search_text" android:icon="@android:drawable/ic_menu_search" android:showAsAction="ifRoom|collapseActionView" android:actionViewClass="android.widget.SearchView" /> 

    Notare l'icona e l' android:showAsAction . Credo che il button Up si visualizzi per impostazione predefinita quando il SearchView è espanso (in alto significa < più l'icona – vedere l'image giusta con il libro blu dalla navigazione ufficiale con Back e Up ). Sembra che l'implementazione del gestore predefinito solo crolli il SearchView espanso (ritorna allo stato dell'icona).

    L'esempio del pulsante * Up * all'immagine giusta

    Quando il debug, ho scoperto che l' onQueryTextChange() viene sparato con il text vuoto quando viene utilizzato l' Up . (Credo che questo non era il caso con Android 4.2.2 perché funzionava come voluto prima dell'aggiornamento del sistema operativo.) Questo è il motivo per cui anche il filtraggio delle voci di elenco viene resettato – vedere la mia onQueryTextChange() sotto. Voglio che il SearchView crollato e il text del filter visualizzato come sottotitolo nella barra delle azioni.

    Finora, il mio codice relativo al SearchView sembra così:

     @Override public boolean onCreateOptionsMenu(Menu menu) { // MenuInflater adds the magnifying glass icon for the SearchView // to the ActionBar as the always visible menu item. MenuInflater inflater = getMenuInflater(); inflater.inflate(R.menu.customers_menu, menu); // Get the related SearchView widget. SearchView sv = (SearchView) menu.findItem(R.id.menu_search_customers) .getActionView(); // Get the changes immediately. sv.setOnQueryTextListener(new SearchView.OnQueryTextListener() { // I am not sure whether the onQueryTextSubmit() is importnt // for the purpose. @Override public boolean onQueryTextSubmit(String query) { getActionBar().setSubtitle(mCurFilter); return true; } @Override public boolean onQueryTextChange(String newText) { // The newText is stored into a member variable that // is used when the new CursorLoader is created. mCurFilter = newText; getActionBar().setSubtitle(mCurFilter); getLoaderManager().restartLoader(0, null, CustomersOverviewActivity.this); return true; } }); return true; } 

    Il loader riavviato chiama l' onCreateLoader . Si noti che mCurFilter è utilizzato per creare la query SQL:

     @Override public Loader<Cursor> onCreateLoader(int id, Bundle args) { String[] projection = { CustomerTable._ID, CustomerTable.CODE, CustomerTable.NAME, CustomerTable.STREET, CustomerTable.TOWN }; String selection = null; // init String[] selectionArgs = null; // init if ( ! mCurFilter.isEmpty()) { selection = CustomerTable.NAME + " like ?"; selectionArgs = new String[]{ "%" + mCurFilter +"%" }; } CursorLoader cursorLoader = new CursorLoader(this, DemoContentProvider.CUSTOMERS_CONTENT_URI, projection, selection, selectionArgs, orderInfo); return cursorLoader; } 

    Vorrei rilevare la situazione quando viene premuto il tasto Up prima che venga chiamata l' onQueryTextChange() . In questo modo (ad esempio) potrei impostare una bandiera e bloccare l'assegnazione mCurFilter dal contenuto di SearchView svuotato. Inoltre, quando l'icona di ricerca viene espansa nuovamente, vorrei inizializzare il text nel SearchView espanso dal mCurFilter prima che venga mostrato (vale a dire la vista espansa è preimpostata con il text del filter). Come si può fare?

    Aggiornamento: l'implementazione precedente del SearchView aveva …

     @Override public void onActionViewCollapsed() { clearFocus(); updateViewsVisibility(true); mQueryTextView.setImeOptions(mCollapsedImeOptions); mExpandedInActionView = false; } 

    Ora, contiene …

     @Override public void onActionViewCollapsed() { setQuery("", false); clearFocus(); updateViewsVisibility(true); mQueryTextView.setImeOptions(mCollapsedImeOptions); mExpandedInActionView = false; } 

    Sai cosa potrebbe essere la ragione per impostare la query sulla string vuota? Devo superare la nuova implementazione dal vecchio codice? O c'è un modo migliore?

  • Come colbind il progetto esistente Android Studio al repository Github esistente
  • Nessun stile ViewPagerIndicator in combinazione con SherlockActionBar
  • Android, telecamera anteriore e posteriore Orientamento, Paesaggio
  • il titolo android non verrà mostrato nella barra degli strumenti
  • Sovrascrivere il button di alimentazione in Android
  • La listview espandibile non è in espansione
  • 3 Solutions collect form web for “SearchView in ActionBar – problemi con il button * Up *”

    Ho scritto un StatefulSearchView che conserva il text:

     import android.content.Context; import android.os.Parcel; import android.os.Parcelable; import android.text.TextUtils; import android.util.AttributeSet; import android.util.Log; import android.view.View; import android.widget.EditText; import android.widget.SearchView; import android.widget.SearchView.OnQueryTextListener; import android.widget.TextView; public class StatefulSearchView extends SearchView implements android.view.View.OnLayoutChangeListener, OnQueryTextListener,android.widget.SearchView.OnCloseListener{ private boolean mSaveText=true; private OnQueryTextListener mQueryListener; private String mQuery; private OnCloseListener mCloseListener; private boolean fromIconify = true; public StatefulSearchView(Context context, AttributeSet attrs) { super(context, attrs); addOnLayoutChangeListener(this); super.setOnCloseListener(this); } public StatefulSearchView(Context context) { super(context); // TODO Auto-generated constructor stub addOnLayoutChangeListener(this); super.setOnCloseListener(this); } public void setSaveSearchTextState(boolean save){ this.mSaveText = save; this.setSaveEnabled(mSaveText); } public void setOnStatefulQueryTextListener(OnQueryTextListener listener) { mQueryListener = listener; super.setOnQueryTextListener(this); } @Override public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) { if(super.isIconfiedByDefault() || !super.isIconified() && !TextUtils.isEmpty(mQuery) && mSaveText){ setSavedText(mQuery); } Log.i("onLayoutChanged()",""+mQuery); } @Override public void setIconified(boolean iconify) { mQuery = getQuery().toString(); Log.i("setIconified()",""+mQuery); super.setOnCloseListener(null); super.setIconified(iconify); super.setIconified(iconify); super.setOnCloseListener(this); fromIconify = true; } @Override public void setOnCloseListener(OnCloseListener listener) { mCloseListener = listener; super.setOnCloseListener(this); } @Override protected Parcelable onSaveInstanceState() { Parcelable state = super.onSaveInstanceState(); return new SearchQueryState(state, mQuery, mSaveText); } @Override protected void onRestoreInstanceState(Parcelable state) { SearchQueryState sqs = (SearchQueryState)state; super.onRestoreInstanceState(sqs.getSuperState()); mQuery = sqs.getSavedQuery(); mSaveText = sqs.getSaveText(); } @Override public boolean onQueryTextChange(String arg0) { mQuery = arg0; return mQueryListener.onQueryTextChange(mQuery); } @Override public boolean onQueryTextSubmit(String arg0) { // TODO Auto-generated method stub return mQueryListener.onQueryTextSubmit(arg0); } private TextView getTextView(){ int searchTextViewId = getContext().getResources().getIdentifier("android:id/search_src_text", null, null); return (TextView) this.findViewById(searchTextViewId); } private void setSavedText(String s){ super.setOnQueryTextListener(null); Log.i("setSavedText()",""+s); TextView t = getTextView(); t.setText(s); if(!TextUtils.isEmpty(s)) ((EditText)t).setSelection(s.length()); super.setOnQueryTextListener(mQueryListener); } private class SearchQueryState extends BaseSavedState{ private boolean mSaveText; private String mQueryText; public SearchQueryState(Parcel arg0) { super(arg0); this.mQueryText = arg0.readString(); this.mSaveText = arg0.readInt() == 1; } public SearchQueryState(Parcelable superState, String queryText, boolean saveText) { super(superState); this.mQueryText = queryText; this.mSaveText = saveText; } public boolean getSaveText(){ return this.mSaveText; } public String getSavedQuery(){ return mQueryText; } @Override public void writeToParcel(Parcel dest, int flags) { // TODO Auto-generated method stub super.writeToParcel(dest, flags); dest.writeString(mQueryText); dest.writeInt(mSaveText? 1: 0); } } @Override public boolean onClose() { Log.i("onClose()", "Is from setIconified(): "+fromIconify); if(!fromIconify){ mQuery = null; fromIconify = false; } return mCloseListener == null ? false : mCloseListener.onClose(); } } 

    In attività dimostrative:

     public class MainActivity extends Activity{ private StatefulSearchView mSearchView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); getActionBar().setHomeButtonEnabled(true); } @Override public boolean onMenuItemSelected(int featureId, MenuItem item) { if(item.getItemId()==android.R.id.home) { mSearchView.setIconified(true); return true; } return super.onMenuItemSelected(featureId, item); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main, menu); MenuItem item = menu.findItem(R.id.action_search); mSearchView =(StatefulSearchView)item.getActionView(); mSearchView.setSaveSearchTextState(true); mSearchView.setOnStatefulQueryTextListener(new OnQueryTextListener(){ @Override public boolean onQueryTextChange(String newText) { // TODO Auto-generated method stub return false; } @Override public boolean onQueryTextSubmit(String query) { // TODO Auto-generated method stub return false; }}); return true; } 

    Nel menu xml:

     <menu xmlns:android="http://schemas.android.com/apk/res/android" > <item android:id="@+id/action_search" android:orderInCategory="100" android:showAsAction="always" android:actionViewClass="com.nikola.despotoski.saveablesearchview.StatefulSearchView" android:title="@string/action_settings"/> </menu> 

    SearchView del SearchView , dice chiaramente che cambiano il text in "" :

     @Override public void onActionViewCollapsed() { setQuery("", false); clearFocus(); updateViewsVisibility(true); mQueryTextView.setImeOptions(mCollapsedImeOptions); mExpandedInActionView = false; } /** * {@inheritDoc} */ @Override public void onActionViewExpanded() { if (mExpandedInActionView) return; mExpandedInActionView = true; mCollapsedImeOptions = mQueryTextView.getImeOptions(); mQueryTextView.setImeOptions(mCollapsedImeOptions | EditorInfo.IME_FLAG_NO_FULLSCREEN); mQueryTextView.setText(""); setIconified(false); } 

    Fammi sapere se hai problemi.

    Non sono sicuro di capire il tuo problema, ma puoi solo rilevare quando viene cliccato in questo modo:

     @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case android.R.id.home: doSOmething(); return true; } return super.onOptionsItemSelected(item); } 

    Se intercetti il ​​click in su, puoi presumibilmente fare tutto quello che vuoi qui. La restituzione della vera e propria verrà consumata dall'evento e dovrebbe impedire qualsiasi azione predefinita. In questo modo puoi fare tutto ciò che si desidera fare il button su e contemporaneamente consumare l'evento in su per evitare la cancellazione dei filtri.

    Lavoro con questo un po 'finché non ho trovato la soluzione.

    Dichiarare il vostro menuItem come questo, controllare l'attributo showAsAction, digitare solo ifRoom, se si imposta collassoActionView il widget verrà crollato e mostrare il button di return sulla barra di azione

     <menu xmlns:android="http://schemas.android.com/apk/res/android" > <item android:id="@+id/search" android:actionViewClass="android.widget.SearchView" android:icon="@drawable/ic_2_action_search" android:showAsAction="ifRoom" android:title="@null"/> </menu> 

    Impostare il SearchView come al solito, ricordatevi di aggiungere setIconifiedByDefault questo farà l'icona per avviarsi come icona

     SearchManager searchManager = (SearchManager)getSystemService(Context.SEARCH_SERVICE); searchView = (SearchView) menu.findItem(R.id.search).getActionView(); searchView.setIconifiedByDefault(true); searchView.setOnQueryTextListener(new SearchViewOnQueryListener()); searchView.setOnCloseListener(new SearchViewOnCloseListener()); searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName())); 

    Sul tuo QueryListener è where gestisci la fine della tua ricerca così, qui è where si utilizza onActionViewCollapse () che crollano indietro il ViewSearch

     @Override public boolean onQueryTextSubmit(String query) { makeSearchRequest(SEARCH_TYPE_KEYWORD, query); searchView.setQuery("", false); searchView.clearFocus(); searchView.onActionViewCollapsed(); buttonClearSearchResults.setVisibility(View.VISIBLE); return false; } 
    L'Android è un fan Android di Google, tutto su telefoni Android, Android Wear, Android Dev e applicazioni Android Games e così via.