diff --git a/app/screenshots/com.karumi.jetpack.superheroes.ui.view.EditSuperHeroActivityTest_showsJustOneSuperHero.png b/app/screenshots/com.karumi.jetpack.superheroes.ui.view.EditSuperHeroActivityTest_showsJustOneSuperHero.png index dbb83c1..e371f10 100644 Binary files a/app/screenshots/com.karumi.jetpack.superheroes.ui.view.EditSuperHeroActivityTest_showsJustOneSuperHero.png and b/app/screenshots/com.karumi.jetpack.superheroes.ui.view.EditSuperHeroActivityTest_showsJustOneSuperHero.png differ diff --git a/app/src/androidTest/java/com/karumi/jetpack/superheroes/data/repository/room/MigrationTest.kt b/app/src/androidTest/java/com/karumi/jetpack/superheroes/data/repository/room/MigrationTest.kt index 3f9d335..9afbe0a 100644 --- a/app/src/androidTest/java/com/karumi/jetpack/superheroes/data/repository/room/MigrationTest.kt +++ b/app/src/androidTest/java/com/karumi/jetpack/superheroes/data/repository/room/MigrationTest.kt @@ -1,9 +1,9 @@ package com.karumi.jetpack.superheroes.data.repository.room -import android.support.test.InstrumentationRegistry import androidx.room.testing.MigrationTestHelper import androidx.sqlite.db.SupportSQLiteDatabase import androidx.sqlite.db.framework.FrameworkSQLiteOpenHelperFactory +import androidx.test.platform.app.InstrumentationRegistry import com.karumi.jetpack.superheroes.common.Migrations import com.karumi.jetpack.superheroes.common.SuperHeroesDatabase import org.junit.Assert.assertEquals diff --git a/app/src/androidTest/java/com/karumi/jetpack/superheroes/ui/view/AcceptanceTest.kt b/app/src/androidTest/java/com/karumi/jetpack/superheroes/ui/view/AcceptanceTest.kt index 2b40c25..450e07d 100644 --- a/app/src/androidTest/java/com/karumi/jetpack/superheroes/ui/view/AcceptanceTest.kt +++ b/app/src/androidTest/java/com/karumi/jetpack/superheroes/ui/view/AcceptanceTest.kt @@ -45,7 +45,6 @@ abstract class AcceptanceTest(clazz: Class) : ScreenshotTest { val app = ApplicationProvider.getApplicationContext() app.override(Kodein.Module("Base test dependencies", allowSilentOverride = true) { import(testDependencies, allowOverride = true) - bind() with instance(executorServiceOnUiThread) }) } diff --git a/app/src/main/java/com/karumi/jetpack/superheroes/SuperHeroesApplication.kt b/app/src/main/java/com/karumi/jetpack/superheroes/SuperHeroesApplication.kt index e62acd9..04f70d0 100644 --- a/app/src/main/java/com/karumi/jetpack/superheroes/SuperHeroesApplication.kt +++ b/app/src/main/java/com/karumi/jetpack/superheroes/SuperHeroesApplication.kt @@ -1,7 +1,6 @@ package com.karumi.jetpack.superheroes import android.app.Application -import android.content.Context import com.karumi.jetpack.superheroes.common.SuperHeroesDatabase import com.karumi.jetpack.superheroes.common.module import com.karumi.jetpack.superheroes.data.repository.LocalSuperHeroDataSource @@ -53,6 +52,4 @@ class SuperHeroesApplication : Application(), KodeinAware { Executors.newCachedThreadPool() } } -} - -fun Context.asApp() = this.applicationContext as SuperHeroesApplication \ No newline at end of file +} \ No newline at end of file diff --git a/app/src/main/java/com/karumi/jetpack/superheroes/ui/presenter/EditSuperHeroPresenter.kt b/app/src/main/java/com/karumi/jetpack/superheroes/ui/presenter/EditSuperHeroPresenter.kt index e1856d7..bee63f1 100644 --- a/app/src/main/java/com/karumi/jetpack/superheroes/ui/presenter/EditSuperHeroPresenter.kt +++ b/app/src/main/java/com/karumi/jetpack/superheroes/ui/presenter/EditSuperHeroPresenter.kt @@ -15,7 +15,7 @@ class EditSuperHeroPresenter( private val getSuperHeroById: GetSuperHeroById, private val saveSuperHero: SaveSuperHero, private val executor: ExecutorService -) : LifecycleObserver { +) : EditSuperHeroListener, LifecycleObserver { private val view: View? by weak(view) private lateinit var id: String @@ -40,7 +40,7 @@ class EditSuperHeroPresenter( executor.shutdownNow() } - fun onSaveSuperHeroSelected( + override fun onSaveSuperHeroSelected( name: String, description: String, isAvenger: Boolean @@ -74,8 +74,16 @@ class EditSuperHeroPresenter( interface View { fun close() - fun showLoading() fun hideLoading() + fun showLoading() fun showSuperHero(superHero: SuperHero) } +} + +interface EditSuperHeroListener { + fun onSaveSuperHeroSelected( + name: String, + description: String, + isAvenger: Boolean + ) } \ No newline at end of file diff --git a/app/src/main/java/com/karumi/jetpack/superheroes/ui/presenter/SuperHeroDetailPresenter.kt b/app/src/main/java/com/karumi/jetpack/superheroes/ui/presenter/SuperHeroDetailPresenter.kt index df5aa3d..8df0af2 100644 --- a/app/src/main/java/com/karumi/jetpack/superheroes/ui/presenter/SuperHeroDetailPresenter.kt +++ b/app/src/main/java/com/karumi/jetpack/superheroes/ui/presenter/SuperHeroDetailPresenter.kt @@ -13,7 +13,7 @@ class SuperHeroDetailPresenter( view: View, private val getSuperHeroById: GetSuperHeroById, private val executor: ExecutorService -) : LifecycleObserver { +) : SuperHeroDetailListener, LifecycleObserver { private val view: View? by weak(view) @@ -38,7 +38,7 @@ class SuperHeroDetailPresenter( executor.shutdownNow() } - fun onEditSelected() { + override fun onEditSelected() { view?.openEditSuperHero(id) } @@ -50,9 +50,13 @@ class SuperHeroDetailPresenter( interface View { fun close() - fun showLoading() fun hideLoading() + fun showLoading() fun showSuperHero(superHero: SuperHero) fun openEditSuperHero(superHeroId: String) } +} + +interface SuperHeroDetailListener { + fun onEditSelected() } \ No newline at end of file diff --git a/app/src/main/java/com/karumi/jetpack/superheroes/ui/presenter/SuperHeroesPresenter.kt b/app/src/main/java/com/karumi/jetpack/superheroes/ui/presenter/SuperHeroesPresenter.kt index 0c0e180..6be0b79 100644 --- a/app/src/main/java/com/karumi/jetpack/superheroes/ui/presenter/SuperHeroesPresenter.kt +++ b/app/src/main/java/com/karumi/jetpack/superheroes/ui/presenter/SuperHeroesPresenter.kt @@ -43,9 +43,9 @@ class SuperHeroesPresenter( interface View { fun hideLoading() - fun showSuperHeroes(superHeroes: List) fun showLoading() fun showEmptyCase() + fun showSuperHeroes(superHeroes: List) fun openDetail(id: String) } } \ No newline at end of file diff --git a/app/src/main/java/com/karumi/jetpack/superheroes/ui/view/BaseActivity.kt b/app/src/main/java/com/karumi/jetpack/superheroes/ui/view/BaseActivity.kt index 261b95a..a692ec3 100644 --- a/app/src/main/java/com/karumi/jetpack/superheroes/ui/view/BaseActivity.kt +++ b/app/src/main/java/com/karumi/jetpack/superheroes/ui/view/BaseActivity.kt @@ -4,12 +4,14 @@ import android.content.Intent import android.os.Bundle import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.widget.Toolbar +import androidx.databinding.DataBindingUtil +import androidx.databinding.ViewDataBinding import androidx.lifecycle.LifecycleObserver import org.kodein.di.Kodein import org.kodein.di.KodeinAware import org.kodein.di.android.closestKodein -abstract class BaseActivity : AppCompatActivity(), KodeinAware { +abstract class BaseActivity : AppCompatActivity(), KodeinAware { private val appKodein by closestKodein() override val kodein: Kodein = Kodein.lazy { @@ -20,11 +22,13 @@ abstract class BaseActivity : AppCompatActivity(), KodeinAware { abstract val layoutId: Int abstract val toolbarView: Toolbar abstract val activityModules: Kodein.Module + protected lateinit var binding: T override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) lifecycle.addObserver(presenter) - setContentView(layoutId) + binding = DataBindingUtil.setContentView(this, layoutId) + configureBinding(binding) setSupportActionBar(toolbarView) prepare(intent) } @@ -34,5 +38,6 @@ abstract class BaseActivity : AppCompatActivity(), KodeinAware { lifecycle.removeObserver(presenter) } + abstract fun configureBinding(binding: T) open fun prepare(intent: Intent?) {} } \ No newline at end of file diff --git a/app/src/main/java/com/karumi/jetpack/superheroes/ui/view/EditSuperHeroActivity.kt b/app/src/main/java/com/karumi/jetpack/superheroes/ui/view/EditSuperHeroActivity.kt index 9b6fd70..88bce13 100644 --- a/app/src/main/java/com/karumi/jetpack/superheroes/ui/view/EditSuperHeroActivity.kt +++ b/app/src/main/java/com/karumi/jetpack/superheroes/ui/view/EditSuperHeroActivity.kt @@ -3,10 +3,10 @@ package com.karumi.jetpack.superheroes.ui.view import android.app.Activity import android.content.Intent import android.os.Bundle -import android.view.View import androidx.appcompat.widget.Toolbar import com.karumi.jetpack.superheroes.R import com.karumi.jetpack.superheroes.common.module +import com.karumi.jetpack.superheroes.databinding.EditSuperHeroActivityBinding import com.karumi.jetpack.superheroes.domain.model.SuperHero import com.karumi.jetpack.superheroes.domain.usecase.GetSuperHeroById import com.karumi.jetpack.superheroes.domain.usecase.SaveSuperHero @@ -17,7 +17,10 @@ import org.kodein.di.erased.bind import org.kodein.di.erased.instance import org.kodein.di.erased.provider -class EditSuperHeroActivity : BaseActivity(), EditSuperHeroPresenter.View { +class EditSuperHeroActivity : + BaseActivity(), + EditSuperHeroPresenter.View { + companion object { private const val SUPER_HERO_ID_KEY = "super_hero_id_key" @@ -45,6 +48,11 @@ class EditSuperHeroActivity : BaseActivity(), EditSuperHeroPresenter.View { } } + override fun configureBinding(binding: EditSuperHeroActivityBinding) { + binding.listener = presenter + binding.isLoading = false + } + override fun prepare(intent: Intent?) { title = superHeroId presenter.preparePresenter(superHeroId) @@ -55,24 +63,16 @@ class EditSuperHeroActivity : BaseActivity(), EditSuperHeroPresenter.View { } override fun showLoading() = runOnUiThread { - et_super_hero_name.isEnabled = false - et_super_hero_description.isEnabled = false - bt_save_edition.isEnabled = false - progress_bar.visibility = View.VISIBLE + binding.isLoading = true } override fun hideLoading() = runOnUiThread { - et_super_hero_name.isEnabled = true - et_super_hero_description.isEnabled = true - bt_save_edition.isEnabled = true - progress_bar.visibility = View.GONE + binding.isLoading = false } override fun showSuperHero(superHero: SuperHero) = runOnUiThread { - et_super_hero_name.setText(superHero.name) - et_super_hero_description.setText(superHero.description) + binding.superHero = superHero iv_super_hero_photo.setImageBackground(superHero.photo) - cb_is_avenger.isChecked = superHero.isAvenger } override val activityModules = module { diff --git a/app/src/main/java/com/karumi/jetpack/superheroes/ui/view/MainActivity.kt b/app/src/main/java/com/karumi/jetpack/superheroes/ui/view/MainActivity.kt index 219c538..4521ade 100644 --- a/app/src/main/java/com/karumi/jetpack/superheroes/ui/view/MainActivity.kt +++ b/app/src/main/java/com/karumi/jetpack/superheroes/ui/view/MainActivity.kt @@ -1,11 +1,11 @@ package com.karumi.jetpack.superheroes.ui.view import android.os.Bundle -import android.view.View import androidx.appcompat.widget.Toolbar import androidx.recyclerview.widget.LinearLayoutManager import com.karumi.jetpack.superheroes.R import com.karumi.jetpack.superheroes.common.module +import com.karumi.jetpack.superheroes.databinding.MainActivityBinding import com.karumi.jetpack.superheroes.domain.model.SuperHero import com.karumi.jetpack.superheroes.domain.usecase.GetSuperHeroes import com.karumi.jetpack.superheroes.ui.presenter.SuperHeroesPresenter @@ -15,7 +15,7 @@ import org.kodein.di.erased.bind import org.kodein.di.erased.instance import org.kodein.di.erased.provider -class MainActivity : BaseActivity(), SuperHeroesPresenter.View { +class MainActivity : BaseActivity(), SuperHeroesPresenter.View { override val presenter: SuperHeroesPresenter by instance() private lateinit var adapter: SuperHeroesAdapter @@ -29,6 +29,11 @@ class MainActivity : BaseActivity(), SuperHeroesPresenter.View { initializeRecyclerView() } + override fun configureBinding(binding: MainActivityBinding) { + binding.isLoading = false + binding.isShowingEmptyCase = false + } + private fun initializeAdapter() { adapter = SuperHeroesAdapter(presenter) } @@ -40,15 +45,15 @@ class MainActivity : BaseActivity(), SuperHeroesPresenter.View { } override fun showLoading() = runOnUiThread { - progress_bar.visibility = View.VISIBLE + binding.isLoading = true } override fun hideLoading() = runOnUiThread { - progress_bar.visibility = View.GONE + binding.isLoading = false } override fun showEmptyCase() = runOnUiThread { - tv_empty_case.visibility = View.VISIBLE + binding.isShowingEmptyCase = true } override fun showSuperHeroes(superHeroes: List) = runOnUiThread { diff --git a/app/src/main/java/com/karumi/jetpack/superheroes/ui/view/SuperHeroDetailActivity.kt b/app/src/main/java/com/karumi/jetpack/superheroes/ui/view/SuperHeroDetailActivity.kt index ee62e3d..c333f5b 100644 --- a/app/src/main/java/com/karumi/jetpack/superheroes/ui/view/SuperHeroDetailActivity.kt +++ b/app/src/main/java/com/karumi/jetpack/superheroes/ui/view/SuperHeroDetailActivity.kt @@ -2,11 +2,10 @@ package com.karumi.jetpack.superheroes.ui.view import android.app.Activity import android.content.Intent -import android.os.Bundle -import android.view.View import androidx.appcompat.widget.Toolbar import com.karumi.jetpack.superheroes.R import com.karumi.jetpack.superheroes.common.module +import com.karumi.jetpack.superheroes.databinding.SuperHeroDetailActivityBinding import com.karumi.jetpack.superheroes.domain.model.SuperHero import com.karumi.jetpack.superheroes.domain.usecase.GetSuperHeroById import com.karumi.jetpack.superheroes.ui.presenter.SuperHeroDetailPresenter @@ -16,8 +15,9 @@ import org.kodein.di.erased.bind import org.kodein.di.erased.instance import org.kodein.di.erased.provider -class SuperHeroDetailActivity : BaseActivity(), SuperHeroDetailPresenter.View { - +class SuperHeroDetailActivity : + BaseActivity(), + SuperHeroDetailPresenter.View { companion object { private const val SUPER_HERO_ID_KEY = "super_hero_id_key" @@ -34,9 +34,9 @@ class SuperHeroDetailActivity : BaseActivity(), SuperHeroDetailPresenter.View { get() = toolbar private val superHeroId: String by lazy { intent?.extras?.getString(SUPER_HERO_ID_KEY) ?: "" } - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - edit_super_hero.setOnClickListener { presenter.onEditSelected() } + override fun configureBinding(binding: SuperHeroDetailActivityBinding) { + binding.listener = presenter + binding.isLoading = false } override fun prepare(intent: Intent?) { @@ -47,22 +47,17 @@ class SuperHeroDetailActivity : BaseActivity(), SuperHeroDetailPresenter.View { override fun close() = runOnUiThread { finish() } override fun showLoading() = runOnUiThread { - progress_bar.visibility = View.VISIBLE + binding.isLoading = true } override fun hideLoading() = runOnUiThread { - progress_bar.visibility = View.GONE + binding.isLoading = false } override fun showSuperHero(superHero: SuperHero) = runOnUiThread { title = superHero.name - tv_super_hero_name.text = superHero.name - tv_super_hero_description.text = superHero.description - iv_avengers_badge.visibility = - if (superHero.isAvenger) View.VISIBLE else View.GONE + binding.superHero = superHero iv_super_hero_photo.setImageBackground(superHero.photo) - edit_super_hero.visibility = View.VISIBLE - super_hero_background.visibility = View.VISIBLE } override fun openEditSuperHero(superHeroId: String) = runOnUiThread { diff --git a/app/src/main/res/layout/edit_super_hero_activity.xml b/app/src/main/res/layout/edit_super_hero_activity.xml index 47821c3..b73e69f 100644 --- a/app/src/main/res/layout/edit_super_hero_activity.xml +++ b/app/src/main/res/layout/edit_super_hero_activity.xml @@ -1,133 +1,160 @@ - + xmlns:tools="http://schemas.android.com/tools"> - + + + + + - + + + + + + android:layout_height="match_parent"> - + android:layout_height="?attr/actionBarSize" + android:background="?attr/colorPrimary" + android:theme="@style/AppTheme.AppBarOverlay" + app:layout_constraintTop_toTopOf="parent" + app:popupTheme="@style/AppTheme.PopupOverlay" /> - - - - - - - + + + android:layout_height="wrap_content"> - + + + + - - - - - - - - - - - - - - - - - - - \ No newline at end of file + android:layout_margin="8dp" + android:textColorHint="@color/white_50" + app:layout_constraintTop_toBottomOf="@id/cb_is_avenger"> + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/main_activity.xml b/app/src/main/res/layout/main_activity.xml index 8f4cf2e..c75c59c 100644 --- a/app/src/main/res/layout/main_activity.xml +++ b/app/src/main/res/layout/main_activity.xml @@ -1,53 +1,70 @@ - + xmlns:tools="http://schemas.android.com/tools"> - - - + + + + + + + + + - - - - - - + android:layout_height="match_parent" + tools:context="com.karumi.jetpack.superheroes.ui.view.MainActivity"> + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/super_hero_detail_activity.xml b/app/src/main/res/layout/super_hero_detail_activity.xml index d91d72c..1dbffa8 100644 --- a/app/src/main/res/layout/super_hero_detail_activity.xml +++ b/app/src/main/res/layout/super_hero_detail_activity.xml @@ -1,112 +1,137 @@ - + xmlns:tools="http://schemas.android.com/tools"> - + + + + + + + + + + + + + android:layout_height="match_parent" + tools:context="com.karumi.jetpack.superheroes.ui.view.SuperHeroDetailActivity"> - - - - - - - - - - - - - - - - - - - + android:layout_height="wrap_content"> + + + + + + + + + + + + + + + + + + + + +