Adding dependency injection with Koin

This commit is contained in:
CorneilleEdi
2020-01-20 05:56:52 +05:30
parent 5a23f0d29b
commit e7a0907855
23 changed files with 273 additions and 71 deletions

1
.idea/.name generated Normal file
View File

@ -0,0 +1 @@
Pokedex

125
.idea/codeStyles/Project.xml generated Normal file
View File

@ -0,0 +1,125 @@
<component name="ProjectCodeStyleConfiguration">
<code_scheme name="Project" version="173">
<AndroidXmlCodeStyleSettings>
<option name="ARRANGEMENT_SETTINGS_MIGRATED_TO_191" value="true" />
</AndroidXmlCodeStyleSettings>
<JetCodeStyleSettings>
<option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" />
</JetCodeStyleSettings>
<codeStyleSettings language="XML">
<indentOptions>
<option name="CONTINUATION_INDENT_SIZE" value="4" />
</indentOptions>
<arrangement>
<rules>
<section>
<rule>
<match>
<AND>
<NAME>xmlns:android</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>^$</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>xmlns:.*</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>^$</XML_NAMESPACE>
</AND>
</match>
<order>BY_NAME</order>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*:id</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*:name</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>name</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>^$</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>style</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>^$</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>^$</XML_NAMESPACE>
</AND>
</match>
<order>BY_NAME</order>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND>
</match>
<order>ANDROID_ATTRIBUTE_ORDER</order>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>.*</XML_NAMESPACE>
</AND>
</match>
<order>BY_NAME</order>
</rule>
</section>
</rules>
</arrangement>
</codeStyleSettings>
<codeStyleSettings language="kotlin">
<option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" />
</codeStyleSettings>
</code_scheme>
</component>

5
.idea/codeStyles/codeStyleConfig.xml generated Normal file
View File

@ -0,0 +1,5 @@
<component name="ProjectCodeStyleConfiguration">
<state>
<option name="USE_PER_PROJECT_SETTINGS" value="true" />
</state>
</component>

9
.idea/misc.xml generated Normal file
View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_7" project-jdk-name="1.8" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/build/classes" />
</component>
<component name="ProjectType">
<option name="id" value="Android" />
</component>
</project>

12
.idea/runConfigurations.xml generated Normal file
View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="RunConfigurationProducerService">
<option name="ignoredProducers">
<set>
<option value="org.jetbrains.plugins.gradle.execution.test.runner.AllInPackageGradleConfigurationProducer" />
<option value="org.jetbrains.plugins.gradle.execution.test.runner.TestClassGradleConfigurationProducer" />
<option value="org.jetbrains.plugins.gradle.execution.test.runner.TestMethodGradleConfigurationProducer" />
</set>
</option>
</component>
</project>

View File

