用观察到的数据更新RecyclerView的正确位置

问题描述 投票:0回答:1

我希望我没错,但是我希望澄清一下下面的代码被视为是一种好习惯。

这里是我的片段(请注意我放置了setupObservers()initRecyclerView的位置。]

private const val TAG = "DAS.SitesFragment"

class SitesFragment : Fragment() {

    private lateinit var businessViewModel: BusinessViewModel
    private var sitesList = ArrayList<SiteObject>()

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?): View? {
        // Inflate the layout for this fragment
        val binding: SitesFragmentBinding = DataBindingUtil.inflate(
            inflater, R.layout.sites_fragment, container, false
        )

        binding.apply {
            sitesFloatingActionButtonAdd.setOnClickListener{
                findNavController().navigate(R.id.action_sitesFragment_to_siteAddEditFragment)
                Log.d(TAG,"sitesFloatingActionButtonAdd clicked, navigating to siteAddEditFragment")
            }

            sitesClearIconImageView.setOnClickListener{
                findNavController().navigate(R.id.action_sitesFragment_to_siteFragment)
                Log.d(TAG,"sitesClearIconImageView clicked, navigating to siteFragment")
            }
        }

        return binding.root
    }

    override fun onActivityCreated(savedInstanceState: Bundle?) {
        super.onActivityCreated(savedInstanceState)

            activity?.let {
                businessViewModel = ViewModelProvider(it).get(BusinessViewModel::class.java)
                Log.d(TAG, "businessViewModel = ${businessViewModel.toString()}")
        }
        setupObservers()
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        initRecyclerView()
    }


    private fun initRecyclerView() {
        Log.d(TAG, "initRecyclerView()")
        sitesRecyclerView.apply {
            adapter = SitesRecyclerViewAdapter(sitesList)
            layoutManager = LinearLayoutManager(activity)
            setHasFixedSize(true)  
        }

    }

    private fun setupObservers() {
        Log.d(TAG, "setupObservers()")
        businessViewModel.listenToSites().observe(viewLifecycleOwner, Observer { allSites ->
            sitesList = allSites
            sitesRecyclerView.adapter = SitesRecyclerViewAdapter(sitesList)
//            sitesRecyclerView.adapter?.notifyDataSetChanged() - don't think I even need this..
            Log.d(TAG,"siteAdapter updated, sitesList size = ${sitesList.size}")
        })
    }

}

这是我的适配器

private const val TAG = "DAS.SitesRViewAdapter"


class SitesRecyclerViewAdapter(private val sitesList: ArrayList<SiteObject>): RecyclerView.Adapter<SitesRecyclerViewAdapter.SiteViewHolder> (){

    class SiteViewHolder (itemView: View): RecyclerView.ViewHolder (itemView) {

        val siteItemTitle: TextView = itemView.sitesItemTitleText
        val siteItemProjectText: TextView = itemView.sitesItemProjectsText

        val siteItemMapImage: ImageView = itemView.sitesItemMapImageView
        val siteItemPriorityImage: ImageView = itemView.sitesItemPriorityImageView
        val siteItemRating1Image: ImageView = itemView.sitesItemRating1ImageView
        val siteItemRating2Image: ImageView = itemView.sitesItemRating2ImageView
        val siteItemRating3Image: ImageView = itemView.sitesItemRating3ImageView

    }


    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): SiteViewHolder {
        Log.d(TAG, "onCreateViewHolder()")
        val itemView = LayoutInflater.from(parent.context).inflate(R.layout.sites_list_item, parent, false)
        return SiteViewHolder(itemView)
    }

    override fun onBindViewHolder(holder: SiteViewHolder, position: Int) {

        val currentItem = sitesList[position]

        Log.d(TAG, "onBindViewHolder(), currentItem = ${currentItem.siteReference}")

        holder.siteItemTitle.text = currentItem.siteReference
        holder.siteItemProjectText.text = currentItem.recentProjectsText

        // Reset visibility
        holder.siteItemPriorityImage.visibility = View.INVISIBLE
        holder.siteItemMapImage.visibility = View.INVISIBLE
        holder.siteItemRating1Image.visibility = View.INVISIBLE
        holder.siteItemRating2Image.visibility = View.INVISIBLE
        holder.siteItemRating3Image.visibility = View.INVISIBLE

        // Make relevant icons visible
        if (currentItem.plusCode.isNotEmpty()) holder.siteItemMapImage.visibility = View.VISIBLE
        if (currentItem.sitePriority) holder.siteItemPriorityImage.visibility = View.VISIBLE
        when (currentItem.siteRating) {
            1 -> holder.siteItemRating1Image.visibility = View.VISIBLE
            2 -> holder.siteItemRating2Image.visibility = View.VISIBLE
            3 -> holder.siteItemRating3Image.visibility = View.VISIBLE
        }
    }

    override fun getItemCount(): Int {
        return sitesList.size
    }
}

我在logcat中看到的是以下内容:

