You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为Kotlin Android应用实现搜索功能的技术求助

在HikeListActivity中实现搜索过滤功能的解决方案

以下是快速实现SearchView过滤徒步列表的具体步骤和代码修改方案:

1. 保存原始徒步数据列表

首先在Activity中新增变量存储所有原始徒步数据,避免每次过滤重复请求数据源:

private var allHikes: List<HikeModel> = emptyList()

修改loadHikes()方法,将原始数据存入该变量:

private fun loadHikes() {
    allHikes = app.hikes.findAll()
    showHikes(allHikes)
}

2. 为SearchView添加实时监听

在onCreate()方法中,给searchView绑定文本变化监听器,实现实时过滤:

override fun onCreate(savedInstanceState: Bundle?) {
    // ... 原有代码 ...
    searchView = findViewById(R.id.searchView)
    
    // 设置搜索监听
    searchView.setOnQueryTextListener(object : SearchView.OnQueryTextListener {
        override fun onQueryTextSubmit(query: String?): Boolean {
            query?.let { filterHikes(it) }
            return true
        }

        override fun onQueryTextChange(newText: String?): Boolean {
            newText?.let { filterHikes(it) }
            return true
        }
    })
    
    // ... 原有代码 ...
}

3. 实现过滤逻辑

新增filterHikes()方法,根据输入关键词筛选数据:

private fun filterHikes(query: String) {
    val filteredList = allHikes.filter { hike ->
        // 这里以徒步名称为过滤字段,忽略大小写
        hike.name.contains(query, ignoreCase = true)
        // 如需多字段过滤,可扩展为:
        // hike.name.contains(query, ignoreCase = true) || hike.location.contains(query, ignoreCase = true)
    }
    showHikes(filteredList)
}

4. 修复现有代码冗余问题

你的onOptionsItemSelected方法存在重复的R.id.item_add分支,删除其中一个即可:

override fun onOptionsItemSelected(item: MenuItem): Boolean {
    when (item.itemId) {
        R.id.item_add -> {
            val launcherIntent = Intent(this, HikeActivity::class.java)
            refreshIntentLauncher.launch(launcherIntent)
        }
        R.id.logout -> {
            FirebaseAuth.getInstance().signOut()
            val launcherIntent = Intent(this, SignInActivity::class.java)
            refreshIntentLauncher.launch(launcherIntent)
        }
    }
    return super.onOptionsItemSelected(item)
}

完整修改后的代码

package org.wit.hikingtrails.activities

import android.content.Intent
import android.os.Bundle
import android.view.Menu
import android.view.MenuItem
import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.contract.ActivityResultContracts
import androidx.appcompat.app.AppCompatActivity
import androidx.recyclerview.widget.LinearLayoutManager
import com.google.firebase.auth.FirebaseAuth
import org.wit.hikingtrails.R
import org.wit.hikingtrails.adapters.HikeAdapter
import org.wit.hikingtrails.adapters.HikeListener
import org.wit.hikingtrails.databinding.ActivityHikeListBinding
import org.wit.hikingtrails.main.MainApp
import org.wit.hikingtrails.models.HikeModel
import android.widget.SearchView

class HikeListActivity : AppCompatActivity(), HikeListener {

    lateinit var app: MainApp
    private lateinit var binding: ActivityHikeListBinding
    private lateinit var refreshIntentLauncher : ActivityResultLauncher<Intent>
    lateinit var searchView: SearchView
    private var allHikes: List<HikeModel> = emptyList()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityHikeListBinding.inflate(layoutInflater)
        setContentView(binding.root)
        binding.toolbar.title = title
        setSupportActionBar(binding.toolbar)
        searchView = findViewById(R.id.searchView)

        app = application as MainApp

        val layoutManager = LinearLayoutManager(this)
        binding.recyclerView.layoutManager = layoutManager

        // 绑定搜索监听
        searchView.setOnQueryTextListener(object : SearchView.OnQueryTextListener {
            override fun onQueryTextSubmit(query: String?): Boolean {
                query?.let { filterHikes(it) }
                return true
            }

            override fun onQueryTextChange(newText: String?): Boolean {
                newText?.let { filterHikes(it) }
                return true
            }
        })

        loadHikes()
        registerRefreshCallback()
    }

    override fun onCreateOptionsMenu(menu: Menu): Boolean {
        menuInflater.inflate(R.menu.menu_main, menu)
        return super.onCreateOptionsMenu(menu)
    }

    override fun onOptionsItemSelected(item: MenuItem): Boolean {
        when (item.itemId) {
            R.id.item_add -> {
                val launcherIntent = Intent(this, HikeActivity::class.java)
                refreshIntentLauncher.launch(launcherIntent)
            }
            R.id.logout -> {
                FirebaseAuth.getInstance().signOut()
                val launcherIntent = Intent(this, SignInActivity::class.java)
                refreshIntentLauncher.launch(launcherIntent)
            }
        }
        return super.onOptionsItemSelected(item)
    }

    override fun onHikeClick(hike: HikeModel) {
        val launcherIntent = Intent(this, HikeActivity::class.java)
        launcherIntent.putExtra("hike_edit", hike)
        refreshIntentLauncher.launch(launcherIntent)
    }

    private fun registerRefreshCallback() {
        refreshIntentLauncher =
            registerForActivityResult(ActivityResultContracts.StartActivityForResult())
            { loadHikes() }
    }

    private fun loadHikes() {
        allHikes = app.hikes.findAll()
        showHikes(allHikes)
    }

    fun showHikes (hikes: List<HikeModel>) {
        binding.recyclerView.adapter = HikeAdapter(hikes, this)
        binding.recyclerView.adapter?.notifyDataSetChanged()
    }

    private fun filterHikes(query: String) {
        val filteredList = allHikes.filter { hike ->
            hike.name.contains(query, ignoreCase = true)
        }
        showHikes(filteredList)
    }
}

关键说明

  • 存储原始数据列表是为了提升过滤性能,避免重复查询数据源
  • 过滤字段可根据需求调整为徒步地点、描述等其他属性
  • 实时过滤通过onQueryTextChange实现,用户输入时列表即时更新

内容的提问来源于stack exchange,提问作者cduff

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.14 17:10:33