Home > Mobile >  How to set up OnClickListener with Button inside PopupDialog?
How to set up OnClickListener with Button inside PopupDialog?

Time:02-20

i want to make an youtube app where you paste a link and after clicking on a button video is added to recyclerView. The button is inside the PopupDialog and there is a EditText field too. So first of all i wanted to add pasted link to titlesList and added a toast so i can see if the button is working. The thing is, nothing happens. here is the preview of the app

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>

CodePudding user response:

You call addDataButton = findViewById(R.id.addButton) in MainActivity.onCreate(). But at this point, the dialog has not been created yet. (It won't get created until you call showDialog()). In order for findViewById() to locate the EditText, the dialog's layout needs to be inflated first.

Typically, each Dialog/Fragment/Activity takes care of inflating its own layout. However, you can inflate the layout in MainActivity.showDialog(), giving you the opportunity to attach your listeners, before you call setContentView() on the dialog.

example 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()
}

Note that we are dismissing the dialog in onPause() to avoid memory leaks.

Next, you'll probably want to create a custom RecyclerView Adapter with an addVideoUrl() method. Inside that method, after adding a new item to titles, you need to invoke notifyItemInserted() so that the RecyclerView knows to update the list.

  • Related