android - 如何使用 Coroutines 在 Kotlin 中正确初始化 Recyclerview?
问题描述
我正在使用 Coroutines 学习 kotlin Android,但无法正确启动 RecyclerView。我在 onCreate 方法之外有函数,但我无法将 Arraylist 从这个方法传递给 onCreate 中的适配器。正如您在我的代码中看到的那样,我在 getCities 函数中设置了 location_recycler_view.apply 但随后我看到: E/RecyclerView: No adapter attach; 跳过日志中的布局。在我的情况下如何正确设置 Recyclerview 的代码?
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_add_location)
addLocationViewModel = ViewModelProviders.of(this, addLocationViewModelFactory).get(AddLocationViewModel::class.java)
window.setFlags(
WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN)
back_button.setOnClickListener {
onBackPressed()
}
getCities()
viewAdapter = LocationAdapter(cities, this) //in this case I can get normal list, but no list from ViewModel
viewManager = LinearLayoutManager(this)
deleteIcon = ContextCompat.getDrawable(this, R.drawable.ic_delete_white_24dp)!!
location_recycler_view.apply { //in this case I can set Recyclerview in normal way
adapter = viewAdapter
layoutManager = viewManager
}
val itemTouchHelperCallback = object : ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.LEFT or ItemTouchHelper.RIGHT) {
override fun onMove(
recyclerView: RecyclerView,
viewHolder: RecyclerView.ViewHolder,
target: RecyclerView.ViewHolder
): Boolean {
return false
}
override fun onSwiped(viewHolder: RecyclerView.ViewHolder, position: Int) {
(viewAdapter as LocationAdapter).removeItem(viewHolder)
Log.e("ALA onSwiped", viewHolder.adapterPosition.toString())
fun deleteLocation() = launch {
addLocationViewModel.deleteLocation((viewAdapter as LocationAdapter).getCityAt(viewHolder.adapterPosition))
Log.e("ALA onSwiped", viewHolder.adapterPosition.toString())
}
}
override fun onChildDraw(
c: Canvas,
recyclerView: RecyclerView,
viewHolder: RecyclerView.ViewHolder,
dX: Float,
dY: Float,
actionState: Int,
isCurrentlyActive: Boolean
) {
val itemView = viewHolder.itemView
val iconMargin = (itemView.height - deleteIcon.intrinsicHeight) / 2
if (dX > 0) {
swipeBackground.setBounds(itemView.left, itemView.top, dX.toInt(), itemView.bottom)
deleteIcon.setBounds(itemView.left + iconMargin, itemView.top + iconMargin, itemView.left + iconMargin + deleteIcon.intrinsicWidth,
itemView.bottom - iconMargin)
} else {
swipeBackground.setBounds(itemView.right + dX.toInt(), itemView.top, itemView.right, itemView.bottom)
deleteIcon.setBounds(itemView.right - iconMargin - deleteIcon.intrinsicWidth, itemView.top + iconMargin, itemView.right - iconMargin,
itemView.bottom - iconMargin)
}
swipeBackground.draw(c)
c.save()
if (dX > 0)
c.clipRect(itemView.left, itemView.top, dX.toInt(), itemView.bottom)
else
c.clipRect(itemView.right + dX.toInt(), itemView.top, itemView.right, itemView.bottom)
deleteIcon.draw(c)
c.restore()
super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive)
}
}
val itemTouchHelper = ItemTouchHelper(itemTouchHelperCallback)
itemTouchHelper.attachToRecyclerView(location_recycler_view)
add_city_button.setOnClickListener {
if (location_edit_text.text.toString().trim().isEmpty()) {
Toast.makeText(this, "Location field is empty!", Toast.LENGTH_SHORT).show()
}
else {
saveLocation()
}
}
}
private fun getCities() = launch(Dispatchers.Main) {
val locationList = addLocationViewModel.locations.await()
locationList.observe(this@AddLocationActivity, Observer {
locationList -> viewAdapter = LocationAdapter(locationList as ArrayList<Location>, this@AddLocationActivity)
location_recycler_view.apply {
adapter = viewAdapter //if I'm using this RV works, but I see error in logs
layoutManager = viewManager
}
})
}
解决方案
似乎您必须在方法LocationAdapter
中使用空列表初始化您,onCreate
然后在getCities
方法中您必须将城市列表设置为适配器,如下所示:
viewAdapter.cities = locationList
viewAdapter.notifyDataSetChanged()
推荐阅读
- php - 我想从我的表中获取结果,按列排序,其中大部分时间重复值在顶部。我正在使用 laravel
- sql - 哪个查询有效且正确,可以根据表中的最高值获取结果
- datepicker - TYPO3 8.7 后端 - 更改日期选择器的范围
- javascript - Angular HttpClient 不包括指定的标头
- vue.js - 如何使用 Vue.js 进行幻灯片调查
- sql - 如何检查列是否正在更新
- c++ - OpenMP 并行 for 循环和 std::vector 缩减
- java - Android Google Maps - 如何检查折线是否为空
- c# - 将 3gp 文件转换为 Ogg Vorbis?
- database - 将一个 Google Bigquery 数据库的内容移动到另一个 Bigquery 数据库