【问题标题】:Recyclerview does not refreshRecyclerview 不刷新
【发布时间】:2021-09-25 14:56:35
【问题描述】:

我尝试使用房间数据库中的数据填充数组。 数据仅在我刷新后填充到回收器视图中 分段。刷新后,所有内容都会显示出来。有人知道为什么吗?

所以奇怪的是一切正常,但只有在片段刷新后。

我已经实现了 notifydataset changed 功能,但没有成功。

class WorkoutFragment : Fragment() {

    private lateinit var homeViewModel: HomeViewModel
    private var _binding: FragmentWorkoutBinding? = null

    // This property is only valid between onCreateView and
    // onDestroyView.
    private val binding get() = _binding!!

    @SuppressLint("NotifyDataSetChanged")
    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        homeViewModel =
            ViewModelProvider(this).get(HomeViewModel::class.java)

        _binding = FragmentWorkoutBinding.inflate(inflater, container, false)
        val root: View = binding.root
        val sharedPreference =  activity?.getSharedPreferences("WORKOUT_BUTTON", Context.MODE_PRIVATE)
        val sharedPreference2 =  activity?.getSharedPreferences("PREFERENCE_NAME", Context.MODE_PRIVATE)
        var editor = sharedPreference?.edit()
        val recyclerView = binding.recyclerview
        recyclerView?.layoutManager = LinearLayoutManager(context)
        var workout: MutableList<String> = mutableListOf()
        var workoutid: MutableList<Int> = mutableListOf()
        workout.clear()
        workoutid.clear()
        val adapter = AdapterWorkoutsHeader(workoutid as ArrayList<Int>,
            workout as ArrayList<String>
        )
        recyclerView?.adapter = adapter


        val user = ParseUser.getCurrentUser()
        val parkname = user.get("parkname")
        val currentSpot: TextView = binding.currentSpot
        currentSpot.text = parkname.toString()
        val openNav: ImageButton = binding.openNav
        openNav.setOnClickListener {
            val mDrawerLayout: DrawerLayout? = activity?.findViewById(R.id.drawer_layout)
            mDrawerLayout!!.openDrawer(GravityCompat.START)
        }
        
        val addWorkout: Button = binding.button
        addWorkout.setOnClickListener {
            val intent = Intent(requireContext(), ChooseWorkoutActivity::class.java)
            startActivity(intent)
        }

        Thread{
            val db = Room.databaseBuilder(
                requireContext(),
                AppDatabase::class.java, "workout.db"
            ).build()
            val userDao = db.todoDao()


            for (i in 0 until userDao.getWorkoutSize()){
                userDao.getChosenWorkout(i)[0].workout?.let { workout.add(it) }
                userDao.getChosenWorkout(i)[0].workoutid?.let { workoutid.add(it) }

                activity?.runOnUiThread {
                    val adapter = AdapterWorkoutsHeader(workoutid as ArrayList<Int>,
                        workout as ArrayList<String>
                    )
                    recyclerView?.adapter = adapter
                    adapter.notifyDataSetChanged()
                }

            }


            //var parkNames2 = parkNames.toTypedArray()
            //recyclerView.adapter?.notifyDataSetChanged()




        }.start()

        

        return root
    }

    
    override fun onDestroyView() {
        super.onDestroyView()
        _binding = null
    }
}

【问题讨论】:

  • 您需要使用函数来分离您的关注点,无法阅读您的代码。规则是每个函数或方法都应该做一件事。你将有数百个错误,因为你不能有效地阅读自己的代码。
  • 为什么要在片段中构建数据库。您应该只观察片段中的实时数据。如果数据已更改,请更新您的回收器适配器。
  • 这不是一个解决方案,但您应该从线程内部删除recyclerView?.adapter = adapter,在外部调用它并为其分配一个数据数组,您应该将适配器初始化为线程外部的 recyclerView 并保留其引用或对数据数组的引用,当一些新项目进入时,将其添加到数据数组中并使用其位置调用adapter.notifyItemInserted(positionOfInsertedItem),而不是为每个项目调用 notifyDataSetChanged。
  • 感谢伊曼纽尔,将努力使其更具可读性。我没有收到任何错误。谢谢奥马尔,会试试看。
  • 嗨 Emmanuel,我现在正在使用实时数据并在片段中观察它。我得到了同样的错误 --> stackoverflow.com/questions/69610704/…

标签: android android-fragments android-recyclerview


【解决方案1】:
  1. 数据更新应该从 UI 线程完成

    runOnUiThread { 
       recyclerView?.adapter = adapter
       adapter.notifyDataSetChanged()
    }
    
  2. 同步问题

    var workout: MutableList<String> = mutableListOf()
    var workoutid: MutableList<Int> = mutableListOf()
    

    在 UI 线程上,但从其他线程修改,因此可以使用同步或同步集合Collections.synchronizedList

【讨论】:

  • 谢谢,但没用。由于“activity?.runOnUiThread”,它也已经在主线程上,对吧?
  • 请尝试更新答案
  • no 也不起作用。还是谢谢
猜你喜欢
  • 2017-03-29
  • 1970-01-01
  • 2020-11-11
  • 1970-01-01
  • 1970-01-01
  • 2021-05-24
  • 1970-01-01
  • 1970-01-01
  • 2015-01-07
相关资源
最近更新 更多