├── app ├── .gitignore ├── src │ └── main │ │ ├── res │ │ ├── drawable │ │ │ ├── sample_image_1.jpg │ │ │ ├── sample_image_2.jpg │ │ │ └── ic_launcher_background.xml │ │ ├── mipmap-hdpi │ │ │ ├── ic_launcher.png │ │ │ └── ic_launcher_round.png │ │ ├── mipmap-mdpi │ │ │ ├── ic_launcher.png │ │ │ └── ic_launcher_round.png │ │ ├── mipmap-xhdpi │ │ │ ├── ic_launcher.png │ │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxhdpi │ │ │ ├── ic_launcher.png │ │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxxhdpi │ │ │ ├── ic_launcher.png │ │ │ └── ic_launcher_round.png │ │ ├── values │ │ │ ├── strings.xml │ │ │ ├── colors.xml │ │ │ ├── attrs.xml │ │ │ └── styles.xml │ │ ├── mipmap-anydpi-v26 │ │ │ ├── ic_launcher.xml │ │ │ └── ic_launcher_round.xml │ │ ├── layout │ │ │ ├── main_activity.xml │ │ │ ├── titled_picture_title_above.xml │ │ │ ├── titled_picture_title_below.xml │ │ │ ├── counter.xml │ │ │ └── main_fragment.xml │ │ └── drawable-v24 │ │ │ └── ic_launcher_foreground.xml │ │ ├── java │ │ └── ru │ │ │ └── impression │ │ │ └── ui_generator_example │ │ │ ├── GreetingStructure.kt │ │ │ ├── MainActivity.kt │ │ │ ├── ToastShower.kt │ │ │ ├── Ext.kt │ │ │ ├── TitledPicture.kt │ │ │ ├── Counter.kt │ │ │ └── MainFragment.kt │ │ └── AndroidManifest.xml ├── proguard-rules.pro └── build.gradle.kts ├── jitpack.yml ├── ui-generator-base ├── consumer-rules.pro ├── .gitignore ├── src │ └── main │ │ ├── AndroidManifest.xml │ │ └── java │ │ └── ru │ │ └── impression │ │ └── ui_generator_base │ │ ├── StateOwner.kt │ │ ├── ComponentScheme.kt │ │ ├── SavedViewState.kt │ │ ├── ClearableCoroutineScope.kt │ │ ├── ViewLifecycleOwner.kt │ │ ├── SimpleLifecycle.kt │ │ ├── Component.kt │ │ ├── Hooks.kt │ │ ├── ObservableEntity.kt │ │ ├── CoroutineViewModel.kt │ │ ├── Binders.kt │ │ ├── StateDelegate.kt │ │ ├── DataBindingManager.kt │ │ ├── Ext.kt │ │ └── ComponentViewModel.kt ├── proguard-rules.pro └── build.gradle.kts ├── ui-generator-annotations ├── consumer-rules.pro ├── .gitignore ├── src │ └── main │ │ └── java │ │ └── ru │ │ └── impression │ │ └── ui_generator_annotations │ │ ├── MakeComponent.kt │ │ ├── SharedViewModel.kt │ │ └── Prop.kt ├── build.gradle.kts └── proguard-rules.pro ├── ui-generator-processor ├── .gitignore ├── src │ └── main │ │ ├── resources │ │ └── META-INF │ │ │ └── services │ │ │ └── com.google.devtools.ksp.processing.SymbolProcessorProvider │ │ └── java │ │ └── ru │ │ └── impression │ │ └── ui_generator_processor │ │ ├── UIGeneratorProcessorProvider.kt │ │ ├── Ext.kt │ │ ├── UIGenerator.kt │ │ ├── ComponentClassBuilder.kt │ │ ├── FragmentComponentClassBuilder.kt │ │ └── ViewComponentClassBuilder.kt └── build.gradle.kts ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── .gitignore ├── settings.gradle.kts ├── gradle.properties ├── gradlew.bat ├── gradlew └── README.md /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /jitpack.yml: -------------------------------------------------------------------------------- 1 | jdk: 2 | - openjdk11 -------------------------------------------------------------------------------- /ui-generator-base/consumer-rules.pro: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /ui-generator-annotations/consumer-rules.pro: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /ui-generator-base/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /ui-generator-annotations/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /ui-generator-processor/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ArTemmey/ui-generator/HEAD/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /app/src/main/res/drawable/sample_image_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ArTemmey/ui-generator/HEAD/app/src/main/res/drawable/sample_image_1.jpg -------------------------------------------------------------------------------- /app/src/main/res/drawable/sample_image_2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ArTemmey/ui-generator/HEAD/app/src/main/res/drawable/sample_image_2.jpg -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ArTemmey/ui-generator/HEAD/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ArTemmey/ui-generator/HEAD/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ArTemmey/ui-generator/HEAD/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ArTemmey/ui-generator/HEAD/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ArTemmey/ui-generator/HEAD/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ArTemmey/ui-generator/HEAD/app/src/main/res/mipmap-hdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ArTemmey/ui-generator/HEAD/app/src/main/res/mipmap-mdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ArTemmey/ui-generator/HEAD/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ArTemmey/ui-generator/HEAD/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ArTemmey/ui-generator/HEAD/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | .idea 5 | .DS_Store 6 | /build 7 | /buildSrc/build 8 | /captures 9 | .externalNativeBuild 10 | .cxx 11 | -------------------------------------------------------------------------------- /app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | UI-generator 3 | %s, %s! 4 | 5 | -------------------------------------------------------------------------------- /ui-generator-base/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | -------------------------------------------------------------------------------- /ui-generator-annotations/src/main/java/ru/impression/ui_generator_annotations/MakeComponent.kt: -------------------------------------------------------------------------------- 1 | package ru.impression.ui_generator_annotations 2 | 3 | annotation class MakeComponent -------------------------------------------------------------------------------- /ui-generator-processor/src/main/resources/META-INF/services/com.google.devtools.ksp.processing.SymbolProcessorProvider: -------------------------------------------------------------------------------- 1 | ru.impression.ui_generator_processor.UIGeneratorProcessorProvider -------------------------------------------------------------------------------- /ui-generator-annotations/src/main/java/ru/impression/ui_generator_annotations/SharedViewModel.kt: -------------------------------------------------------------------------------- 1 | package ru.impression.ui_generator_annotations 2 | 3 | annotation class SharedViewModel -------------------------------------------------------------------------------- /ui-generator-annotations/src/main/java/ru/impression/ui_generator_annotations/Prop.kt: -------------------------------------------------------------------------------- 1 | package ru.impression.ui_generator_annotations 2 | 3 | annotation class Prop(val twoWay: Boolean = false) -------------------------------------------------------------------------------- /settings.gradle.kts: -------------------------------------------------------------------------------- 1 | include( 2 | // ":app", 3 | ":ui-generator-annotations", 4 | ":ui-generator-processor", 5 | ":ui-generator-base", 6 | ) 7 | 8 | rootProject.name = "UI-generator" -------------------------------------------------------------------------------- /ui-generator-base/src/main/java/ru/impression/ui_generator_base/StateOwner.kt: -------------------------------------------------------------------------------- 1 | package ru.impression.ui_generator_base 2 | 3 | interface StateOwner { 4 | fun onStateChanged(renderImmediately: Boolean = false) 5 | } -------------------------------------------------------------------------------- /ui-generator-base/src/main/java/ru/impression/ui_generator_base/ComponentScheme.kt: -------------------------------------------------------------------------------- 1 | package ru.impression.ui_generator_base 2 | 3 | abstract class ComponentScheme( 4 | val render: (C.(viewModel: VM) -> Int?)? = null 5 | ) -------------------------------------------------------------------------------- /app/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #6200EE 4 | #3700B3 5 | #03DAC5 6 | 7 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Mon Dec 07 12:49:46 MSK 2020 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.0.2-bin.zip 7 | -------------------------------------------------------------------------------- /ui-generator-base/src/main/java/ru/impression/ui_generator_base/SavedViewState.kt: -------------------------------------------------------------------------------- 1 | package ru.impression.ui_generator_base 2 | 3 | import android.os.Parcelable 4 | import kotlinx.parcelize.Parcelize 5 | 6 | @Parcelize 7 | class SavedViewState(val superState: Parcelable?, val viewModelState: Parcelable?): Parcelable -------------------------------------------------------------------------------- /app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/values/attrs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /app/src/main/java/ru/impression/ui_generator_example/GreetingStructure.kt: -------------------------------------------------------------------------------- 1 | package ru.impression.ui_generator_example 2 | 3 | import kotlinx.serialization.Serializable 4 | import ru.impression.ui_generator_base.ObservableEntity 5 | import ru.impression.ui_generator_base.ObservableEntityImpl 6 | 7 | @Serializable 8 | class GreetingStructure(private var greetingAddressee: String) : 9 | ObservableEntity by ObservableEntityImpl() { 10 | 11 | var greetingAddresseeState by state(greetingAddressee) { greetingAddressee = it } 12 | } -------------------------------------------------------------------------------- /app/src/main/res/layout/main_activity.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 12 | 13 | -------------------------------------------------------------------------------- /ui-generator-processor/src/main/java/ru/impression/ui_generator_processor/UIGeneratorProcessorProvider.kt: -------------------------------------------------------------------------------- 1 | package ru.impression.ui_generator_processor 2 | 3 | import com.google.devtools.ksp.processing.SymbolProcessorEnvironment 4 | import com.google.devtools.ksp.processing.SymbolProcessorProvider 5 | 6 | class UIGeneratorProcessorProvider : SymbolProcessorProvider { 7 | override fun create(environment: SymbolProcessorEnvironment) = 8 | UIGenerator(environment.codeGenerator, environment.logger, environment.options["packageName"]!!) 9 | } -------------------------------------------------------------------------------- /app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 10 | 11 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /ui-generator-base/src/main/java/ru/impression/ui_generator_base/ClearableCoroutineScope.kt: -------------------------------------------------------------------------------- 1 | package ru.impression.ui_generator_base 2 | 3 | import kotlinx.coroutines.CoroutineScope 4 | import kotlinx.coroutines.Job 5 | import kotlin.coroutines.CoroutineContext 6 | 7 | interface ClearableCoroutineScope : CoroutineScope { 8 | fun clear() 9 | } 10 | 11 | class ClearableCoroutineScopeImpl(coroutineContext: CoroutineContext) : 12 | ClearableCoroutineScope { 13 | 14 | override var coroutineContext: CoroutineContext = coroutineContext + Job() 15 | 16 | override fun clear() { 17 | coroutineContext[Job]?.cancel() 18 | ?.also { coroutineContext = coroutineContext.minusKey(Job) + Job() } 19 | } 20 | } -------------------------------------------------------------------------------- /ui-generator-annotations/build.gradle.kts: -------------------------------------------------------------------------------- 1 | plugins { 2 | kotlin("jvm") 3 | 4 | `maven-publish` 5 | } 6 | 7 | group = "com.github.ArtemiyDmtrvch" 8 | 9 | val sourcesJar by tasks.registering(Jar::class) { 10 | classifier = "sources" 11 | from(sourceSets.main.get().allSource) 12 | } 13 | 14 | publishing { 15 | repositories { 16 | maven(url = "https://jitpack.io") 17 | } 18 | publications { 19 | register("mavenJava", MavenPublication::class) { 20 | from(components["java"]) 21 | artifact(sourcesJar.get()) 22 | 23 | // groupId = "com.github.ArtemiyDmtrvch" 24 | // artifactId = "ui-generator-annotations" 25 | // version = "LOCAL" 26 | } 27 | } 28 | } -------------------------------------------------------------------------------- /ui-generator-processor/src/main/java/ru/impression/ui_generator_processor/Ext.kt: -------------------------------------------------------------------------------- 1 | @file:OptIn(KspExperimental::class) 2 | 3 | package ru.impression.ui_generator_processor 4 | 5 | import com.google.devtools.ksp.KspExperimental 6 | import com.google.devtools.ksp.getAnnotationsByType 7 | import com.google.devtools.ksp.symbol.KSPropertyDeclaration 8 | 9 | inline fun KSPropertyDeclaration.hasAnnotation() = 10 | (getAnnotationsByType(T::class).count() > 0) 11 | 12 | fun KSPropertyDeclaration.getParentTree(): List = 13 | findOverridee()?.let { listOf(it) + it.getParentTree() }.orEmpty() 14 | 15 | inline fun KSPropertyDeclaration.hasAnnotationInTree(): Boolean = 16 | getParentTree().none { it.hasAnnotation() } && hasAnnotation() -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile 22 | -------------------------------------------------------------------------------- /ui-generator-base/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile 22 | -------------------------------------------------------------------------------- /ui-generator-annotations/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile 22 | -------------------------------------------------------------------------------- /app/src/main/java/ru/impression/ui_generator_example/MainActivity.kt: -------------------------------------------------------------------------------- 1 | package ru.impression.ui_generator_example 2 | 3 | import android.os.Bundle 4 | import androidx.appcompat.app.AppCompatActivity 5 | 6 | class MainActivity : AppCompatActivity() { 7 | 8 | override fun onCreate(savedInstanceState: Bundle?) { 9 | super.onCreate(savedInstanceState) 10 | setContentView(R.layout.main_activity) 11 | supportFragmentManager.findFragmentByTag(MainFragmentComponent::class.qualifiedName) 12 | ?: supportFragmentManager.beginTransaction().replace( 13 | R.id.container, 14 | MainFragmentComponent().apply { 15 | welcomeText = "Hello"; greetingStructure = GreetingStructure("world") 16 | }, 17 | MainFragmentComponent::class.qualifiedName 18 | ).commit() 19 | } 20 | } -------------------------------------------------------------------------------- /app/src/main/java/ru/impression/ui_generator_example/ToastShower.kt: -------------------------------------------------------------------------------- 1 | package ru.impression.ui_generator_example 2 | 3 | import android.view.View 4 | import android.widget.Toast 5 | import ru.impression.ui_generator_annotations.MakeComponent 6 | import ru.impression.ui_generator_annotations.Prop 7 | import ru.impression.ui_generator_annotations.SharedViewModel 8 | import ru.impression.ui_generator_base.ComponentScheme 9 | import ru.impression.ui_generator_base.ComponentViewModel 10 | 11 | @MakeComponent 12 | class ToastShower : ComponentScheme({ viewModel -> 13 | viewModel.toastMessage?.let { 14 | viewModel.toastMessage = null 15 | Toast.makeText(context, it, Toast.LENGTH_SHORT).show() 16 | } 17 | null 18 | }) 19 | 20 | @SharedViewModel 21 | class ToastShowerViewModel : ComponentViewModel() { 22 | 23 | var toastMessage by state(null) 24 | } -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 12 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /app/src/main/java/ru/impression/ui_generator_example/Ext.kt: -------------------------------------------------------------------------------- 1 | package ru.impression.ui_generator_example 2 | 3 | import android.view.View 4 | import androidx.core.view.isGone 5 | import androidx.core.view.isInvisible 6 | import androidx.core.view.isVisible 7 | import androidx.databinding.BindingAdapter 8 | import ru.impression.ui_generator_base.ComponentViewModel 9 | 10 | fun ComponentViewModel.showToast(toastMessage: String) { 11 | getSharedViewModel().toastMessage = toastMessage 12 | } 13 | 14 | object DataBindingExt { 15 | 16 | @JvmStatic 17 | @BindingAdapter("isInvisible") 18 | fun setIsInvisible(view: View, value: Boolean) { 19 | view.isInvisible = value 20 | } 21 | 22 | @JvmStatic 23 | @BindingAdapter("isVisible") 24 | fun setIsVisible(view: View, value: Boolean) { 25 | view.isVisible = value 26 | } 27 | 28 | @JvmStatic 29 | @BindingAdapter("isGone") 30 | fun setIsGone(view: View, value: Boolean) { 31 | view.isGone = value 32 | } 33 | } -------------------------------------------------------------------------------- /ui-generator-base/src/main/java/ru/impression/ui_generator_base/ViewLifecycleOwner.kt: -------------------------------------------------------------------------------- 1 | package ru.impression.ui_generator_base 2 | 3 | import android.view.View 4 | import androidx.lifecycle.Lifecycle 5 | import androidx.lifecycle.LifecycleOwner 6 | 7 | class ViewLifecycleOwner(private val parent: View) : LifecycleOwner { 8 | 9 | private val lifecycle = SimpleLifecycle(this) 10 | 11 | private val onAttachStateChangeListener = object : View.OnAttachStateChangeListener { 12 | override fun onViewAttachedToWindow(v: View?) { 13 | lifecycle.handleLifecycleEvent(Lifecycle.Event.ON_CREATE) 14 | } 15 | 16 | override fun onViewDetachedFromWindow(v: View?) { 17 | lifecycle.handleLifecycleEvent(Lifecycle.Event.ON_DESTROY) 18 | } 19 | } 20 | 21 | init { 22 | parent.addOnAttachStateChangeListener(onAttachStateChangeListener) 23 | } 24 | 25 | override fun getLifecycle() = lifecycle 26 | 27 | fun destroy() { 28 | parent.removeOnAttachStateChangeListener(onAttachStateChangeListener) 29 | } 30 | } -------------------------------------------------------------------------------- /ui-generator-processor/build.gradle.kts: -------------------------------------------------------------------------------- 1 | plugins { 2 | kotlin("jvm") 3 | `maven-publish` 4 | } 5 | 6 | group = "com.github.ArtemiyDmtrvch" 7 | 8 | dependencies { 9 | implementation(project(":ui-generator-annotations")) 10 | implementation("com.squareup:kotlinpoet:$kotlinpoet_version") 11 | implementation("com.squareup:kotlinpoet-ksp:$kotlinpoet_version") 12 | implementation("org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version") 13 | implementation("org.jetbrains.kotlin:kotlin-reflect:$kotlin_version") 14 | implementation("com.google.devtools.ksp:symbol-processing-api:$ksp_version") 15 | } 16 | 17 | val sourcesJar by tasks.registering(Jar::class) { 18 | classifier = "sources" 19 | from(sourceSets.main.get().allSource) 20 | } 21 | 22 | publishing { 23 | repositories { 24 | maven(url = "https://jitpack.io") 25 | } 26 | publications { 27 | register("mavenJava", MavenPublication::class) { 28 | from(components["java"]) 29 | artifact(sourcesJar.get()) 30 | 31 | // groupId = "com.github.ArtemiyDmtrvch" 32 | // artifactId = "ui-generator-processor" 33 | // version = "LOCAL" 34 | } 35 | } 36 | } -------------------------------------------------------------------------------- /app/src/main/res/layout/titled_picture_title_above.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 9 | 10 | 11 | 17 | 18 | 23 | 24 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /app/src/main/res/layout/titled_picture_title_below.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 9 | 10 | 11 | 17 | 18 | 24 | 25 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | # Project-wide Gradle settings. 2 | # IDE (e.g. Android Studio) users: 3 | # Gradle settings configured through the IDE *will override* 4 | # any settings specified in this file. 5 | # For more details on how to configure your build environment visit 6 | # http://www.gradle.org/docs/current/userguide/build_environment.html 7 | # Specifies the JVM arguments used for the daemon process. 8 | # The setting is particularly useful for tweaking memory settings. 9 | org.gradle.jvmargs=-Xmx1536m 10 | # When configured, Gradle will run in incubating parallel mode. 11 | # This option should only be used with decoupled projects. More details, visit 12 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 13 | # org.gradle.parallel=true 14 | # AndroidX package structure to make it clearer which packages are bundled with the 15 | # Android operating system, and which are packaged with your app's APK 16 | # https://developer.android.com/topic/libraries/support-library/androidx-rn 17 | android.useAndroidX=true 18 | # Automatically convert third-party libraries to use AndroidX 19 | android.enableJetifier=true 20 | # Kotlin code style for this project: "official" or "obsolete": 21 | kotlin.code.style=official 22 | 23 | kapt.use.worker.api=true -------------------------------------------------------------------------------- /app/src/main/res/layout/counter.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 9 | 10 | 11 | 16 | 17 |