首页 > 解决方案 > SearchView 在回收站视图中不起作用

问题描述

我正在尝试在 recyclerview 上添加 searchview,但它甚至没有显示任何错误也无法正常工作。我在stackoverflow上准备了很多答案,但它们对我不起作用。请告诉我我的代码中有什么错误。当我调试我的代码时,搜索的值显示在结果变量中,但没有显示在 recyclerview 中。我想用 1) 国家名称 2) 大写 3) 和 id 来搜索可以帮助我

我的适配器在这里

class ProfileListAdapter(var profiles:ArrayList<Profile>):RecyclerView.Adapter<ProfileListAdapter.ProfileViewHolder>(),Filterable {

   
    fun updateProfile(newProfiles:List<Profile>){
        profiles.clear()
        profiles.addAll(newProfiles)
        notifyDataSetChanged()
    }
    var profileFilterList = ArrayList<Profile>()
    init {
        profileFilterList = profiles
    }
    class ProfileViewHolder(view: View):RecyclerView.ViewHolder(view){
       private var id = view.findViewById<TextView>(R.id.tv_id)
       private var name = view.findViewById<TextView>(R.id.tv_name)
       private var fatherName = view.findViewById<TextView>(R.id.tv_father_name)
       private var profileImage = view.findViewById<ImageView>(R.id.iv_profile_image)
       private var progressDrawable = getProgressDrawable(view.context)

       fun bind(profile: Profile){
          id.text = profile.id.toString()
           name.text = profile.name
           fatherName.text = profile.fatherName
           profileImage.loadImage(profile.profilePicture,progressDrawable)
       }
   }
    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = ProfileViewHolder(
        LayoutInflater.from(parent.context).inflate(R.layout.rv_dummy_items,parent,false)
    )
    override fun onBindViewHolder(holder: ProfileViewHolder, position: Int) {
        holder.bind(profiles[position])
    }
    override fun getItemCount() = profiles.size


// Search items
    override fun getFilter(): Filter {
        return object : Filter() {
            override fun performFiltering(constraint: CharSequence?): FilterResults {
                val charString = constraint?.toString() ?: ""
                if (charString.isEmpty()){
                    profiles.also { profileFilterList = it }
                } else {
                    val filteredList = ArrayList<Profile>()
                    profiles
                        .filter {
                            (it.name.contains(constraint!!)) or (it.fatherName.contains(constraint))
                        }
                        .forEach { filteredList.add(it) }
                    profileFilterList = filteredList
                }
                return FilterResults().apply { values = profileFilterList }
            }
            override fun publishResults(constraint: CharSequence?, results: FilterResults?) {
                profileFilterList = if (results?.values == null) ArrayList()
                else
                    results.values as ArrayList<Profile>
                notifyDataSetChanged()
            }
        }
    }

    
}

我的主要活动在这里

class MainActivity : AppCompatActivity() {
    lateinit var binding: ActivityMainBinding
    lateinit var viewModel: ListViewModel
    var profileAdapter = ProfileListAdapter(arrayListOf())

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityMainBinding.inflate(layoutInflater)
        val view = binding.root
        setContentView(view)
        //here I'm calling search profile function
        searchProfile()
        //
        viewModel = ViewModelProviders.of(this).get(ListViewModel::class.java)
        viewModel.refresh()

        binding.rvProfileList.apply {
            layoutManager = LinearLayoutManager(context)
            adapter = profileAdapter
        }
        observeViewModel()
        filterButtons()
    }
    fun observeViewModel() {
        viewModel.profiles.observe(this, Observer { profiles: List<Profile>? ->
            profiles?.let {
                binding.rvProfileList.visibility = View.VISIBLE
                profileAdapter.updateProfile(it)
            }
        })
        viewModel.profileLoadingError.observe(this, Observer { isError: Boolean? ->
            isError?.let {
                binding.listError.visibility = if (it) View.VISIBLE else View.GONE
            }
        })
        viewModel.loading.observe(this, Observer { isLoading ->
            isLoading?.let {
                binding.loadingView.visibility = if (it) View.VISIBLE else View.GONE
            }
        })

    }

    //search function
    fun searchProfile(){

        binding.searchView.setOnQueryTextListener(object: SearchView.OnQueryTextListener{
            override fun onQueryTextSubmit(query: String?): Boolean {
                profileAdapter.filter.filter(query)
                return false
            }
            override fun onQueryTextChange(newText: String?): Boolean {
                profileAdapter.filter.filter(newText)
                return false
            }

        })
    }
}

标签: androidkotlinandroid-recyclerviewretrofitsearchview

解决方案


我在您的适配器中进行编辑,并且过滤器在修改后与我的代码正常工作

class ProfileListAdapter():RecyclerView.Adapter<ProfileListAdapter.ProfileViewHolder>(),Filterable {
  
