侦听器从 DialogFragment 获取信息到父片段的上下文是什么

What is the Context for a listener to get Info From a DialogFragment to the Parent Fragment

我一直在尝试自己寻找答案,但似乎没有人在谈论我的确切问题。一般都是RecyclerView Adapter Listener的问题,我用过,每次都有效

当我 运行 我的代码时,我得到这个错误, java.lang.ClassCastException: com.wereworkingonit.communitystore.SettingsActivity@d180f18must implement ExampleDialogListener

没有 try, catch 块给我 java.lang.ClassCastException: com.wereworkingonit.communitystore.SettingsActivity cannot be cast to com.wereworkingonit.communitystore.JoinStoreDialog$EngagedDialogListener,这没有意义,因为我遵循了教程并将其翻译成 Kotlin。我想我遗漏了一些关于 Java 和 Kotlin 的区别。

我的问题是,我在 OnAttach 函数的 listener = 行中输入了什么?

这就是问题所在。

override fun onAttach(context: Context) {
        super.onAttach(context)
        try {
            listener = context as EngagedDialogListener
        } catch (e: ClassCastException) {
            throw ClassCastException(
                context.toString() +
                        "must implement ExampleDialogListener"
            )
        }
    }

这是对话框的父级 Activity

package com.wereworkingonit.communitystore

import android.content.Context
import android.content.Intent
import android.content.SharedPreferences
import android.os.Bundle
import android.util.Log
import androidx.appcompat.app.AppCompatActivity
import androidx.preference.PreferenceFragmentCompat
import androidx.preference.SwitchPreferenceCompat
import com.wereworkingonit.communitystore.participant.ParticipantLandingPage
import com.wereworkingonit.communitystore.user.UserLandingPage
import com.wereworkingonit.communitystore.util.FirestoreUtil

private const val TAG = "SettingsActivity"

class SettingsActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.settings_activity)
        supportFragmentManager
            .beginTransaction()
            .replace(R.id.settings, SettingsFragment())
            .commit()
        supportActionBar?.setDisplayHomeAsUpEnabled(true)
    }

    class SettingsFragment : PreferenceFragmentCompat(),
        SharedPreferences.OnSharedPreferenceChangeListener, JoinStoreDialog.EngagedDialogListener {
        private lateinit var contextForPreferences: Context
        private var engagedPreference: Boolean = false
        private lateinit var sharedPref: SharedPreferences
        private var switchPreference: SwitchPreferenceCompat? = null

        override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
            setPreferencesFromResource(R.xml.root_preferences, rootKey)

            switchPreference = findPreference("engage")

            androidx.preference.PreferenceManager.setDefaultValues(
                contextForPreferences,
                R.xml.root_preferences,
                false
            )
            sharedPref =
                androidx.preference.PreferenceManager.getDefaultSharedPreferences(
                    contextForPreferences
                )
            engagedPreference = sharedPref.getBoolean(AppConstants.ENGAGEMENT, false)
            Log.d(TAG, "onCreate: $engagedPreference")
            FirestoreUtil.getCurrentUser {
                switchPreference!!.isChecked = it.engagement
            }
        }

        override fun onAttach(context: Context) {
            super.onAttach(context)
            contextForPreferences = context
        }

        override fun onStart() {
            super.onStart()
            androidx.preference.PreferenceManager.getDefaultSharedPreferences(contextForPreferences)
                .registerOnSharedPreferenceChangeListener(this)
        }

        override fun onStop() {
            super.onStop()
            androidx.preference.PreferenceManager.getDefaultSharedPreferences(contextForPreferences)
                .unregisterOnSharedPreferenceChangeListener(this)
        }

        override fun onPause() {
            super.onPause()
            engagedPreference = sharedPref.getBoolean(AppConstants.ENGAGEMENT, false)
            Log.d(TAG, "onPause: $engagedPreference")

            if (engagedPreference) {
                //TODO: Add welcome splash for Engagement Change
                val intent = Intent(contextForPreferences, ParticipantLandingPage::class.java)
                startActivity(intent)
            } else {
                val intent = Intent(contextForPreferences, UserLandingPage::class.java)
                startActivity(intent)
            }
        }

        override fun notThisTime(nope: Boolean) {
            FirestoreUtil.getCurrentUser {
                switchPreference!!.isChecked = nope
            }
        }

        override fun onSharedPreferenceChanged(
            sharedPreferences: SharedPreferences?,
            key: String?
        ) {
            when (key) {
                "engage" -> {
                    val joinStoreDialog = JoinStoreDialog()

                    if (switchPreference!!.isChecked) {
                        joinStoreDialog.show(childFragmentManager, "JoinStoreDialog")
                    } else {
                        FirestoreUtil.updateCurrentUser("", null, switchPreference!!.isChecked)
                    }
                    //TODO: One way trip, or what happens if the user clicks to end engagement?
                }
            }
        }
    }
}

这是创建侦听器的对话片段


package com.wereworkingonit.communitystore

import android.app.AlertDialog
import android.app.Dialog
import android.content.Context
import android.content.Intent
import android.content.SharedPreferences
import android.os.Bundle
import androidx.appcompat.app.AppCompatDialogFragment
import com.wereworkingonit.communitystore.participant.ParticipantLandingPage
import com.wereworkingonit.communitystore.util.FirestoreUtil
import kotlinx.android.synthetic.main.dialog_join_the_fold.view.*

class JoinStoreDialog : AppCompatDialogFragment() {
    private lateinit var sharedPreferences: SharedPreferences
    private lateinit var listener: EngagedDialogListener

    override fun onAttach(context: Context) {
        super.onAttach(context)
        try {
            listener = context as EngagedDialogListener
        } catch (e: ClassCastException) {
            throw ClassCastException(
                context.toString() +
                        "must implement ExampleDialogListener"
            )
        }
    }

    interface EngagedDialogListener {
        fun notThisTime(nope: Boolean)
    }

    override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
        sharedPreferences =
            androidx.preference.PreferenceManager.getDefaultSharedPreferences(
                activity
            )
        val builder = AlertDialog.Builder(activity)
        val inflater = requireActivity().layoutInflater
        val view = inflater.inflate(R.layout.dialog_join_the_fold, null)
        view.dialog_new_store_name
        view.dialog_new_store_email
        view.dialog_new_store_password

        builder.setView(view)
            .setTitle("Thank You for Joining")
            .setNegativeButton("Na, Not Now") { dialogInterface, i ->
                engagedParticipant(false)
                listener.notThisTime(false)
                dialogInterface.dismiss()
            }
            .setPositiveButton("Let's Get Started") { dialogInterface, i ->
                engagedParticipant(true)
                FirestoreUtil.updateCurrentUser("", null, true)

                val intent = Intent(activity, ParticipantLandingPage::class.java)
                startActivity(intent)
            }



        return builder.create()
    }

    private fun engagedParticipant(engagement: Boolean) {
        val editor = sharedPreferences.edit()
        editor.putBoolean(AppConstants.ENGAGEMENT, engagement)
        editor.apply()
    }

}

Context 是你的Activity。如果你想引用你的父片段,你需要使用 parentFragment (或者,在更新版本的片段中,使用 requireParentFragment() 来获得一个非空片段):

override fun onAttach(context: Context) {
    super.onAttach(context)
    try {
        listener = requireParentFragment() as EngagedDialogListener
    } catch (e: ClassCastException) {
        throw ClassCastException(
            requireParentFragment().toString() +
                    "must implement ExampleDialogListener"
        )
    }
}