滑动刷新后删除项目不更新 RecyclerView
Remove Item Not Updating RecyclerView After Swipe Refresh
我在 RecyclerView
中实现了滑动删除项目以及拉动刷新项目。删除按预期工作,直到我执行拉动刷新。拉动刷新后,当我执行删除时,回收站视图似乎没有响应 notifyItemRemoved
.
我也试过 notifyDataSetChanged
结果相同。
正在检索和更新数据:
private fun callForEarthquakeData() {
swipe_refresh.isRefreshing = true
earthquakeApiEndpoint.getEarthquakes()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribeBy(::errorOnGetEarthquakes, ::successOnGetEarthquakes)
}
在成功调用数据后设置RecyclerView
:
private fun successOnGetEarthquakes(it: EarthquakeFeed) {
swipe_refresh.isRefreshing = false
rvEarthQuakes.layoutManager = LinearLayoutManager(this)
adapter = AdapterEarthquake(this, it.features.toMutableList())
rvEarthQuakes.adapter = adapter
val dragDirs = ItemTouchHelper.UP or ItemTouchHelper.DOWN
val recyclerItemTouchHelper = RecyclerItemTouchHelper(dragDirs, adapter)
val itemTouchHelper = ItemTouchHelper(recyclerItemTouchHelper)
itemTouchHelper.attachToRecyclerView(rvEarthQuakes)
}
滑动刷新布局以检索数据的侦听器:
swipe_refresh.setOnRefreshListener { callForEarthquakeData() }
完整适配器代码:
class AdapterEarthquake(private val context: Context, private val items: MutableList<Feature>)
: RecyclerView.Adapter<RecyclerView.ViewHolder>(), ItemTouchHelperAdapter {
private val sdf = SimpleDateFormat(context.getString(R.string.earthquake_date_format), Locale.US)
override fun onItemMove(fromPosition: Int, toPosition: Int): Boolean {
Collections.swap(items, fromPosition, toPosition)
notifyItemMoved(fromPosition, toPosition)
return true
}
override fun onItemDismiss(position: Int) {
items.removeAt(position)
notifyDataSetChanged()
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder =
ViewHolder(LayoutInflater.from(parent.context)
.inflate(R.layout.quake_list_item, parent, false))
override fun getItemCount(): Int = items.size
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
val viewHolder = holder as ViewHolder
val item = items[position]
val formattedLocalDateTime = sdf.format(item.properties.time)
val formattedCoordinates = item.geometry.coordinates.let { "[${it[0]}, ${it[1]}, ${it[2]}]" }
viewHolder.title.text = item.properties.title
viewHolder.date.text = formattedLocalDateTime
viewHolder.coordinates.text = formattedCoordinates
when {
item.properties.magnitude >= 7 -> viewHolder.itemView.setBackgroundColor(Color.RED)
item.properties.magnitude >= 5 -> viewHolder.itemView.setBackgroundColor(ContextCompat.getColor(context, R.color.lightRed))
else -> viewHolder.itemView.setBackgroundColor(Color.WHITE)
}
}
inner class ViewHolder(view: View) : RecyclerView.ViewHolder(view) {
init {
view.setOnClickListener {
context.startActivity(Intent(
Intent.ACTION_VIEW, Uri.parse(items[adapterPosition].properties.detailsUrl)))
}
}
val title = view.quake_title!!
val coordinates = view.quake_coordinates!!
val date = view.quake_date!!
}
}
我希望 RecyclerView
在调用 notifyDataSetChanged()
后用删除的项目进行更新(就像在刷卡数据刷新之前所做的那样),但结果如下。
我认为问题出在您再次拉动并刷新 RecyclerView
时设置新项目的位置。在 successOnGetEarthquakes
方法中,每次从服务器获取数据时都会初始化一个新的适配器。
您可以只更改传递给适配器的列表并在您的适配器上调用 notifyDataSetChanged()
。我只是在 Java 中提出了一些伪代码。希望对您有所帮助!
private fun successOnGetEarthquakes(it: EarthquakeFeed) {
swipe_refresh.isRefreshing = false
rvEarthQuakes.layoutManager = LinearLayoutManager(this)
// Just feed the list, do not create a new adapter
if(adapter != null) {
adapter = AdapterEarthquake(this, it.features.toMutableList())
rvEarthQuakes.adapter = adapter
}
else adapter.setItemsList(it.features.toMutableList())
// Call the notifyDataSetChanged here
adapter.notifyDataSetChanged()
val dragDirs = ItemTouchHelper.UP or ItemTouchHelper.DOWN
val recyclerItemTouchHelper = RecyclerItemTouchHelper(dragDirs, adapter)
val itemTouchHelper = ItemTouchHelper(recyclerItemTouchHelper)
itemTouchHelper.attachToRecyclerView(rvEarthQuakes)
}
因此在您的适配器中创建一个新函数,它只更改 items
列表。我希望你明白了。
我在 RecyclerView
中实现了滑动删除项目以及拉动刷新项目。删除按预期工作,直到我执行拉动刷新。拉动刷新后,当我执行删除时,回收站视图似乎没有响应 notifyItemRemoved
.
我也试过 notifyDataSetChanged
结果相同。
正在检索和更新数据:
private fun callForEarthquakeData() {
swipe_refresh.isRefreshing = true
earthquakeApiEndpoint.getEarthquakes()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribeBy(::errorOnGetEarthquakes, ::successOnGetEarthquakes)
}
在成功调用数据后设置RecyclerView
:
private fun successOnGetEarthquakes(it: EarthquakeFeed) {
swipe_refresh.isRefreshing = false
rvEarthQuakes.layoutManager = LinearLayoutManager(this)
adapter = AdapterEarthquake(this, it.features.toMutableList())
rvEarthQuakes.adapter = adapter
val dragDirs = ItemTouchHelper.UP or ItemTouchHelper.DOWN
val recyclerItemTouchHelper = RecyclerItemTouchHelper(dragDirs, adapter)
val itemTouchHelper = ItemTouchHelper(recyclerItemTouchHelper)
itemTouchHelper.attachToRecyclerView(rvEarthQuakes)
}
滑动刷新布局以检索数据的侦听器:
swipe_refresh.setOnRefreshListener { callForEarthquakeData() }
完整适配器代码:
class AdapterEarthquake(private val context: Context, private val items: MutableList<Feature>)
: RecyclerView.Adapter<RecyclerView.ViewHolder>(), ItemTouchHelperAdapter {
private val sdf = SimpleDateFormat(context.getString(R.string.earthquake_date_format), Locale.US)
override fun onItemMove(fromPosition: Int, toPosition: Int): Boolean {
Collections.swap(items, fromPosition, toPosition)
notifyItemMoved(fromPosition, toPosition)
return true
}
override fun onItemDismiss(position: Int) {
items.removeAt(position)
notifyDataSetChanged()
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder =
ViewHolder(LayoutInflater.from(parent.context)
.inflate(R.layout.quake_list_item, parent, false))
override fun getItemCount(): Int = items.size
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
val viewHolder = holder as ViewHolder
val item = items[position]
val formattedLocalDateTime = sdf.format(item.properties.time)
val formattedCoordinates = item.geometry.coordinates.let { "[${it[0]}, ${it[1]}, ${it[2]}]" }
viewHolder.title.text = item.properties.title
viewHolder.date.text = formattedLocalDateTime
viewHolder.coordinates.text = formattedCoordinates
when {
item.properties.magnitude >= 7 -> viewHolder.itemView.setBackgroundColor(Color.RED)
item.properties.magnitude >= 5 -> viewHolder.itemView.setBackgroundColor(ContextCompat.getColor(context, R.color.lightRed))
else -> viewHolder.itemView.setBackgroundColor(Color.WHITE)
}
}
inner class ViewHolder(view: View) : RecyclerView.ViewHolder(view) {
init {
view.setOnClickListener {
context.startActivity(Intent(
Intent.ACTION_VIEW, Uri.parse(items[adapterPosition].properties.detailsUrl)))
}
}
val title = view.quake_title!!
val coordinates = view.quake_coordinates!!
val date = view.quake_date!!
}
}
我希望 RecyclerView
在调用 notifyDataSetChanged()
后用删除的项目进行更新(就像在刷卡数据刷新之前所做的那样),但结果如下。
我认为问题出在您再次拉动并刷新 RecyclerView
时设置新项目的位置。在 successOnGetEarthquakes
方法中,每次从服务器获取数据时都会初始化一个新的适配器。
您可以只更改传递给适配器的列表并在您的适配器上调用 notifyDataSetChanged()
。我只是在 Java 中提出了一些伪代码。希望对您有所帮助!
private fun successOnGetEarthquakes(it: EarthquakeFeed) {
swipe_refresh.isRefreshing = false
rvEarthQuakes.layoutManager = LinearLayoutManager(this)
// Just feed the list, do not create a new adapter
if(adapter != null) {
adapter = AdapterEarthquake(this, it.features.toMutableList())
rvEarthQuakes.adapter = adapter
}
else adapter.setItemsList(it.features.toMutableList())
// Call the notifyDataSetChanged here
adapter.notifyDataSetChanged()
val dragDirs = ItemTouchHelper.UP or ItemTouchHelper.DOWN
val recyclerItemTouchHelper = RecyclerItemTouchHelper(dragDirs, adapter)
val itemTouchHelper = ItemTouchHelper(recyclerItemTouchHelper)
itemTouchHelper.attachToRecyclerView(rvEarthQuakes)
}
因此在您的适配器中创建一个新函数,它只更改 items
列表。我希望你明白了。