android - 使用 SearchView 时如何处理 ActionBar 的图标可见性

标签 android searchview android-actionbar-compat

好吧,我想要的是:

  • 使用除“searchSettings”之外的所有项初始化 ActionBar;
  • 单击“搜索”图标时,会出现 searchSettings,其余图标会消失;
  • 当关闭搜索 EditText(按设备的后退按钮或 ActionBar 的后退按钮)时,ActionBar 返回到其原始状态(出现的所有图标,“searchSettings”除外)。

我的实际代码如下:

(我导入了 android.support.v7.widget.SearchView 而不是 android.widget.SearchView。当我使用 android.widget 时。 SearchView 这工作正常,但其他事情没有)

private MenuItem searchIteam, searchSettings;
private SearchView searchView;

@Override
public boolean onCreateOptionsMenu(final Menu menu) {

    MenuInflater inflater = getMenuInflater();
    inflater.inflate(R.menu.menu_main, menuMain);
    searchItem = menu.findItem(R.id.search);
    searchSettings = menu.findItem(R.id.action_searchSettings);
    searchView = (SearchView)MenuItemCompat.getActionView(item);
    searchSettings.setVisible(false); // hide searchSettings Item when Menu is created

    searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
        @Override
        public boolean onQueryTextSubmit(String query) {
            return false;
        }

        @Override
        public boolean onQueryTextChange(String newText) {
            (...)

            return false;
        }
    });

    // Detect SearchView icon clicks
    searchView.setOnSearchClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            setItemsVisibility(menuMain, item, false);
            searchSettings.setVisible(true);
        }
    });
    // Detect SearchView close
    searchView.setOnCloseListener(new SearchView.OnCloseListener() {
        @Override
        public boolean onClose() {
            supportInvalidateOptionsMenu(); //shouldn't this reload the Action Bar as it was when onCreate?
            return true;
        }
    });

    return super.onCreateOptionsMenu(menu);

}

private void setItemsVisibility(Menu menu, MenuItem exception, boolean visible) {
    for (int i=0; i<menu.size(); ++i) {
        MenuItem item = menu.getItem(i);
        if (item != exception) item.setVisible(visible);
    }
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    int id = item.getItemId();

    if (id == android.R.id.home) {
        onBackPressed();
    }

    return super.onOptionsItemSelected(item);
}

@Override
public void onBackPressed() {
    supportInvalidadeOptionsMenu();
    super.onBackPressed();
}

此代码不起作用,当我第一次按“后退”时,它只会关闭搜索的 EditText 并且图标不会改变。如果我再次按回, Activity 会上升一个级别,但我可以看到图标开始(当我第一次按下“后退”时应该像他们应该的那样)在 Activity 关闭前一段时间......

--- 编辑 ---

目前,如果我点击“搜索操作栏”图标,然后开始反复按“后退按钮”,则会发生以下情况:

  • 第1次按下:键盘隐藏,但仍打开搜索EditText;
  • 第2次按下:搜索结束(搜索EditText关闭,显示正常activity的内容);
  • 第三次按下: Activity 结束。

然后,出于测试目的,我这样做了:

boolean pressed1, pressed2, pressed3;

searchView.setOnSearchClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            pressed1 = false;
            pressed2 = false;
            pressed3 = false;
            setItemsVisibility(menuMain, item, false);
            searchSettings.setVisible(true);
        }
    });

@Override
public void onBackPressed() {
    if (!pressed1) {
        pressed1 = true;
    }
    else if(!pressed2) {
        pressed2 = true;
    }
    else if(!pressed3) {
        pressed3 = true;
        supportInvalidateOptionsMenu();
    }
    else {
        super.onBackPressed();
    }
}

现在,发生的是:

  • 第1次按下:键盘隐藏,但仍打开搜索EditText;
  • 第2次按下:搜索结束(搜索EditText关闭,显示正常activity的内容);
  • 第三次按下:没有任何反应;
  • 第四次按下:没有任何反应;
  • 第 5 次按下:ActionBar 按我的意愿重新加载;
  • 第六次按下: Activity 结束;

--- 编辑 2 ---

然后我改成了这样:

@Override
public void onBackPressed() {
    if (!pressed1) {
        pressed1 = true;
        onBackPressed();
    }
    else if(!pressed2){
        pressed2 = true;
        onBackPressed();
    }
    else if(!pressed3){
        pressed3 = true;
        supportInvalidateOptionsMenu();
    }
    else {
        super.onBackPressed();
    }
}

现在发生的事情是:

  • 第1次按下:键盘隐藏,但仍打开搜索EditText;
  • 第2次按下:搜索结束(搜索EditText关闭,显示正常activity的内容);
  • 第三次按下:ActionBar 根据需要重新加载;
  • 第四次按下: Activity 结束;

--- 编辑 3 ---(解决方案)---

我猜 setOnSearchClickListenersetOnCloseListener 方法来自 android.widget.SearchView... 因为我导入了 相反,我将 android.support.v7.widget.SearchView 更改为:

MenuItemCompat.setOnActionExpandListener(searchItem,
            new MenuItemCompat.OnActionExpandListener() {
                @Override
                public boolean onMenuItemActionExpand(MenuItem menuItem) {
                    setItemsVisibility(menu, searchItem, false);
                    return true;
                }
                @Override
                public boolean onMenuItemActionCollapse(MenuItem menuItem) {
                    supportInvalidateOptionsMenu();
                    return true;
                }
            });

现在一切正常 (:

最佳答案

希望我没说错:第一次按 BACK 键时,键盘会隐藏起来。第二次按 BACK 时,应用程序退出。

如果是这种情况,那么一切正常。因为这是 super.onBackPressed() 应该做的。如果显示,它将尝试隐藏键盘。如果没有,它将尝试进行上一个 Activity 。如果没有,它将退出该应用程序。

所以您需要做的是使用 onBackPressed() 方法。基本上,如果您确定应该做什么,则不一定需要调用 super 方法。

@Override
public void onBackPressed() {
    if ( isSearching) {
        supportInvalidadeOptionsMenu();
        isSearching = false;     
    } else {
        super.onBackPressed();
    }
}

所以现在,当您从不按 BACK 按钮时,Activity 将检查是否正在搜索,并决定重新呈现操作栏或照常执行其正常操作。

您需要添加一些逻辑来设置 bool 标志 isSearching,例如,在单击“搜索”时将 isSearching 设置为 true。

我不确定 supportInvalidadeOptionsMenu() 是否会重置您的操作栏。无论如何,您可以改为调整每个 View 的可见性。

关于android - 使用 SearchView 时如何处理 ActionBar 的图标可见性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44578040/

相关文章:

java - 使用自定义分隔符自动完成搜索 View

android - ActionBarCompat - showAsAction ="always|withText"不工作

java - ListView 问题

android - 如何在android中实现不自定义的SD卡库?

java - sendMultipartTextMessage 作为多条 SMS 消息发送?

android - 无法在 fragment 中转换 SearchView (AppCompat)

android - AdMob 如何识别它是测试设备还是真实用户?

java - 搜索 View 折叠时搜索图标被非功能性溢出替换

android - 为 android 2.3 及更高版本实现 Action Bar 支持 v7 库时应用程序崩溃

android - DialogFragment 上的 ActionBar Action