Java 如何使用Groupie RecyclerView库和Kotlin在项目被删除时通知和更新列表
我用Groupie库实现了一个RecyclerView,我可以从列表中删除一个项目,但是需要更新视图才能看到更改。我想改为更改类似NotifyDataSetChange的内容,以便列表立即更新。在这个阶段我有点困惑,尝试了几种不同的方法从承载我的视图持有者的类中获取一个接口,该接口将从保存适配器的片段中触发,但我想如果我能得到一些帮助,我现在就卡住了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
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的情况下仍然可以工作,但只是没有时间删除它并仔细检查它。再次感谢你的帮助。