侦听器从 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"
)
}
}
我一直在尝试自己寻找答案,但似乎没有人在谈论我的确切问题。一般都是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"
)
}
}