如何实现SearchView跳转Fragment后用RecyclerView展示搜索建议并取消已输入字符高亮
实现基于RecyclerView的搜索建议(无高亮)及Fragment跳转
1. 处理原Fragment中SearchView的跳转逻辑
在包含Toolbar和SearchView的原Fragment里,给SearchView设置点击监听,触发跳转到搜索Fragment:
// 原Fragment的onViewCreated方法中 val searchView = toolbar.findViewById<SearchView>(R.id.search_view) searchView.setOnSearchClickListener { // 通过FragmentTransaction跳转(也可使用Navigation组件) parentFragmentManager.beginTransaction() .replace(R.id.container, SearchFragment()) .addToBackStack(null) .commit() }
如果使用Navigation组件,可简化为:
findNavController().navigate(R.id.action_homeFragment_to_searchFragment)
2. 搜索Fragment的布局实现
创建搜索Fragment的布局,包含顶部SearchView和下方RecyclerView:
<!-- fragment_search.xml --> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <SearchView android:id="@+id/search_view" android:layout_width="match_parent" android:layout_height="wrap_content" android:iconifiedByDefault="false" android:queryHint="输入搜索内容"/> <androidx.recyclerview.widget.RecyclerView android:id="@+id/suggestions_recycler" android:layout_width="match_parent" android:layout_height="match_parent"/> </LinearLayout>
3. 实现搜索建议的RecyclerView适配器
创建适配器直接绑定原始文本(不做高亮处理):
class SuggestionsAdapter(private val suggestions: MutableList<String>) : RecyclerView.Adapter<SuggestionsAdapter.SuggestionViewHolder>() { inner class SuggestionViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { val suggestionText: TextView = itemView.findViewById(R.id.suggestion_text) } override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): SuggestionViewHolder { val view = LayoutInflater.from(parent.context) .inflate(R.layout.item_suggestion, parent, false) return SuggestionViewHolder(view) } override fun onBindViewHolder(holder: SuggestionViewHolder, position: Int) { // 直接设置原始文本,取消高亮效果 holder.suggestionText.text = suggestions[position] // 点击建议项填充到SearchView holder.itemView.setOnClickListener { (holder.itemView.context as? AppCompatActivity)?.let { activity -> val searchView = activity.findViewById<SearchView>(R.id.search_view) searchView.setQuery(suggestions[position], false) } } } override fun getItemCount() = suggestions.size // 更新建议列表 fun updateSuggestions(newSuggestions: List<String>) { suggestions.clear() suggestions.addAll(newSuggestions) notifyDataSetChanged() } }
对应的item布局(item_suggestion.xml):
<TextView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/suggestion_text" android:layout_width="match_parent" android:layout_height="wrap_content" android:padding="16dp" android:textSize="16sp"/>
4. 在搜索Fragment中处理文本变化和建议更新
监听SearchView文本变化,实时过滤并更新RecyclerView:
class SearchFragment : Fragment() { private lateinit var suggestionsAdapter: SuggestionsAdapter // 模拟建议数据源,可替换为本地历史或接口返回数据 private val allSuggestions = listOf( "Android开发", "Kotlin教程", "Jetpack组件", "RecyclerView优化", "SearchView使用" ) override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) val searchView = view.findViewById<SearchView>(R.id.search_view) val recyclerView = view.findViewById<RecyclerView>(R.id.suggestions_recycler) // 初始化RecyclerView recyclerView.layoutManager = LinearLayoutManager(requireContext()) suggestionsAdapter = SuggestionsAdapter(mutableListOf()) recyclerView.adapter = suggestionsAdapter // 监听文本变化过滤建议 searchView.setOnQueryTextListener(object : SearchView.OnQueryTextListener { override fun onQueryTextSubmit(query: String?): Boolean { // 处理搜索提交逻辑 return true } override fun onQueryTextChange(newText: String?): Boolean { val filteredSuggestions = newText?.let { input -> allSuggestions.filter { it.contains(input, ignoreCase = true) } } ?: emptyList() suggestionsAdapter.updateSuggestions(filteredSuggestions) return true } }) // 默认展开SearchView并获取焦点 searchView.isIconified = false searchView.requestFocus() } }
关键注意点
- 若建议数据来自网络,需添加防抖处理(比如用Handler延迟请求,避免频繁调用接口)
- 可通过SharedPreferences或Room保存用户搜索历史,作为建议数据源
- 取消高亮的核心是直接绑定原始文本,不使用SpannableString等高亮逻辑
内容的提问来源于stack exchange,提问作者Cam
相关产品推荐
相关产品推荐

