如何在 PopupDialog 中使用 Button 设置 OnClickListener?

How to set up OnClickListener with Button inside PopupDialog?

我想制作一个 youtube 应用程序,您可以在其中粘贴 link,然后在点击 button 视频后添加到 recyclerView。该按钮位于 PopupDialog 内,并且还有一个 EditText 字段。所以首先我想将粘贴的 link 添加到 titlesList 并添加一个 toast 以便我可以查看按钮是否正常工作。问题是,什么也没有发生。 here 是应用程序的预览

MainActivity.kt

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)

    val popupButton: FloatingActionButton = findViewById(R.id.fab)
    val bottomNav: BottomNavigationView = findViewById(R.id.bottomNavigationView)
    addDataButton = findViewById(R.id.addButton)

    bottomNav.background = null
    bottomNav.menu.findItem(R.id.placeholder).isEnabled = false

    replaceFragment(home)
    bottomNav.setOnItemSelectedListener {
        when (it.itemId) {
            R.id.home -> replaceFragment(home)
            R.id.player -> replaceFragment(player)
            R.id.profile -> replaceFragment(profile)
            R.id.settings -> replaceFragment(settings)
        }
        true
    }
    popupButton.setOnClickListener {
        showDialog()
    }

    addDataButton?.setOnClickListener {
        implementAdapterData()
    }
}

private fun replaceFragment(fragment: Fragment) {
    val transaction = supportFragmentManager.beginTransaction()
    transaction.replace(R.id.fragment_container, fragment)
    transaction.commit()
}

private fun showDialog() {
    val dialog = Dialog(this)
    dialog.setContentView(R.layout.popup)
    dialog.show()
}

private fun implementAdapterData() {
    val title = RecyclerAdapter().titles
    val editText: EditText = findViewById(R.id.plain_text_input)
    if (editText.text.isEmpty()) {
        Toast.makeText(applicationContext, "Empty field", Toast.LENGTH_SHORT).show()
    } else {
        title.add(editText.text.toString())
        Toast.makeText(applicationContext, "Added", Toast.LENGTH_SHORT).show()
    }
  }
}

RecycleAdapter.kt

open class RecyclerAdapter: RecyclerView.Adapter<RecyclerAdapter.ViewHolder>() {



public open var titles = mutableListOf(
    "Chapter one",
    "Chapter two",
    "Chapter three",
    "Chapter four",
    "Chapter five",
    "Chapter six",
    "Chapter seven",
    "Chapter eight",
    "Chapter nine",
    "Chapter ten",
    "Chapter eleven",
    "Chapter twelve",
    "Chapter thirteen",
    "Chapter fourteen",
    "Chapter fifteen",
    "Chapter sixteen")
private var details = mutableListOf(
    "Item one details",
    "Item two details",
    "Item three details",
    "Item four details",
    "Item five details",
    "Item six details",
    "Item seven details",
    "Item eight details",
    "Item nine details",
    "Item ten details",
    "Item eleven details",
    "Item twelve details",
    "Item thirteen details",
    "Item fourteen details",
    "Item fifteen details",
    "Item sixteen details",)
private var images = mutableListOf(
    R.drawable.samoyed,
    R.drawable.samoyed,
    R.drawable.samoyed,
    R.drawable.samoyed,
    R.drawable.samoyed,
    R.drawable.samoyed,
    R.drawable.samoyed,
    R.drawable.samoyed,
    R.drawable.samoyed,
    R.drawable.samoyed,
    R.drawable.samoyed,
    R.drawable.samoyed,
    R.drawable.samoyed,
    R.drawable.samoyed,
    R.drawable.samoyed,
    R.drawable.samoyed)
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
    val vi = LayoutInflater.from(parent.context).inflate(R.layout.card_layout, parent, false)
    return ViewHolder(vi)
}

override fun onBindViewHolder(holder: ViewHolder, position: Int) {
    holder.itemTitle.text = titles[position]
    holder.itemDetails.text = details[position]
    holder.itemImage.setImageResource(images[position])
}

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

inner class ViewHolder(itemView: View): RecyclerView.ViewHolder(itemView){
    var itemImage: ImageView
    var itemTitle: TextView
    var itemDetails: TextView
    init {
        itemImage = itemView.findViewById(R.id.tv_thumbnail)
        itemTitle = itemView.findViewById(R.id.tv_title)
        itemDetails = itemView.findViewById(R.id.tv_description)
    }
}

}

