Skip to content

Instantly share code, notes, and snippets.

@GregKluska
Last active July 11, 2020 22:04
Show Gist options
  • Select an option

  • Save GregKluska/6145d98c8d1833e5bc95db3eec7d384d to your computer and use it in GitHub Desktop.

Select an option

Save GregKluska/6145d98c8d1833e5bc95db3eec7d384d to your computer and use it in GitHub Desktop.
Gist of generic classes from codingwithmitch.com
Gist of generic classes from codingwithmitch.com
List:
- StateResource.kt
- DataState.kt
- BaseViewModel.kt
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.Transformations
import androidx.lifecycle.ViewModel
abstract class BaseViewModel<StateEvent, ViewState>: ViewModel() {
val TAG: String = "AppDebug"
protected val _stateEvent: MutableLiveData<StateEvent> = MutableLiveData()
protected val _viewState: MutableLiveData<ViewState> = MutableLiveData()
val viewState:LiveData<ViewState>
get() = _viewState
val dataState: LiveData<DataState<ViewState>> = Transformations
.switchMap(_stateEvent) { stateEvent ->
stateEvent?.let {
handleStateEvent(stateEvent)
}
}
fun setStateEvent(event: StateEvent) {
_stateEvent.value = event
}
fun getCurrentViewStateOrNew(): ViewState {
val value = viewState.value?.let {
it
}?: initNewViewState()
return value
}
abstract fun initNewViewState(): ViewState
abstract fun handleStateEvent(stateEvent: StateEvent): LiveData<DataState<ViewState>>
}
data class Loading(val isLoading: Boolean)
data class Data<T>(val data: Event<T>?, val response: Event<Response>?)
data class StateError(val response: Response)
data class Response(val message: String?, val responseType: ResponseType)
sealed class ResponseType{
class Toast: ResponseType()
class Dialog: ResponseType()
class None: ResponseType()
}
/**
* Used as a wrapper for data that is exposed via a LiveData that represents an event.
*/
open class Event<out T>(private val content: T) {
var hasBeenHandled = false
private set // Allow external read but not write
/**
* Returns the content and prevents its use again.
*/
fun getContentIfNotHandled(): T? {
return if (hasBeenHandled) {
null
} else {
hasBeenHandled = true
content
}
}
/**
* Returns the content, even if it's already been handled.
*/
fun peekContent(): T = content
override fun toString(): String {
return "Event(content=$content, hasBeenHandled=$hasBeenHandled)"
}
companion object{
private val TAG: String = "AppDebug"
// we don't want an event if the data is null
fun <T> dataEvent(data: T?): Event<T>?{
data?.let {
return Event(it)
}
return null
}
// we don't want an event if the response is null
fun responseEvent(response: Response?): Event<Response>?{
response?.let{
return Event(response)
}
return null
}
}
}
data class Loading(val isLoading: Boolean)
data class Data<T>(val data: Event<T>?, val response: Event<Response>?)
data class StateError(val response: Response)
data class Response(val message: String?, val responseType: ResponseType)
sealed class ResponseType{
class Toast: ResponseType()
class Dialog: ResponseType()
class None: ResponseType()
}
/**
* Used as a wrapper for data that is exposed via a LiveData that represents an event.
*/
open class Event<out T>(private val content: T) {
var hasBeenHandled = false
private set // Allow external read but not write
/**
* Returns the content and prevents its use again.
*/
fun getContentIfNotHandled(): T? {
return if (hasBeenHandled) {
null
} else {
hasBeenHandled = true
content
}
}
/**
* Returns the content, even if it's already been handled.
*/
fun peekContent(): T = content
override fun toString(): String {
return "Event(content=$content, hasBeenHandled=$hasBeenHandled)"
}
companion object{
private val TAG: String = "AppDebug"
// we don't want an event if the data is null
fun <T> dataEvent(data: T?): Event<T>?{
data?.let {
return Event(it)
}
return null
}
// we don't want an event if the response is null
fun responseEvent(response: Response?): Event<Response>?{
response?.let{
return Event(response)
}
return null
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment