刷新后删除不更新RecyclerView的项目

时间:2019-05-14 22:52:32

标签: android kotlin android-recyclerview swiperefreshlayout

我已经实现了滑动操作以删除项目以及拉动刷新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()之后(以刷新数据刷新之前的方式)以删除的项目进行更新,但是结果如下。

enter image description here

1 个答案:

答案 0 :(得分:0)

我认为问题在于,当您再次拉动并刷新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列表即可。希望您能明白。