In my Android App, I have navigation drawer activity as the MainActivity
.
And I do not intend to do any tasks in the MainActivity
other than navigation, I want to keep it simple and use Fragments
for my tasks.
So I have a Fragment
which calls a DialogFragment
, the DialogFragment
passes back events to the Fragment
. My implementation is similar to the code given here in the docs.
But, my app crashes when the dialog is needed to appear.
This is my DialogFragment
:
class DialogSubjectsProgress: DialogFragment() {
internal lateinit var listener: TheDialogListener
interface TheDialogListener {
fun onDialogCancel(dialog: DialogFragment)
fun onDialogDismiss(dialog: DialogFragment)
}
override fun onAttach(context: Context) {
super.onAttach(context)
listener = context as TheDialogListener
}
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
super.onCreateDialog(savedInstanceState)
// show progress dialog
val progressView = activity!!.layoutInflater.inflate(R.layout.dialog_progress_i, null)
progressView.findViewById<TextView>(R.id.progress_message).text = "Fetching data"
return activity!!.let {
val progressBuilder = AlertDialog.Builder(it, R.style.ThemeOverlay_AppCompat_Dialog)
progressBuilder
.setView(progressView)
.setOnCancelListener {
listener.onDialogCancel(this)
}
.setOnDismissListener {
listener.onDialogDismiss(this)
}
.create()
}
}
}
And this my Fragment
code, which according to the docs is for an Activity
:
class FragmentSubjects: Fragment(), DialogSubjectsProgress.TheDialogListener {
// other code
private fun addSubject() {
// show progress dialog
val progressDialog = DialogSubjectsProgress()
progressDialog.show(activity!!.supportFragmentManager, "null")
// todo
// progressDialog.dismiss()
}
override fun onDialogCancel(dialog: DialogFragment) {
// User canceled the dialog
}
override fun onDialogDismiss(dialog: DialogFragment) {
// Dialog's work is done
// todo
}
}
I have found a solution to this here, but I don't really understand it because it is written in Java
, and I don't understand Java
. I need help in Kotlin
!!
----edit----
This is the log
:
java.lang.ClassCastException: com.example.kotlinappv3.MainActivity cannot be cast to com.example.kotlinappv3.DialogSubjectsProgress$TheDialogListener
at com.example.kotlinappv3.DialogSubjectsProgress.onAttach(DialogSubjectsProgress.kt:27)
at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManager.java:1404)
at androidx.fragment.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManager.java:1784)
at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManager.java:1852)
at androidx.fragment.app.BackStackRecord.executeOps(BackStackRecord.java:802)
at androidx.fragment.app.FragmentManagerImpl.executeOps(FragmentManager.java:2625)
at androidx.fragment.app.FragmentManagerImpl.executeOpsTogether(FragmentManager.java:2411)
at androidx.fragment.app.FragmentManagerImpl.removeRedundantOperationsAndExecute(FragmentManager.java:2366)
at androidx.fragment.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:2273)
at androidx.fragment.app.FragmentManagerImpl$1.run(FragmentManager.java:733)
at android.os.Handler.handleCallback(Handler.java:874)
at android.os.Handler.dispatchMessage(Handler.java:100)
at android.os.Looper.loop(Looper.java:198)
at android.app.ActivityThread.main(ActivityThread.java:6729)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
The line
at com.example.kotlinappv3.DialogSubjectsProgress.onAttach(DialogSubjectsProgress.kt:27)
is pointing to
listener = context as TheDialogListener
in my DialogFragment
code.
in your addSubject
method instead of
activity!!.supportFragmentManager
use:
childFragmentManager
and in DialogFragment
code, change:
override fun onAttach(context: Context) {
super.onAttach(context)
listener = context as TheDialogListener
}
to:
override fun onAttachFragment(childFragment: Fragment?) {
super.onAttachFragment(childFragment)
listener = context as TheDialogListener
}