30

如何onBackPressed()在搜索模式下处理?我已经在 中实现了搜索ActionBar,并且我想处理onBackPressed().

编辑:

MainActivity我添加了这个,但只有在搜索关闭时才会收到通知

@Override
public void onBackPressed() {
    mMenu.findItem(R.id.menu_eye).setVisible(true);
    mMenu.findItem(R.id.menu_layers).setVisible(true);
    super.onBackPressed();  
};

我的搜索操作监听器如下所示:

import com.cyrilmottier.polaris.PolarisMapView;

import android.app.SearchManager.OnCancelListener;
import android.content.Context;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.SearchView;

public class SearchListener implements SearchView.OnQueryTextListener, SearchView.OnCloseListener, SearchView.OnSuggestionListener, OnClickListener, OnCancelListener{

    private Context mContext;
    private PolarisMapView mMapView;
    private Menu mMenu;
    private SearchView mSearchView;

    public SearchListener(Context c, PolarisMapView mMapView, Menu mMenu, SearchView mSearchView){
        this.setmContext(c);
        this.setmMapView(mMapView);
        this.setmMenu(mMenu);
        this.mSearchView = mSearchView;
    }

    @Override
    public boolean onQueryTextChange(String newText) {
        return false;
    }

    @Override
    public boolean onQueryTextSubmit(String query) {
        if (Constants.searchPlaceNavigate(query, mContext, mMapView))
            return this.onClose();
        return false;
    }

    public Context getmContext() {
        return mContext;
    }

    public void setmContext(Context mContext) {
        this.mContext = mContext;
    }

    public PolarisMapView getmMapView() {
        return mMapView;
    }

    public void setmMapView(PolarisMapView mMapView) {
        this.mMapView = mMapView;
    }

    @Override
    public boolean onSuggestionClick(int position) {
        String p = mSearchView.getSuggestionsAdapter().getCursor().getString(position);
        if(position== 0)
            p = mSearchView.getSuggestionsAdapter().getCursor().getString(position*4+1);
        if(p != null)
            if(position== 0)
                Constants.searchPlaceNavigate(mSearchView.getSuggestionsAdapter().getCursor().getString(position*4+1), mContext, mMapView);
            else
                Constants.searchPlaceNavigate(mSearchView.getSuggestionsAdapter().getCursor().getString(position), mContext, mMapView);
        return this.onClose();
    }

    @Override
    public boolean onSuggestionSelect(int position) {

        return false;
    }

    @Override
    public boolean onClose() {
        mMenu.findItem(R.id.menu_eye).setVisible(true);
        mMenu.findItem(R.id.menu_layers).setVisible(true);
        mMenu.findItem(R.id.menu_search).collapseActionView();
        return true;
    }

    public Menu getmMenu() {
        return mMenu;
    }

    public void setmMenu(Menu mMenu) {
        this.mMenu = mMenu;
    }

    public SearchView getmSearchView() {
        return mSearchView;
    }

    public void setmSearchView(SearchView mSearchView) {
        this.mSearchView = mSearchView;
    }

    @Override
    public void onClick(View v) {
        this.onClose();
    }

    @Override
    public void onCancel() {
        this.onClose();

    }

}
4

9 回答 9

41

另一种方法是在 MenuItem 上监听 ActionExpand/Collapse :

    MenuItem searchMenuItem = menu.findItem(R.id.menu_search);
    searchMenuItem.setOnActionExpandListener(new MenuItem.OnActionExpandListener() {

        @Override
        public boolean onMenuItemActionExpand(MenuItem item) {
            // Do whatever you need
            return true; // KEEP IT TO TRUE OR IT DOESN'T OPEN !!
        }

        @Override
        public boolean onMenuItemActionCollapse(MenuItem item) {
            // Do whatever you need
            return true; // OR FALSE IF YOU DIDN'T WANT IT TO CLOSE!
        }
    });
    SearchView searchView = (SearchView) searchMenuItem.getActionView();
    ... // Keep doing as you do

我认为这种方式更干净,因为您可以直接听自己想要的内容

感谢这个线程

于 2014-03-29T11:43:34.110 回答
20

为了支持旧设备,可以使用以下代码:

        MenuItemCompat.setOnActionExpandListener(searchItem,new MenuItemCompat.OnActionExpandListener() {

            @Override
            public boolean onMenuItemActionExpand(MenuItem item) {
                //Do whatever you want                   
                return true;
            }

            @Override
            public boolean onMenuItemActionCollapse(MenuItem item) {
                //Do whatever you want
                return true;
            }
        });
于 2014-06-09T07:04:25.533 回答
6

您可以扩展 SearchView 并覆盖 dispatchKeyEventPreIme:

    公共类 CustomSearchView 扩展 SearchView{
        公共CustomSearchView(最终上下文上下文){
            超级(上下文);
            this.setIconifiedByDefault(true);
        }

        @覆盖
        公共布尔dispatchKeyEventPreIme(KeyEvent事件){
            if (event.getKeyCode() == KeyEvent.KEYCODE_BACK &&
                event.getAction() == KeyEvent.ACTION_UP) {
                this.onActionViewCollapsed();
            }
            return super.dispatchKeyEventPreIme(event);
        }
    }

于 2015-08-19T04:30:05.513 回答
4

与制作自定义搜索视图但带有侦听器的答案相同

public class SearchViewer extends SearchView {
    private OnBackPressListener onBackPressListener;
    private boolean isKeyboardVisible;

        public SearchViewer(Context context) {
            super(context);
        }

        public SearchViewer(Context context, AttributeSet attrs) {
            super(context, attrs);
        }

        public SearchViewer(Context context, AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
        }

