未调用 RecyclerVIew onCreateViewHolder 和 onBindViewHolder

Posted

技术标签:

【中文标题】未调用 RecyclerVIew onCreateViewHolder 和 onBindViewHolder【英文标题】:RecyclerVIew onCreateViewHolder and onBindViewHolder is not called 【发布时间】:2021-08-07 19:27:42 【问题描述】:

我有两个片段 1.UploadFragment - 将数据上传到 Firestore 2.FetchFragemnt - 从 firestore 获取数据并在 recyclerView 中显示 这两个片段在 N​​avigationDrawer 中使用。

我的问题在于 fetchFragment 最初 recyclerView 显示从 firestore 获取的数据。 但是当我导航到 UploadFragment 并返回 FetchFragment 时,RecyclerView 没有加载。

此外,当我导航到 UploadFragment 并返回 FetchFragment 时,不会调用 onCreateViewHolder 和 onBindViewHolder。

请人帮忙。

FetchFragment code :
class FetchFragment : Fragment(R.layout.fragment_fetch) 
    private lateinit var binding : FragmentFetchBinding
    private lateinit var adapter: PersonsAdapter
    private lateinit var personsList: MutableList<PersonsDb>
    private val personCollectionRef = Firebase.firestore.collection("persons")
    override fun onViewCreated(view: View, savedInstanceState: Bundle?) 
        super.onViewCreated(view, savedInstanceState)
        binding = FragmentFetchBinding.bind(view)
        personsList = mutableListOf()
        adapter = PersonsAdapter(personsList)item ->
            Intent(requireContext(),UpdateActivity::class.java).also
                it.putExtra("EXTRA_DETAILS",item.id)
                startActivity(it)
            
        
        binding.rvPersons.adapter = adapter
        binding.rvPersons.layoutManager = LinearLayoutManager(requireContext())
        fetchPPerson()
        binding.svFilter.setOnQueryTextListener(object : SearchView.OnQueryTextListener 
            override fun onQueryTextSubmit(p0: String?): Boolean 
                //Performs search when user hit the search button on the keyboard
//                adapter.getFilter().filter(p0);
                return false
            
            override fun onQueryTextChange(p0: String?): Boolean 
                //Start filtering the list as user start entering the characters
                adapter.getFilter().filter(p0);
                return false
            
        )

    
    private fun fetchPPerson() = CoroutineScope(Dispatchers.IO).launch

        try
            val querySnapshot = personCollectionRef.get().await()
            personsList.clear()
            for(document in querySnapshot.documents)
                val person = document.toObject<Person>()
                personsList.add(
                    PersonsDb(document.id,
                            person?.name.toString(),
                        person?.age.toString().toInt(),
                        Date(person?.dob.toString())
                ))

            
            withContext(Dispatchers.Main)
                adapter.notifyDataSetChanged()
            

        catch (e:Exception)
            withContext(Dispatchers.Main)
                Toast.makeText(requireContext(),e.message, Toast.LENGTH_LONG).show()
                Log.d("Fetch Error", e.message)
            

        
    


My Recycler Adapter :
class PersonsAdapter (
    var persons : List<PersonsDb>,
    private val listener: (PersonsDb) -> Unit
):RecyclerView.Adapter<PersonsAdapter.PersonsViewHolder>(),Filterable
    var personsList = persons
    inner class PersonsViewHolder(val binding : ItemPersonBinding):
            RecyclerView.ViewHolder(binding.root)
    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): PersonsViewHolder 
        val binding = ItemPersonBinding.inflate(LayoutInflater.from(parent.context),parent,false)
        return PersonsViewHolder(binding)
    

    override fun getItemCount(): Int 
        return persons.size
    

    override fun getFilter(): Filter 
        return filter
    

    override fun onBindViewHolder(holder: PersonsViewHolder, position: Int) 
        val item = persons[position]
        with(holder)
            with(persons[position])
                binding.tvName.text = this.name
                binding.tvAge.text = this.age.toString()
//                binding.tvDob.text = this.dob.toString()
                binding.tvDob.text = updateDateInView(this.dob)
            
        

        holder.itemView.setOnClickListener  listener(item) 
    

    private fun updateDateInView(cal : Date) : String
        val myFormat = "dd/MM/yyyy" // mention the format you need
        val sdf = SimpleDateFormat(myFormat, Locale.US)
//        binding.dpDob.setText(sdf.format(cal.getTime()))
        return sdf.format(cal.getTime())
    

    private val filter: Filter = object : Filter() 
        override fun performFiltering(constraint: CharSequence): FilterResults 
            var filteredList: MutableList<PersonsDb> = arrayListOf()

            if (constraint.isEmpty()) 
                filteredList.addAll(personsList)
             else 
                val filterPattern = constraint.toString().toLowerCase().trim  it <= ' ' 
                for (item in 0..persons.size -1) 
                    if (persons[item].name.toLowerCase().contains(filterPattern)
                            || persons[item].age.toString().contains(filterPattern)) 
                        filteredList.add(persons[item])
                    
                
            
            val results = FilterResults()
            results.count = filteredList.size
            results.values = filteredList
//            Log.d("Filter Values", results.values.toString())
            return results
        

        override fun publishResults(charSequence: CharSequence, filterResults: FilterResults) 
            persons = if(filterResults == null || filterResults.values == null)
                personsList
            
            else
                filterResults.values as List<PersonsDb>
            notifyDataSetChanged()

        
    


【问题讨论】:

【参考方案1】:

你能检查项目计数(日志项目计数)。这样你就会知道数据是否存在 返回 FetchFragment 时用于 recyclerview 。我怀疑空数据可能是原因。

【讨论】:

嗨。我也试过了。但是,当我导航到 FetchFragment 时,我第一次获得了项目计数,并显示了数据。但是当我导航到 UploadFragment 并返回到 FetchFragment 时,项目计数为 0。并且 onCreateViewHolder 和 onBindViewHolder 也没有被调用。

以上是关于未调用 RecyclerVIew onCreateViewHolder 和 onBindViewHolder的主要内容,如果未能解决你的问题,请参考以下文章

在 RecyclerView 适配器 notifyDataSetChanged() 之后未调用 onBindViewHolder

未调用 RecyclerVIew onCreateViewHolder 和 onBindViewHolder

recyclerview加载更多后怎么从头加载列表

Android 11 onCreate() 调用每秒钟都丢失

在 NestedScrollView 中使用两个具有不同适配器的 RecyclerView 加载速度非常慢

RecyclerView不调用onCreateViewHolder和onBindViewHolder的解决方法