SearchView in ActionBar — problems with the *Up* button

前端 未结 3 756
南笙
南笙 2020-12-16 04:07

I am using the the SearchView in the ActionBar of the ListView. The magnifying glass can be touched, the SearchView shows

相关标签:
3条回答
  • 2020-12-16 05:01

    I struggle with this a little until I found the solution.

    Declare your menuItem like this, check the showAsAction attribute, type only ifRoom, if you set collapseActionView the widget will collapse and show the back button on the actionbar

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

    Set up your SearchView as usual, remember to Add setIconifiedByDefault this will make the icon to start up as an icon

    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()));
    

    On your QueryListener is where you handle the end of your search like so, here is where you use onActionViewCollapse() which collapse back the 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;
        }
    
    0 讨论(0)
  • 2020-12-16 05:04

    I have written a StatefulSearchView which retains the 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 demonstration activity:

    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;
        }
    

    In 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>
    

    In the source of the SearchView, it clearly says that they change the text to "":

    @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);
        }
    

    Let me know if you have issues.

    0 讨论(0)
  • 2020-12-16 05:09

    I'm not sure I understand your problem but you can just detect when up is clicked like this:

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

    If you intercept the up click, you can presumably do anything you want here. Returning true will consume the event and that should prevent any default action from taking place. This way you can do whatever you want the up button to do while at the same time consuming the up event to prevent clearing of your filters.

    0 讨论(0)
提交回复
热议问题