I'm trying to inflate a custom dialog in my "CreateShoppingListMenuFragment" I've followed android's documentation but seem to be having a problem with the Listener, I know FragmentManager() is deprecated and used both parentFragmentManager & child FragmentManager to no success, maybe it's related?
Here is the error message:
logo1200.shoppinglist, PID: 24194
java.lang.ClassCastException: com.camilogo1200.shoppinglist.presentation.MainActivity@11852bbmust implement ShoppingListNameRequestListener
at com.camilogo1200.shoppinglist.presentation.fragments.ShoppingListNameRequestDialog.onAttach(ShoppinListNameRequestDialog.kt:68)
at androidx.fragment.app.Fragment.performAttach(Fragment.java:2922)
at androidx.fragment.app.FragmentStateManager.attach(FragmentStateManager.java:464)
at androidx.fragment.app.FragmentStateManager.moveToExpectedState(FragmentStateManager.java:275)
at androidx.fragment.app.FragmentManager.executeOpsTogether(FragmentManager.java:2189)
This is my DialogFragment:
class ShoppingListNameRequestDialog : DialogFragment() {
private lateinit var listener: ShoppingListNameRequestListener
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
return activity?.let {
val builder = AlertDialog.Builder(it)
val inflater: LayoutInflater = requireActivity().layoutInflater
val requestNameView = inflater.inflate(R.layout.shopping_list_name_request_dialog, null)
val nameInput = requestNameView.findViewById<TextView>(R.id.shopping_list_dialog_input)
var listName = ""
builder.setView(requestNameView)
.setPositiveButton(R.string.save_shopping_list,
DialogInterface.OnClickListener {dialog, id ->
if(nameInput.text.toString() != "")
listName = nameInput.text.toString()
listener.onDialogPositiveClick(this,listName);
})
.setNegativeButton(R.string.cancel,
DialogInterface.OnClickListener{dialog, id ->
listener.onDialogNegativeClick(this)
})
builder.create()
} ?: throw IllegalStateException("Activity cannot be null")
}
interface ShoppingListNameRequestListener {
fun onDialogPositiveClick(dialog: DialogFragment,listName:String)
fun onDialogNegativeClick(dialog: DialogFragment)
}
override fun onAttach(context: Context) {
super.onAttach(context)
try {
listener = context as ShoppingListNameRequestListener
} catch (e: ClassCastException) {
throw ClassCastException((context.toString() +
"must implement ShoppingListNameRequestListener"))
}
}
This is my "CreateShoppingListMenuFragment" (the host fragment where I'm inflating the dialog):
class CreateShoppingListMenuFragment : Fragment(),
ShoppingListNameRequestDialog.ShoppingListNameRequestListener {
private lateinit var binding: FragmentCreateShoppingListMenuBinding
private val viewModel: CreateShoppingListMenuViewModel by activityViewModels()
private val args: CreateShoppingListMenuFragmentArgs by navArgs()
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View {
binding = DataBindingUtil.inflate(
layoutInflater,
R.layout.fragment_create_shopping_list_menu,
container,
false
)
binding.lifecycleOwner = this
viewModel.createItems()
viewModel.viewState.observe(viewLifecycleOwner, ::handleViewState)
val login = args.ownerName
val listId = args.listId
viewModel.setOwnerAndList(login, listId)
binding.createItemButton.setOnClickListener {
val directionToFragment =
CreateShoppingListMenuFragmentDirections.actionCreateShoppingListMenuFragmentToCreateItemMenuFragment(
login,
listId
)
Navigation.findNavController(binding.root).navigate(directionToFragment)
}
binding.completeShoppingListButton.setOnClickListener {
showNoticeDialog()
}
return binding.root
}
private fun showNoticeDialog() {
val dialog = ShoppingListNameRequestDialog()
dialog.show(parentFragmentManager, "ShoppingListNameRequestDialog")
}
override fun onDialogPositiveClick(dialog: DialogFragment,listName: String) {
val result = viewModel.saveShoppingList(listName)
Log.i("shoppingListResult", "$result")
// travel to final fragment sent shoppinglist as arg
}
override fun onDialogNegativeClick(dialog: DialogFragment) {
// User touched the dialog's negative button
}
private fun handleViewState(viewState: CreateShoppingListMenuViewState) {
when (viewState) {
is CreateShoppingListMenuViewState.ErrorViewState -> showError(viewState.exception as ShoppingException)
//is RegisterViewState.SuccessViewState ->showSuccess()
else -> showSuccess(viewState)
}
}
private fun showSuccess(viewState: CreateShoppingListMenuViewState) {
val receivedList = viewState as CreateShoppingListMenuViewState.SuccessViewState
val dataList = receivedList.data
val adapter = ShoppingListMenuAdapter(dataList, viewModel::changeItemCount)
binding.itemListArray.adapter = adapter
}
private fun showError(exception: ShoppingException) {
if (exception.idError as? ItemError == ItemError.NO_ITEMS_CREATED) {
val message = getString(R.string.no_items_created_error_messages)
Toast.makeText(activity, message, Toast.LENGTH_LONG).show()
}
Any help would be greatly appreciated!