如何使用 Groupie RecyclerView 库和 Kotlin 删除项目时通知和更新列表
How to notify and update list when item has been deleted using Groupie RecyclerView library and Kotlin
我有一个用 Groupie 库实现的 RecyclerView,我可以很好地从列表中删除一个项目,但是需要更新视图才能看到更改。我想要类似 notifyDataSetChanged() 的东西,所以列表会立即更新。虽然我在这个阶段有点困惑,但尝试了几种不同的方法从 class 获取一个接口,该接口承载我的视图持有者,以便从持有适配器的片段中触发,但我想我现在被卡住了如果我能得到一些帮助的话。
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)
}
}
非常感谢。
我认为您从追星族自述文件中遗漏了这个概念:
Modifying the contents of the GroupAdapter in any way automatically sends change notifications. Adding an item calls notifyItemAdded(); adding a group calls notifyItemRangeAdded(), etc.
所以要删除一个项目,请调用 section.remove(item)
。但是,在您的 onClickItem
函数中,您目前仅传递位置。改为传递 clickListener?.onClickItem(this@RecyclerProductItem)
之类的项目。
更理想和安全的是,您应该按 product.id
删除,例如clickListener?.onClickItem(this@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)
}
}
和
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))
}
})
}
我有一个用 Groupie 库实现的 RecyclerView,我可以很好地从列表中删除一个项目,但是需要更新视图才能看到更改。我想要类似 notifyDataSetChanged() 的东西,所以列表会立即更新。虽然我在这个阶段有点困惑,但尝试了几种不同的方法从 class 获取一个接口,该接口承载我的视图持有者,以便从持有适配器的片段中触发,但我想我现在被卡住了如果我能得到一些帮助的话。
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)
}
}
非常感谢。
我认为您从追星族自述文件中遗漏了这个概念:
Modifying the contents of the GroupAdapter in any way automatically sends change notifications. Adding an item calls notifyItemAdded(); adding a group calls notifyItemRangeAdded(), etc.
所以要删除一个项目,请调用 section.remove(item)
。但是,在您的 onClickItem
函数中,您目前仅传递位置。改为传递 clickListener?.onClickItem(this@RecyclerProductItem)
之类的项目。
更理想和安全的是,您应该按 product.id
删除,例如clickListener?.onClickItem(this@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)
}
}
和
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))
}
})
}