使用Groupie RecyclerView库和Kotlin删除项目后如何通知和更新列表

时间:2020-07-05 08:03:44

标签: java android kotlin android-recyclerview android-adapter

我有一个用Groupie库实现的RecyclerView,可以从列表中删除一个项目,但是需要更新视图才能看到更改。我想拥有类似notifyDataSetChanged()之类的东西,因此列表会立即更新。我在这个阶段有点困惑,尝试了几种不同的方法来从承载我的视图持有者的类中获取一个接口,该接口是从保存适配器的片段中触发的,但是我认为如果我能得到的话,我现在就陷入了困境请一些帮助。

class RecyclerProductItem(
private val activity: MainActivity,
private val product: Product, private val adapterListener: AdapterListener
) : Item<GroupieViewHolder>() {

companion object {
    var clickListener: AdapterListener? = null
}

override fun bind(viewHolder: GroupieViewHolder, position: Int) {

    viewHolder.apply {

        with(viewHolder.itemView) {

            clickListener = adapterListener

            ivTrash.setOnClickListener(object : View.OnClickListener {
                override fun onClick(v: View?) {
                    if (clickListener != null) {
                        Toast.makeText(context, "delete method to be added here", Toast.LENGTH_SHORT).show()
                        clickListener?.onClickItem(position)
                    } 
                }
            })

        }

    }
}

override fun getLayout() = R.layout.recyclerview_item_row

interface AdapterListener {
    fun onClickItem(position: Int)
}

}

这是我的片段。我试图在适配器中添加一个部分,以查看是否允许我为其检索一个侦听器,但是由于我的侦听器应在布局中的特定项下触发,因此这可能不是最佳解决方案,尽管无法也可以进行这项工作。

class ProductsListFragment : Fragment(), RecyclerProductItem.AdapterListener {

private lateinit var adapter: GroupAdapter<GroupieViewHolder>
private val section = Section()

override fun onCreateView(
    inflater: LayoutInflater,
    container: ViewGroup?,
    savedInstanceState: Bundle?
): View? {
    return inflater.inflate(R.layout.fragment_products_list, container, false)
}

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

    val linearLayoutManager = LinearLayoutManager(activity)
    recyclerView.layoutManager = linearLayoutManager

    adapter = GroupAdapter()

    adapter.add(section)


    recyclerView.adapter = adapter

    loadProducts()

}


private fun loadProducts() {

    GetProductsAPI.postData(object : GetProductsAPI.ThisCallback {

        override fun onSuccess(productList: List<JsonObject>) {

            for (jo in productList) {

                val gson = GsonBuilder().setPrettyPrinting().create()
                val product: Product =
                    gson.fromJson(jo, Product::class.java)

                adapter.add(
                    RecyclerProductItem(
                        activity as MainActivity,
                        Product(
                            product.id,
                            product.title,
                            product.description,
                            product.price
                        ),adapterListenerToBePassedHere 
                    )
                ) // This part is where I should be giving the listener, but get a red line since not sure how to get it to include it here.

            }

        }

    })

}


companion object {
    fun newInstance(): ProductsListFragment {
        return ProductsListFragment()
    }
}


override fun onClickItem(position: Int) {
    
    adapter.notifyItemRemoved(position)
}

}

非常感谢。

2 个答案:

答案 0 :(得分:2)

我认为您在追随者自述文件中缺少此概念:

以任何方式修改GroupAdapter的内容都会自动发送更改通知。添加项目调用notifyItemAdded();添加组会调用notifyItemRangeAdded()等。

因此,要删除项目,请致电section.remove(item)。但是,在onClickItem函数中,您当前仅通过该职位。像clickListener?.onClickItem(this@RecyclerProductItem)这样传递项目。 更理想和更安全的是,您应该使用product.id删除,例如clickListener?.onClickItem(this@RecyclerProductItem.product.id),然后在onClickItem()中搜索具有该产品ID的商品并将其删除。让我知道是否不清楚。

答案 1 :(得分:0)

根据@carson的回复,这对我有用。必须将项目添加到该部分中,然后将该部分添加到适配器中,然后在单击该侦听器之后根据适配器位置从该部分中删除该项目,并将实现该侦听器的方法作为完成GroupAdapter的参数之一。

class RecyclerProductItem(
private val activity: MainActivity,
private val product: Product, private val adapterListener: AdapterListener
) : Item<GroupieViewHolder>() {

companion object {
    var clickListener: AdapterListener? = null
}

override fun bind(viewHolder: GroupieViewHolder, position: Int) {

    viewHolder.apply {

        with(viewHolder.itemView) {

            tvTitle.text = product.title

            clickListener = adapterListener

            ivTrash.setOnClickListener(object : View.OnClickListener {
                override fun onClick(v: View?) {
                    if (clickListener != null) {
                        Toast.makeText(context, "delete method to be added here", Toast.LENGTH_SHORT).show()
                        clickListener?.onClickItem(this@RecyclerProductItem.product.id, adapterPosition)
                    }
                }
            })

        }

    }
}

override fun getLayout() = R.layout.recyclerview_item_row

interface AdapterListener {
    fun onClickItem(id: Int, position: Int)
}

}

private fun loadProducts() {

    GetProductsAPI.postData(object : GetProductsAPI.ThisCallback,
        RecyclerProductItem.AdapterListener {

        override fun onSuccess(productList: List<JsonObject>) {

            Log.i(LOG_TAG, "onSuccess $LOG_TAG")

            for (jo in productList) {

                val gson = GsonBuilder().setPrettyPrinting().create()
                val product: Product =
                    gson.fromJson(jo, Product::class.java)

                val linearLayoutManager = LinearLayoutManager(activity)
                recyclerView.layoutManager = linearLayoutManager

                adapter = GroupAdapter()
                section.add(
                    RecyclerProductItem(
                        activity as MainActivity,
                        Product(
                            product.id,
                            product.title,
                            product.description,
                            product.price
                        ), this
                    )
                ) 

                adapter.add(section)
                recyclerView.adapter = adapter
            }

        }

        override fun onFailure() {
            Log.e(LOG_TAG, "onFailure $LOG_TAG")
        }

        override fun onError() {
            Log.e(LOG_TAG, "onError $LOG_TAG")
        }

        override fun onClickItem(id: Int, position: Int) {
            section.remove(adapter.getItem(position))
        }

    })

}