Kotlin:如何从适配器 class 中调用 DialogFragment?

Kotlin: How do I call a DialogFragment from within an Adapter class?

我有一个 MainAdapter.kt class 来处理 RecyclerView。在其 Holder class 中,我使用调用函数 deleteCategory(categoryId) 的 OnLongClickListener 来删除我的 Firebase 数据库中的条目。这非常有效:

class CategoryHolder(val customView: View, var category: Category? = null) : RecyclerView.ViewHolder(customView) {
    private val TAG = CategoryHolder::class.java.simpleName

    fun bind(category: Category) {
        with(category) {
            customView.textView_name?.text = category.name
            customView.textView_description?.text = category.description

            val categoryId = category.id

            customView.setOnClickListener {
                    // do something
            }

            customView.setOnLongClickListener(
                    {
                       deleteCategory(categoryId)
                       true
                    }
            )
        }
    }

    private fun deleteCategory(categoryId: String) {
        val database = FirebaseDatabase.getInstance()

        val myRef = database.getReference("categories").child(categoryId)
        myRef.removeValue()
        Log.d(TAG, "Category with id " + categoryId + " deleted")
    }
}

但我更想在 DialogFragment class 中调用函数而不是 deleteCategory(id) 函数,如下所示:

  // Create an instance of a DeleteCategoryDialogFragment and show it
  fun showDeleteCategoryDialog(view: View, categoryId: String) {
      val dialog = DeleteCategoryDialogFragment.newInstance(categoryId)
      dialog.show(this@MainActivity.supportFragmentManager, 
      "DeleteCategoryDialog")
  }

这给了我一个 "Unresolved reference: @MainActivity" 错误。 我该如何解决这个问题?有没有办法在我的 MainActivity 中获取 categoryId(String 类型)?这将允许我将函数 showDeleteCategoryDialog 移动到 MainActivity 并解决问题。

我的建议是创建对此操作的回调并在您的 MainActivity 上实现此回调并直接在您的 activity 上创建对话框。

interface ClickListener {
    fun onLongClickListener(categoryId: Int)
}

然后

class CategoryHolder(val customView: View, var category: Category? = null, var mListener: ClickListener?)

...
customView.setOnLongClickListener({
      mListener?.onLongClickListener(categoryId)
      ...
}

在您的 MainActivity 上:

 class MainActivity : AppCompatActivity, ClickListener {

    override fun onLongClickListener(categoryId: Int) {
     // Create your dialog
    }


    ...
        /* when creating your adapter you need to pass the listener to
         * adapter, so it can be used on your viewholder
         * mElements are the category elements, 'this' is the impl of
         * the adapter that was implemented here
        */
        mAdapter = CategoryAdapter(mElements, this)
 }

在您的适配器上:

class CategoryAdapter(var mElements: List<Category>, var mListener: ClickListener) : RecyclerView.Adapter<> ...

     // When creating your viewHolder
    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CategoryHolder {
        return CategoryHolder(LayoutInflater.from(parent.context) 
            .inflate(R.layout.category_row, parent, false), listener)
}

您不能像上面的代码那样引用您的 MainActivity。在使用它之前,您必须将 ViewHoldercontext 转换为 MainActivity

val activity =  itemView.context as? MainActivity
// then you can show your dialog with activity?.supportFragmentManager

这里是解决这个问题的详细信息:

  1. 在class类别持有人中

    customView.setOnLongClickListener(
        {
          showDeleteCategoryDialog(it, categoryId)
          true
        } 
    )
    
  2. 在函数 showDeleteCategoryDialog

    // Create an instance of a DeleteCategoryDialogFragment and show it
    fun showDeleteCategoryDialog(view: View, categoryId: String) {
        val activity = itemView.context as? MainActivity
        val dialog = DeleteCategoryDialogFragment.newInstance(categoryId)
        dialog.show(activity?.supportFragmentManager, "DeleteCategoryDialog")
    }