Toolbar中SearchView展开显示内置时间按钮,折叠隐藏及监听失效问题
解决SearchView展开折叠监听不触发的问题
看起来你遇到的核心问题是手动创建并替换SearchView实例,导致MenuItem的OnActionExpandListener失去了和SearchView的关联,所以回调方法根本不会被调用。下面是具体的修复方案和原因分析:
问题根源
你在代码中手动new SearchView(),然后通过MenuItemCompat.setActionView(item, searchView)替换了Menu中原本由app:actionViewClass指定生成的SearchView。这种操作会打破MenuItem和SearchView之间的默认关联机制——系统原本会监听默认SearchView的展开/折叠状态,并触发MenuItem的OnActionExpandListener,但替换成自定义实例后,这个关联就断了,所以你的回调永远不会执行。
修复方案
我们需要复用系统根据menu.xml生成的SearchView实例,而不是手动创建新的。同时调整监听逻辑,确保按钮的显示/隐藏和SearchView状态同步:
修改后的onCreateOptionsMenu代码
@Override public void onCreateOptionsMenu(final Menu menu, final MenuInflater inflater) { super.onCreateOptionsMenu(menu, inflater); menu.clear(); inflater.inflate(R.menu.nearby_friends_menu, menu); MenuItem searchItem = menu.findItem(R.id.search_PTL); // 从MenuItem获取系统生成的SearchView实例,而非手动创建 searchView = (SearchView) MenuItemCompat.getActionView(searchItem); if (searchView != null) { searchView.setIconified(true); searchView.setQueryHint("Search User & Business"); // 创建并添加时间按钮到SearchView Button timeButton = new Button(getActivity()); LinearLayout.LayoutParams navButtonsParams = new LinearLayout.LayoutParams( toolbar.getHeight() * 2 / 3, toolbar.getHeight() * 2 / 3 ); timeButton.setBackgroundDrawable(getResources().getDrawable(R.drawable.ic_access_time_black_24dp)); LinearLayout searchLayout = (LinearLayout) searchView.getChildAt(0); searchLayout.addView(timeButton, navButtonsParams); searchLayout.setGravity(Gravity.CENTER_VERTICAL); // 初始状态隐藏按钮(因为SearchView默认是折叠的) timeButton.setVisibility(View.GONE); // 设置MenuItem的展开折叠监听(现在能正常触发了) MenuItemCompat.setOnActionExpandListener(searchItem, new MenuItemCompat.OnActionExpandListener() { @Override public boolean onMenuItemActionExpand(MenuItem menuItem) { Log.d(TAG, "On Menu Expand"); timeButton.setVisibility(View.VISIBLE); return true; } @Override public boolean onMenuItemActionCollapse(MenuItem menuItem) { Log.d(TAG, "On Menu Collapse"); timeButton.setVisibility(View.GONE); return true; } }); } }
备选方案:直接监听SearchView的状态
如果你不想依赖MenuItem的监听,也可以直接监听SearchView自身的展开/折叠事件,逻辑更直观:
// 替换上面的MenuItemCompat.setOnActionExpandListener代码 searchView.setOnSearchClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // 点击搜索图标展开时显示按钮 timeButton.setVisibility(View.VISIBLE); } }); searchView.setOnCloseListener(new SearchView.OnCloseListener() { @Override public boolean onClose() { // 关闭搜索时隐藏按钮 timeButton.setVisibility(View.GONE); return false; // 返回false让系统处理关闭逻辑 } });
额外注意事项
- 确保你的
toolbar对象已经正确初始化,否则toolbar.getHeight()可能会导致空指针。 - 如果使用AndroidX库,
MenuItemCompat可以替换为MenuItem的原生方法(API 16+支持),但为了兼容低版本,保留MenuItemCompat更稳妥。 - 初始状态下要把按钮设为
GONE,因为SearchView默认是折叠状态的。
内容的提问来源于stack exchange,提问作者androidXP
相关产品推荐
相关产品推荐