@ -62,7 +62,7 @@ Also available in Play Store
- [x] Offline Persistence with Room
- [x] Databinding
- [ ] ~[Jetpack Compose](https://github.com/mrcsxsiq/Kotlin-Pokedex/issues/4)~ - See [compose-pokedex](https://github.com/zsoltk/compose-pokedex)
- [ ] Coroutines
- [x] Coroutines
- [ ] Koin
- [ ] JUnit
- [ ] MotionLayout

View File

@ -53,6 +53,14 @@ dependencies {
kapt 'com.github.bumptech.glide:compiler:4.9.0'
implementation 'com.github.bumptech.glide:glide:4.9.0'
// DI
// Koin for Android
implementation "org.koin:koin-android:2.0.1"
// or Koin for Lifecycle scoping
implementation "org.koin:koin-androidx-scope:2.0.1"
// or Koin for Android Architecture ViewModel
implementation "org.koin:koin-androidx-viewmodel:2.0.1"
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test.ext:junit:1.1.1'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'

View File

@ -4,26 +4,24 @@ import android.app.Application
import android.content.Context
import androidx.room.Room
import dev.marcosfarias.pokedex.database.AppDatabase
import dev.marcosfarias.pokedex.di.appComponent
import org.koin.android.ext.koin.androidContext
import org.koin.core.context.startKoin
class App : Application() {
companion object {
lateinit var context: Context
lateinit var database: AppDatabase
}
override fun onCreate() {
super.onCreate()
context = this
database = Room.databaseBuilder(
this,
AppDatabase::class.java,
getString(R.string.app_name)
)
.fallbackToDestructiveMigration()
.build()
configureDI()
}
private fun configureDI() = startKoin {
androidContext(this@App)
modules(provideComponent())
}
private fun provideComponent() = appComponent
}

View File

@ -0,0 +1,8 @@
package dev.marcosfarias.pokedex.di
val appComponent = listOf(
databaseModule,
networkModule,
viewModelsModule
)

View File

@ -0,0 +1,20 @@
package dev.marcosfarias.pokedex.di
import androidx.room.Room
import dev.marcosfarias.pokedex.database.AppDatabase
import org.koin.android.ext.koin.androidApplication
import org.koin.dsl.module
val databaseModule = module {
single {
Room.databaseBuilder(
androidApplication(),
AppDatabase::class.java,
"rapidsend.db"
).build()
}
single {
get<AppDatabase>().pokemonDAO()
}
}

View File

@ -0,0 +1,21 @@
package dev.marcosfarias.pokedex.di
import dev.marcosfarias.pokedex.repository.PokemonService
import org.koin.dsl.module
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
val networkModule = module {
single<Retrofit> {
Retrofit.Builder()
.baseUrl("https://gist.githubusercontent.com/mrcsxsiq/b94dbe9ab67147b642baa9109ce16e44/raw/97811a5df2df7304b5bc4fbb9ee018a0339b8a38/")
.addConverterFactory(GsonConverterFactory.create())
.build()
}
factory<PokemonService> {
get<Retrofit>().create(
PokemonService::class.java
)
}
}

View File

@ -0,0 +1,15 @@
package dev.marcosfarias.pokedex.di
import dev.marcosfarias.pokedex.ui.dashboard.DashboardViewModel
import dev.marcosfarias.pokedex.ui.generation.GenerationViewModel
import dev.marcosfarias.pokedex.ui.home.HomeViewModel
import dev.marcosfarias.pokedex.ui.pokedex.PokedexViewModel
import org.koin.androidx.viewmodel.dsl.viewModel
import org.koin.dsl.module
val viewModelsModule = module {
viewModel { DashboardViewModel(get()) }
viewModel { GenerationViewModel(get()) }
viewModel { HomeViewModel(get()) }
viewModel { PokedexViewModel(get(), get()) }
}

View File

@ -14,15 +14,12 @@ import com.bumptech.glide.Glide
import dev.marcosfarias.pokedex.R
import dev.marcosfarias.pokedex.utils.PokemonColorUtil
import kotlinx.android.synthetic.main.fragment_dashboard.*
import org.koin.androidx.viewmodel.ext.android.viewModel
class DashboardFragment : Fragment() {
private lateinit var dashboardViewModel: DashboardViewModel
private val dashboardViewModel: DashboardViewModel by viewModel()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
dashboardViewModel = ViewModelProviders.of(this).get(DashboardViewModel::class.java)
}
override fun onCreateView(
inflater: LayoutInflater,

View File

@ -6,9 +6,7 @@ import dev.marcosfarias.pokedex.App
import dev.marcosfarias.pokedex.database.dao.PokemonDAO
import dev.marcosfarias.pokedex.model.Pokemon
class DashboardViewModel : ViewModel() {
private val pokemonDAO: PokemonDAO = App.database.pokemonDAO()
class DashboardViewModel(private val pokemonDAO: PokemonDAO) : ViewModel() {
fun getPokemonById(id: String?): LiveData<Pokemon> {
return pokemonDAO.getById(id)

View File

@ -10,6 +10,7 @@ import androidx.lifecycle.ViewModelProviders
import dev.marcosfarias.pokedex.R
import dev.marcosfarias.pokedex.ui.dashboard.DashboardViewModel
import kotlinx.android.synthetic.main.fragment_about.*
import org.koin.androidx.viewmodel.ext.android.viewModel
class AboutFragment : Fragment() {
@ -22,12 +23,8 @@ class AboutFragment : Fragment() {
}
}
private lateinit var dashboardViewModel: DashboardViewModel
private val dashboardViewModel: DashboardViewModel by viewModel()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
dashboardViewModel = ViewModelProviders.of(this).get(DashboardViewModel::class.java)
}
override fun onCreateView(
inflater: LayoutInflater,

View File

@ -8,15 +8,12 @@ import androidx.fragment.app.Fragment
import androidx.lifecycle.ViewModelProviders
import dev.marcosfarias.pokedex.R
import dev.marcosfarias.pokedex.ui.dashboard.DashboardViewModel
import org.koin.androidx.viewmodel.ext.android.viewModel
class EvolutionFragment : Fragment() {
private lateinit var dashboardViewModel: DashboardViewModel
private val dashboardViewModel: DashboardViewModel by viewModel()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
dashboardViewModel = ViewModelProviders.of(this).get(DashboardViewModel::class.java)
}
override fun onCreateView(
inflater: LayoutInflater,

View File

@ -10,6 +10,7 @@ import androidx.lifecycle.ViewModelProviders
import dev.marcosfarias.pokedex.R
import dev.marcosfarias.pokedex.ui.dashboard.DashboardViewModel
import kotlinx.android.synthetic.main.fragment_stats.*
import org.koin.androidx.viewmodel.ext.android.viewModel
class StatsFragment : Fragment() {
@ -22,12 +23,8 @@ class StatsFragment : Fragment() {
}
}
private lateinit var dashboardViewModel: DashboardViewModel
private val dashboardViewModel: DashboardViewModel by viewModel()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
dashboardViewModel = ViewModelProviders.of(this).get(DashboardViewModel::class.java)
}
override fun onCreateView(
inflater: LayoutInflater,

View File

@ -11,15 +11,12 @@ import com.google.android.material.bottomsheet.BottomSheetDialogFragment
import dev.marcosfarias.pokedex.R
import dev.marcosfarias.pokedex.model.Generation
import kotlinx.android.synthetic.main.fragment_generation.*
import org.koin.androidx.viewmodel.ext.android.viewModel
class GenerationFragment : BottomSheetDialogFragment() {
private lateinit var generationViewModel: GenerationViewModel
private val generationViewModel: GenerationViewModel by viewModel()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
generationViewModel = ViewModelProviders.of(this).get(GenerationViewModel::class.java)
}
override fun onCreateView(
inflater: LayoutInflater,

View File

@ -1,5 +1,6 @@
package dev.marcosfarias.pokedex.ui.generation
import android.content.Context
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
@ -7,7 +8,7 @@ import dev.marcosfarias.pokedex.App
import dev.marcosfarias.pokedex.R
import dev.marcosfarias.pokedex.model.Generation
class GenerationViewModel : ViewModel() {
class GenerationViewModel(private val context: Context) : ViewModel() {
private val listGeneration = MutableLiveData<List<Generation>>()
@ -15,42 +16,42 @@ class GenerationViewModel : ViewModel() {
listGeneration.value = listOf(
Generation(
1,
App.context.resources.getString(R.string.generation_item_1),
context.resources.getString(R.string.generation_item_1),
R.drawable.gen1
),
Generation(
1,
App.context.resources.getString(R.string.generation_item_2),
context.resources.getString(R.string.generation_item_2),
R.drawable.gen2
),
Generation(
1,
App.context.resources.getString(R.string.generation_item_3),
context.resources.getString(R.string.generation_item_3),
R.drawable.gen3
),
Generation(
1,
App.context.resources.getString(R.string.generation_item_4),
context.resources.getString(R.string.generation_item_4),
R.drawable.gen4
),
Generation(
1,
App.context.resources.getString(R.string.generation_item_5),
context.resources.getString(R.string.generation_item_5),
R.drawable.gen5
),
Generation(
1,
App.context.resources.getString(R.string.generation_item_6),
context.resources.getString(R.string.generation_item_6),
R.drawable.gen6
),
Generation(
1,
App.context.resources.getString(R.string.generation_item_7),
context.resources.getString(R.string.generation_item_7),
R.drawable.gen7
),
Generation(
1,
App.context.resources.getString(R.string.generation_item_8),
context.resources.getString(R.string.generation_item_8),
R.drawable.gen8
)
)

View File

@ -14,15 +14,12 @@ import dev.marcosfarias.pokedex.model.Menu
import dev.marcosfarias.pokedex.model.News
import dev.marcosfarias.pokedex.utils.PokemonColorUtil
import kotlinx.android.synthetic.main.fragment_home.*
import org.koin.androidx.viewmodel.ext.android.viewModel
class HomeFragment : Fragment() {
private lateinit var homeViewModel: HomeViewModel
private val homeViewModel: HomeViewModel by viewModel()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
homeViewModel = ViewModelProviders.of(this).get(HomeViewModel::class.java)
}
override fun onCreateView(
inflater: LayoutInflater,

View File

@ -1,5 +1,6 @@
package dev.marcosfarias.pokedex.ui.home
import android.content.Context
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
@ -8,19 +9,19 @@ import dev.marcosfarias.pokedex.R
import dev.marcosfarias.pokedex.model.Menu
import dev.marcosfarias.pokedex.model.News
class HomeViewModel : ViewModel() {
class HomeViewModel(private val context: Context) : ViewModel() {
private val listMenu = MutableLiveData<List<Menu>>()
private val listNews = MutableLiveData<List<News>>()
fun getListMenu(): LiveData<List<Menu>> {
listMenu.value = listOf(
Menu(1, App.context.resources.getString(R.string.menu_item_1), R.color.lightTeal),
Menu(1, App.context.resources.getString(R.string.menu_item_2), R.color.lightRed),
Menu(1, App.context.resources.getString(R.string.menu_item_3), R.color.lightBlue),
Menu(1, App.context.resources.getString(R.string.menu_item_4), R.color.lightYellow),
Menu(1, App.context.resources.getString(R.string.menu_item_5), R.color.lightPurple),
Menu(1, App.context.resources.getString(R.string.menu_item_6), R.color.lightBrown)
Menu(1, context.resources.getString(R.string.menu_item_1), R.color.lightTeal),
Menu(1, context.resources.getString(R.string.menu_item_2), R.color.lightRed),
Menu(1, context.resources.getString(R.string.menu_item_3), R.color.lightBlue),
Menu(1, context.resources.getString(R.string.menu_item_4), R.color.lightYellow),
Menu(1, context.resources.getString(R.string.menu_item_5), R.color.lightPurple),
Menu(1, context.resources.getString(R.string.menu_item_6), R.color.lightBrown)
)
return listMenu
}

View File

@ -15,15 +15,12 @@ import dev.marcosfarias.pokedex.ui.generation.GenerationFragment
import dev.marcosfarias.pokedex.ui.search.SearchFragment
import dev.marcosfarias.pokedex.utils.PokemonColorUtil
import kotlinx.android.synthetic.main.fragment_pokedex.*
import org.koin.androidx.viewmodel.ext.android.viewModel
class PokedexFragment : Fragment() {
private lateinit var pokedexViewModel: PokedexViewModel
private val pokedexViewModel: PokedexViewModel by viewModel()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
pokedexViewModel = ViewModelProviders.of(this).get(PokedexViewModel::class.java)
}
override fun onCreateView(
inflater: LayoutInflater,

View File

@ -6,21 +6,22 @@ import dev.marcosfarias.pokedex.App
import dev.marcosfarias.pokedex.database.dao.PokemonDAO
import dev.marcosfarias.pokedex.model.Pokemon
import dev.marcosfarias.pokedex.repository.APIService
import dev.marcosfarias.pokedex.repository.PokemonService
import retrofit2.Call
import retrofit2.Callback
import retrofit2.Response
import kotlin.concurrent.thread
class PokedexViewModel : ViewModel() {
class PokedexViewModel(private val pokemonDAO: PokemonDAO, private val pokemonService: PokemonService ) : ViewModel() {
private val pokemonDAO: PokemonDAO = App.database.pokemonDAO()
init {
initNetworkRequest()
}
private fun initNetworkRequest() {
val call = APIService.pokemonService.get()
val call = pokemonService.get()
call.enqueue(object : Callback<List<Pokemon>?> {
override fun onResponse(
call: Call<List<Pokemon>?>?,