Store and restore ThemeChooserPreference state
This commit is contained in:
@@ -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"
|
||||
|
||||
Reference in New Issue
Block a user