Store and restore ThemeChooserPreference state

pull/299/head
Koitharu 3 years ago
parent d05e777b2c
commit 5ce2bc92d6
No known key found for this signature in database
GPG Key ID: 8E861F8CE6E7CE27

@ -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

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

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

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

Loading…
Cancel
Save