如何将Google搜索界面与Navigation Component导航组件模式集成
核心逻辑:系统搜索服务默认仅支持向Activity分发搜索结果,我们只需要在单Activity架构中增加一层透明的结果转发即可,完全不破坏原有的Navigation导航流程。
方案1:App内搜索优先用SearchView直接监听(最简便)
如果是应用内的搜索场景,不需要配置系统Searchable能力,直接在Fragment中对SearchView设置监听即可直接获取搜索关键词,完全绕开Activity的中间回调:
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) { inflater.inflate(R.menu.search_menu, menu) val searchItem = menu.findItem(R.id.action_search) val searchView = searchItem.actionView as SearchView // 关联系统搜索服务(可选,需要系统搜索联想能力才加) val searchManager = requireContext().getSystemService(Context.SEARCH_SERVICE) as SearchManager searchView.setSearchableInfo(searchManager.getSearchableInfo(requireActivity().componentName)) searchView.setOnQueryTextListener(object : SearchView.OnQueryTextListener { override fun onQueryTextSubmit(query: String?): Boolean { query?.let { handleSearchLogic(it) } // 收起软键盘 searchView.clearFocus() return true } override fun onQueryTextChange(newText: String?): Boolean { // 按需实现实时搜索联想逻辑 return true } }) super.onCreateOptionsMenu(menu, inflater) }
方案2:适配系统Searchable回调的转发流程
如果需要支持全局搜索唤起等依赖系统Searchable能力的场景,按以下步骤配置:
1. 修改Manifest配置
不要创建独立的Searchable Activity,直接在你的单主Activity中添加搜索配置,同时设置launchMode为singleTop避免Activity重建:
<activity android:name=".MainActivity" android:launchMode="singleTop"> <intent-filter> <action android:name="android.intent.action.SEARCH" /> </intent-filter> <meta-data android:name="android.app.searchable" android:resource="@xml/searchable" /> </activity>
2. 主Activity中转发搜索结果到Fragment
在主Activity中重写onNewIntent接收搜索回调,直接通过NavController完成导航和参数传递,全程符合Navigation Component的规范:
override fun onNewIntent(intent: Intent?) { super.onNewIntent(intent) if (Intent.ACTION_SEARCH == intent?.action) { val searchQuery = intent.getStringExtra(SearchManager.QUERY) ?: return // 直接通过导航组件跳转到搜索结果Fragment,携带搜索参数 val navDirection = HomeFragmentDirections.actionHomeToSearchResult(searchQuery) findNavController(R.id.nav_host_fragment_container).navigate(navDirection) } }
注意事项
- 不需要修改任何Navigation Component的原有配置,所有页面跳转仍然通过NavController控制,不会破坏现有导航栈逻辑
- 如果搜索触发时当前页面就是搜索结果Fragment,也可以直接获取当前栈顶的Fragment实例调用自定义方法传递参数,不需要重新导航
内容的提问来源于stack exchange,提问作者Ziyaad Shiraz
相关产品推荐
相关产品推荐