2020-05-11 18:09:02.221 30982-30982/com.xxx.acorn D/DAS.SplashActivity: firebaseAuth = com.google.firebase.auth.internal.zzl@cb43e66, firebaseUser = com.google.firebase.auth.internal.zzn@ca5d5a7
2020-05-11 18:09:02.737 30982-30982/com.xxx.acorn D/DAS.SitesFragment: initRecyclerView()
2020-05-11 18:09:02.785 30982-30982/com.xxx.acorn D/DAS.SitesFragment: businessViewModel = com.locators.acorn.business.BusinessViewModel@f994bce
2020-05-11 18:09:02.785 30982-30982/com.xxx.acorn D/DAS.SitesFragment: setupObservers()
2020-05-11 18:09:02.785 30982-30982/com.xxx.acorn D/DAS.BusinessViewModel: listenToSites()
2020-05-11 18:09:03.414 30982-30982/com.xxx.acorn D/DAS.SitesFragment: siteAdapter updated, sitesList size = 12
2020-05-11 18:09:03.418 30982-30982/com.xxx.acorn D/DAS.SitesRViewAdapter: onCreateViewHolder()
2020-05-11 18:09:03.440 30982-30982/com.xxx.acorn D/DAS.SitesRViewAdapter: onBindViewHolder(), currentItem = Company 88383
2020-05-11 18:09:03.454 30982-30982/com.xxx.acorn D/DAS.SitesRViewAdapter: onCreateViewHolder()
2020-05-11 18:09:03.464 30982-30982/com.xxx.acorn D/DAS.SitesRViewAdapter: onBindViewHolder(), currentItem = Company HEY1
2020-05-11 18:09:03.476 30982-30982/com.xxx.acorn D/DAS.SitesRViewAdapter: onCreateViewHolder()
2020-05-11 18:09:03.484 30982-30982/com.xxx.acorn D/DAS.SitesRViewAdapter: onBindViewHolder(), currentItem = Company 9677
2020-05-11 18:09:03.490 30982-30982/com.xxx.acorn D/DAS.SitesRViewAdapter: onCreateViewHolder()
2020-05-11 18:09:03.501 30982-30982/com.xxx.acorn D/DAS.SitesRViewAdapter: onBindViewHolder(), currentItem = Company 313
2020-05-11 18:09:03.513 30982-30982/com.xxx.acorn D/DAS.SitesRViewAdapter: onCreateViewHolder()
2020-05-11 18:09:03.522 30982-30982/com.xxx.acorn D/DAS.SitesRViewAdapter: onBindViewHolder(), currentItem = Company 123
2020-05-11 18:09:03.528 30982-30982/com.xxx.acorn D/DAS.SitesRViewAdapter: onCreateViewHolder()
2020-05-11 18:09:03.537 30982-30982/com.xxx.acorn D/DAS.SitesRViewAdapter: onBindViewHolder(), currentItem = Company UTY
2020-05-11 18:09:03.546 30982-30982/com.xxx.acorn D/DAS.SitesRViewAdapter: onCreateViewHolder()
2020-05-11 18:09:03.566 30982-30982/com.xxx.acorn D/DAS.SitesRViewAdapter: onBindViewHolder(), currentItem = Company TJJF
2020-05-11 18:19:22.769 30982-30982/com.xxx.acorn D/DAS.SitesRViewAdapter: onCreateViewHolder()
2020-05-11 18:19:22.775 30982-30982/com.xxx.acorn D/DAS.SitesRViewAdapter: onBindViewHolder(), currentItem = Company ZHHPE
2020-05-11 18:19:22.852 30982-30982/com.xxx.acorn D/DAS.SitesRViewAdapter: onCreateViewHolder()
2020-05-11 18:19:22.861 30982-30982/com.xxx.acorn D/DAS.SitesRViewAdapter: onBindViewHolder(), currentItem = Company ZZZZ
2020-05-11 18:19:23.963 30982-30982/com.xxx.acorn D/DAS.SitesRViewAdapter: onCreateViewHolder()
2020-05-11 18:19:23.970 30982-30982/com.xxx.acorn D/DAS.SitesRViewAdapter: onBindViewHolder(), currentItem = Company XYZ
2020-05-11 18:19:24.047 30982-30982/com.xxx.acorn D/DAS.SitesRViewAdapter: onBindViewHolder(), currentItem = Company ABC
2020-05-11 18:19:25.096 30982-30982/com.xxx.acorn D/DAS.SitesRViewAdapter: onBindViewHolder(), currentItem = Company ABCCC

所以它似乎正确触发,并且以后的条目仅在您向下滚动时显示(并且重要的是,OnCreateViewHolder在循环回收ViewHolders时停止触发,但是我担心这是不正确的,因为我正在创建带有空列表的RecyclerView,然后在设置了观察者之后填充它。.

有趣的是,我注意到的一件事是,当我添加一个新站点时,观察者会触发两次,因此我在logcat中得到如下内容:

2020-05-11 18:09:03.414 30982-30982/com.xxx.acorn D/DAS.SitesFragment: siteAdapter updated, sitesList size = 13
2020-05-11 18:09:03.414 30982-30982/com.xxx.acorn D/DAS.SitesFragment: siteAdapter updated, sitesList size = 13

它似乎还会在RecyclerView中填充两次(包括复制上面的内容,但是我认为这是观察者的怪癖,超出了此问题的范围。]]

我希望我做对了,但是我希望澄清一下下面的代码是一种好的做法。这是我的片段(请注意,我在其中放置了setupObservers()和...

android kotlin android-recyclerview recycler-adapter
1个回答
0
投票

请执行onViewCreated回调中的所有操作

© www.soinside.com 2019 - 2024. All rights reserved.