viewcontroller viewModel management logic now in separate module

rename FragmentWithState to StatefulFragment
fix navigation class files packages
This commit is contained in:
alex 2020-05-28 13:26:54 +03:00
parent 2015daf5d1
commit 372750eee4
26 changed files with 268 additions and 143 deletions

View File

@ -20,7 +20,8 @@ android {
}
dependencies {
api project(":navigation-base")
implementation project(":logging")
implementation project(":navigation-base")
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"

View File

@ -1,4 +1,4 @@
package ru.touchin.roboswag.bottom_navigation_fragment
package ru.touchin.roboswag.bottom_navigation_base
import android.os.Parcelable
import androidx.annotation.IdRes
@ -6,13 +6,14 @@ import androidx.fragment.app.FragmentManager
import ru.touchin.roboswag.navigation_base.FragmentNavigation
import ru.touchin.roboswag.navigation_base.activities.NavigationActivity
abstract class BaseBottomNavigationActivity<
TNavigation : FragmentNavigation,
TNavigationFragment : BaseBottomNavigationFragment<*>,
TNavigationContainer : BaseNavigationContainerFragment<*, TNavigation>> : NavigationActivity<TNavigation>() {
abstract class BaseBottomNavigationActivity<TNavigation, TNavigationFragment, TNavigationContainer> : NavigationActivity<TNavigation>()
where TNavigation : FragmentNavigation,
TNavigationFragment : BaseBottomNavigationFragment<*>,
TNavigationContainer : BaseNavigationContainerFragment<*, TNavigation>
{
val innerNavigation: TNavigation
get() = getNavigationContainer(supportFragmentManager)?.navigation ?: navigation
get() = getNavigationContainer(supportFragmentManager)?.navigation ?: navigation
/**
* Navigates to the given navigation tab.

View File

@ -1,4 +1,4 @@
package ru.touchin.roboswag.bottom_navigation_fragment
package ru.touchin.roboswag.bottom_navigation_base
import android.content.Context
import android.os.Bundle
@ -13,16 +13,17 @@ import androidx.core.view.children
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentManager
import ru.touchin.roboswag.core.utils.ShouldNotHappenException
import ru.touchin.roboswag.navigation_base.fragments.BaseFragment
import ru.touchin.roboswag.navigation_base.fragments.StatefulFragment
abstract class BaseBottomNavigationController<TNavigationTab : BaseNavigationTab>(
private val tabs: SparseArray<TNavigationTab>,
private val context: Context,
private val fragmentManager: FragmentManager,
@IdRes private val defaultTabId: Int = 0, // If it zero back press with empty fragment back stack would close the app
@IdRes private val contentContainerViewId: Int,
@LayoutRes private val contentContainerLayoutId: Int,
private val wrapWithNavigationContainer: Boolean = false
@IdRes private val contentContainerViewId: Int,
@IdRes private val defaultTabId: Int = 0, // If it zero back press with empty fragment back stack would close the app
private val wrapWithNavigationContainer: Boolean = false,
private val onReselectListener: (() -> Unit)? = null
) {
private var callback: FragmentManager.FragmentLifecycleCallbacks? = null
@ -111,7 +112,9 @@ abstract class BaseBottomNavigationController<TNavigationTab : BaseNavigationTab
protected open fun getNavigationContainerClass(): Class<out BaseNavigationContainerFragment<*, *>> = BaseNavigationContainerFragment::class.java
protected open fun onTabReselected() = Unit
protected open fun onTabReselected() {
onReselectListener?.invoke()
}
protected open fun isTabClass(tab: TNavigationTab, fragment: Fragment?) = if (wrapWithNavigationContainer) {
(fragment as BaseNavigationContainerFragment<*, *>).getContainedClass()
@ -130,7 +133,7 @@ abstract class BaseBottomNavigationController<TNavigationTab : BaseNavigationTab
Fragment.instantiate(
context,
clazz.name,
BaseFragment.args(state)
StatefulFragment.args(state)
)
}

View File

@ -1,4 +1,4 @@
package ru.touchin.roboswag.bottom_navigation_fragment
package ru.touchin.roboswag.bottom_navigation_base
import android.os.Bundle
import android.os.Parcelable

View File

@ -1,4 +1,4 @@
package ru.touchin.roboswag.bottom_navigation_fragment
package ru.touchin.roboswag.bottom_navigation_base
import android.os.Bundle
import android.os.Parcelable

View File

@ -1,8 +1,7 @@
package ru.touchin.roboswag.bottom_navigation_fragment
package ru.touchin.roboswag.bottom_navigation_base
import android.os.Parcel
import android.os.Parcelable
import ru.touchin.roboswag.navigation_base.fragments.EmptyState
import ru.touchin.roboswag.navigation_base.extensions.copy
open class BaseNavigationTab(
open val cls: Class<*>,
@ -14,31 +13,13 @@ open class BaseNavigationTab(
val saveStateOnSwitching: Boolean = true
) {
/**
* It is value as class body property instead of value as constructor parameter to specify
* custom getter of this field which returns copy of Parcelable every time it be called.
* This is necessary to avoid modifying this value if it would be a value as constructor parameter
* and every getting of this value would return the same instance.
*/
val state = state
get() = field.copy()
private fun Parcelable.copy(): Parcelable =
if (this is EmptyState) {
EmptyState
} else {
val parcel = Parcel.obtain()
parcel.writeParcelable(this, 0)
parcel.setDataPosition(0)
val result = parcel.readParcelable<Parcelable>(
javaClass.classLoader ?: Thread.currentThread().contextClassLoader
) ?: throw IllegalStateException("Failed to copy tab state")
parcel.recycle()
result
}
/**
* It is value as class body property instead of value as constructor parameter to specify
* custom getter of this field which returns copy of Parcelable every time it be called.
* This is necessary to avoid modifying this value if it would be a value as constructor parameter
* and every getting of this value would return the same instance.
*/
val state = state
get() = field.copy()
}

View File

@ -20,8 +20,8 @@ android {
}
dependencies {
api project(":navigation-base")
api project(":bottom-navigation-base")
implementation project(":navigation-base")
implementation project(":bottom-navigation-base")
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"

View File

@ -1,5 +1,6 @@
package ru.touchin.roboswag.bottom_navigation_fragment
import ru.touchin.roboswag.bottom_navigation_base.BaseBottomNavigationActivity
import ru.touchin.roboswag.navigation_base.FragmentNavigation
abstract class BottomNavigationActivity :

View File

@ -5,21 +5,23 @@ import android.util.SparseArray
import androidx.annotation.IdRes
import androidx.annotation.LayoutRes
import androidx.fragment.app.FragmentManager
import ru.touchin.roboswag.bottom_navigation_base.BaseBottomNavigationController
class BottomNavigationController(
context: Context,
fragments: SparseArray<NavigationTab>,
fragmentManager: FragmentManager,
wrapWithNavigationContainer: Boolean = false,
@IdRes private val defaultTabId: Int = 0, // If it zero back press with empty fragment back stack would close the app
@IdRes private val contentContainerViewId: Int,
@LayoutRes private val contentContainerLayoutId: Int,
private val onReselectListener: (() -> Unit)? = null
@IdRes private val contentContainerViewId: Int,
@IdRes private val defaultTabId: Int = 0, // If it zero back press with empty fragment back stack would close the app
onReselectListener: (() -> Unit)? = null
) : BaseBottomNavigationController<NavigationTab>(
tabs = fragments,
context = context,
fragmentManager = fragmentManager,
defaultTabId = defaultTabId,
onReselectListener = onReselectListener,
contentContainerViewId = contentContainerViewId,
contentContainerLayoutId = contentContainerLayoutId,
wrapWithNavigationContainer = wrapWithNavigationContainer
@ -27,8 +29,4 @@ class BottomNavigationController(
override fun getNavigationContainerClass() = NavigationContainerFragment::class.java
override fun onTabReselected() {
onReselectListener?.invoke()
}
}

View File

@ -1,5 +1,7 @@
package ru.touchin.roboswag.bottom_navigation_fragment
import ru.touchin.roboswag.bottom_navigation_base.BaseBottomNavigationFragment
abstract class BottomNavigationFragment : BaseBottomNavigationFragment<NavigationTab>() {
override fun createNavigationController() = BottomNavigationController(

View File

@ -1,10 +1,12 @@
package ru.touchin.roboswag.bottom_navigation_fragment
import android.os.Parcelable
import ru.touchin.roboswag.bottom_navigation_base.BaseNavigationContainerFragment
import ru.touchin.roboswag.navigation_base.FragmentNavigation
import ru.touchin.roboswag.navigation_base.fragments.BaseFragment
import ru.touchin.roboswag.navigation_base.fragments.StatefulFragment
class NavigationContainerFragment : BaseNavigationContainerFragment<BaseFragment<out BottomNavigationActivity, Parcelable>, FragmentNavigation>() {
class NavigationContainerFragment :
BaseNavigationContainerFragment<StatefulFragment<out BottomNavigationActivity, Parcelable>, FragmentNavigation>() {
override val navigation by lazy {
FragmentNavigation(

View File

@ -1,10 +1,11 @@
package ru.touchin.roboswag.bottom_navigation_fragment
import android.os.Parcelable
import ru.touchin.roboswag.navigation_base.fragments.BaseFragment
import ru.touchin.roboswag.bottom_navigation_base.BaseNavigationTab
import ru.touchin.roboswag.navigation_base.fragments.StatefulFragment
class NavigationTab(
override val cls: Class<out BaseFragment<*, *>>,
override val cls: Class<out StatefulFragment<*, *>>,
state: Parcelable,
saveStateOnSwitching: Boolean = true
) : BaseNavigationTab(cls, state, saveStateOnSwitching)

1
lifecycle-viewcontroller/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
/build

View File

@ -0,0 +1,35 @@
apply plugin: 'com.android.library'
apply plugin: 'kotlin-android'
android {
compileSdkVersion versions.compileSdk
defaultConfig {
minSdkVersion 16
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = JavaVersion.VERSION_1_8.toString()
}
}
dependencies {
implementation project(":lifecycle")
implementation project(":navigation-viewcontroller")
compileOnly "javax.inject:javax.inject:1"
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation "androidx.appcompat:appcompat:$versions.appcompat"
implementation "androidx.fragment:fragment:$versions.fragment"
implementation "androidx.fragment:fragment-ktx:$versions.fragment"
implementation "androidx.lifecycle:lifecycle-extensions:$versions.lifecycle"
}

View File

@ -0,0 +1 @@
<manifest package="ru.touchin.lifecycle_viewcontroller"/>

View File

@ -0,0 +1,37 @@
package ru.touchin.lifecycle_viewcontroller.extensions
import androidx.annotation.MainThread
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.ViewModelStoreOwner
import ru.touchin.lifecycle_viewcontroller.viewmodel.LifecycleViewModelProviders
import ru.touchin.roboswag.navigation_viewcontroller.viewcontrollers.ViewController
import androidx.fragment.app.activityViewModels as androidActivityViewModels
import androidx.fragment.app.viewModels as androidViewModels
@MainThread
inline fun <reified VM : ViewModel> ViewController<*, *>.viewModels(
noinline ownerProducer: () -> ViewModelStoreOwner = { this.fragment },
noinline factoryProducer: () -> ViewModelProvider.Factory = { LifecycleViewModelProviders.getViewModelFactory(this) }
) = this.fragment.androidViewModels<VM>(ownerProducer, factoryProducer)
@MainThread
inline fun <reified VM : ViewModel> ViewController<*, *>.parentViewModels(
noinline ownerProducer: () -> ViewModelStoreOwner = { this.fragment.parentFragment!! },
noinline factoryProducer: () -> ViewModelProvider.Factory = {
LifecycleViewModelProviders.getViewModelFactory(this.fragment.parentFragment!!)
}
) = viewModels<VM>(ownerProducer, factoryProducer)
@MainThread
inline fun <reified VM : ViewModel> ViewController<*, *>.targetViewModels(
noinline ownerProducer: () -> ViewModelStoreOwner = { this.fragment.targetFragment!! },
noinline factoryProducer: () -> ViewModelProvider.Factory = {
LifecycleViewModelProviders.getViewModelFactory(this.fragment.targetFragment!!)
}
) = viewModels<VM>(ownerProducer, factoryProducer)
@MainThread
inline fun <reified VM : ViewModel> ViewController<*, *>.activityViewModels(
noinline factoryProducer: () -> ViewModelProvider.Factory = { LifecycleViewModelProviders.getViewModelFactory(activity) }
) = this.fragment.androidActivityViewModels<VM>(factoryProducer)

View File

@ -0,0 +1,30 @@
package ru.touchin.lifecycle_viewcontroller.viewmodel
import android.app.Activity
import androidx.fragment.app.Fragment
import androidx.lifecycle.ViewModelProvider
import ru.touchin.lifecycle.viewmodel.BaseLifecycleViewModelProviders
import ru.touchin.lifecycle.viewmodel.ViewModelFactoryProvider
import ru.touchin.roboswag.navigation_viewcontroller.viewcontrollers.ViewController
object LifecycleViewModelProviders : BaseLifecycleViewModelProviders() {
/**
* Returns ViewModelProvider.Factory instance from current lifecycleOwner.
* Search #ViewModelFactoryProvider are produced according to priorities:
* 1. View controller;
* 2. Fragment;
* 3. Parent fragment recursively;
* 4. Activity;
* 5. Application.
*/
override fun getViewModelFactory(provider: Any): ViewModelProvider.Factory =
when (provider) {
is ViewModelFactoryProvider -> provider.viewModelFactory
is ViewController<*, *> -> getViewModelFactory(provider.fragment)
is Fragment -> getViewModelFactory(provider.parentFragment ?: provider.requireActivity())
is Activity -> getViewModelFactory(provider.application)
else -> throw IllegalArgumentException("View model factory not found.")
}
}

View File

@ -19,8 +19,6 @@ android {
}
dependencies {
api project(":navigation-viewcontroller")
compileOnly "javax.inject:javax.inject:1"
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"

View File

@ -0,0 +1,47 @@
package ru.touchin.lifecycle.viewmodel
import android.app.Activity
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentActivity
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.ViewModelProvider
abstract class BaseLifecycleViewModelProviders {
/**
* Creates a {@link ViewModelProvider}, which retains ViewModels while a scope of given
* {@code lifecycleOwner} is alive. More detailed explanation is in {@link ViewModel}.
* <p>
* It uses the given {@link Factory} to instantiate new ViewModels.
*
* @param lifecycleOwner a lifecycle owner, in whose scope ViewModels should be retained (ViewController, Fragment, Activity)
* @param factory a {@code Factory} to instantiate new ViewModels
* @return a ViewModelProvider instance
*/
open fun of(
lifecycleOwner: LifecycleOwner,
factory: ViewModelProvider.Factory = LifecycleViewModelProviders.getViewModelFactory(lifecycleOwner)
): ViewModelProvider =
when (lifecycleOwner) {
is Fragment -> ViewModelProvider(lifecycleOwner, factory)
is FragmentActivity -> ViewModelProvider(lifecycleOwner, factory)
else -> throw IllegalArgumentException("Not supported LifecycleOwner.")
}
/**
* Returns ViewModelProvider.Factory instance from current lifecycleOwner.
* Search #ViewModelFactoryProvider are produced according to priorities:
* 1. Fragment;
* 2. Parent fragment recursively;
* 3. Activity;
* 4. Application.
*/
open fun getViewModelFactory(provider: Any): ViewModelProvider.Factory =
when (provider) {
is ViewModelFactoryProvider -> provider.viewModelFactory
is Fragment -> LifecycleViewModelProviders.getViewModelFactory(provider.parentFragment ?: provider.requireActivity())
is Activity -> LifecycleViewModelProviders.getViewModelFactory(provider.application)
else -> throw IllegalArgumentException("View model factory not found.")
}
}

View File

@ -1,49 +1,3 @@
package ru.touchin.lifecycle.viewmodel
import android.app.Activity
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentActivity
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.ViewModelProviders
import ru.touchin.roboswag.navigation_viewcontroller.viewcontrollers.ViewController
object LifecycleViewModelProviders {
/**
* Creates a {@link ViewModelProvider}, which retains ViewModels while a scope of given
* {@code lifecycleOwner} is alive. More detailed explanation is in {@link ViewModel}.
* <p>
* It uses the given {@link Factory} to instantiate new ViewModels.
*
* @param lifecycleOwner a lifecycle owner, in whose scope ViewModels should be retained (ViewController, Fragment, Activity)
* @param factory a {@code Factory} to instantiate new ViewModels
* @return a ViewModelProvider instance
*/
fun of(lifecycleOwner: LifecycleOwner, factory: ViewModelProvider.Factory = getViewModelFactory(lifecycleOwner)): ViewModelProvider =
when (lifecycleOwner) {
is ViewController<*, *> -> ViewModelProviders.of(lifecycleOwner.fragment, factory)
is Fragment -> ViewModelProviders.of(lifecycleOwner, factory)
is FragmentActivity -> ViewModelProviders.of(lifecycleOwner, factory)
else -> throw IllegalArgumentException("Not supported LifecycleOwner.")
}
/**
* Returns ViewModelProvider.Factory instance from current lifecycleOwner.
* Search #ViewModelFactoryProvider are produced according to priorities:
* 1. View controller;
* 2. Fragment;
* 3. Parent fragment recursively;
* 4. Activity;
* 5. Application.
*/
fun getViewModelFactory(provider: Any): ViewModelProvider.Factory =
when (provider) {
is ViewModelFactoryProvider -> provider.viewModelFactory
is ViewController<*, *> -> getViewModelFactory(provider.fragment)
is Fragment -> getViewModelFactory(provider.parentFragment ?: provider.requireActivity())
is Activity -> getViewModelFactory(provider.application)
else -> throw IllegalArgumentException("View model factory not found.")
}
}
object LifecycleViewModelProviders : BaseLifecycleViewModelProviders()

View File

@ -21,12 +21,12 @@ android {
}
dependencies {
api project(":utils")
api project(":logging")
implementation project(":utils")
implementation project(":logging")
api 'androidx.multidex:multidex:2.0.1'
implementation 'androidx.multidex:multidex:2.0.1'
api 'net.danlew:android.joda:2.10.2'
implementation 'net.danlew:android.joda:2.10.2'
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"

View File

@ -28,7 +28,7 @@ import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentManager
import androidx.fragment.app.FragmentTransaction
import ru.touchin.roboswag.core.log.Lc
import ru.touchin.roboswag.navigation_base.fragments.FragmentWithState
import ru.touchin.roboswag.navigation_base.fragments.StatefulFragment
import kotlin.reflect.KClass
/**
@ -169,14 +169,14 @@ open class FragmentNavigation(
* @param transactionSetup Function to setup transaction before commit. It is useful to specify transition animations or additional info.
*/
fun <T : Parcelable> push(
fragmentClass: KClass<out FragmentWithState<*, out T>>,
fragmentClass: KClass<out StatefulFragment<*, out T>>,
state: T,
addToStack: Boolean = true,
backStackName: String? = null,
tag: String? = null,
transactionSetup: ((FragmentTransaction) -> Unit)? = null
) {
push(fragmentClass.java, FragmentWithState.args(state), addToStack, backStackName, tag, transactionSetup)
push(fragmentClass.java, StatefulFragment.args(state), addToStack, backStackName, tag, transactionSetup)
}
/**
@ -216,14 +216,14 @@ open class FragmentNavigation(
* @param transactionSetup Function to setup transaction before commit. It is useful to specify transition animations or additional info.
*/
fun <T : Parcelable> pushForResult(
fragmentClass: KClass<out FragmentWithState<*, out T>>,
fragmentClass: KClass<out StatefulFragment<*, out T>>,
targetFragment: Fragment,
targetRequestCode: Int,
state: T,
tag: String? = null,
transactionSetup: ((FragmentTransaction) -> Unit)? = null
) {
pushForResult(fragmentClass.java, targetFragment, targetRequestCode, FragmentWithState.args(state), tag, transactionSetup)
pushForResult(fragmentClass.java, targetFragment, targetRequestCode, StatefulFragment.args(state), tag, transactionSetup)
}
/**
@ -270,13 +270,13 @@ open class FragmentNavigation(
* @param transactionSetup Function to setup transaction before commit. It is useful to specify transition animations or additional info.
*/
fun <T : Parcelable> setInitial(
fragmentClass: KClass<out FragmentWithState<*, out T>>,
fragmentClass: KClass<out StatefulFragment<*, out T>>,
state: T,
tag: String? = null,
transactionSetup: ((FragmentTransaction) -> Unit)? = null
) {
beforeSetInitialActions()
setAsTop(fragmentClass.java, FragmentWithState.args(state), false, tag, transactionSetup)
setAsTop(fragmentClass.java, StatefulFragment.args(state), false, tag, transactionSetup)
}
/**

View File

@ -0,0 +1,47 @@
package ru.touchin.roboswag.navigation_base.extensions
import android.os.Parcel
import android.os.Parcelable
import ru.touchin.roboswag.navigation_base.fragments.EmptyState
// This method used to check unique state of each fragment.
// If two fragments share same class for state, you should not pass state instance of current fragment to the one you transition to
fun <T : Parcelable> Parcelable.reserialize(): T {
var parcel = Parcel.obtain()
parcel.writeParcelable(this, 0)
val serializableBytes = parcel.marshall()
parcel.recycle()
parcel = Parcel.obtain().apply {
unmarshall(serializableBytes, 0, serializableBytes.size)
setDataPosition(0)
}
val result = parcel.readParcelable<T>(Thread.currentThread().contextClassLoader)
?: throw IllegalStateException("It must not be null")
parcel.recycle()
return result
}
fun Parcelable.copy(): Parcelable =
if (this is EmptyState) {
EmptyState
} else {
val parcel = Parcel.obtain()
parcel.writeParcelable(this, 0)
parcel.setDataPosition(0)
val result = parcel.readParcelable<Parcelable>(
javaClass.classLoader ?: Thread.currentThread().contextClassLoader
) ?: throw IllegalStateException("Failed to copy tab state")
parcel.recycle()
result
}

View File

@ -1,13 +1,13 @@
package ru.touchin.roboswag.navigation_base.fragments
import android.os.Bundle
import android.os.Parcel
import android.os.Parcelable
import androidx.annotation.LayoutRes
import androidx.fragment.app.FragmentActivity
import ru.touchin.roboswag.navigation_base.BuildConfig
import ru.touchin.roboswag.navigation_base.extensions.reserialize
open class FragmentWithState<TActivity : FragmentActivity, TState : Parcelable>(
open class StatefulFragment<TActivity : FragmentActivity, TState : Parcelable>(
@LayoutRes layoutRes: Int
) : BaseFragment<TActivity>(layoutRes) {
@ -16,20 +16,6 @@ open class FragmentWithState<TActivity : FragmentActivity, TState : Parcelable>(
fun args(state: Parcelable?): Bundle = Bundle().also { it.putParcelable(BASE_FRAGMENT_STATE_EXTRA, state) }
// This method used to check unique state of each fragment.
// If two fragments share same class for state, you should not pass state instance of current fragment to the one you transition to
private fun <T : Parcelable> reserialize(parcelable: T): T {
var parcel = Parcel.obtain()
parcel.writeParcelable(parcelable, 0)
val serializableBytes = parcel.marshall()
parcel.recycle()
parcel = Parcel.obtain()
parcel.unmarshall(serializableBytes, 0, serializableBytes.size)
parcel.setDataPosition(0)
val result = parcel.readParcelable<T>(Thread.currentThread().contextClassLoader) ?: throw IllegalStateException("It must not be null")
parcel.recycle()
return result
}
}
protected lateinit var state: TState
@ -43,7 +29,7 @@ open class FragmentWithState<TActivity : FragmentActivity, TState : Parcelable>(
?: throw IllegalStateException("Fragment state can't be null")
if (BuildConfig.DEBUG) {
state = reserialize(state)
state = state.reserialize()
}
}

View File

@ -9,12 +9,11 @@ import androidx.lifecycle.LifecycleObserver
import ru.touchin.roboswag.components.utils.UiUtils
import ru.touchin.roboswag.navigation_base.activities.BaseActivity
import ru.touchin.roboswag.navigation_base.activities.OnBackPressedListener
import ru.touchin.roboswag.navigation_base.fragments.BaseFragment
import ru.touchin.roboswag.navigation_base.fragments.FragmentWithState
import ru.touchin.roboswag.navigation_base.fragments.StatefulFragment
abstract class KeyboardResizeableFragment<TActivity : BaseActivity, TState : Parcelable>(
@LayoutRes layoutRes: Int
) : FragmentWithState<TActivity, TState>(
) : StatefulFragment<TActivity, TState>(
layoutRes
) {

View File

@ -21,13 +21,13 @@ android {
}
dependencies {
api project(":utils")
api project(":logging")
api project(":navigation-base")
implementation project(":utils")
implementation project(":logging")
implementation project(":navigation-base")
api 'androidx.multidex:multidex:2.0.1'
implementation 'androidx.multidex:multidex:2.0.1'
api 'net.danlew:android.joda:2.10.2'
implementation 'net.danlew:android.joda:2.10.2'
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"