Sfoglia il codice sorgente

Retain scroll position when selecting app theme preference

Co-authored-by: Jays2Kings <[email protected]>
arkon 3 anni fa
parent
commit
0de3558ab3

+ 24 - 1
app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsAppearanceController.kt

@@ -1,6 +1,8 @@
 package eu.kanade.tachiyomi.ui.setting
 
 import android.os.Build
+import android.os.Bundle
+import android.view.View
 import androidx.core.app.ActivityCompat
 import androidx.preference.PreferenceScreen
 import eu.kanade.tachiyomi.R
@@ -23,6 +25,8 @@ import eu.kanade.tachiyomi.data.preference.PreferenceValues as Values
 
 class SettingsAppearanceController : SettingsController() {
 
+    private var themesPreference: ThemesPreference? = null
+
     override fun setupPreferenceScreen(screen: PreferenceScreen) = screen.apply {
         titleRes = R.string.pref_category_appearance
 
@@ -59,7 +63,7 @@ class SettingsAppearanceController : SettingsController() {
 
                 summary = "%s"
             }
-            initThenAdd(ThemesPreference(context)) {
+            themesPreference = initThenAdd(ThemesPreference(context)) {
                 key = Keys.appTheme
                 titleRes = R.string.pref_app_theme
 
@@ -158,4 +162,23 @@ class SettingsAppearanceController : SettingsController() {
             }
         }
     }
+
+    override fun onSaveViewState(view: View, outState: Bundle) {
+        themesPreference?.let {
+            outState.putInt(THEMES_SCROLL_POSITION, it.lastScrollPosition ?: 0)
+        }
+        super.onSaveInstanceState(outState)
+    }
+
+    override fun onRestoreViewState(view: View, savedViewState: Bundle) {
+        super.onRestoreViewState(view, savedViewState)
+        themesPreference?.lastScrollPosition = savedViewState.getInt(THEMES_SCROLL_POSITION, 0)
+    }
+
+    override fun onDestroyView(view: View) {
+        super.onDestroyView(view)
+        themesPreference = null
+    }
 }
+
+private const val THEMES_SCROLL_POSITION = "themesScrollPosition"

+ 33 - 7
app/src/main/java/eu/kanade/tachiyomi/widget/preference/ThemesPreference.kt

@@ -8,13 +8,23 @@ import androidx.recyclerview.widget.LinearLayoutManager
 import androidx.recyclerview.widget.RecyclerView
 import eu.kanade.tachiyomi.R
 import eu.kanade.tachiyomi.data.preference.PreferenceValues
+import eu.kanade.tachiyomi.util.system.dpToPx
 
 class ThemesPreference @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) :
     ListPreference(context, attrs),
     ThemesPreferenceAdapter.OnItemClickListener {
 
+    private var recycler: RecyclerView? = null
     private val adapter = ThemesPreferenceAdapter(this)
 
+    var lastScrollPosition: Int? = null
+
+    var entries: List<PreferenceValues.AppTheme> = emptyList()
+        set(value) {
+            field = value
+            adapter.setItems(value)
+        }
+
     init {
         layoutResource = R.layout.pref_themes_list
     }
@@ -22,9 +32,18 @@ class ThemesPreference @JvmOverloads constructor(context: Context, attrs: Attrib
     override fun onBindViewHolder(holder: PreferenceViewHolder) {
         super.onBindViewHolder(holder)
 
-        val themesList = holder.findViewById(R.id.themes_list) as RecyclerView
-        themesList.layoutManager = LinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, false)
-        themesList.adapter = adapter
+        recycler = holder.findViewById(R.id.themes_list) as RecyclerView
+        recycler?.layoutManager = LinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, false)
+        recycler?.adapter = adapter
+
+        // Retain scroll position on activity recreate after changing theme
+        recycler?.addOnScrollListener(object : RecyclerView.OnScrollListener() {
+            override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
+                super.onScrolled(recyclerView, dx, dy)
+                lastScrollPosition = recyclerView.computeHorizontalScrollOffset()
+            }
+        })
+        lastScrollPosition?.let { scrollToOffset(it) }
     }
 
     override fun onItemClick(position: Int) {
@@ -36,9 +55,16 @@ class ThemesPreference @JvmOverloads constructor(context: Context, attrs: Attrib
         // no-op; not actually a DialogPreference
     }
 
-    var entries: List<PreferenceValues.AppTheme> = emptyList()
-        set(value) {
-            field = value
-            adapter.setItems(value)
+    private fun scrollToOffset(lX: Int) {
+        recycler?.let {
+            (it.layoutManager as LinearLayoutManager).apply {
+                scrollToPositionWithOffset(
+                    // 118dp is the width of the pref_theme_item layout
+                    lX / 118.dpToPx,
+                    -lX % 118.dpToPx
+                )
+            }
+            lastScrollPosition = it.computeHorizontalScrollOffset()
         }
+    }
 }