Android 在激活SearchView时,如何启动Backpressed()?
如何在搜索模式下处理Android 在激活SearchView时,如何启动Backpressed()?,android,searchview,Android,Searchview,如何在搜索模式下处理onBackPressed()?我已经在ActionBar上实现了搜索,我想处理onBackPressed() 编辑: 在MainActivity中,我添加了这个,但它只在搜索关闭时收到通知 @Override public void onBackPressed() { mMenu.findItem(R.id.menu_eye).setVisible(true); mMenu.findItem(R.id.menu_layers).setVisible(true
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();
}
}
class MySearchView extends SearchView {
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
return super.onKeyDown(keyCode, event); //don't forget call this
}
}
重写此方法可能会对您有所帮助
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
// TODO Auto-generated method stub
return super.onKeyDown(keyCode, event);
}
您始终可以扩展任何视图并覆盖侦听方法,如下所示:
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();
}
}
class MySearchView extends SearchView {
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
return super.onKeyDown(keyCode, event); //don't forget call this
}
}
我找到了答案,关键是阿里·伊姆兰先生和新世界的先前答案 我必须重写此方法:
@Override
public void onActionViewCollapsed() {
//do somethink
super.onActionViewCollapsed();
}
每次searchView关闭时都会调用它,因此它可以处理backbutton案例。另一种方法是在菜单项上侦听操作展开/折叠:
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
我认为这种方式更干净,因为你直接听你想要什么
由于支持较旧的设备,可以使用以下代码:
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;
}
});
您可以扩展SearchView并覆盖dispatchKeyEventPreIme: public class CustomSearchView extends SearchView{ public CustomSearchView(final Context context) { super(context); this.setIconifiedByDefault(true); } @Override public boolean dispatchKeyEventPreIme(KeyEvent event) { if (event.getKeyCode() == KeyEvent.KEYCODE_BACK && event.getAction() == KeyEvent.ACTION_UP) { this.onActionViewCollapsed(); } return super.dispatchKeyEventPreIme(event); } } 公共类CustomSearchView扩展了SearchView{ 公共CustomSearchView(最终上下文){ 超级(上下文); 此.setIconifiedByDefault(true); } @凌驾 公共布尔dispatchKeyEventPreIme(KeyEvent事件){ 如果(event.getKeyCode()==KeyEvent.KEYCODE\u返回&& event.getAction()==KeyEvent.ACTION\u UP){ 这个.onActionViewCollapsed(); } 返回super.dispatchKeyEventPreIme(事件); } }
答案与创建自定义搜索视图相同,但使用侦听器
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类,因此如果键盘可见,则按back 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);
}
}
使用此代码处理
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);
}
}
我已经更新了我的问题:如何在搜索模式下处理onBackPressed?我应该绑定这个侦听器什么?要继续活动吗?因为searchview没有setOnKeyDown()方法,所以只有setOnKeyListenerbut@Override public boolean onKey(视图v,int keyCode,KeyEvent event){//TODO自动生成的方法存根返回false;}不起作用。这不起作用,因为:在按下某个键时调用,并且没有被活动内部的任何视图处理。但是您可以扩展
SearchView
并覆盖它自己的onKeyDown
方法。我同意可以扩展SearchView来覆盖onKeyDown()。但是如何将searchItem.getActionView()返回的SearchView对象强制转换为扩展类?这并不能回答问题<当用户按下“主”箭头(<代码>搜索视图左侧)但未按下(硬件)后退按钮时,code>onActionViewCollapsed()也将触发。扩展时不需要定义默认构造函数吗?publicmysearchview(Context){super(Context);}是的,您需要定义一个默认构造函数,这是显而易见的。作为回答,我只写了解决问题的实际代码。谢谢!你救了我的命day@raheel不过有一个问题,我支持的最低API是14,那么为什么我还必须使用MenuItemCompat呢?我在其他一些论坛上读到,只有当最低API级别低于14时才需要这样做。。不过,谢谢你,它成功了!现在已经弃用了,有人可以更新答案吗?当我在一个对话框片段中以非常规方式使用SearchView时,有人帮我更新了答案,该对话框完全在默认操作栏之外,带有setIconifiedByDefault(false);。干杯这个解决方案也帮助了我。我在setOnBackPressListener中调用onBackPressed时遇到问题,因为在我的活动中重写的onBackPressed被调用了两次。如果有人有这个问题,只需在dispatchKeyEventPreIme中添加那些行If(onBackPressListener!=null&!isKeyboardVisible){onBackPressListener.backPress();return true;}
我也在this.onActionViewCollapsed()之后调用this.clearFocus()
否则,我会在actionBar的其他地方出现一些奇怪的突出显示