【问题标题】:RecyclerView only displaying data after restarting ActivityRecyclerView只在重启Activity后显示数据
【发布时间】:2021-06-17 20:40:25
【问题描述】:

所以我有这种奇怪的行为,我的RecyclerView 仅在我启动应用程序然后通过 Android Studio 重新启动活动时显示数据。或者在 XML 中进行更改,然后撤消并重新启动。 然后显示的数据是正确的,并且在我添加内容时也会更新,但在启动应用程序后它不可见。

谁能帮帮我?我真的不知道为什么会这样。

片段:

@AndroidEntryPoint
class HistoryFragment : Fragment(R.layout.fragment_history) {

    private val viewModel: PurchaseViewmodel by viewModels()

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

        val binding = FragmentHistoryBinding.bind(view)

        val exampleAdapter = ExampleAdapter()

        binding.apply{
            recyclerView.apply{

                layoutManager = LinearLayoutManager(requireContext())
                adapter = exampleAdapter
                setHasFixedSize(true)
            }
            ItemTouchHelper(object : ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.LEFT or ItemTouchHelper.RIGHT) {
                override fun onMove(
                    recyclerView: RecyclerView,
                    viewHolder: RecyclerView.ViewHolder,
                    target: RecyclerView.ViewHolder
                ): Boolean {
                    return false /// We dont need any interaction with Drag&Drop we only want swipe left&right
                }

                override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) {
                    val receipt = exampleAdapter.currentList[viewHolder.adapterPosition]
                     viewModel.onSwipe(receipt)
                }
            }).attachToRecyclerView(recyclerView)
        }

        setFragmentResultListener("add_receipt_request"){_,bundle ->
            val result = bundle.getInt("add_receipt_request")
            viewModel.onAddResult(result)
        }

        viewModel.receipts.observe(viewLifecycleOwner){ /// New Items get passed to the List
            exampleAdapter.submitList(it)
        }
        viewLifecycleOwner.lifecycleScope.launchWhenStarted { //as soon as we close our app the events will be suspended, but not deleted and will remain after restart
            viewModel.addTaskEvent.collect {  event->
                when(event){
                    is PurchaseViewmodel.TasksEvent.ShowUndoDelete -> {
                        Snackbar.make(requireView(),"Tasks deleted", Snackbar.LENGTH_LONG)
                            .setAction("UNDO"){
                                viewModel.unDoDeleteClick(event.receipts)
                            }.show()
                    }
                }
            }
        }

    }
}

适配器:

class ExampleAdapter : ListAdapter<Receipts,ExampleAdapter.ExampleViewHolder>(DiffCallback()) {

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ExampleViewHolder { 
        val binding = ReceiptsBinding.inflate(LayoutInflater.from(parent.context),parent,false)
        return ExampleViewHolder(binding)
    }

    override fun onBindViewHolder(holder: ExampleViewHolder, position: Int) {
        val currentItem = getItem(position)
        holder.bind(currentItem)
    }

    override fun getItemCount(): Int {
        return super.getItemCount()
    }

    class ExampleViewHolder(private val binding: ReceiptsBinding) : RecyclerView.ViewHolder(binding.root){ //Examples One Row in our list
        fun bind (receipts: Receipts) {
            binding.apply {
                storeHistory.text = receipts.store
                amountHistory.text = receipts.total
                dateHistory.text  = receipts.date
            }
        }
    }


    class DiffCallback : DiffUtil.ItemCallback<Receipts>() {
        override fun areItemsTheSame(oldItem: Receipts, newItem: Receipts) =
            oldItem.id == newItem.id


        override fun areContentsTheSame(oldItem: Receipts, newItem: Receipts) =
            oldItem == newItem
    }
}

【问题讨论】:

  • 您是否在任何地方的适配器上调用notifyDataSetChanged()notifyItemChanged()?我在您发布的代码中没有看到它。这些方法告诉适配器在添加或删除元素时更新视图。
  • 我没有,但我的问题不是数据更新时列表不显示,而是当我最初启动应用程序时。
  • bindingonViewCreated 中创建的对象是什么?实际上,fragment 有一个名为onCreateView 的函数,您可以在该函数中实例化绑定并将其存储在fragment 中的属性中并返回binding.root,在onViewCreated 中您将使用该属性。在onViewCreated 中创建一个新的绑定只是创建一个无用的对象,对其进行一些操作,然后将其扔掉。如果您也添加onCreateView 也会有所帮助
  • 谢谢!但我不确定如何实施您的想法。我必须在 onViewCreated 中添加什么以及在 onCreate 中添加什么?

标签: android kotlin android-fragments android-recyclerview android-diffutils


【解决方案1】:

您应该比较areContentsTheSame()中旧/新Receipts的对应字段,而不是比较整个旧/新对象

override fun areContentsTheSame(oldItem: Receipts, newItem: Receipts) = 
    oldItem.store == newItem.store 
            && oldItem.total == newItem.total 
            && oldItem.date == newItem.date

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-12-22
    • 2019-01-26
    • 2023-03-07
    • 2021-01-09
    • 2019-08-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多