diff --git a/app/build.gradle b/app/build.gradle
index 952fb2a9..78096397 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -19,6 +19,7 @@ plugins {
id("jacoco-android")
id("com.mikepenz.aboutlibraries.plugin")
id("com.google.firebase.crashlytics")
+ id("androidx.navigation.safeargs")
}
jacoco {
@@ -144,6 +145,10 @@ dependencies {
implementation appDependencies.koinAndroid
implementation appDependencies.koinAndroidViewModel
+ //navigation
+ implementation appDependencies.navigationFragment
+ implementation appDependencies.navigationUi
+
//Test Libs
testImplementation testDependencies.junit
testImplementation testDependencies.robolectric
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 08462a89..01c10730 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -10,25 +10,9 @@
android:roundIcon="@mipmap/ic_launcher_round"
android:theme="@style/AppTheme">
-
-
-
-
-
-
diff --git a/app/src/main/kotlin/com/k0d4black/theforce/activities/SettingsActivity.kt b/app/src/main/kotlin/com/k0d4black/theforce/activities/SettingsActivity.kt
deleted file mode 100644
index 45e9ae98..00000000
--- a/app/src/main/kotlin/com/k0d4black/theforce/activities/SettingsActivity.kt
+++ /dev/null
@@ -1,35 +0,0 @@
-/**
- *
- * Copyright 2020 David Odari
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
- * in compliance with the License. You may obtain a copy of the License at
- * http://www.apache.org/licenses/LICENSE-2.0
- * Unless required by applicable law or agreed to in writing, software distributed under the License
- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
- * or implied. See the License for the specific language governing permissions and limitations under
- * the License.
- *
- **/
-package com.k0d4black.theforce.activities
-
-import android.os.Bundle
-import android.view.View
-import com.k0d4black.theforce.base.BaseActivity
-import com.k0d4black.theforce.commons.startActivity
-import com.k0d4black.theforce.databinding.ActivitySettingsBinding
-import com.k0d4black.theforce.activities.AboutActivity
-
-internal class SettingsActivity : BaseActivity() {
-
- override fun onCreate(savedInstanceState: Bundle?) {
- super.onCreate(savedInstanceState)
- val binding = ActivitySettingsBinding.inflate(layoutInflater)
- setContentView(binding.root)
- setSupportActionBar(binding.settingsToolbar)
- supportActionBar?.setDisplayHomeAsUpEnabled(true)
- }
-
- fun openAboutActivity(view: View) = startActivity()
-
-}
diff --git a/app/src/main/kotlin/com/k0d4black/theforce/base/BaseFavoritesActivity.kt b/app/src/main/kotlin/com/k0d4black/theforce/base/BaseFavoritesFragment.kt
similarity index 76%
rename from app/src/main/kotlin/com/k0d4black/theforce/base/BaseFavoritesActivity.kt
rename to app/src/main/kotlin/com/k0d4black/theforce/base/BaseFavoritesFragment.kt
index ca6beac8..a88732b6 100644
--- a/app/src/main/kotlin/com/k0d4black/theforce/base/BaseFavoritesActivity.kt
+++ b/app/src/main/kotlin/com/k0d4black/theforce/base/BaseFavoritesFragment.kt
@@ -16,19 +16,19 @@
package com.k0d4black.theforce.base
import android.os.Bundle
-import android.view.Menu
-import android.view.MenuItem
-import android.view.ViewGroup
+import android.view.*
+import androidx.annotation.LayoutRes
import androidx.lifecycle.Observer
import com.k0d4black.theforce.R
-import com.k0d4black.theforce.activities.IFavoritesBinder
import com.k0d4black.theforce.commons.NavigationUtils
import com.k0d4black.theforce.commons.showSnackbar
import com.k0d4black.theforce.models.FavoritePresentation
+import com.k0d4black.theforce.ui.IFavoritesBinder
import com.k0d4black.theforce.viewmodel.FavoriteViewModel
import org.koin.androidx.viewmodel.ext.android.viewModel
-internal abstract class BaseFavoritesActivity : BaseActivity(), IFavoritesBinder {
+internal abstract class BaseFavoritesFragment(@LayoutRes contentLayoutId: Int) :
+ BaseFragment(contentLayoutId), IFavoritesBinder {
// region Members
@@ -44,34 +44,35 @@ internal abstract class BaseFavoritesActivity : BaseActivity(), IFavoritesBinder
// region Android API
- override fun onCreate(savedInstanceState: Bundle?) {
- super.onCreate(savedInstanceState)
+ override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
+ super.onViewCreated(view, savedInstanceState)
+
val favorite =
- intent.getParcelableExtra(NavigationUtils.FAVORITE_PARCEL_KEY)
+ requireArguments().get(NavigationUtils.FAVORITE_PARCEL_KEY) as FavoritePresentation?
favorite?.let { favoritePresentation ->
bindFavorite(favoritePresentation)
characterName = favoritePresentation.characterPresentation.name
this.favoritePresentation = favoritePresentation
checkIfFavorite()
- invalidateOptionsMenu()
+ requireActivity().invalidateOptionsMenu()
}
observeFavoriteViewState()
}
- override fun onCreateOptionsMenu(menu: Menu?): Boolean {
- menuInflater.inflate(R.menu.favorites_menu, menu)
- return super.onCreateOptionsMenu(menu)
+ override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
+ inflater.inflate(R.menu.favorites_menu, menu)
+ super.onCreateOptionsMenu(menu, inflater)
}
- override fun onPrepareOptionsMenu(menu: Menu?): Boolean {
- val menuItem = menu?.getItem(0)
+ override fun onPrepareOptionsMenu(menu: Menu) {
+ val menuItem = menu.getItem(0)
if (isFavorite)
menuItem?.setIcon(R.drawable.ic_favs_24dp)
else
menuItem?.setIcon(R.drawable.ic_no_favs_24dp)
- return super.onPrepareOptionsMenu(menu)
+ super.onPrepareOptionsMenu(menu)
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
@@ -86,7 +87,7 @@ internal abstract class BaseFavoritesActivity : BaseActivity(), IFavoritesBinder
isFavorite = !isFavorite
}
}
- invalidateOptionsMenu()
+ requireActivity().invalidateOptionsMenu()
true
}
else -> super.onOptionsItemSelected(item)
@@ -122,9 +123,9 @@ internal abstract class BaseFavoritesActivity : BaseActivity(), IFavoritesBinder
}
private fun observeFavoriteViewState() {
- favoritesViewModel.favoriteViewState.observe(this, Observer {
+ favoritesViewModel.favoriteViewState.observe(viewLifecycleOwner, Observer {
isFavorite = it.isFavorite
- invalidateOptionsMenu()
+ requireActivity().invalidateOptionsMenu()
it.error?.let { e ->
showSnackbar(rootViewGroup, getString(e.message))
}
diff --git a/app/src/main/kotlin/com/k0d4black/theforce/base/BaseActivity.kt b/app/src/main/kotlin/com/k0d4black/theforce/base/BaseFragment.kt
similarity index 74%
rename from app/src/main/kotlin/com/k0d4black/theforce/base/BaseActivity.kt
rename to app/src/main/kotlin/com/k0d4black/theforce/base/BaseFragment.kt
index c0342d7f..bdb68194 100644
--- a/app/src/main/kotlin/com/k0d4black/theforce/base/BaseActivity.kt
+++ b/app/src/main/kotlin/com/k0d4black/theforce/base/BaseFragment.kt
@@ -16,12 +16,14 @@ package com.k0d4black.theforce.base
import android.os.Build
import android.os.Bundle
import android.view.View
-import androidx.appcompat.app.AppCompatActivity
+import androidx.annotation.LayoutRes
+import androidx.fragment.app.Fragment
import androidx.lifecycle.Observer
import com.k0d4black.theforce.commons.NetworkUtils
import com.k0d4black.theforce.commons.versionFrom
-internal open class BaseActivity : AppCompatActivity() {
+internal open class BaseFragment(@LayoutRes layoutId : Int) : Fragment(layoutId) {
+
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
whiteStatusBar()
@@ -29,13 +31,13 @@ internal open class BaseActivity : AppCompatActivity() {
private fun whiteStatusBar() {
if (versionFrom(Build.VERSION_CODES.M)) {
- window.decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR
- window.statusBarColor = getColor(android.R.color.white)
+ requireActivity().window.decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR
+ requireActivity().window.statusBarColor = requireContext().getColor(android.R.color.white)
}
}
protected fun onNetworkChange(block: (Boolean) -> Unit) {
- NetworkUtils.getNetworkStatus(this)
+ NetworkUtils.getNetworkStatus(requireContext())
.observe(this, Observer { isConnected ->
block(isConnected)
})
diff --git a/app/src/main/kotlin/com/k0d4black/theforce/commons/ContextExtensions.kt b/app/src/main/kotlin/com/k0d4black/theforce/commons/ContextExtensions.kt
index fd382cb4..6416092b 100644
--- a/app/src/main/kotlin/com/k0d4black/theforce/commons/ContextExtensions.kt
+++ b/app/src/main/kotlin/com/k0d4black/theforce/commons/ContextExtensions.kt
@@ -15,23 +15,10 @@
*/
package com.k0d4black.theforce.commons
-import android.app.Activity
import android.content.Context
-import android.content.Intent
-import android.widget.Toast
import androidx.annotation.ColorRes
import androidx.core.content.ContextCompat
internal fun Context.loadColor(@ColorRes colorRes: Int): Int {
return ContextCompat.getColor(this, colorRes)
-}
-
-internal fun Context.showToast(message: String) {
- Toast.makeText(this, message, Toast.LENGTH_SHORT).show()
-}
-
-internal inline fun Context.startActivity(block: Intent.() -> Unit = {}) {
- val intent = Intent(this, T::class.java)
- block(intent)
- startActivity(intent)
}
\ No newline at end of file
diff --git a/app/src/main/kotlin/com/k0d4black/theforce/commons/ActivityExtensions.kt b/app/src/main/kotlin/com/k0d4black/theforce/commons/FragmentExtensions.kt
similarity index 68%
rename from app/src/main/kotlin/com/k0d4black/theforce/commons/ActivityExtensions.kt
rename to app/src/main/kotlin/com/k0d4black/theforce/commons/FragmentExtensions.kt
index 4d50606b..b17dbc3a 100644
--- a/app/src/main/kotlin/com/k0d4black/theforce/commons/ActivityExtensions.kt
+++ b/app/src/main/kotlin/com/k0d4black/theforce/commons/FragmentExtensions.kt
@@ -15,20 +15,20 @@
*/
package com.k0d4black.theforce.commons
-import android.app.Activity
import android.view.View
+import androidx.fragment.app.Fragment
import com.google.android.material.snackbar.Snackbar
import com.k0d4black.theforce.R
-internal fun Activity.showSnackbar(view: View, message: String, isError: Boolean = false) {
+internal fun Fragment.showSnackbar(view: View, message: String, isError: Boolean = false) {
val sb = Snackbar.make(view, message, Snackbar.LENGTH_LONG)
if (isError)
- sb.setBackgroundTint(loadColor(R.color.colorError))
- .setTextColor(loadColor(R.color.colorOnError))
+ sb.setBackgroundTint(requireContext().loadColor(R.color.colorError))
+ .setTextColor(requireContext().loadColor(R.color.colorOnError))
.show()
else
- sb.setBackgroundTint(loadColor(R.color.colorSecondary))
- .setTextColor(loadColor(R.color.colorOnSecondary))
+ sb.setBackgroundTint(requireContext().loadColor(R.color.colorSecondary))
+ .setTextColor(requireContext().loadColor(R.color.colorOnSecondary))
.show()
}
\ No newline at end of file
diff --git a/app/src/main/kotlin/com/k0d4black/theforce/commons/NavigationUtils.kt b/app/src/main/kotlin/com/k0d4black/theforce/commons/NavigationUtils.kt
index 0e9ac366..454c6d08 100644
--- a/app/src/main/kotlin/com/k0d4black/theforce/commons/NavigationUtils.kt
+++ b/app/src/main/kotlin/com/k0d4black/theforce/commons/NavigationUtils.kt
@@ -14,6 +14,6 @@
package com.k0d4black.theforce.commons
internal object NavigationUtils {
- const val CHARACTER_PARCEL_KEY = "character_url"
+ const val CHARACTER_PARCEL_KEY = "character"
const val FAVORITE_PARCEL_KEY = "favorite"
}
diff --git a/app/src/main/kotlin/com/k0d4black/theforce/models/CharacterPresentation.kt b/app/src/main/kotlin/com/k0d4black/theforce/models/CharacterPresentation.kt
index 43b980a6..ebd7b500 100644
--- a/app/src/main/kotlin/com/k0d4black/theforce/models/CharacterPresentation.kt
+++ b/app/src/main/kotlin/com/k0d4black/theforce/models/CharacterPresentation.kt
@@ -17,7 +17,7 @@ import android.os.Parcelable
import kotlinx.android.parcel.Parcelize
@Parcelize
-internal data class CharacterPresentation(
+data class CharacterPresentation(
val name: String,
val birthYear: String,
val heightInCm: String,
diff --git a/app/src/main/kotlin/com/k0d4black/theforce/models/FavoritePresentation.kt b/app/src/main/kotlin/com/k0d4black/theforce/models/FavoritePresentation.kt
index 03a619ff..c4f381c4 100644
--- a/app/src/main/kotlin/com/k0d4black/theforce/models/FavoritePresentation.kt
+++ b/app/src/main/kotlin/com/k0d4black/theforce/models/FavoritePresentation.kt
@@ -17,7 +17,7 @@ import android.os.Parcelable
import kotlinx.android.parcel.Parcelize
@Parcelize
-internal data class FavoritePresentation(
+data class FavoritePresentation(
val characterPresentation: CharacterPresentation,
val planetPresentation: PlanetPresentation,
val speciePresentation: List,
diff --git a/app/src/main/kotlin/com/k0d4black/theforce/models/FilmPresentation.kt b/app/src/main/kotlin/com/k0d4black/theforce/models/FilmPresentation.kt
index bfb17988..77364fee 100644
--- a/app/src/main/kotlin/com/k0d4black/theforce/models/FilmPresentation.kt
+++ b/app/src/main/kotlin/com/k0d4black/theforce/models/FilmPresentation.kt
@@ -17,4 +17,4 @@ import android.os.Parcelable
import kotlinx.android.parcel.Parcelize
@Parcelize
-internal data class FilmPresentation(val title: String, val openingCrawl: String) : Parcelable
+data class FilmPresentation(val title: String, val openingCrawl: String) : Parcelable
diff --git a/app/src/main/kotlin/com/k0d4black/theforce/models/PlanetPresentation.kt b/app/src/main/kotlin/com/k0d4black/theforce/models/PlanetPresentation.kt
index 5eada6f1..2b611830 100644
--- a/app/src/main/kotlin/com/k0d4black/theforce/models/PlanetPresentation.kt
+++ b/app/src/main/kotlin/com/k0d4black/theforce/models/PlanetPresentation.kt
@@ -17,4 +17,4 @@ import android.os.Parcelable
import kotlinx.android.parcel.Parcelize
@Parcelize
-internal data class PlanetPresentation(val name: String, val population: Long) : Parcelable
\ No newline at end of file
+data class PlanetPresentation(val name: String, val population: Long) : Parcelable
\ No newline at end of file
diff --git a/app/src/main/kotlin/com/k0d4black/theforce/models/SpeciePresentation.kt b/app/src/main/kotlin/com/k0d4black/theforce/models/SpeciePresentation.kt
index 490edb87..33b634b4 100644
--- a/app/src/main/kotlin/com/k0d4black/theforce/models/SpeciePresentation.kt
+++ b/app/src/main/kotlin/com/k0d4black/theforce/models/SpeciePresentation.kt
@@ -17,4 +17,4 @@ import android.os.Parcelable
import kotlinx.android.parcel.Parcelize
@Parcelize
-internal data class SpeciePresentation(val name: String, val language: String) : Parcelable
+data class SpeciePresentation(val name: String, val language: String) : Parcelable
diff --git a/app/src/main/kotlin/com/k0d4black/theforce/activities/AboutActivity.kt b/app/src/main/kotlin/com/k0d4black/theforce/ui/AboutFragment.kt
similarity index 58%
rename from app/src/main/kotlin/com/k0d4black/theforce/activities/AboutActivity.kt
rename to app/src/main/kotlin/com/k0d4black/theforce/ui/AboutFragment.kt
index 3d2ddd0e..e93f17ea 100644
--- a/app/src/main/kotlin/com/k0d4black/theforce/activities/AboutActivity.kt
+++ b/app/src/main/kotlin/com/k0d4black/theforce/ui/AboutFragment.kt
@@ -11,28 +11,29 @@
* the License.
*
**/
-package com.k0d4black.theforce.activities
+package com.k0d4black.theforce.ui
import android.os.Bundle
+import android.view.View
import com.k0d4black.theforce.R
-import com.k0d4black.theforce.base.BaseActivity
-import com.k0d4black.theforce.databinding.ActivityAboutBinding
+import com.k0d4black.theforce.base.BaseFragment
import com.mikepenz.aboutlibraries.LibsBuilder
+import kotlinx.android.synthetic.main.fragment_about.*
-internal class AboutActivity : BaseActivity() {
+internal class AboutFragment : BaseFragment(R.layout.fragment_about) {
- override fun onCreate(savedInstanceState: Bundle?) {
- super.onCreate(savedInstanceState)
- val binding = ActivityAboutBinding.inflate(layoutInflater)
- setContentView(binding.root)
- setSupportActionBar(binding.aboutToolbar)
- supportActionBar?.setDisplayHomeAsUpEnabled(true)
+ override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
+ super.onViewCreated(view, savedInstanceState)
+
+ (requireActivity() as DashboardActivity).setSupportActionBar(about_toolbar)
+ (requireActivity() as DashboardActivity).supportActionBar?.setDisplayHomeAsUpEnabled(true)
val fragment = LibsBuilder()
.withAboutIconShown(true)
.supportFragment()
- supportFragmentManager.beginTransaction()
+ requireActivity().supportFragmentManager.beginTransaction()
.add(R.id.fragment_container, fragment).commit()
}
+
}
diff --git a/app/src/main/kotlin/com/k0d4black/theforce/activities/CharacterDetailsActivity.kt b/app/src/main/kotlin/com/k0d4black/theforce/ui/CharacterDetailsFragment.kt
similarity index 66%
rename from app/src/main/kotlin/com/k0d4black/theforce/activities/CharacterDetailsActivity.kt
rename to app/src/main/kotlin/com/k0d4black/theforce/ui/CharacterDetailsFragment.kt
index 68031730..e0186a60 100644
--- a/app/src/main/kotlin/com/k0d4black/theforce/activities/CharacterDetailsActivity.kt
+++ b/app/src/main/kotlin/com/k0d4black/theforce/ui/CharacterDetailsFragment.kt
@@ -11,49 +11,69 @@
* the License.
*
**/
-package com.k0d4black.theforce.activities
+package com.k0d4black.theforce.ui
import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
import android.view.ViewGroup
import androidx.databinding.DataBindingUtil
import androidx.lifecycle.Observer
import com.k0d4black.theforce.R
-import com.k0d4black.theforce.base.BaseFavoritesActivity
-import com.k0d4black.theforce.commons.*
-import com.k0d4black.theforce.databinding.ActivityCharacterDetailBinding
-import com.k0d4black.theforce.idlingresource.EspressoIdlingResource
-import com.k0d4black.theforce.models.*
import com.k0d4black.theforce.adapters.createFilmsAdapter
import com.k0d4black.theforce.adapters.createSpeciesAdapter
+import com.k0d4black.theforce.base.BaseFavoritesFragment
+import com.k0d4black.theforce.commons.hide
+import com.k0d4black.theforce.commons.remove
+import com.k0d4black.theforce.commons.show
+import com.k0d4black.theforce.commons.showSnackbar
+import com.k0d4black.theforce.databinding.FragmentCharacterDetailBinding
+import com.k0d4black.theforce.idlingresource.EspressoIdlingResource
+import com.k0d4black.theforce.models.*
import com.k0d4black.theforce.viewmodel.CharacterDetailViewModel
+import kotlinx.android.synthetic.main.fragment_character_detail.*
+import kotlinx.android.synthetic.main.layout_films.view.*
+import kotlinx.android.synthetic.main.layout_planet.view.*
+import kotlinx.android.synthetic.main.layout_specie.view.*
import org.koin.androidx.viewmodel.ext.android.viewModel
-internal class CharacterDetailsActivity : BaseFavoritesActivity(), ICharacterDetailsBinder {
+internal class CharacterDetailsFragment : BaseFavoritesFragment(R.layout.fragment_character_detail),
+ ICharacterDetailsBinder {
// region Members
private val characterDetailViewModel by viewModel()
- private lateinit var binding: ActivityCharacterDetailBinding
-
private val filmsAdapter = createFilmsAdapter()
private val speciesAdapter = createSpeciesAdapter()
+ private lateinit var binding: FragmentCharacterDetailBinding
+
// endregion
// region Android API
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
+ (requireActivity() as DashboardActivity).setSupportActionBar(details_toolbar)
+ (requireActivity() as DashboardActivity).supportActionBar?.setDisplayHomeAsUpEnabled(true)
+ }
- binding = DataBindingUtil.setContentView(this, R.layout.activity_character_detail)
+ override fun onCreateView(
+ inflater: LayoutInflater,
+ container: ViewGroup?,
+ savedInstanceState: Bundle?
+ ): View {
+ binding = DataBindingUtil.inflate(
+ inflater, R.layout.fragment_character_detail, container, false)
+ return binding.root
+ }
- setSupportActionBar(binding.detailsToolbar)
- supportActionBar?.setDisplayHomeAsUpEnabled(true)
+ override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
+ super.onViewCreated(view, savedInstanceState)
- val character =
- intent.getParcelableExtra(NavigationUtils.CHARACTER_PARCEL_KEY)
+ val character = CharacterDetailsFragmentArgs.fromBundle(requireArguments()).character
if (character == null) {
characterDetailViewModel
@@ -79,14 +99,14 @@ internal class CharacterDetailsActivity : BaseFavoritesActivity(), ICharacterDet
}
override val rootViewGroup: ViewGroup
- get() = binding.characterDetailsLayout
+ get() = character_details_layout
// endregion
// region Private API
private fun observeDetailViewState() {
- characterDetailViewModel.detailViewState.observe(this, Observer {
+ characterDetailViewModel.detailViewState.observe(viewLifecycleOwner, Observer {
bindCharacterBasicInfo(it.info)
bindSpecies(it.specie)
bindFilms(it.films)
@@ -96,7 +116,7 @@ internal class CharacterDetailsActivity : BaseFavoritesActivity(), ICharacterDet
}
if (it.isComplete) {
showSnackbar(
- binding.characterDetailsLayout,
+ character_details_layout,
getString(R.string.info_loading_complete)
)
characterDetailViewModel.createFavoritePresentationFromRemoteCharacter()
@@ -106,28 +126,29 @@ internal class CharacterDetailsActivity : BaseFavoritesActivity(), ICharacterDet
private fun observeFavoritePresentationCreationFromRemote() {
characterDetailViewModel.remoteToFavoritePresentation
- .observe(this, Observer { favPresentation ->
+ .observe(viewLifecycleOwner, Observer { favPresentation ->
favoritePresentation = favPresentation
})
}
private fun onError(message: String) {
- binding.filmsLayout.filmsProgressBar.hide()
- binding.planetLayout.planetProgressBar.hide()
- binding.specieLayout.speciesProgressBar.hide()
- binding.filmsLayout.filmsErrorTextView.show()
- binding.planetLayout.planetErrorTextView.show()
- binding.specieLayout.specieErrorTextView.show()
- showSnackbar(binding.characterDetailsLayout, message, isError = true)
+ films_layout.films_progress_bar.hide()
+ planet_layout.planet_progress_bar.hide()
+ specie_layout.species_progress_bar.hide()
+ films_layout.films_error_text_view.show()
+ planet_layout.planet_error_text_view.show()
+ specie_layout.specie_error_text_view.show()
+ showSnackbar(character_details_layout, message, isError = true)
}
private fun onErrorResolved() {
- binding.filmsLayout.filmsErrorTextView.remove()
- binding.planetLayout.planetErrorTextView.remove()
- binding.specieLayout.specieErrorTextView.remove()
- binding.filmsLayout.filmsProgressBar.show()
- binding.planetLayout.planetProgressBar.show()
- binding.specieLayout.speciesProgressBar.show()
+ films_layout.films_error_text_view.remove()
+ planet_layout.planet_error_text_view.remove()
+ specie_layout.specie_error_text_view.remove()
+
+ films_layout.films_progress_bar.show()
+ planet_layout.planet_progress_bar.show()
+ specie_layout.species_progress_bar.show()
}
private fun observeNetworkChanges(characterUrl: String) {
@@ -146,7 +167,7 @@ internal class CharacterDetailsActivity : BaseFavoritesActivity(), ICharacterDet
// region ICharacterDetailsBinder
override fun bindCharacterBasicInfo(character: CharacterPresentation?) {
- supportActionBar?.title = character?.name ?: ""
+ requireActivity().actionBar?.title = character?.name ?: ""
binding.infoLayout.character = character
}
diff --git a/app/src/main/kotlin/com/k0d4black/theforce/ui/DashboardActivity.kt b/app/src/main/kotlin/com/k0d4black/theforce/ui/DashboardActivity.kt
new file mode 100644
index 00000000..c7809cb8
--- /dev/null
+++ b/app/src/main/kotlin/com/k0d4black/theforce/ui/DashboardActivity.kt
@@ -0,0 +1,21 @@
+package com.k0d4black.theforce.ui
+
+import android.os.Bundle
+import android.view.MenuItem
+import androidx.appcompat.app.AppCompatActivity
+import com.k0d4black.theforce.R
+
+class DashboardActivity: AppCompatActivity() {
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ setContentView(R.layout.activity_dashboard)
+ }
+
+ override fun onOptionsItemSelected(item: MenuItem): Boolean {
+ if (item.itemId != R.id.action_settings)
+ onBackPressed()
+ return false
+ }
+
+}
\ No newline at end of file
diff --git a/app/src/main/kotlin/com/k0d4black/theforce/activities/DashboardActivity.kt b/app/src/main/kotlin/com/k0d4black/theforce/ui/DashboardFragment.kt
similarity index 68%
rename from app/src/main/kotlin/com/k0d4black/theforce/activities/DashboardActivity.kt
rename to app/src/main/kotlin/com/k0d4black/theforce/ui/DashboardFragment.kt
index 2f32e1c1..561dfbb7 100644
--- a/app/src/main/kotlin/com/k0d4black/theforce/activities/DashboardActivity.kt
+++ b/app/src/main/kotlin/com/k0d4black/theforce/ui/DashboardFragment.kt
@@ -11,50 +11,42 @@
* the License.
*
**/
-package com.k0d4black.theforce.activities
+package com.k0d4black.theforce.ui
import android.os.Bundle
-import android.view.Menu
-import android.view.MenuItem
-import android.view.View
+import android.view.*
import androidx.core.widget.doOnTextChanged
-import androidx.databinding.DataBindingUtil
import androidx.lifecycle.Observer
+import androidx.navigation.fragment.findNavController
import com.k0d4black.theforce.R
-import com.k0d4black.theforce.base.BaseActivity
+import com.k0d4black.theforce.adapters.createFavoritesAdapter
+import com.k0d4black.theforce.adapters.createSearchResultAdapter
+import com.k0d4black.theforce.base.BaseFragment
import com.k0d4black.theforce.commons.*
-import com.k0d4black.theforce.databinding.ActivityDashboardBinding
import com.k0d4black.theforce.idlingresource.EspressoIdlingResource
import com.k0d4black.theforce.models.CharacterPresentation
import com.k0d4black.theforce.models.FavoritePresentation
import com.k0d4black.theforce.models.states.DashboardFavoritesViewState
import com.k0d4black.theforce.models.states.DashboardSearchViewState
-import com.k0d4black.theforce.adapters.createFavoritesAdapter
-import com.k0d4black.theforce.adapters.createSearchResultAdapter
import com.k0d4black.theforce.viewmodel.DashboardFavoritesViewModel
import com.k0d4black.theforce.viewmodel.DashboardSearchViewModel
import jp.wasabeef.recyclerview.adapters.ScaleInAnimationAdapter
+import kotlinx.android.synthetic.main.fragment_dashboard.*
import org.koin.androidx.viewmodel.ext.android.viewModel
-internal class DashboardActivity : BaseActivity() {
+internal class DashboardFragment : BaseFragment(R.layout.fragment_dashboard) {
// region Members
private val characterSearchViewModel by viewModel()
private val favoritesViewModel by viewModel()
- private lateinit var binding: ActivityDashboardBinding
-
private val searchResultAdapter = createSearchResultAdapter {
- startActivity {
- putExtra(NavigationUtils.CHARACTER_PARCEL_KEY, it)
- }
+ findNavController().navigate(DashboardFragmentDirections.actionToCharacterDetailsFragment(it))
}
private val favoritesAdapter = createFavoritesAdapter {
- startActivity {
- putExtra(NavigationUtils.FAVORITE_PARCEL_KEY, it)
- }
+ findNavController().navigate(DashboardFragmentDirections.actionToFavoriteDetailsFragment(it))
}
// endregion
@@ -63,71 +55,72 @@ internal class DashboardActivity : BaseActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
- binding = DataBindingUtil.setContentView(this, R.layout.activity_dashboard)
+ setHasOptionsMenu(true)
+ }
+
+ override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
+ super.onViewCreated(view, savedInstanceState)
configSupportActionBar()
observeSearchViewState()
observeFavoritesViewState()
onInitialEditTextClick()
-
handleTextChanges()
+ handleUpButtonClick()
}
override fun onResume() {
super.onResume()
- if (binding.dashboardLayout.currentState == binding.dashboardLayout.startState)
+ if (dashboard_layout.currentState == dashboard_layout.startState)
favoritesViewModel.getAllFavorites()
}
- override fun onCreateOptionsMenu(menu: Menu): Boolean {
- menuInflater.inflate(R.menu.main_menu, menu)
- return super.onCreateOptionsMenu(menu)
+ override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
+ inflater.inflate(R.menu.main_menu, menu)
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
return if (item.itemId == R.id.action_settings) {
- startActivity()
+ findNavController().navigate(DashboardFragmentDirections.actionToSettingsFragment())
true
} else super.onOptionsItemSelected(item)
}
// endregion
- // region Public API
-
- fun handleUpButtonClick(view: View) {
- binding.dashboardLayout.transitionToStart()
- }
-
- // endregion
-
// region Private API
private fun configSupportActionBar() {
- setSupportActionBar(binding.searchToolbar)
- supportActionBar?.setDisplayShowTitleEnabled(false)
+ (requireActivity() as DashboardActivity).setSupportActionBar(search_toolbar)
+ (requireActivity() as DashboardActivity).supportActionBar?.setDisplayShowTitleEnabled(false)
}
private fun onInitialEditTextClick() {
- binding.searchEditText.setOnFocusChangeListener { _, _ ->
- binding.dashboardLayout.transitionToEnd()
+ search_edit_text.setOnFocusChangeListener { _, _ ->
+ dashboard_layout.transitionToEnd()
}
}
private fun handleTextChanges() {
- binding.searchEditText.doOnTextChanged { text, _, _, _ ->
+ search_edit_text.doOnTextChanged { text, _, _, _ ->
text?.let { name ->
if (name.length >= 2) {
- binding.dashboardLayout.transitionToEnd()
+ dashboard_layout.transitionToEnd()
characterSearchViewModel.executeCharacterSearch(name.toString())
}
}
}
}
+ private fun handleUpButtonClick() {
+ back_to_start_state_image_button.setOnClickListener {
+ dashboard_layout.transitionToStart()
+ }
+ }
+
private fun observeFavoritesViewState() {
- favoritesViewModel.favoritesViewState.observe(this, Observer { state ->
+ favoritesViewModel.favoritesViewState.observe(viewLifecycleOwner, Observer { state ->
handleFavoritesLoading(state)
@@ -135,7 +128,7 @@ internal class DashboardActivity : BaseActivity() {
if (favorites.isNotEmpty()) {
handleFavorites(favorites)
} else {
- binding.noFavoritesTextView.show()
+ no_favorites_text_view.show()
}
}
@@ -144,7 +137,7 @@ internal class DashboardActivity : BaseActivity() {
}
private fun observeSearchViewState() {
- characterSearchViewModel.searchViewState.observe(this, Observer { state ->
+ characterSearchViewModel.searchViewState.observe(viewLifecycleOwner, Observer { state ->
handleSearchLoading(state)
@@ -164,42 +157,42 @@ internal class DashboardActivity : BaseActivity() {
private fun handleSearchLoading(state: DashboardSearchViewState) {
EspressoIdlingResource.decrement()
if (state.isLoading) {
- binding.searchResultsRecyclerView.hide()
- binding.searchResultsProgressBar.show()
+ search_results_recycler_view.hide()
+ search_results_progress_bar.show()
} else {
- binding.searchResultsProgressBar.hide()
- binding.searchResultsRecyclerView.show()
+ search_results_progress_bar.hide()
+ search_results_recycler_view.show()
}
}
private fun handleFavoritesLoading(state: DashboardFavoritesViewState) {
EspressoIdlingResource.decrement()
if (state.isLoading) {
- binding.favoritesProgressBar.show()
+ favorites_progress_bar.show()
} else {
- binding.favoritesProgressBar.hide()
+ favorites_progress_bar.hide()
}
}
private fun handleSearchResults(searchResults: List) {
EspressoIdlingResource.decrement()
showSnackbar(
- binding.searchResultsRecyclerView,
+ search_results_recycler_view,
getString(R.string.info_search_done)
)
- binding.searchResultsRecyclerView.apply {
+ search_results_recycler_view.apply {
adapter = ScaleInAnimationAdapter(searchResultAdapter.apply {
submitList(searchResults)
EspressoIdlingResource.decrement()
})
- initRecyclerViewWithLineDecoration(this@DashboardActivity)
+ initRecyclerViewWithLineDecoration(requireContext())
}
}
private fun handleFavorites(favorites: List) {
- binding.noFavoritesTextView.hide()
- binding.favoritesRecyclerView.show()
- binding.favoritesRecyclerView.apply {
+ no_favorites_text_view.hide()
+ favorites_recycler_view.show()
+ favorites_recycler_view.apply {
adapter = ScaleInAnimationAdapter(favoritesAdapter.apply {
submitList(favorites)
EspressoIdlingResource.decrement()
@@ -209,9 +202,9 @@ internal class DashboardActivity : BaseActivity() {
private fun handleNoSearchResults() {
EspressoIdlingResource.decrement()
- binding.searchResultsRecyclerView.hide()
+ search_results_recycler_view.hide()
showSnackbar(
- binding.searchResultsRecyclerView,
+ search_results_recycler_view,
getString(R.string.info_no_results)
)
}
@@ -220,7 +213,7 @@ internal class DashboardActivity : BaseActivity() {
EspressoIdlingResource.decrement()
state.error?.run {
showSnackbar(
- binding.searchResultsRecyclerView,
+ search_results_recycler_view,
getString(this.message),
isError = true
)
@@ -231,7 +224,7 @@ internal class DashboardActivity : BaseActivity() {
EspressoIdlingResource.decrement()
state.error?.run {
showSnackbar(
- binding.favoritesRecyclerView,
+ favorites_recycler_view,
getString(this.message),
isError = true
)
diff --git a/app/src/main/kotlin/com/k0d4black/theforce/activities/FavoriteDetailsActivity.kt b/app/src/main/kotlin/com/k0d4black/theforce/ui/FavoriteDetailsFragment.kt
similarity index 69%
rename from app/src/main/kotlin/com/k0d4black/theforce/activities/FavoriteDetailsActivity.kt
rename to app/src/main/kotlin/com/k0d4black/theforce/ui/FavoriteDetailsFragment.kt
index 10b9866c..fbb26f4c 100644
--- a/app/src/main/kotlin/com/k0d4black/theforce/activities/FavoriteDetailsActivity.kt
+++ b/app/src/main/kotlin/com/k0d4black/theforce/ui/FavoriteDetailsFragment.kt
@@ -1,22 +1,26 @@
-package com.k0d4black.theforce.activities
+package com.k0d4black.theforce.ui
import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
import android.view.ViewGroup
import androidx.databinding.DataBindingUtil
import com.k0d4black.theforce.R
-import com.k0d4black.theforce.base.BaseFavoritesActivity
+import com.k0d4black.theforce.adapters.createFilmsAdapter
+import com.k0d4black.theforce.adapters.createSpeciesAdapter
+import com.k0d4black.theforce.base.BaseFavoritesFragment
import com.k0d4black.theforce.commons.remove
import com.k0d4black.theforce.commons.show
-import com.k0d4black.theforce.databinding.ActivityFavoritesBinding
+import com.k0d4black.theforce.databinding.FragmentFavoritesBinding
import com.k0d4black.theforce.models.*
-import com.k0d4black.theforce.adapters.createFilmsAdapter
-import com.k0d4black.theforce.adapters.createSpeciesAdapter
+import kotlinx.android.synthetic.main.fragment_favorites.*
-internal class FavoriteDetailsActivity : BaseFavoritesActivity(), ICharacterDetailsBinder {
+internal class FavoriteDetailsFragment : BaseFavoritesFragment(R.layout.fragment_favorites),
+ ICharacterDetailsBinder {
// region Members
- private lateinit var binding: ActivityFavoritesBinding
+ private lateinit var binding: FragmentFavoritesBinding
private val filmsAdapter = createFilmsAdapter()
@@ -27,14 +31,23 @@ internal class FavoriteDetailsActivity : BaseFavoritesActivity(), ICharacterDeta
// region Android API
override fun onCreate(savedInstanceState: Bundle?) {
- binding = DataBindingUtil.setContentView(this, R.layout.activity_favorites)
setupToolbar()
super.onCreate(savedInstanceState)
}
+ override fun onCreateView(
+ inflater: LayoutInflater,
+ container: ViewGroup?,
+ savedInstanceState: Bundle?
+ ): View {
+ binding = DataBindingUtil.inflate(
+ inflater, R.layout.fragment_favorites, container, false)
+ return binding.root
+ }
+
// endregion
- // region BaseFavoritesActivity
+ // region BaseFavoritesFragment
override fun bindFavorite(favoritePresentation: FavoritePresentation) {
bindCharacterBasicInfo(favoritePresentation.characterPresentation)
@@ -44,15 +57,15 @@ internal class FavoriteDetailsActivity : BaseFavoritesActivity(), ICharacterDeta
}
override val rootViewGroup: ViewGroup
- get() = binding.favoritesLayout
+ get() = favorites_layout
// endregion
// region Private API
private fun setupToolbar() {
- setSupportActionBar(binding.favoritesToolbar)
- supportActionBar?.setDisplayHomeAsUpEnabled(true)
+ (requireActivity() as DashboardActivity).setSupportActionBar(favorites_toolbar)
+ (requireActivity() as DashboardActivity).supportActionBar?.setDisplayHomeAsUpEnabled(true)
}
// endregion
@@ -60,7 +73,7 @@ internal class FavoriteDetailsActivity : BaseFavoritesActivity(), ICharacterDeta
// region ICharacterDetailsBinder
override fun bindCharacterBasicInfo(character: CharacterPresentation?) {
- supportActionBar?.title = character?.name ?: ""
+ (requireActivity() as DashboardActivity).supportActionBar?.title = character?.name ?: ""
binding.infoLayout.character = character
}
diff --git a/app/src/main/kotlin/com/k0d4black/theforce/activities/ICharacterDetailsBinder.kt b/app/src/main/kotlin/com/k0d4black/theforce/ui/ICharacterDetailsBinder.kt
similarity index 96%
rename from app/src/main/kotlin/com/k0d4black/theforce/activities/ICharacterDetailsBinder.kt
rename to app/src/main/kotlin/com/k0d4black/theforce/ui/ICharacterDetailsBinder.kt
index 4706c5d2..5e2f0912 100644
--- a/app/src/main/kotlin/com/k0d4black/theforce/activities/ICharacterDetailsBinder.kt
+++ b/app/src/main/kotlin/com/k0d4black/theforce/ui/ICharacterDetailsBinder.kt
@@ -13,7 +13,7 @@
* the License.
*
*/
-package com.k0d4black.theforce.activities
+package com.k0d4black.theforce.ui
import com.k0d4black.theforce.models.CharacterPresentation
import com.k0d4black.theforce.models.FilmPresentation
diff --git a/app/src/main/kotlin/com/k0d4black/theforce/activities/IFavoritesBinder.kt b/app/src/main/kotlin/com/k0d4black/theforce/ui/IFavoritesBinder.kt
similarity index 94%
rename from app/src/main/kotlin/com/k0d4black/theforce/activities/IFavoritesBinder.kt
rename to app/src/main/kotlin/com/k0d4black/theforce/ui/IFavoritesBinder.kt
index cd8d82ff..4636d0dc 100644
--- a/app/src/main/kotlin/com/k0d4black/theforce/activities/IFavoritesBinder.kt
+++ b/app/src/main/kotlin/com/k0d4black/theforce/ui/IFavoritesBinder.kt
@@ -13,7 +13,7 @@
* the License.
*
*/
-package com.k0d4black.theforce.activities
+package com.k0d4black.theforce.ui
import com.k0d4black.theforce.models.FavoritePresentation
diff --git a/app/src/main/kotlin/com/k0d4black/theforce/ui/SettingsFragment.kt b/app/src/main/kotlin/com/k0d4black/theforce/ui/SettingsFragment.kt
new file mode 100644
index 00000000..6e02c6dd
--- /dev/null
+++ b/app/src/main/kotlin/com/k0d4black/theforce/ui/SettingsFragment.kt
@@ -0,0 +1,34 @@
+/**
+ *
+ * Copyright 2020 David Odari
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ *
+ **/
+package com.k0d4black.theforce.ui
+
+import android.os.Bundle
+import android.view.View
+import androidx.navigation.fragment.findNavController
+import com.k0d4black.theforce.R
+import com.k0d4black.theforce.base.BaseFragment
+import kotlinx.android.synthetic.main.fragment_settings.*
+
+internal class SettingsFragment : BaseFragment(R.layout.fragment_settings) {
+
+ override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
+ super.onViewCreated(view, savedInstanceState)
+ (requireActivity() as DashboardActivity).setSupportActionBar(settings_toolbar)
+ (requireActivity() as DashboardActivity).supportActionBar?.setDisplayHomeAsUpEnabled(true)
+
+ about_card_view.setOnClickListener {
+ findNavController().navigate(SettingsFragmentDirections.actionToAboutFragment())
+ }
+ }
+}
diff --git a/app/src/main/res/layout/activity_dashboard.xml b/app/src/main/res/layout/activity_dashboard.xml
index 929e08a1..9df643ff 100644
--- a/app/src/main/res/layout/activity_dashboard.xml
+++ b/app/src/main/res/layout/activity_dashboard.xml
@@ -1,112 +1,15 @@
-
-
-
-
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+ app:defaultNavHost="true"
+ app:navGraph="@navigation/nav_graph" />
-
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_about.xml b/app/src/main/res/layout/fragment_about.xml
similarity index 97%
rename from app/src/main/res/layout/activity_about.xml
rename to app/src/main/res/layout/fragment_about.xml
index 3a7a102b..5c563d76 100644
--- a/app/src/main/res/layout/activity_about.xml
+++ b/app/src/main/res/layout/fragment_about.xml
@@ -19,7 +19,7 @@
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
- tools:context=".activities.AboutActivity">
+ tools:context=".ui.AboutFragment">
+ tools:context=".ui.CharacterDetailsFragment">
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_favorites.xml b/app/src/main/res/layout/fragment_favorites.xml
similarity index 96%
rename from app/src/main/res/layout/activity_favorites.xml
rename to app/src/main/res/layout/fragment_favorites.xml
index 553d944f..6b235c2c 100644
--- a/app/src/main/res/layout/activity_favorites.xml
+++ b/app/src/main/res/layout/fragment_favorites.xml
@@ -25,7 +25,7 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/margin_default"
- tools:context=".activities.FavoriteDetailsActivity">
+ tools:context=".ui.FavoriteDetailsFragment">
+ tools:context=".ui.SettingsFragment">
diff --git a/app/src/main/res/navigation/nav_graph.xml b/app/src/main/res/navigation/nav_graph.xml
new file mode 100644
index 00000000..9a4b8fa2
--- /dev/null
+++ b/app/src/main/res/navigation/nav_graph.xml
@@ -0,0 +1,63 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index ba47ca50..e58bd624 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -14,7 +14,7 @@
The Force
-
+
No matching results
No Matching Search Results
No Favorite Characters
@@ -27,10 +27,10 @@
Removed From Favorites
Added To Favorites
-
+
Settings
-
+
Birth Year
Height
Planet
@@ -50,11 +50,11 @@
%s inches
Language : %s
-
+
Settings
Star Wars and all associated names are copyright Lucasfilm ltd.
-
+
About
Version %s
diff --git a/build.gradle b/build.gradle
index 59611d5a..b816f04f 100644
--- a/build.gradle
+++ b/build.gradle
@@ -24,6 +24,7 @@ buildscript {
classpath 'com.dicedmelon.gradle:jacoco-android:0.1.4'
classpath 'com.google.firebase:firebase-crashlytics-gradle:2.1.1'
classpath "com.mikepenz.aboutlibraries.plugin:aboutlibraries-plugin:8.1.2"
+ classpath "android.arch.navigation:navigation-safe-args-gradle-plugin:1.0.0"
}
}
diff --git a/dependencies.gradle b/dependencies.gradle
index fd63ae06..4ca50ff9 100644
--- a/dependencies.gradle
+++ b/dependencies.gradle
@@ -32,6 +32,7 @@ ext {
aboutLibsVersion = '8.0.0-rc01'
stethoVersion = '1.5.1'
kielVersion = '1.2.1'
+ navigation = '2.2.2'
// Data
retrofitVersion = '2.7.0'
@@ -76,7 +77,9 @@ ext {
koinLifeCycleScope : "org.koin:koin-android-scope:$koinVersion",
koinAndroidViewModel : "org.koin:koin-androidx-viewmodel:$koinVersion",
stetho : "com.facebook.stetho:stetho:$stethoVersion",
- kiel : "me.ibrahimyilmaz:kiel:$kielVersion"
+ kiel : "me.ibrahimyilmaz:kiel:$kielVersion",
+ navigationFragment : "androidx.navigation:navigation-fragment-ktx:$navigation",
+ navigationUi : "androidx.navigation:navigation-ui-ktx:$navigation"
]
dataDependencies = [