【问题标题】:How to use a variable outside function onBindViewHolder declared inside it?如何使用在函数内部声明的 onBindViewHolder 外部变量?
【发布时间】:2020-10-20 03:16:21
【问题描述】:

我正在 kotlin 中创建一个基本的 ToDo 列表应用程序,并将其数据存储在 SQLiteDatabase 中。我正在尝试添加滑动以删除功能。该功能有效,但我无法将任务的 ID 传递给删除功能。我可以在上面的 onCreate 类中使用 DisplayAdapter 中的 list[p1].id 吗?

显示适配器:

class DashboardAdapter(private val activity: dashboard, var list: MutableList<ToDo>) :
        RecyclerView.Adapter<DashboardAdapter.ViewHolder>(){


        override fun onCreateViewHolder(p0: ViewGroup, p1: Int): ViewHolder {
            return ViewHolder(LayoutInflater.from(activity).inflate(R.layout.rv_child_layout,p0,false))

        }
        override fun onBindViewHolder(holder: ViewHolder, p1: Int) {
            holder.toDoName.text = list[p1].name
            holder.toDoName.setOnClickListener{
                val id_long = list[p1].id
                val intent = Intent(activity,subtask_list::class.java)
                intent.putExtra(INTENT_TODO_ID,id_long)
                intent.putExtra(INTENT_TODO_NAME,list[p1].name)
                activity.startActivity(intent)
            }

        }

        override fun getItemCount(): Int {
            return list.size
        }


        fun removeItem(todoId: Long) {
            val db = DBHandler(null).db
            db.delete(TABLE_TODO_ITEM,"$COL_TODO_ID=?", arrayOf(todoId.toString()))
            db.delete(TABLE_TODO,"$COL_ID=?", arrayOf(todoId.toString()))
        }

        class ViewHolder(v : View) : RecyclerView.ViewHolder(v){
            val toDoName : TextView = v.findViewById(R.id.tv_todo_name)
        }

    }

removeItem 是需要 list.id 的删除功能

调用 removeItem 函数:

val itemTouchHelperCallback = object : ItemTouchHelper.SimpleCallback(0,ItemTouchHelper.LEFT){
            override fun onMove(
                recyclerView: RecyclerView,
                viewHolder: RecyclerView.ViewHolder,
                target: RecyclerView.ViewHolder
            ): Boolean {
                return false
            }

            override fun onSwiped(viewHolder: RecyclerView.ViewHolder, position: Int) {
                DashboardAdapter(dashboard(),dataset).removeItem(list[p1].id)
            }

        }
        val itemTouchHelper = ItemTouchHelper(itemTouchHelperCallback)
        itemTouchHelper.attachToRecyclerView(rv_dashboard)

我尝试过声明但不明白如何初始化以下内容:

private var dataset= mutableListOf<ToDo>()

    lateinit var list: MutableList<ToDo>

我在 displayAdapter 之外还有一个 refreshList 函数,用于在更新后刷新 ToDo 列表:

private fun refreshList(){
        rv_dashboard.adapter  = DashboardAdapter(this,dbHandler.getToDo())
    }

如何初始化列表变量或从显示适配器获取列表[p1].id?

【问题讨论】:

    标签: android android-studio kotlin android-recyclerview


    【解决方案1】:

    有很多方法可以解决这个问题。我建议您不要在您的适配器中执行您的数据库和导航逻辑,而是为项目单击实现一个侦听器并在片段/活动中编写您的数据库逻辑(最好在您的 ViewModel 中有逻辑)。我已经重构了你的代码。

    适配器:

    class DashboardAdapter(
        private var list: MutableList<ToDo>,
        private val itemClickListener: (Long) -> Unit,
    ) : RecyclerView.Adapter<DashboardAdapter.ViewHolder>() {
    
        override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
            return ViewHolder.create(parent, itemClickListener)
        }
    
        override fun onBindViewHolder(viewHolder: ViewHolder, position: Int) {
            viewHolder.bind(list[position])
        }
    
        override fun getItemCount() = list.size
    
        fun refreshList(list: List<Todo>) {
            this.list = list
            notifyDataSetChanged()
        }
    
        fun removeItemAt(position: Int) {
            list.removeAt(position)
            notifyItemRemoved(position)
        }
    
        class ViewHolder private constructor(
            v: View,
            private val itemClickListener: (Long) -> Unit,
        ) : RecyclerView.ViewHolder(v) {
            private val toDoName: TextView = v.findViewById(R.id.tv_todo_name)
    
            fun bind(todo: ToDo) {
                toDoName.text = todo.name
                toDoName.setOnClickListener {
                    itemClickListener.invoke(todo.id)
                }
            }
    
            companion object {
                fun create(parent: ViewGroup, itemClickListener: (Long) -> Unit): ViewHolder {
                    val view = LayoutInflater.from(parent.context).inflate(R.layout.rv_child_layout, parent, false)
                    return ViewHolder(view, itemClickListener)
                }
            }
        }
    }
    

    片段/活动:

    private lateinit var listAdapter: DashboardAdapter
    
    fun setupRecyclerView() {
        ...
    
        listAdapter = DashboardAdapter(list) { id: Long ->
            // Navigate to sub list task activity
        }
    
        rv_dashboard.adapter = listAdapter
    
        val swipeCallback = object : ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.LEFT) {
            override fun onMove(
                recyclerView: RecyclerView,
                viewHolder: RecyclerView.ViewHolder,
                target: RecyclerView.ViewHolder,
            ): Boolean {
                return false
            }
    
            override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) {
                val position = viewHolder.adapterPosition
    
                //Get id from list and delete from database
    
                listAdapter.removeItemAt(position)
            }
        }
    
        val itemTouchHelper = ItemTouchHelper(swipeCallback)
        itemTouchHelper.attachToRecyclerView(rv_dashboard)
    }
    

    要刷新您的列表,请调用适配器中的 refreshList 函数:

    listAdapter.refreshList(list)
    

    【讨论】:

    • DisplayAdapter 外的 refreshList 函数中的 itemClickListener 参数是什么?
    • 什么refreshList函数??
    • 我在DisplayAdapter外有一个函数可以刷新ToDo列表:private fun refreshList(){ rv_dashboard.adapter = DashboardAdapter(dbHandler.getToDo()) }
    • 在您的问题中发布您的 refreshList。我会相应地更新我的答案。
    • 已更新我的答案。您无需重新创建适配器即可刷新列表。
    猜你喜欢
    • 1970-01-01
    • 2019-02-08
    • 2023-04-03
    • 2019-09-23
    • 2012-07-07
    • 2021-08-08
    • 1970-01-01
    • 2014-01-17
    • 2015-02-10
    相关资源
    最近更新 更多