Popup.xml

 <?xml version="1.0" encoding="utf-8"?>
 <androidx.constraintlayout.widget.ConstraintLayout
 xmlns:android="http://schemas.android.com/apk/res/android"
 xmlns:app="http://schemas.android.com/apk/res-auto"
 android:layout_width="350dp"
 android:layout_height="350dp"
 android:layout_gravity="center"
 android:background="@drawable/cercle_backgoud">

   <ImageView
    android:id="@+id/imageView"
    android:layout_width="100dp"
    android:layout_height="100dp"
    android:layout_marginTop="36dp"
    android:contentDescription="@string/samoyed"
    android:src="@drawable/samoyed_popup"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="parent" />

   <TextView
    android:id="@+id/textView"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:fontFamily="@font/roboto_light_italic"
    android:gravity="center"
    android:text="@string/enter_youtube_video_link"
    android:textColor="@color/white"
    android:textSize="20sp"
    app:layout_constraintBottom_toTopOf="@+id/plain_text_input"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toBottomOf="@+id/imageView" />

  <EditText
    android:id="@+id/plain_text_input"
    android:layout_width="match_parent"
    android:layout_height="30dp"
    android:hint="@string/here_paste_the_link"
    android:inputType="text"
    android:minHeight="48dp"
    android:gravity="center"
    android:textColor="@color/white"
    android:textColorHint="@color/white"
    android:textSize="12sp"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="parent"
    app:layout_constraintVertical_bias="0.612"
    android:autofillHints=""
    />

  <Button
    android:id="@+id/button"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:fontFamily="@font/roboto_light_italic"
    android:text="@string/add"
    android:textColor="@color/white"
    android:textStyle="bold"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toBottomOf="@+id/plain_text_input"
    app:layout_constraintVertical_bias="0.26" />


</androidx.constraintlayout.widget.ConstraintLayout>

你打电话给addDataButton = findViewById(R.id.addButton)MainActivity.onCreate()。但是此时,对话框还没有创建。 (在您调用 showDialog() 之前,它不会被创建)。为了让 findViewById() 找到 EditText,对话框的布局需要先膨胀。

通常,每个 Dialog/Fragment/Activity 负责扩充自己的布局。但是,您 可以 在 MainActivity.showDialog() 中扩充布局,让您有机会在对话框中调用 setContentView() 之前附加您的听众。

示例MainActivity.kt:

var dialog:Dialog?=null

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)

    val popupButton: FloatingActionButton = findViewById(R.id.fab)
    val bottomNav: BottomNavigationView = findViewById(R.id.bottomNavigationView)
    addDataButton = findViewById(R.id.addButton)

    bottomNav.background = null
    bottomNav.menu.findItem(R.id.placeholder).isEnabled = false

    replaceFragment(home)
    bottomNav.setOnItemSelectedListener {
        when (it.itemId) {
            R.id.home -> replaceFragment(home)
            R.id.player -> replaceFragment(player)
            R.id.profile -> replaceFragment(profile)
            R.id.settings -> replaceFragment(settings)
        }
        true
    }
    popupButton.setOnClickListener {
        showDialog()
    }

    addDataButton?.setOnClickListener {
        implementAdapterData()
    }
}

private fun replaceFragment(fragment: Fragment) {
    val transaction = supportFragmentManager.beginTransaction()
    transaction.replace(R.id.fragment_container, fragment)
    transaction.commit()
}

private fun showDialog() {
    dialog = Dialog(this)
    val dialogView:View = d.layoutInflater.inflate(R.layout.popup, null)
        val editText = dialogView.findViewById<EditText>(R.id.plain_text_input)
        dialogView.findViewById<Button>(R.id.button)?.setOnClickListener {
            if (editText.text.isEmpty()) {
                Toast.makeText(applicationContext, "Empty field", Toast.LENGTH_SHORT).show()
            } else {
                // title.add(editText.text.toString())
                Toast.makeText(applicationContext, "Added", Toast.LENGTH_SHORT).show()
            }
        }
        d.setContentView(dialogView)
    dialog.show()
}

private fun implementAdapterData() {
    val title = RecyclerAdapter().titles
    val editText: EditText = findViewById(R.id.plain_text_input)
    if (editText.text.isEmpty()) {
        Toast.makeText(applicationContext, "Empty field", Toast.LENGTH_SHORT).show()
    } else {
        title.add(editText.text.toString())
        Toast.makeText(applicationContext, "Added", Toast.LENGTH_SHORT).show()
    }
  }
}

override fun onPause() {
  dialog?.dismiss()
  super.onPause()
}

请注意,我们正在关闭 onPause() 中的对话框以避免内存泄漏。

接下来,您可能想要使用 addVideoUrl() 方法创建自定义 RecyclerView 适配器。在该方法中,将新项目添加到标题后,您需要调用 notifyItemInserted() 以便 RecyclerView 知道更新列表。