commit
e40a30ec2a
|
|
@ -1 +1 @@
|
|||
Subproject commit c8e8b1f521316083a4a49c36b0a3e7af84026e7c
|
||||
Subproject commit 15ca24b0ac2078fe4a9994290dc69d9aea2630b9
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
buildscript {
|
||||
ext.kotlin_version = '1.3.0'
|
||||
ext.kotlin_version = '1.3.11'
|
||||
repositories {
|
||||
google()
|
||||
jcenter()
|
||||
|
|
@ -9,7 +9,7 @@ buildscript {
|
|||
classpath 'com.android.tools.build:gradle:3.2.1'
|
||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
||||
classpath 'de.aaschmid:gradle-cpd-plugin:1.1'
|
||||
classpath "io.gitlab.arturbosch.detekt:detekt-gradle-plugin:1.0.0-RC10"
|
||||
classpath "io.gitlab.arturbosch.detekt:detekt-gradle-plugin:1.0.0-RC12"
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -26,8 +26,10 @@ task clean(type: Delete) {
|
|||
}
|
||||
|
||||
ext {
|
||||
ext.buildScriptsDir = "$rootDir/BuildScripts"
|
||||
versions = [
|
||||
compileSdk : 28,
|
||||
appcompat : '1.0.2',
|
||||
androidx : '1.0.0',
|
||||
material : '1.0.0',
|
||||
lifecycle : '2.0.0',
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ dependencies {
|
|||
|
||||
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
|
||||
|
||||
implementation "androidx.appcompat:appcompat:$versions.androidx"
|
||||
implementation "androidx.appcompat:appcompat:$versions.appcompat"
|
||||
|
||||
implementation "androidx.lifecycle:lifecycle-extensions:$versions.lifecycle"
|
||||
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ dependencies {
|
|||
|
||||
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
|
||||
|
||||
implementation "androidx.appcompat:appcompat:$versions.androidx"
|
||||
implementation "androidx.appcompat:appcompat:$versions.appcompat"
|
||||
|
||||
implementation "androidx.lifecycle:lifecycle-extensions:$versions.lifecycle"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,6 +20,6 @@ dependencies {
|
|||
|
||||
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
|
||||
|
||||
implementation "androidx.appcompat:appcompat:$versions.androidx"
|
||||
implementation "androidx.appcompat:appcompat:$versions.appcompat"
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,7 +25,6 @@ import android.content.Intent
|
|||
import android.os.Bundle
|
||||
import android.os.Parcel
|
||||
import android.os.Parcelable
|
||||
import android.os.SystemClock
|
||||
import android.view.LayoutInflater
|
||||
import android.view.Menu
|
||||
import android.view.MenuInflater
|
||||
|
|
@ -33,14 +32,11 @@ import android.view.MenuItem
|
|||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.view.animation.Animation
|
||||
import androidx.annotation.CallSuper
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.fragment.app.FragmentActivity
|
||||
import androidx.lifecycle.Lifecycle
|
||||
import ru.touchin.roboswag.components.navigation.BuildConfig
|
||||
import ru.touchin.roboswag.components.navigation.viewcontrollers.ViewController
|
||||
import ru.touchin.roboswag.core.log.LcGroup
|
||||
import kotlin.IllegalArgumentException
|
||||
|
||||
/**
|
||||
* Created by Gavriil Sitnikov on 21/10/2015.
|
||||
|
|
@ -49,24 +45,14 @@ import kotlin.IllegalArgumentException
|
|||
* @param <TState> Type of object which is representing it's fragment state;
|
||||
* @param <TActivity> Type of [FragmentActivity] where fragment could be attached to.
|
||||
</TActivity></TState> */
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
class ViewControllerFragment<TActivity : FragmentActivity, TState : Parcelable> : Fragment() {
|
||||
@Suppress("detekt.TooManyFunctions", "UNCHECKED_CAST")
|
||||
open class ViewControllerFragment<TActivity : FragmentActivity, TState : Parcelable> : Fragment() {
|
||||
|
||||
companion object {
|
||||
|
||||
private const val VIEW_CONTROLLER_CLASS_EXTRA = "VIEW_CONTROLLER_CLASS_EXTRA"
|
||||
private const val VIEW_CONTROLLER_STATE_EXTRA = "VIEW_CONTROLLER_STATE_EXTRA"
|
||||
|
||||
private var acceptableUiCalculationTime: Long = 100
|
||||
|
||||
/**
|
||||
* Sets acceptable UI calculation time so there will be warnings in logs if ViewController's inflate/layout actions will take more than that time.
|
||||
* It's 100ms by default.
|
||||
*/
|
||||
fun setAcceptableUiCalculationTime(acceptableUiCalculationTime: Long) {
|
||||
ViewControllerFragment.acceptableUiCalculationTime = acceptableUiCalculationTime
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates [Bundle] which will store state.
|
||||
*
|
||||
|
|
@ -92,8 +78,7 @@ class ViewControllerFragment<TActivity : FragmentActivity, TState : Parcelable>
|
|||
}
|
||||
}
|
||||
|
||||
lateinit var state: TState
|
||||
private set
|
||||
lateinit var state: TState private set
|
||||
|
||||
private var viewController: ViewController<out TActivity, out TState>? = null
|
||||
private var pendingActivityResult: ActivityResult? = null
|
||||
|
|
@ -133,15 +118,18 @@ class ViewControllerFragment<TActivity : FragmentActivity, TState : Parcelable>
|
|||
|
||||
override fun onActivityCreated(savedInstanceState: Bundle?) {
|
||||
super.onActivityCreated(savedInstanceState)
|
||||
if (viewController != null && pendingActivityResult != null) {
|
||||
viewController!!.onActivityResult(pendingActivityResult!!.requestCode, pendingActivityResult!!.resultCode, pendingActivityResult!!.data)
|
||||
val activityResult = pendingActivityResult
|
||||
if (viewController != null && activityResult != null) {
|
||||
viewController?.onActivityResult(activityResult.requestCode, activityResult.resultCode, activityResult.data)
|
||||
pendingActivityResult = null
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCreateAnimation(transit: Int, enter: Boolean, nextAnim: Int): Animation? = viewController?.onCreateAnimation(transit, enter, nextAnim)
|
||||
override fun onCreateAnimation(transit: Int, enter: Boolean, nextAnim: Int): Animation? =
|
||||
viewController?.onCreateAnimation(transit, enter, nextAnim)
|
||||
|
||||
override fun onCreateAnimator(transit: Int, enter: Boolean, nextAnim: Int): Animator? = viewController?.onCreateAnimator(transit, enter, nextAnim)
|
||||
override fun onCreateAnimator(transit: Int, enter: Boolean, nextAnim: Int): Animator? =
|
||||
viewController?.onCreateAnimator(transit, enter, nextAnim)
|
||||
|
||||
override fun onViewStateRestored(savedInstanceState: Bundle?) {
|
||||
super.onViewStateRestored(savedInstanceState)
|
||||
|
|
@ -161,8 +149,7 @@ class ViewControllerFragment<TActivity : FragmentActivity, TState : Parcelable>
|
|||
* Called when fragment is moved in started state and it's [.isMenuVisible] sets to true.
|
||||
* Usually it is indicating that user can't see fragment on screen and useful to track analytics events.
|
||||
*/
|
||||
@CallSuper
|
||||
protected fun onAppear() {
|
||||
private fun onAppear() {
|
||||
appeared = true
|
||||
viewController?.onAppear()
|
||||
}
|
||||
|
|
@ -178,13 +165,11 @@ class ViewControllerFragment<TActivity : FragmentActivity, TState : Parcelable>
|
|||
}
|
||||
|
||||
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
|
||||
super.onCreateOptionsMenu(menu, inflater)
|
||||
viewController?.onCreateOptionsMenu(menu, inflater)
|
||||
}
|
||||
|
||||
override fun onOptionsItemSelected(item: MenuItem): Boolean = viewController != null
|
||||
&& viewController!!.onOptionsItemSelected(item)
|
||||
|| super.onOptionsItemSelected(item)
|
||||
override fun onOptionsItemSelected(item: MenuItem): Boolean =
|
||||
viewController?.onOptionsItemSelected(item) == true || super.onOptionsItemSelected(item)
|
||||
|
||||
override fun onPause() {
|
||||
super.onPause()
|
||||
|
|
@ -201,8 +186,7 @@ class ViewControllerFragment<TActivity : FragmentActivity, TState : Parcelable>
|
|||
* Called when fragment is moved in stopped state or it's [.isMenuVisible] sets to false.
|
||||
* Usually it is indicating that user can't see fragment on screen and useful to track analytics events.
|
||||
*/
|
||||
@CallSuper
|
||||
protected fun onDisappear() {
|
||||
private fun onDisappear() {
|
||||
appeared = false
|
||||
viewController?.onDisappear()
|
||||
}
|
||||
|
|
@ -216,10 +200,8 @@ class ViewControllerFragment<TActivity : FragmentActivity, TState : Parcelable>
|
|||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
if (viewController != null) {
|
||||
viewController!!.onDestroy()
|
||||
viewController = null
|
||||
}
|
||||
viewController?.onDestroy()
|
||||
viewController = null
|
||||
super.onDestroyView()
|
||||
}
|
||||
|
||||
|
|
@ -256,24 +238,11 @@ class ViewControllerFragment<TActivity : FragmentActivity, TState : Parcelable>
|
|||
throw IllegalStateException("There should be single constructor for $viewControllerClass")
|
||||
}
|
||||
val constructor = viewControllerClass.constructors[0]
|
||||
try {
|
||||
return when (constructor.parameterTypes.size) {
|
||||
2 -> constructor.newInstance(creationContext, savedInstanceState)
|
||||
3 -> constructor.newInstance(this, creationContext, savedInstanceState)
|
||||
else -> throw IllegalArgumentException("Wrong constructor parameters count: ${constructor.parameterTypes.size}")
|
||||
} as ViewController<out TActivity, out TState>
|
||||
} finally {
|
||||
checkCreationTime(if (BuildConfig.DEBUG) SystemClock.elapsedRealtime() else 0)
|
||||
}
|
||||
}
|
||||
|
||||
private fun checkCreationTime(creationTime: Long) {
|
||||
if (BuildConfig.DEBUG) {
|
||||
val creationPeriod = SystemClock.elapsedRealtime() - creationTime
|
||||
if (creationPeriod > acceptableUiCalculationTime) {
|
||||
LcGroup.UI_METRICS.w("Creation of %s took too much: %dms", viewControllerClass, creationPeriod)
|
||||
}
|
||||
}
|
||||
return when (constructor.parameterTypes.size) {
|
||||
1 -> constructor.newInstance(creationContext)
|
||||
2 -> constructor.newInstance(creationContext, savedInstanceState)
|
||||
else -> throw IllegalArgumentException("Wrong constructor parameters count: ${constructor.parameterTypes.size}")
|
||||
} as ViewController<out TActivity, out TState>
|
||||
}
|
||||
|
||||
override fun toString(): String = "${super.toString()} ViewController: $viewControllerClass"
|
||||
|
|
|
|||
|
|
@ -58,16 +58,18 @@ import ru.touchin.roboswag.core.log.LcGroup
|
|||
* @param <TActivity> Type of activity where such [ViewController] could be;
|
||||
* @param <TState> Type of state;
|
||||
</TState></TActivity> */
|
||||
@Suppress("PMD.UnusedFormalParameter", "UNCHECKED_CAST")
|
||||
@Suppress("detekt.TooManyFunctions", "UNCHECKED_CAST")
|
||||
open class ViewController<TActivity : FragmentActivity, TState : Parcelable>(
|
||||
creationContext: CreationContext,
|
||||
savedInstanceState: Bundle?,
|
||||
@LayoutRes layoutRes: Int
|
||||
) : LifecycleOwner {
|
||||
|
||||
val activity: TActivity = creationContext.activity as TActivity
|
||||
|
||||
val fragment: ViewControllerFragment<out TActivity, out TState> = creationContext.fragment as ViewControllerFragment<out TActivity, out TState>
|
||||
|
||||
val state = fragment.state
|
||||
|
||||
val view: View = creationContext.inflater.inflate(layoutRes, creationContext.container, false)
|
||||
|
||||
private val lifecycleRegistry = LifecycleRegistry(this)
|
||||
|
|
@ -185,7 +187,7 @@ open class ViewController<TActivity : FragmentActivity, TState : Parcelable>(
|
|||
* [FragmentTransaction.setCustomAnimations], or
|
||||
* 0 if neither was called. The value will depend on the current operation.
|
||||
*/
|
||||
fun onCreateAnimation(transit: Int, enter: Boolean, nextAnim: Int): Animation? = null
|
||||
open fun onCreateAnimation(transit: Int, enter: Boolean, nextAnim: Int): Animation? = null
|
||||
|
||||
/**
|
||||
* Called when a fragment loads an animator. This will be called when
|
||||
|
|
@ -203,13 +205,13 @@ open class ViewController<TActivity : FragmentActivity, TState : Parcelable>(
|
|||
* [FragmentTransaction.setCustomAnimations], or
|
||||
* 0 if neither was called. The value will depend on the current operation.
|
||||
*/
|
||||
fun onCreateAnimator(transit: Int, enter: Boolean, nextAnim: Int): Animator? = null
|
||||
open fun onCreateAnimator(transit: Int, enter: Boolean, nextAnim: Int): Animator? = null
|
||||
|
||||
/**
|
||||
* Calls when [ViewController] saved state has been restored into the view hierarchy.
|
||||
* Happens at [ViewControllerFragment.onViewStateRestored].
|
||||
*/
|
||||
fun onViewStateRestored(savedInstanceState: Bundle?) = Unit
|
||||
open fun onViewStateRestored(savedInstanceState: Bundle?) = Unit
|
||||
|
||||
/**
|
||||
* Calls when [ViewController] have started.
|
||||
|
|
@ -263,7 +265,7 @@ open class ViewController<TActivity : FragmentActivity, TState : Parcelable>(
|
|||
* Try not to use such method for saving state but use [ViewControllerFragment.state] from [.getFragment].
|
||||
*/
|
||||
@CallSuper
|
||||
fun onSaveInstanceState(savedInstanceState: Bundle) {
|
||||
open fun onSaveInstanceState(savedInstanceState: Bundle) {
|
||||
LcGroup.UI_LIFECYCLE.i(Lc.getCodePoint(this))
|
||||
}
|
||||
|
||||
|
|
@ -271,7 +273,7 @@ open class ViewController<TActivity : FragmentActivity, TState : Parcelable>(
|
|||
* Called when fragment is moved in stopped state or it's [.getFragment] sets to false.
|
||||
* Usually it is indicating that user can't see fragment on screen and useful to track analytics events.
|
||||
*/
|
||||
fun onDisappear() {
|
||||
open fun onDisappear() {
|
||||
LcGroup.UI_LIFECYCLE.i(Lc.getCodePoint(this))
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -14,9 +14,27 @@ android {
|
|||
}
|
||||
|
||||
buildTypes {
|
||||
release {
|
||||
debug {
|
||||
versionNameSuffix ".debug"
|
||||
minifyEnabled false
|
||||
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
||||
shrinkResources false
|
||||
}
|
||||
release {
|
||||
minifyEnabled true
|
||||
shrinkResources true
|
||||
}
|
||||
}
|
||||
|
||||
flavorDimensions "proguardSettings"
|
||||
|
||||
productFlavors {
|
||||
noObfuscate {
|
||||
dimension "proguardSettings"
|
||||
proguardFiles getDefaultProguardFile('proguard-android.txt'), "$buildScriptsDir/proguard/noObfuscate.pro"
|
||||
}
|
||||
obfuscate {
|
||||
dimension "proguardSettings"
|
||||
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), "$buildScriptsDir/proguard/obfuscate.pro"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -24,9 +42,7 @@ android {
|
|||
dependencies {
|
||||
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
|
||||
|
||||
implementation "androidx.appcompat:appcompat:$versions.androidx"
|
||||
implementation 'androidx.constraintlayout:constraintlayout:2.0.0-alpha2'
|
||||
implementation "androidx.appcompat:appcompat:$versions.appcompat"
|
||||
}
|
||||
|
||||
ext.buildScriptsDir = "$rootDir/BuildScripts"
|
||||
apply from: "$buildScriptsDir/gradle/staticAnalysis.gradle"
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
<FrameLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
|
|
@ -10,10 +9,7 @@
|
|||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Hello World!"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"/>
|
||||
android:layout_gravity="center"
|
||||
android:text="Hello World!"/>
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
</FrameLayout>
|
||||
|
|
|
|||
|
|
@ -19,11 +19,11 @@ dependencies {
|
|||
api project(":api-logansquare")
|
||||
api project(":navigation")
|
||||
|
||||
api 'androidx.multidex:multidex:2.0.0'
|
||||
api 'androidx.multidex:multidex:2.0.1'
|
||||
|
||||
api 'net.danlew:android.joda:2.9.9.4'
|
||||
|
||||
implementation "androidx.appcompat:appcompat:$versions.androidx"
|
||||
implementation "androidx.appcompat:appcompat:$versions.appcompat"
|
||||
|
||||
implementation("com.crashlytics.sdk.android:crashlytics:$versions.crashlytics@aar") {
|
||||
transitive = true
|
||||
|
|
|
|||
Loading…
Reference in New Issue