Store and restore ThemeChooserPreference state

This commit is contained in:
Koitharu
2023-02-12 09:44:53 +02:00
parent d05e777b2c
commit 5ce2bc92d6
4 changed files with 99 additions and 4 deletions

View File

@@ -17,6 +17,7 @@ import org.koitharu.kotatsu.parsers.model.MangaSource
import org.koitharu.kotatsu.parsers.model.SortOrder
import org.koitharu.kotatsu.shelf.domain.ShelfSection
import org.koitharu.kotatsu.utils.ext.connectivityManager
import org.koitharu.kotatsu.utils.ext.filterToSet
import org.koitharu.kotatsu.utils.ext.getEnumValue
import org.koitharu.kotatsu.utils.ext.observe
import org.koitharu.kotatsu.utils.ext.putEnumValue
@@ -183,7 +184,9 @@ class AppSettings @Inject constructor(@ApplicationContext context: Context) {
}
var hiddenSources: Set<String>
get() = prefs.getStringSet(KEY_SOURCES_HIDDEN, null) ?: emptySet()
get() = prefs.getStringSet(KEY_SOURCES_HIDDEN, null)?.filterToSet { name ->
remoteSources.any { it.name == name }
}.orEmpty()
set(value) = prefs.edit { putStringSet(KEY_SOURCES_HIDDEN, value) }
val isSourcesSelected: Boolean

View File

@@ -3,12 +3,17 @@ package org.koitharu.kotatsu.settings.utils
import android.content.Context
import android.content.res.TypedArray
import android.os.Build
import android.os.Parcel
import android.os.Parcelable
import android.util.AttributeSet
import android.view.LayoutInflater
import android.view.View
import android.view.ViewTreeObserver
import android.widget.HorizontalScrollView
import android.widget.LinearLayout
import androidx.appcompat.view.ContextThemeWrapper
import androidx.core.view.isVisible
import androidx.customview.view.AbsSavedState
import androidx.preference.Preference
import androidx.preference.PreferenceViewHolder
import org.koitharu.kotatsu.R
@@ -24,10 +29,12 @@ class ThemeChooserPreference @JvmOverloads constructor(
private val entries = ColorScheme.getAvailableList()
private var currentValue: ColorScheme = ColorScheme.default
private val lastScrollPosition = intArrayOf(-1)
private val itemClickListener = View.OnClickListener {
val tag = it.tag as? ColorScheme ?: return@OnClickListener
setValueInternal(tag.name, true)
}
private var scrollPersistListener: ScrollPersistListener? = null
var value: String
get() = currentValue.name
@@ -36,7 +43,9 @@ class ThemeChooserPreference @JvmOverloads constructor(
override fun onBindViewHolder(holder: PreferenceViewHolder) {
super.onBindViewHolder(holder)
val layout = holder.findViewById(R.id.linear) as? LinearLayout ?: return
val scrollView = holder.findViewById(R.id.scrollView) as? HorizontalScrollView ?: return
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
scrollView.suppressLayout(true)
layout.suppressLayout(true)
}
layout.removeAllViews()
@@ -52,8 +61,19 @@ class ThemeChooserPreference @JvmOverloads constructor(
item.card.setOnClickListener(itemClickListener)
layout.addView(item.root)
}
if (lastScrollPosition[0] >= 0) {
val scroller = Scroller(scrollView, lastScrollPosition[0])
scroller.run()
scrollView.post(scroller)
}
scrollView.viewTreeObserver.run {
scrollPersistListener?.let { removeOnScrollChangedListener(it) }
scrollPersistListener = ScrollPersistListener(scrollView, lastScrollPosition)
addOnScrollChangedListener(scrollPersistListener)
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
layout.suppressLayout(false)
scrollView.suppressLayout(false)
}
}
@@ -71,6 +91,24 @@ class ThemeChooserPreference @JvmOverloads constructor(
return a.getInt(index, 0)
}
override fun onSaveInstanceState(): Parcelable? {
val superState = super.onSaveInstanceState() ?: return null
return SavedState(
superState = superState,
scrollPosition = lastScrollPosition[0],
)
}
override fun onRestoreInstanceState(state: Parcelable?) {
if (state !is SavedState) {
super.onRestoreInstanceState(state)
return
}
super.onRestoreInstanceState(state.superState)
lastScrollPosition[0] = state.scrollPosition
// notifyChanged()
}
private fun setValueInternal(enumName: String, notifyChanged: Boolean) {
val newValue = ColorScheme.safeValueOf(enumName) ?: return
if (newValue != currentValue) {
@@ -81,4 +119,55 @@ class ThemeChooserPreference @JvmOverloads constructor(
}
}
}
private class SavedState : AbsSavedState {
val scrollPosition: Int
constructor(
superState: Parcelable,
scrollPosition: Int
) : super(superState) {
this.scrollPosition = scrollPosition
}
constructor(source: Parcel, classLoader: ClassLoader?) : super(source, classLoader) {
scrollPosition = source.readInt()
}
override fun writeToParcel(out: Parcel, flags: Int) {
super.writeToParcel(out, flags)
out.writeInt(scrollPosition)
}
companion object {
@Suppress("unused")
@JvmField
val CREATOR: Parcelable.Creator<SavedState> = object : Parcelable.Creator<SavedState> {
override fun createFromParcel(`in`: Parcel) = SavedState(`in`, SavedState::class.java.classLoader)
override fun newArray(size: Int): Array<SavedState?> = arrayOfNulls(size)
}
}
}
private class ScrollPersistListener(
private val scrollView: HorizontalScrollView,
private val lastScrollPosition: IntArray,
) : ViewTreeObserver.OnScrollChangedListener {
override fun onScrollChanged() {
lastScrollPosition[0] = scrollView.scrollX
}
}
private class Scroller(
private val scrollView: HorizontalScrollView,
private val position: Int,
) : Runnable {
override fun run() {
scrollView.scrollTo(position, 0)
}
}
}

View File

@@ -1,7 +1,7 @@
package org.koitharu.kotatsu.utils.ext
import androidx.collection.ArraySet
import java.util.*
import java.util.Collections
fun <T> MutableList<T>.move(sourceIndex: Int, targetIndex: Int) {
if (sourceIndex <= targetIndex) {
@@ -11,14 +11,12 @@ fun <T> MutableList<T>.move(sourceIndex: Int, targetIndex: Int) {
}
}
@Suppress("FunctionName")
inline fun <T> MutableSet(size: Int, init: (index: Int) -> T): MutableSet<T> {
val set = ArraySet<T>(size)
repeat(size) { index -> set.add(init(index)) }
return set
}
@Suppress("FunctionName")
inline fun <T> Set(size: Int, init: (index: Int) -> T): Set<T> = when (size) {
0 -> emptySet()
1 -> Collections.singleton(init(0))
@@ -39,3 +37,7 @@ fun <K, V> Map<K, V>.findKeyByValue(value: V): K? {
}
return null
}
inline fun <T> Collection<T>.filterToSet(predicate: (T) -> Boolean): Set<T> {
return filterTo(ArraySet(size), predicate)
}

View File

@@ -55,6 +55,7 @@
</LinearLayout>
<HorizontalScrollView
android:id="@+id/scrollView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="2dp"