Java 如何使用Groupie RecyclerView库和Kotlin在项目被删除时通知和更新列表

Java 如何使用Groupie RecyclerView库和Kotlin在项目被删除时通知和更新列表,java,android,kotlin,android-recyclerview,android-adapter,Java,Android,Kotlin,Android Recyclerview,Android Adapter,我用Groupie库实现了一个RecyclerView,我可以从列表中删除一个项目,但是需要更新视图才能看到更改。我想改为更改类似NotifyDataSetChange的内容,以便列表立即更新。在这个阶段我有点困惑,尝试了几种不同的方法从承载我的视图持有者的类中获取一个接口,该接口将从保存适配器的片段中触发,但我想如果我能得到一些帮助,我现在就卡住了 class RecyclerProductItem( private val activity: MainActivity, private va

我用Groupie库实现了一个RecyclerView,我可以从列表中删除一个项目,但是需要更新视图才能看到更改。我想改为更改类似NotifyDataSetChange的内容,以便列表立即更新。在这个阶段我有点困惑,尝试了几种不同的方法从承载我的视图持有者的类中获取一个接口,该接口将从保存适配器的片段中触发,但我想如果我能得到一些帮助,我现在就卡住了

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)
}

}

非常感谢。

我想你在groupie自述中遗漏了这个概念:

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

因此,要删除项目,请调用section.removietem。但是,在onClickItem函数中,您当前只传递该位置。像clickListener?一样传递项目?。onClickItemthis@RecyclerProductItem相反
更理想、更安全的是,您应该按product.id删除,例如clickListener?。onClickItemthis@RecyclerProductItem.product.id然后在onClickItem中,您只需搜索具有该产品id的项目并将其删除。如果我不清楚,请告诉我。

我想你在groupie自述中遗漏了这个概念:

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

因此,要删除项目,请调用section.removietem。但是,在onClickItem函数中,您当前只传递该位置。像clickListener?一样传递项目?。onClickItemthis@RecyclerProductItem相反
更理想、更安全的是,您应该按product.id删除,例如clickListener?。onClickItemthis@RecyclerProductItem.product.id然后在onClickItem中,您只需搜索具有该产品id的项目并将其删除。如果我不清楚,请告诉我。

根据@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)
}

}


根据@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)
}

}


我认为这太复杂了,因为可以调用适配器上的方法。例如:viewHolder中是否缺少getLayout函数?你们不应该添加到你们添加到适配器的部分,而不是适配器本身吗?嗨,不。我没有添加它是为了删除与我面临的问题没有直接关系的代码,所以这里的代码被缩短了。如果这样可以避免混淆的话,我会把它放回去。我认为这太复杂了,因为可以在适配器上调用方法。例如:viewHolder中是否缺少getLayout函数?你们不应该添加到你们添加到适配器的部分,而不是适配器本身吗?嗨,不。我没有添加它是为了删除与我面临的问题没有直接关系的代码,所以这里的代码被缩短了。如果这样可以避免混淆的话,我会把它放回去。Groupie库的卓越之处在于它的功能性/声明性方法。您的组适配器在一个地方有状态,您不需要担心notifyItemRemoved之类的事情,因为它为您抽象了所有复杂的代码。谢谢@Carson。谢谢你的答复。稍后我需要回到这一点上,但我会让你知道是否可以根据你的建议使用它。Groupie库的卓越之处在于它的功能性/声明性方法。您的组适配器在一个地方有状态,您不需要担心notifyItemRemoved之类的事情,因为它为您抽象了所有复杂的代码。谢谢@Carson。谢谢你的答复。我需要稍后再讨论这个问题,但我会让你们知道,你们的建议是否可行。好吧,我没意识到groupie依赖于位置来删除。您可能不再需要传递产品id,只需要传递位置。对不起。不用担心!是的,我想我注意到它可能在没有id的情况下仍然可以工作,但只是没有时间删除它并仔细检查它。再次感谢你们的帮助。好吧,我不知道groupie依赖于位置来删除。你可能不需要
d再传递产品id,只是位置对不起,不用担心!是的,我想我注意到它可能在没有id的情况下仍然可以工作,但只是没有时间删除它并仔细检查它。再次感谢你的帮助。