zawadz88 / MaterialPopupMenu

Shows Material popup menus grouped in sections & more
Apache License 2.0
646 stars 57 forks source link

Make it possible to dismiss popup from viewBoundCallback #57

Closed Tunous closed 5 years ago

Tunous commented 5 years ago

Use case

I want to be able to dismiss popup when user performs action on a custom item's view.

Current solution

Impossible?

Implemented solution

When building custom item it is now possible to set viewBoundCallback to an instance of ViewBoundCallback class instead of a regular closure, which then allows user to access dismissPopup function.

section {
  item {
    viewBoundCallback = ViewBoundCallback {
      val someView = it.findViewById(R.id.some_view)
      someView.setOnClickListener {
        dismissPopup()
      }
    }
  }
}

Sample

Here sample has been modified to dismiss the popup when only when checkbox gets checked.

zawadz88 commented 5 years ago

Thanks for the changes! I'll try to have a look on Monday and get back to you.

zawadz88 commented 5 years ago

Hi @Tunous, I've checked and it is actually possible to achieve the effect you presented with the following lines of code:

        var popupMenu by Delegates.notNull<MaterialPopupMenu>()
        popupMenu = popupMenu {
            dropdownGravity = Gravity.END
            section {
                customItem {
                    layoutResId = R.layout.view_custom_item_checkable
                    viewBoundCallback = { view ->
                        val checkBox: CheckBox = view.findViewById(R.id.customItemCheckbox)
                        checkBox.isChecked = true
                        checkBox.setOnCheckedChangeListener { _, isChecked ->
                            if (isChecked) {
                                popupMenu.dismiss()
                            }
                        }
                    }
                    callback = {
                        Toast.makeText(this@LightActivity, "Disabled!", Toast.LENGTH_SHORT).show()
                    }
                }
            }
        }

        popupMenu.show(this@LightActivity, view)

MaterialPopupMenu has a dismiss() method you can use.

Tunous commented 5 years ago

Hmm, true didn't think of that way. But it feels more like a hack than a real solution because you have to create a variable that is initialized later. With that I can't isolate the code that creates the pop-up from the code which shows it, as I have to somehow send the pop-up to builder code...

zawadz88 commented 5 years ago

it feels more like a hack than a real solution because you have to create a variable that is initialized later.

Kinda feels this way although using Delegates.notNull sometimes can be useful if all else fails.

With that I can't isolate the code that creates the pop-up from the code which shows it, as I have to somehow send the pop-up to builder code...

That's a very good point.