summaryrefslogtreecommitdiff
path: root/Source/Android/app/src/main/java
diff options
context:
space:
mode:
authorJosJuice <josjuice@gmail.com>2025-05-13 14:31:57 +0200
committerJosJuice <josjuice@gmail.com>2025-06-07 10:20:19 +0200
commit5d7cba8cd95333cddb113956bc352cc00f474fe9 (patch)
treec3a496da4755b399c917c4294f029dddfd058fc6 /Source/Android/app/src/main/java
parent4214cb6eb8828e319b90cfde6604cc36eb236f19 (diff)
Android: Make SettingViewHolder a LifecycleOwner
Diffstat (limited to 'Source/Android/app/src/main/java')
-rw-r--r--Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/SettingsAdapter.kt20
-rw-r--r--Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/SettingsFragment.kt6
-rw-r--r--Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/SettingsFragmentView.kt6
-rw-r--r--Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/viewholder/SettingViewHolder.kt6
-rw-r--r--Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/LifecycleViewHolder.kt59
5 files changed, 94 insertions, 3 deletions
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/SettingsAdapter.kt b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/SettingsAdapter.kt
index 59e76ae178..1c230f4447 100644
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/SettingsAdapter.kt
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/SettingsAdapter.kt
@@ -16,6 +16,7 @@ import androidx.annotation.ColorInt
import androidx.appcompat.app.AlertDialog
import androidx.core.content.ContextCompat
import androidx.fragment.app.FragmentActivity
+import androidx.lifecycle.Lifecycle
import androidx.recyclerview.widget.RecyclerView
import com.google.android.material.color.MaterialColors
import com.google.android.material.datepicker.CalendarConstraints
@@ -543,6 +544,25 @@ class SettingsAdapter(
}
}
+ override fun onViewRecycled(holder: SettingViewHolder) {
+ super.onViewRecycled(holder)
+ holder.onViewRecycled()
+ }
+
+ override fun onViewAttachedToWindow(holder: SettingViewHolder) {
+ super.onViewAttachedToWindow(holder)
+ holder.onViewAttachedToWindow()
+ }
+
+ override fun onViewDetachedFromWindow(holder: SettingViewHolder) {
+ super.onViewDetachedFromWindow(holder)
+ holder.onViewDetachedFromWindow()
+ }
+
+ fun getFragmentLifecycle(): Lifecycle {
+ return fragmentView.getFragmentLifecycle()
+ }
+
private fun getValueForSingleChoiceSelection(item: SingleChoiceSetting, which: Int): Int {
val valuesId = item.valuesId
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/SettingsFragment.kt b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/SettingsFragment.kt
index 6a294ee139..991d3c3c2b 100644
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/SettingsFragment.kt
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/SettingsFragment.kt
@@ -18,6 +18,7 @@ import androidx.core.view.updatePadding
import androidx.fragment.app.DialogFragment
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentActivity
+import androidx.lifecycle.Lifecycle
import androidx.recyclerview.widget.LinearLayoutManager
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.google.android.material.snackbar.Snackbar
@@ -25,7 +26,6 @@ import org.dolphinemu.dolphinemu.R
import org.dolphinemu.dolphinemu.databinding.FragmentSettingsBinding
import org.dolphinemu.dolphinemu.features.settings.model.Settings
import org.dolphinemu.dolphinemu.features.settings.model.view.SettingsItem
-import org.dolphinemu.dolphinemu.ui.main.MainActivity
import org.dolphinemu.dolphinemu.ui.main.MainPresenter
import org.dolphinemu.dolphinemu.utils.GpuDriverInstallResult
import org.dolphinemu.dolphinemu.utils.SerializableHelper.serializable
@@ -200,6 +200,10 @@ class SettingsFragment : Fragment(), SettingsFragmentView {
.show()
}
+ override fun getFragmentLifecycle(): Lifecycle {
+ return lifecycle
+ }
+
private fun askForDriverFile() {
val intent = Intent(Intent.ACTION_GET_CONTENT).apply {
addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/SettingsFragmentView.kt b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/SettingsFragmentView.kt
index 076beaff6f..b0ad3e28b1 100644
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/SettingsFragmentView.kt
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/SettingsFragmentView.kt
@@ -4,6 +4,7 @@ package org.dolphinemu.dolphinemu.features.settings.ui
import androidx.fragment.app.DialogFragment
import androidx.fragment.app.FragmentActivity
+import androidx.lifecycle.Lifecycle
import org.dolphinemu.dolphinemu.features.settings.model.Settings
import org.dolphinemu.dolphinemu.features.settings.model.view.SettingsItem
import org.dolphinemu.dolphinemu.utils.GpuDriverInstallResult
@@ -119,4 +120,9 @@ interface SettingsFragmentView {
* Shows a dialog asking the user to install or uninstall a GPU driver
*/
fun showGpuDriverDialog()
+
+ /**
+ * Returns the Lifecycle for the Fragment.
+ */
+ fun getFragmentLifecycle(): Lifecycle
}
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/viewholder/SettingViewHolder.kt b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/viewholder/SettingViewHolder.kt
index 2054b08f43..dd5d4c97f0 100644
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/viewholder/SettingViewHolder.kt
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/viewholder/SettingViewHolder.kt
@@ -9,15 +9,17 @@ import android.view.View
import android.view.View.OnLongClickListener
import android.widget.TextView
import android.widget.Toast
-import androidx.recyclerview.widget.RecyclerView
+import androidx.lifecycle.LifecycleOwner
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import org.dolphinemu.dolphinemu.DolphinApplication
import org.dolphinemu.dolphinemu.R
import org.dolphinemu.dolphinemu.features.settings.model.view.SettingsItem
import org.dolphinemu.dolphinemu.features.settings.ui.SettingsAdapter
+import org.dolphinemu.dolphinemu.utils.LifecycleViewHolder
abstract class SettingViewHolder(itemView: View, protected val adapter: SettingsAdapter) :
- RecyclerView.ViewHolder(itemView), View.OnClickListener, OnLongClickListener {
+ LifecycleViewHolder(itemView, adapter.getFragmentLifecycle()),
+ LifecycleOwner, View.OnClickListener, OnLongClickListener {
init {
itemView.setOnClickListener(this)
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/LifecycleViewHolder.kt b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/LifecycleViewHolder.kt
new file mode 100644
index 0000000000..47696ac4bb
--- /dev/null
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/LifecycleViewHolder.kt
@@ -0,0 +1,59 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+package org.dolphinemu.dolphinemu.utils
+
+import android.view.View
+import androidx.lifecycle.DefaultLifecycleObserver
+import androidx.lifecycle.Lifecycle
+import androidx.lifecycle.LifecycleOwner
+import androidx.lifecycle.LifecycleRegistry
+import androidx.recyclerview.widget.RecyclerView
+
+/**
+ * A ViewHolder with an attached Lifecycle.
+ *
+ * @param itemView The view held by the ViewHolder.
+ * @param parentLifecycle If the passed-in Lifecycle changes state to DESTROYED, this ViewHolder
+ * will also change state to DESTROYED. This should normally be set to the
+ * Lifecycle of the containing Fragment or Activity to prevent instances
+ * of this class from leaking.
+ */
+abstract class LifecycleViewHolder(itemView: View, parentLifecycle: Lifecycle) :
+ RecyclerView.ViewHolder(itemView), LifecycleOwner {
+
+ private val lifecycleRegistry = LifecycleRegistry(this)
+
+ override val lifecycle: Lifecycle
+ get() = lifecycleRegistry
+
+ init {
+ lifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_CREATE)
+ parentLifecycle.addObserver(object : DefaultLifecycleObserver {
+ override fun onDestroy(owner: LifecycleOwner) {
+ // Make sure this ViewHolder doesn't leak if its lifecycle has observers
+ lifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_DESTROY)
+ }
+ })
+ }
+
+ /**
+ * To be called from a function overriding [RecyclerView.Adapter.onViewRecycled].
+ */
+ fun onViewRecycled() {
+ lifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_STOP)
+ }
+
+ /**
+ * To be called from a function overriding [RecyclerView.Adapter.onViewAttachedToWindow].
+ */
+ fun onViewAttachedToWindow() {
+ lifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_RESUME)
+ }
+
+ /**
+ * To be called from a function overriding [RecyclerView.Adapter.onViewDetachedFromWindow].
+ */
+ fun onViewDetachedFromWindow() {
+ lifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_STOP)
+ }
+}