From a133144eeb6c6b499a5000ffe63837bf23182247 Mon Sep 17 00:00:00 2001 From: Goran Luketic Date: Fri, 26 Jul 2019 11:10:15 +0200 Subject: [PATCH 1/2] added container activity that can contain multiple fragments --- app/src/main/AndroidManifest.xml | 2 ++ .../common/extensions/AndroidExtensions.kt | 14 +++++++++++ .../template/routing/AppNavigator.kt | 15 ++++++++++++ .../cobeisfresh/template/routing/Navigator.kt | 2 ++ .../template/ui/weather/base/BaseActivity.kt | 6 +++++ .../ui/weather/base/ContainerActivity.kt | 23 +++++++++++++++++++ .../weather/presentation/WeatherViewModel.kt | 12 +++++++++- .../ui/weather/view/WeatherActivity.kt | 5 +++- .../ui/weather/view/WeatherDetailsFragment.kt | 17 ++++++++++++++ .../main/res/layout/activity_container.xml | 5 ++++ app/src/main/res/layout/activity_weather.xml | 14 +++++++++-- .../res/layout/fragment_weather_details.xml | 16 +++++++++++++ 12 files changed, 127 insertions(+), 4 deletions(-) create mode 100644 app/src/main/java/com/cobeisfresh/template/ui/weather/base/ContainerActivity.kt create mode 100644 app/src/main/java/com/cobeisfresh/template/ui/weather/view/WeatherDetailsFragment.kt create mode 100644 app/src/main/res/layout/activity_container.xml create mode 100644 app/src/main/res/layout/fragment_weather_details.xml diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 7724aab..2365fd2 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -22,6 +22,8 @@ + + \ No newline at end of file diff --git a/app/src/main/java/com/cobeisfresh/template/common/extensions/AndroidExtensions.kt b/app/src/main/java/com/cobeisfresh/template/common/extensions/AndroidExtensions.kt index d2bd62f..121c9cd 100644 --- a/app/src/main/java/com/cobeisfresh/template/common/extensions/AndroidExtensions.kt +++ b/app/src/main/java/com/cobeisfresh/template/common/extensions/AndroidExtensions.kt @@ -1,7 +1,10 @@ package com.cobeisfresh.template.common.extensions import android.view.View +import androidx.annotation.IdRes import androidx.annotation.StringRes +import androidx.fragment.app.Fragment +import androidx.fragment.app.FragmentActivity import androidx.lifecycle.LifecycleOwner import androidx.lifecycle.LiveData import androidx.lifecycle.Observer @@ -24,4 +27,15 @@ fun View.gone() { inline fun View.onClick(crossinline onClick: () -> Unit) { setOnClickListener { onClick() } +} + +fun FragmentActivity.showFragment(fragment: Fragment, @IdRes container: Int, addToBackStack: Boolean = false) { + supportFragmentManager.beginTransaction() + .apply { + if (addToBackStack) { + addToBackStack(fragment.tag) + } + } + .replace(container, fragment) + .commitAllowingStateLoss() } \ No newline at end of file diff --git a/app/src/main/java/com/cobeisfresh/template/routing/AppNavigator.kt b/app/src/main/java/com/cobeisfresh/template/routing/AppNavigator.kt index 0a402a4..5f34030 100644 --- a/app/src/main/java/com/cobeisfresh/template/routing/AppNavigator.kt +++ b/app/src/main/java/com/cobeisfresh/template/routing/AppNavigator.kt @@ -3,13 +3,28 @@ package com.cobeisfresh.template.routing import android.content.Intent import androidx.appcompat.app.AppCompatActivity import com.cobeisfresh.template.ui.weather.base.BaseActivity +import com.cobeisfresh.template.ui.weather.base.ContainerActivity import com.cobeisfresh.template.ui.weather.view.WeatherActivity +import java.io.Serializable class AppNavigator(private val activity: AppCompatActivity) : Navigator { + companion object { + const val SCREEN_TYPE = "screen_type" + } + override fun showWeather() = navigateTo(getIntent()) + override fun showWeatherDetails() = navigateTo(getIntent().apply { + putExtra(SCREEN_TYPE, ScreenType.WEATHER_DETAILS) + }) + private fun navigateTo(intent: Intent) = activity.startActivity(intent) private inline fun getIntent() = Intent(activity, T::class.java) + +} + +enum class ScreenType : Serializable { + WEATHER_DETAILS } \ No newline at end of file diff --git a/app/src/main/java/com/cobeisfresh/template/routing/Navigator.kt b/app/src/main/java/com/cobeisfresh/template/routing/Navigator.kt index 8ffd98b..958e8ef 100644 --- a/app/src/main/java/com/cobeisfresh/template/routing/Navigator.kt +++ b/app/src/main/java/com/cobeisfresh/template/routing/Navigator.kt @@ -3,4 +3,6 @@ package com.cobeisfresh.template.routing interface Navigator { fun showWeather() + + fun showWeatherDetails() } \ No newline at end of file diff --git a/app/src/main/java/com/cobeisfresh/template/ui/weather/base/BaseActivity.kt b/app/src/main/java/com/cobeisfresh/template/ui/weather/base/BaseActivity.kt index 86588f0..cef5596 100644 --- a/app/src/main/java/com/cobeisfresh/template/ui/weather/base/BaseActivity.kt +++ b/app/src/main/java/com/cobeisfresh/template/ui/weather/base/BaseActivity.kt @@ -4,8 +4,10 @@ import android.view.View import android.widget.ProgressBar import androidx.annotation.StringRes import androidx.appcompat.app.AppCompatActivity +import androidx.fragment.app.Fragment import com.cobeisfresh.template.common.EMPTY_STRING import com.cobeisfresh.template.common.extensions.gone +import com.cobeisfresh.template.common.extensions.showFragment import com.cobeisfresh.template.common.extensions.snackbar import com.cobeisfresh.template.common.extensions.visible import com.cobeisfresh.template.routing.AppNavigator @@ -23,4 +25,8 @@ abstract class BaseActivity : AppCompatActivity() { fun showLoading(progressBar: ProgressBar) = progressBar.visible() fun hideLoading(progressBar: ProgressBar) = progressBar.gone() + + fun addFragment(fragment: Fragment, containerId: Int, addToBackStack: Boolean = false) { + showFragment(fragment, containerId, addToBackStack) + } } \ No newline at end of file diff --git a/app/src/main/java/com/cobeisfresh/template/ui/weather/base/ContainerActivity.kt b/app/src/main/java/com/cobeisfresh/template/ui/weather/base/ContainerActivity.kt new file mode 100644 index 0000000..b182fc3 --- /dev/null +++ b/app/src/main/java/com/cobeisfresh/template/ui/weather/base/ContainerActivity.kt @@ -0,0 +1,23 @@ +package com.cobeisfresh.template.ui.weather.base + +import android.os.Bundle +import com.cobeisfresh.template.R +import com.cobeisfresh.template.common.extensions.showFragment +import com.cobeisfresh.template.routing.AppNavigator +import com.cobeisfresh.template.routing.ScreenType +import com.cobeisfresh.template.ui.weather.view.WeatherDetailsFragment + +/** + * Activity that shows fragment inside container. ScreenType is sent through bundle + */ +class ContainerActivity : BaseActivity() { + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setContentView(R.layout.activity_container) + when (intent.getSerializableExtra(AppNavigator.SCREEN_TYPE)) { + ScreenType.WEATHER_DETAILS -> addFragment(WeatherDetailsFragment.newInstance(), R.id.fragmentContainer) + else -> finish() + } + } +} diff --git a/app/src/main/java/com/cobeisfresh/template/ui/weather/presentation/WeatherViewModel.kt b/app/src/main/java/com/cobeisfresh/template/ui/weather/presentation/WeatherViewModel.kt index ee0a975..841d8cb 100644 --- a/app/src/main/java/com/cobeisfresh/template/ui/weather/presentation/WeatherViewModel.kt +++ b/app/src/main/java/com/cobeisfresh/template/ui/weather/presentation/WeatherViewModel.kt @@ -5,6 +5,8 @@ import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import com.cobeisfresh.template.common.DEFAULT_CITY_NAME +import com.cobeisfresh.template.routing.AppNavigator +import com.cobeisfresh.template.ui.weather.base.NavigatorViewModel import com.cobeisfresh.template.ui.weather.base.ViewState import com.example.domain.interaction.weather.GetWeatherUseCase import com.example.domain.model.WeatherInfo @@ -14,7 +16,7 @@ import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import kotlinx.coroutines.withContext -class WeatherViewModel(private val getWeather: GetWeatherUseCase) : ViewModel() { +class WeatherViewModel(private val getWeather: GetWeatherUseCase) : NavigatorViewModel() { // we make this private and provide only immutable live data to observers so they can't change anything private val _weatherLiveData = MutableLiveData>() @@ -29,4 +31,12 @@ class WeatherViewModel(private val getWeather: GetWeatherUseCase) : ViewModel() .onFailure { _weatherLiveData.postValue(ViewState.error(it.throwable)) } } } + + fun showWeatherDetails() { + appNavigator.showWeatherDetails() + } + + override fun initAppNavigator(appNavigator: AppNavigator) { + this.appNavigator = appNavigator + } } diff --git a/app/src/main/java/com/cobeisfresh/template/ui/weather/view/WeatherActivity.kt b/app/src/main/java/com/cobeisfresh/template/ui/weather/view/WeatherActivity.kt index e0f5516..ff245e3 100644 --- a/app/src/main/java/com/cobeisfresh/template/ui/weather/view/WeatherActivity.kt +++ b/app/src/main/java/com/cobeisfresh/template/ui/weather/view/WeatherActivity.kt @@ -8,6 +8,7 @@ import com.cobeisfresh.template.R import com.cobeisfresh.template.common.convertKelvinToCelsius import com.cobeisfresh.template.common.extensions.onClick import com.cobeisfresh.template.common.extensions.subscribe +import com.cobeisfresh.template.routing.AppNavigator import com.cobeisfresh.template.ui.weather.base.BaseActivity import com.cobeisfresh.template.ui.weather.base.ViewState import com.cobeisfresh.template.ui.weather.base.ViewState.Status.* @@ -23,7 +24,7 @@ class WeatherActivity : BaseActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_weather) - + viewModel.initAppNavigator(appNavigator) viewModel.getWeatherForLocation() subscribeToData() @@ -32,6 +33,8 @@ class WeatherActivity : BaseActivity() { imm.hideSoftInputFromWindow(weatherActivityContainer.windowToken, InputMethodManager.HIDE_NOT_ALWAYS) viewModel.getWeatherForLocation(cityInput.text.toString()) } + + showWeatherDetails.onClick { viewModel.showWeatherDetails() } } private fun subscribeToData() = with(viewModel) { diff --git a/app/src/main/java/com/cobeisfresh/template/ui/weather/view/WeatherDetailsFragment.kt b/app/src/main/java/com/cobeisfresh/template/ui/weather/view/WeatherDetailsFragment.kt new file mode 100644 index 0000000..ab0efec --- /dev/null +++ b/app/src/main/java/com/cobeisfresh/template/ui/weather/view/WeatherDetailsFragment.kt @@ -0,0 +1,17 @@ +package com.cobeisfresh.template.ui.weather.view + +import com.cobeisfresh.template.R +import com.cobeisfresh.template.ui.weather.base.BaseFragment + +class WeatherDetailsFragment: BaseFragment() { + + override fun viewReady() { + + } + + override fun getLayout() = R.layout.fragment_weather_details + + companion object{ + fun newInstance() = WeatherDetailsFragment() + } +} \ No newline at end of file diff --git a/app/src/main/res/layout/activity_container.xml b/app/src/main/res/layout/activity_container.xml new file mode 100644 index 0000000..5034785 --- /dev/null +++ b/app/src/main/res/layout/activity_container.xml @@ -0,0 +1,5 @@ + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_weather.xml b/app/src/main/res/layout/activity_weather.xml index 1e8e174..6d31d7f 100644 --- a/app/src/main/res/layout/activity_weather.xml +++ b/app/src/main/res/layout/activity_weather.xml @@ -1,6 +1,5 @@ - +