        private void init() {
            KeyboardUtils.addKeyboardToggleListener((Activity) getContext(), new KeyboardUtils.SoftKeyboardToggleListener() {
                @Override
                public void onToggleSoftKeyboard(boolean isVisible) {
                    SearchViewer.this.isKeyboardVisible = isVisible;
                }
            });

        }

        @Override
        protected void onAttachedToWindow() {
            super.onAttachedToWindow();
            init();
        }

        @Override
        protected void onDetachedFromWindow() {
            super.onDetachedFromWindow();
            KeyboardUtils.removeAllKeyboardToggleListeners();
        }

        @Override
        public boolean dispatchKeyEventPreIme(KeyEvent event) {
            if (event.getKeyCode() == KeyEvent.KEYCODE_BACK) {
                if (onBackPressListener != null && !isKeyboardVisible)
                    onBackPressListener.backPress();
            }
            return super.dispatchKeyEventPreIme(event);
        }

        public OnBackPressListener getOnBackPressListener() {
            return onBackPressListener;
        }

        public void setOnBackPressListener(OnBackPressListener onBackPressListener) {
            this.onBackPressListener = onBackPressListener;
        }

        public interface OnBackPressListener {
            void backPress();
        }
    }

用于键盘可见性的 Util 类,因此如果键盘可见返回 Press 将隐藏它而不关闭活动

public class KeyboardUtils implements ViewTreeObserver.OnGlobalLayoutListener {
    private static HashMap<SoftKeyboardToggleListener, KeyboardUtils> sListenerMap = new HashMap<>();
    private SoftKeyboardToggleListener mCallback;
    private View mRootView;
    private float mScreenDensity = 1;
    private KeyboardUtils(Activity act, SoftKeyboardToggleListener listener) {
        mCallback = listener;

        mRootView = ((ViewGroup) act.findViewById(android.R.id.content)).getChildAt(0);
        mRootView.getViewTreeObserver().addOnGlobalLayoutListener(this);

        mScreenDensity = act.getResources().getDisplayMetrics().density;
    }

    public static void addKeyboardToggleListener(Activity act, SoftKeyboardToggleListener listener) {
        removeKeyboardToggleListener(listener);

        sListenerMap.put(listener, new KeyboardUtils(act, listener));
    }

    public static void removeKeyboardToggleListener(SoftKeyboardToggleListener listener) {
        if (sListenerMap.containsKey(listener)) {
            KeyboardUtils k = sListenerMap.get(listener);
            k.removeListener();

            sListenerMap.remove(listener);
        }
    }

    public static void removeAllKeyboardToggleListeners() {
        for (SoftKeyboardToggleListener l : sListenerMap.keySet())
            sListenerMap.get(l).removeListener();

        sListenerMap.clear();
    }

    @Override
    public void onGlobalLayout() {
        Rect r = new Rect();
        //r will be populated with the coordinates of your view that area still visible.
        mRootView.getWindowVisibleDisplayFrame(r);

        int heightDiff = mRootView.getRootView().getHeight() - (r.bottom - r.top);
        float dp = heightDiff / mScreenDensity;

        if (mCallback != null)
            mCallback.onToggleSoftKeyboard(dp > 200);
    }

    private void removeListener() {
        mCallback = null;

        mRootView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
    }

    public interface SoftKeyboardToggleListener {
        void onToggleSoftKeyboard(boolean isVisible);
    }

}

示例代码:

searchView.setOnBackPressListener(new SearchViewer.OnBackPressListener() {
    @Override
    public void backPress() {
        onBackPressed();
    }
});
于 2017-02-02T09:59:04.860 回答
3

我找到了答案,它的关键是之前来自 Mr.Ali Imran 和来自 neworld 的答案,我必须重写这个方法:

@Override
public void onActionViewCollapsed() {
    //do somethink
    super.onActionViewCollapsed();
}

每次关闭 searchView 时都会调用它,因此它可以处理后退按钮的情况。

于 2012-11-30T06:23:32.627 回答
2

您始终可以像这样扩展任何视图并覆盖侦听方法:

class MySearchView extends SearchView {
  @Override
  public boolean onKeyDown(int keyCode, KeyEvent event) {
     return super.onKeyDown(keyCode, event); //don't forget call this
  }
}
于 2012-11-29T14:02:55.090 回答
1

覆盖此方法可能会对您有所帮助

 @Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
    // TODO Auto-generated method stub
    return super.onKeyDown(keyCode, event);
}
于 2012-11-29T13:26:19.060 回答
0

尝试这个

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {

        getMenuInflater().inflate(R.menu.menu_main, menu);

        MenuItem searchItem = menu.findItem(R.id.action_search);

        searchItem.setOnActionExpandListener(new MenuItem.OnActionExpandListener() {
        @Override
        public boolean onMenuItemActionExpand(MenuItem item) {
             //do something here

              return true;
        }

        @Override
        public boolean onMenuItemActionCollapse(MenuItem item) {
            //do something here
            
            //YourActivity is acitvity where you define searchview and fragment
            YourActivity.super.onBackPressed();  //remove fragment from backstack

            return true;
        }
    });

    //Any other code

}

onMenuItemActionCollapse(MenuItem item)当单击向上按钮SearchView或按返回按钮时将运行。它将从后台堆栈中删除片段。

于 2021-08-06T13:33:42.267 回答
-2

使用此代码处理onBackPressed()转到以前的活动

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Handle action bar item clicks here. The action bar will
    // automatically handle clicks on the Home/Up button, so long
    // as you specify a parent activity in AndroidManifest.xml.

    int id = item.getItemId();
    switch (id){
        case android.R.id.home:
            onBackPressed();
            return true;
        default:
            return super.onOptionsItemSelected(item);
    }

}
于 2019-12-19T08:09:01.087 回答