如何在 Kotlin 中使用与 Activity 和 Fragment 相同的 RecyclerView 适配器?
How to use the same RecyclerView adapter with Activity and Fragment in Kotlin?
我创建了一个完美运行的应用程序。我决定对我的应用程序进行一些更改,即在某些地方使用 Fragment
而不是 Activity
。 activity 中有一个 RecyclerView
,用于加载从 Firestore
中获取的数据。除了将使用 Fragment
而不是 Activity
.
之外,一切都将保持不变
现在我遇到的问题是 recyclerView
适配器需要上下文。
open class CargoListAdapter(
private val context: Context,
private var list: ArrayList<Cargo>
) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
单击按钮时,我必须检查上下文以采取相应的进一步操作。
holder.binding.ibDelete.setOnClickListener {
when (context) {
is OrderActivity -> {
val activity = holder.itemView.context as? OrderActivity
activity?.viewSpecialRequest(
model.custom_request
)
}
is MyOrderDetailsActivity -> {
val activity = holder.itemView.context as? MyOrderDetailsActivity
activity?.viewSpecialRequest(
model.custom_request
)
}
is CargoFragment -> {
val activity = holder.itemView.context as? CargoFragment
activity?.editDeleteSpecialRequestDialog(
holder.binding.ibEditDeleteNote,
holder.binding.ibAddNote,
model.id,
model.custom_request
)
}
}
}
这就是我在其中一项活动中打电话的方式。
val cargoListAdapter = CargoListAdapter(this@OrderActivity, mCargoList)
我尝试像下面这样从 fragment
调用,但我在 is CargoFragment -> {
看到错误“不兼容的类型:CargoFragment 和上下文”
val cargoListAdapter = CargoListAdapter(requireContext(), mCargoList)
编辑:
这不是问题的一部分,而是展示当 recyclerView
中有几个按钮时我做了什么,并根据单击哪个按钮采取行动。已采纳答案的评论区已经有人问过了
现在适配器 class 的 onClickItem
已根据我的要求更改。如您所见,我有 action:String
,这会让我知道单击了哪个按钮以及 function/action 需要进一步完成什么。
open class CargoListAdapter(
private val context: Context,
private var list: ArrayList<Cargo>,
private val onClickItem: (pos: Int,addButton: ImageButton,deleteButton: ImageButton,model: Cargo,action:String) -> Unit
) : RecyclerView.Adapter<RecyclerView.ViewHolder>()
在 onBindViewHolder
我有以下内容。
holder.binding.ibRemoveItem.setOnClickListener {
onClickItem(holder.adapterPosition,
holder.binding.ibAddNote,
holder.binding.ibDeleteNote,
model,
"removeItem")
}
每当单击一个按钮时,按钮 onClickListener
就会像上面那样设置,并且根据按钮我会更改 'action' 的值。如您所见,在上面的示例中,它是 'removeItem',因此从下面的代码中,将发生 'removeItem' 下的操作。
以下是我在 'CargoFragment'
中的内容
when (action) {
"DeleteNote" -> {
///TAKE SOME ACTION HERE
}
"AddNote" -> {
///TAKE SOME ACTION HERE
}
"removeItem" -> {
///TAKE SOME ACTION HERE
}
这就是我为处理 recyclerView
中有多个按钮的情况所做的工作,并且它没有任何缺陷。希望有高手给点意见,让新手知道可不可以照着做。
您检查上下文,然后将其转换为创建适配器的 activity 或片段,并且在您调用 activity/fragment 方法后 viewSpecialRequest
这不是很正确,如果您要在单击 ibDelete
后调用 activity/fragment 方法,您需要添加一个接口。
open class CargoListAdapter(
private val context: Context,
private var list: ArrayList<Cargo>
) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
interface OnItemActionsListener {
fun onDeleteClicked()
}
var onItemActionsListener:OnItemActionsListener? =null
holder.binding.ibDelete.setOnClickListener {
onItemActionsListener?.onDeleteClicked()
}
*********
}
}
订单活动
adapter = CargoListAdapter(this, arrayListOf())
adapter.onItemActionsListener = object : CargoListAdapter.OnItemActionsListener {
override fun onDeleteClicked() {
// TODO logic
}
}
CargoFragment
adapter = CargoListAdapter(requireActivity(), arrayListOf())
adapter.onItemActionsListener = object : CargoListAdapter.OnItemActionsListener {
override fun onDeleteClicked() {
// TODO logic
}
}
如果您需要在适配器中执行逻辑,而不是上下文检查,您可以使用枚举。
public enum DeleteCaseEnum {
NONE, CASE_1, CASE_2, CASE_3
}
open class CargoListAdapter(
private val context: Context,
private var list: ArrayList<Cargo>
) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
var deleteCase:DeleteCaseEnum = DeleteCaseEnum .NONE
holder.binding.ibDelete.setOnClickListener {
when (deleteCase) {
is DeleteCaseEnum.CASE_1-> {
// TODO
}
is DeleteCaseEnum.CASE_2-> {
// TODO
}
}
订单活动
adapter = CargoListAdapter(this, arrayListOf())
adapter.deleteCase = DeleteCaseEnum.CASE_1
CargoFragment
adapter = CargoListAdapter(requireActivity(), arrayListOf())
adapter.deleteCase = DeleteCaseEnum.CASE_2
您可以使用 Kotlin 高阶函数使适配器独立并在代码中的任何位置使用它,而不是使用接口并通过使用 Activity 或 Fragment 实例访问函数。
open class CargoListAdapter(
private val context: Context,
private var list: ArrayList<Cargo>,
private val onClickItem:(pos: Int, viewId: Int) -> Unit
) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
点击时在 ViewHolder 中调用 onClickItem :
holder.binding.ibDelete.setOnClickListener {
onClickItem(adapterPosition, it.id)
}
holder.binding.ibEdit.setOnClickListener {
onClickItem(adapterPosition, it.id)
}
在 Activity 或片段中:
adapter = CargoListAdapter(context, list){position, viewId->
//receive click here
when(viewId){
R.id.ibDelete -> //Delete Action
R.id.ibEdit -> //Delete Action
// You can use sam click listener for multiple views by passing id
}
}
查看此要点以获得完整的适配器示例:https://github.com/Noddy20/Gists/blob/master/RecyclerViewAdapter-1.kt
我创建了一个完美运行的应用程序。我决定对我的应用程序进行一些更改,即在某些地方使用 Fragment
而不是 Activity
。 activity 中有一个 RecyclerView
,用于加载从 Firestore
中获取的数据。除了将使用 Fragment
而不是 Activity
.
现在我遇到的问题是 recyclerView
适配器需要上下文。
open class CargoListAdapter(
private val context: Context,
private var list: ArrayList<Cargo>
) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
单击按钮时,我必须检查上下文以采取相应的进一步操作。
holder.binding.ibDelete.setOnClickListener {
when (context) {
is OrderActivity -> {
val activity = holder.itemView.context as? OrderActivity
activity?.viewSpecialRequest(
model.custom_request
)
}
is MyOrderDetailsActivity -> {
val activity = holder.itemView.context as? MyOrderDetailsActivity
activity?.viewSpecialRequest(
model.custom_request
)
}
is CargoFragment -> {
val activity = holder.itemView.context as? CargoFragment
activity?.editDeleteSpecialRequestDialog(
holder.binding.ibEditDeleteNote,
holder.binding.ibAddNote,
model.id,
model.custom_request
)
}
}
}
这就是我在其中一项活动中打电话的方式。
val cargoListAdapter = CargoListAdapter(this@OrderActivity, mCargoList)
我尝试像下面这样从 fragment
调用,但我在 is CargoFragment -> {
val cargoListAdapter = CargoListAdapter(requireContext(), mCargoList)
编辑:
这不是问题的一部分,而是展示当 recyclerView
中有几个按钮时我做了什么,并根据单击哪个按钮采取行动。已采纳答案的评论区已经有人问过了
现在适配器 class 的 onClickItem
已根据我的要求更改。如您所见,我有 action:String
,这会让我知道单击了哪个按钮以及 function/action 需要进一步完成什么。
open class CargoListAdapter(
private val context: Context,
private var list: ArrayList<Cargo>,
private val onClickItem: (pos: Int,addButton: ImageButton,deleteButton: ImageButton,model: Cargo,action:String) -> Unit
) : RecyclerView.Adapter<RecyclerView.ViewHolder>()
在 onBindViewHolder
我有以下内容。
holder.binding.ibRemoveItem.setOnClickListener {
onClickItem(holder.adapterPosition,
holder.binding.ibAddNote,
holder.binding.ibDeleteNote,
model,
"removeItem")
}
每当单击一个按钮时,按钮 onClickListener
就会像上面那样设置,并且根据按钮我会更改 'action' 的值。如您所见,在上面的示例中,它是 'removeItem',因此从下面的代码中,将发生 'removeItem' 下的操作。
以下是我在 'CargoFragment'
when (action) {
"DeleteNote" -> {
///TAKE SOME ACTION HERE
}
"AddNote" -> {
///TAKE SOME ACTION HERE
}
"removeItem" -> {
///TAKE SOME ACTION HERE
}
这就是我为处理 recyclerView
中有多个按钮的情况所做的工作,并且它没有任何缺陷。希望有高手给点意见,让新手知道可不可以照着做。
您检查上下文,然后将其转换为创建适配器的 activity 或片段,并且在您调用 activity/fragment 方法后 viewSpecialRequest
这不是很正确,如果您要在单击 ibDelete
后调用 activity/fragment 方法,您需要添加一个接口。
open class CargoListAdapter(
private val context: Context,
private var list: ArrayList<Cargo>
) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
interface OnItemActionsListener {
fun onDeleteClicked()
}
var onItemActionsListener:OnItemActionsListener? =null
holder.binding.ibDelete.setOnClickListener {
onItemActionsListener?.onDeleteClicked()
}
*********
}
}
订单活动
adapter = CargoListAdapter(this, arrayListOf())
adapter.onItemActionsListener = object : CargoListAdapter.OnItemActionsListener {
override fun onDeleteClicked() {
// TODO logic
}
}
CargoFragment
adapter = CargoListAdapter(requireActivity(), arrayListOf())
adapter.onItemActionsListener = object : CargoListAdapter.OnItemActionsListener {
override fun onDeleteClicked() {
// TODO logic
}
}
如果您需要在适配器中执行逻辑,而不是上下文检查,您可以使用枚举。
public enum DeleteCaseEnum {
NONE, CASE_1, CASE_2, CASE_3
}
open class CargoListAdapter(
private val context: Context,
private var list: ArrayList<Cargo>
) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
var deleteCase:DeleteCaseEnum = DeleteCaseEnum .NONE
holder.binding.ibDelete.setOnClickListener {
when (deleteCase) {
is DeleteCaseEnum.CASE_1-> {
// TODO
}
is DeleteCaseEnum.CASE_2-> {
// TODO
}
}
订单活动
adapter = CargoListAdapter(this, arrayListOf())
adapter.deleteCase = DeleteCaseEnum.CASE_1
CargoFragment
adapter = CargoListAdapter(requireActivity(), arrayListOf())
adapter.deleteCase = DeleteCaseEnum.CASE_2
您可以使用 Kotlin 高阶函数使适配器独立并在代码中的任何位置使用它,而不是使用接口并通过使用 Activity 或 Fragment 实例访问函数。
open class CargoListAdapter(
private val context: Context,
private var list: ArrayList<Cargo>,
private val onClickItem:(pos: Int, viewId: Int) -> Unit
) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
点击时在 ViewHolder 中调用 onClickItem :
holder.binding.ibDelete.setOnClickListener {
onClickItem(adapterPosition, it.id)
}
holder.binding.ibEdit.setOnClickListener {
onClickItem(adapterPosition, it.id)
}
在 Activity 或片段中:
adapter = CargoListAdapter(context, list){position, viewId->
//receive click here
when(viewId){
R.id.ibDelete -> //Delete Action
R.id.ibEdit -> //Delete Action
// You can use sam click listener for multiple views by passing id
}
}
查看此要点以获得完整的适配器示例:https://github.com/Noddy20/Gists/blob/master/RecyclerViewAdapter-1.kt