kotlin-state-manager
0.0.5indexedOffers an extensible state management solution for managing and updating values, supporting validation, error handling, serialization, and state restoration, with integration into UI frameworks.
Offers an extensible state management solution for managing and updating values, supporting validation, error handling, serialization, and state restoration, with integration into UI frameworks.
A multiplatform and extensible state manager. Its wrapper the managed value to deliver a better, easy and extensible way. It's like a Value class with powerS.
The project is not a replacement for Coroutines Flow or Compose State. Your origin is from 2022 when Compose wasn't multiplatform.
There are a lot of ways to use a Value Manager
class CounterViewModel {
val counter = basicValueManager(initialValue = 0)
val counterFlow = counter.asMutableStateFlow() // StateFlow version
var value by basicValueManager(initialValue = 0) // Delegate property version available
}
class CounterViewModel {
fun increment() {
anyValueManagerType.update { current -> current + 1 }
anyValueManager = anyValueManager + 1 // update method as a Delegate property
anyValueManager++ // same as previous
}
}
class CounterViewModel {
fun listen() {
anyValueManagerType.collect {
// collect without suspend is available
}
coroutinesScope.launch {
flowValueManagerType.collect {
// suspend collect available in Flow
}
}
}
}
@Composable
fun HomeScreen() {
val counter = remember { basicValueManager(initialValue = 0) }
var counterState by remember { counter.asState() } // remember or rememberSaveable are available
// Update and listen operations are the same
}
class CounterViewModel {
val counter = basicValueManager(initialValue = 0)
init {
counter.onError {
}
}
}
class CounterViewModel {
val counter = basicValueManager(initialValue = 0)
init {
counter.onChanged {
}
}
}
A value manager can be encoded or decoded using Kotlin Serialization and serialization module.
It is a good use case whether you have model shared with serialization infrastructure as network requests
import dev.programadorthi.state.serialization.ValueManager // Not from core package
@Serializable
data class MyClass(
val count: ValueManager<Int>,
)
val data = MyClass(count = basicValueManager(1))
val json = Json.encodeToString(data)
println(json)
decoded = Json.decodeFromString<MyClass>(json)
println( == decoded)
val counter by rememberSaveableValueManager { ... }
Without remember function or using a class to manager, you need to pass a SaveableStateRegistry
class MyComposeViewModel(stateRegistry: SaveableStateRegistry) {
private var counter by composeValueManager(0, stateRegistry = stateRegistry)
}
Checkout MVIViewModel sample for more details
class MyActivity : ComponentActivity {
private var counter by androidValueManager(0)
}
class MyFragment : AndroidXFragment {
private var counter by androidValueManager(0)
}
class MyViewModel(savedStateHandle: SavedStateHandle) : AndroidXViewModel {
private var counter by androidValueManager(0, savedStateHandle = savedStateHandle)
}
Checkout MainActivity sample for more details
class CounterValueManager : BaseValueManager<Int>(initialValue = 0) {
// Now all operations is available here
}
Samples folder have a mix of usage.
Close usage to real project here
class PositiveValidator(
override val message: (Int) -> String = { "Value $it should be positive" }
) : Validator<Int> {
override fun isValid(value: Int): Boolean = value > 0
}
val counter = basicValueManager(initialValue = 0)
counter.addValidator(PositiveValidator())
// or
counter += PositiveValidator()
counter.onValidated {
// Listen on each validation operation
}
// Put a value don't trigger validations
counter.value = -1
// Call validate() to trigger validations
counter.validate()
// Calling update always trigger validations and don't need call validate()
counter.update { -1 }
// Checking is valid
counter.isValid()
// Getting validators messages
counter.messages()
Surfaced from shared tags and platforms — no rankings paid for.