 var profileList: ArrayList<Profile> = ArrayList()
 var profileListFiltered: ArrayList<Profile> = ArrayList()


fun updateProfile(newProfiles:List<Profile>){
    
     profileList = ArrayList(newProfiles)
     profileListFiltered = profileList
    notifyDataSetChanged()
}

class ProfileViewHolder(view: View):RecyclerView.ViewHolder(view){
   private var id = view.findViewById<TextView>(R.id.tv_id)
   private var name = view.findViewById<TextView>(R.id.tv_name)
   private var fatherName = view.findViewById<TextView>(R.id.tv_father_name)
   private var profileImage = view.findViewById<ImageView>(R.id.iv_profile_image)
   private var progressDrawable = getProgressDrawable(view.context)

   fun bind(profile: Profile){
      id.text = profile.id.toString()
       name.text = profile.name
       fatherName.text = profile.fatherName
       profileImage.loadImage(profile.profilePicture,progressDrawable)
   }
  }
     override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = 
    ProfileViewHolder(
    


LayoutInflater.from(parent.context).inflate(R.layout.rv_dummy_items,parent,false)
)
        override fun onBindViewHolder(holder: ProfileViewHolder, position: Int) 
      {
           holder.bind(profileListFiltered[position])
        }
          override fun getItemCount() = profileListFiltered.size


         // Search items
        override fun getFilter(): Filter {
              return object : Filter() {
        override fun performFiltering(constraint: CharSequence?): FilterResults 
           {
            val charString = constraint?.toString() ?: ""
            if (charString.isEmpty()){
               profileListFiltered = profileList
            } else {
                val filteredList = ArrayList<Profile>()
                profileList
                    .filter {
                        (it.name.contains(constraint!!)) or 
                  (it.fatherName.contains(constraint))
                    }
                    .forEach { filteredList.add(it) }
                profileFilterList = filteredList
            }
            return FilterResults().apply { values = profileFilterList }
        }
        override fun publishResults(constraint: CharSequence?, results: 
    FilterResults?) {
            profileFilterList = if (results?.values == null) ArrayList()
            else
                results.values as ArrayList<Profile>
            notifyDataSetChanged()
          }
      }
    }


 }

在您的活动中,只需在使用适配器 updateProfile 中的函数获取数据后声明不带参数构造函数的适配器,然后就可以与您的 ISA 一起正常工作

为您的适配器编辑

class ProfileListAdapter(var 
    profiles:ArrayList<Profile>)
  :RecyclerView.Adapter<ProfileListAdapter.Profile 
 ViewHolder>(),Filterable {


fun updateProfile(newProfiles:List<Profile>){
    profiles.clear()
    profiles.addAll(newProfiles)
    notifyDataSetChanged()
}
var profileFilterList = ArrayList<Profile>()
init {
    profileFilterList = profiles
}
class ProfileViewHolder(view: View):RecyclerView.ViewHolder(view){
   private var id = view.findViewById<TextView>(R.id.tv_id)
   private var name = view.findViewById<TextView>(R.id.tv_name)
   private var fatherName = view.findViewById<TextView> 
    (R.id.tv_father_name)
   private var profileImage = view.findViewById<ImageView> 
   (R.id.iv_profile_image)
   private var progressDrawable = getProgressDrawable(view.context)

   fun bind(profile: Profile){
      id.text = profile.id.toString()
       name.text = profile.name
       fatherName.text = profile.fatherName
       profileImage.loadImage(profile.profilePicture,progressDrawable)
   }
  }
    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = 
  ProfileViewHolder(
   LayoutInflater.from(parent.context)
   .inflate(R.layout.rv_dummy_items,parent,false)
     )
      override fun onBindViewHolder(holder: ProfileViewHolder, position: 
      Int) 
   {
    holder.bind(profileFilterList[position])
    }
    override fun getItemCount() = profileFilterList.size


  // Search items
   override fun getFilter(): Filter {
      return object : Filter() {
        override fun performFiltering(constraint: CharSequence?): 
         FilterResults {
            val charString = constraint?.toString() ?: ""
            if (charString.isEmpty()){
               profileFilterList = profiles
            } else {
                val filteredList = ArrayList<Profile>()
                profiles
                    .filter {
                        (it.name.contains(constraint!!)) or 
          (it.fatherName.contains(constraint))
                    }
                    .forEach { filteredList.add(it) }
                profileFilterList = filteredList
            }
            return FilterResults().apply { values = profileFilterList }
        }
        override fun publishResults(constraint: CharSequence?, results: 
     FilterResults?) {
            profileFilterList = if (results?.values == null) ArrayList()
            else
                results.values as ArrayList<Profile>
            notifyDataSetChanged()
        }
    }
    }


  }

推荐阅读