Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Handle LocationStateButton saved state using Bundle #5535

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,15 @@ import android.content.Context
import android.content.res.ColorStateList
import android.content.res.TypedArray
import android.graphics.drawable.Animatable
import android.os.Parcel
import android.os.Bundle
import android.os.Parcelable
import android.util.AttributeSet
import android.view.View
import androidx.annotation.Keep
import androidx.appcompat.widget.AppCompatImageButton
import androidx.core.os.bundleOf
import de.westnordost.streetcomplete.R
import de.westnordost.streetcomplete.util.ktx.parcelable
import de.westnordost.streetcomplete.util.ktx.serializable

/**
* An image button which shows the current location state
Expand Down Expand Up @@ -84,49 +86,20 @@ class LocationStateButton @JvmOverloads constructor(
return drawableState
}

public override fun onSaveInstanceState(): Parcelable {
val superState = super.onSaveInstanceState()
val ss = SavedState(superState)
ss.state = state
ss.activated = isActivated
ss.navigation = isNavigation
return ss
}

public override fun onRestoreInstanceState(s: Parcelable) {
val ss = s as SavedState
super.onRestoreInstanceState(ss.superState)
state = ss.state
isActivated = ss.activated
isNavigation = ss.navigation
requestLayout()
}

internal class SavedState : BaseSavedState {
var state: State = State.DENIED
var activated = false
var navigation = false

constructor(superState: Parcelable?) : super(superState)
constructor(parcel: Parcel) : super(parcel) {
state = State.valueOf(parcel.readString()!!)
activated = parcel.readInt() == 1
navigation = parcel.readInt() == 1
}

override fun writeToParcel(out: Parcel, flags: Int) {
super.writeToParcel(out, flags)
out.writeString(state.name)
out.writeInt(if (activated) 1 else 0)
out.writeInt(if (navigation) 1 else 0)
}

companion object {
@JvmField @Keep
val CREATOR = object : Parcelable.Creator<SavedState> {
override fun createFromParcel(parcel: Parcel) = SavedState(parcel)
override fun newArray(size: Int) = arrayOfNulls<SavedState>(size)
}
override fun onSaveInstanceState() = bundleOf(
KEY_SUPER_STATE to super.onSaveInstanceState(),
KEY_STATE to state,
KEY_IS_ACTIVATED to isActivated,
KEY_IS_NAVIGATION to isNavigation,
)

override fun onRestoreInstanceState(state: Parcelable?) {
if (state is Bundle) {
super.onRestoreInstanceState(state.parcelable(KEY_SUPER_STATE))
this.state = state.serializable(KEY_STATE)!!
isActivated = state.getBoolean(KEY_IS_ACTIVATED)
isNavigation = state.getBoolean(KEY_IS_NAVIGATION)
requestLayout()
}
}

Expand All @@ -148,4 +121,11 @@ class LocationStateButton @JvmOverloads constructor(
R.attr.state_searching,
R.attr.state_updating
).subList(0, ordinal)

companion object {
private const val KEY_SUPER_STATE = "superState"
private const val KEY_STATE = "state"
private const val KEY_IS_ACTIVATED = "isActivated"
private const val KEY_IS_NAVIGATION = "isNavigation"
}
}
18 changes: 18 additions & 0 deletions app/src/main/java/de/westnordost/streetcomplete/util/ktx/Bundle.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package de.westnordost.streetcomplete.util.ktx

import android.os.Build
import android.os.Bundle
import android.os.Parcelable
import androidx.core.os.BundleCompat
import java.io.Serializable

inline fun <reified T : Serializable> Bundle.serializable(key: String?): T? =
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
getSerializable(key, T::class.java)
} else {
@Suppress("DEPRECATION")
getSerializable(key) as? T
}

inline fun <reified T : Parcelable> Bundle.parcelable(key: String?): T? =
BundleCompat.getParcelable(this, key, T::class.java)