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

问题描述 投票:0回答:1

我一直在尝试自己寻找答案,但似乎没有人在谈论我的确切问题。通常,这是有关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的区别的一些信息。

我的问题是,我应该在listener =函数的OnAttach行中放入什么?

这是问题所在。

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

这是对话框的父活动

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

}
android kotlin android-dialogfragment
1个回答
2
投票

Context是您的Activity。如果要引用父片段,则需要使用parentFragment(或者,在较新版本的Fragments中,请使用requireParentFragment()获取非空片段):

override fun onAttach(context: Context) {
    super.onAttach(context)
    try {
        listener = requireParentFragment() as EngagedDialogListener
    } catch (e: ClassCastException) {
        throw ClassCastException(
            requireParentFragment().toString() +
                    "must implement ExampleDialogListener"
        )
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.