Funny app which loads pokemons from pokeapi, these are displaying in recyclerview + list adapter. All items are stored in localstorage using room. Just apps to make funny things.
Code based following StateFlow, MVI(State, Intent), Flow, Coroutines, Room + Unit Test
Right now you can configure how many pokemons you want to display aka: All pokes.
Look for
// Defined how many pokemons you want to request, every pokemon info is requested one per one, processed and stored in localstorage
const val POKE_COUNT = 50
// Defined after module of pokemons loaded should reload types filter
const val REFRESHING_OFFSET = 10
If you're familiar when you use State partern would great try to define what view will perform, hence I defined following states:
sealed class PokeState {
object Ilde: PokeState()
object PerformTopScroll: PokeState()
data class ShowOrHideEmptyData(
val isVisible: Boolean,
val title: String = "",
val description: String = ""
): PokeState()
data class ShowOrHideLoader(val isVisible: Boolean) : PokeState()
data class ReloadPokes(val pokes: List<Poke>) : PokeState()
data class ReloadFilters(val filters: List<Filter>): PokeState()
}
I guest you can deduce what I'm doing
Also you should get familiar about Intent, right now I'm mapping actions to load pokes and filter pokes, can be more in the future
sealed class PokeIntent {
object LoadPokeList: PokeIntent()
data class FilterPokesUsing(val filter: Filter): PokeIntent()
}
Hell yeah, I've used my custom one implementation of MVI attached to ViewModel look here: https://github.com/cbedoy/PokeFlow/blob/master/app/src/main/java/cbedoy/pokeflow/helpers/BaseViewModel.kt
The great one is I only have to define my State, Intent and InitialState, also never forget you business componet which it going to produce states
class ExampleViewModel : BaseMVIViewModel<ExampleState, ExampleIntent>(initialState = ExampleState.Ilde){
override suspend fun onCollect(intent : ExampleIntent, producer : Producer<PokeState>){
when(intent){
ExampleIntent.AnyAmazingDefinition {
producer(useCase.invokeExample) // producer will invoke collecting in Dispatchers.IO, and refreshing view in Dispatchers.Main :)
}
}
Well you can use alternatives like Orbit-MVI or Uniflow-kt
- data:
- Contains all DTO responses, Database models, repository, and service
- di
- Contains all DI injections and configurations, had done with Koin
- domain
- Contains use case, intent and state.
- util
- It contains all the helpers, extensions, utils, etc
- presentation
- Contains fragments, viewmodel, and adapters
- Pull down the code locally.
- Open Android Studio and select 'Open an existing Android Studio Project'
- Navigate to checked out repository.
- Inside 'PokeFlow' folder select 'settings.gradle' file
- Run the application.