Kapt: Gradle integration tests for the new kapt
(cherry picked from commit 467d0fd)
@@ -26,7 +26,6 @@
|
|||||||
<groupId>org.jetbrains.kotlin</groupId>
|
<groupId>org.jetbrains.kotlin</groupId>
|
||||||
<artifactId>kotlin-stdlib</artifactId>
|
<artifactId>kotlin-stdlib</artifactId>
|
||||||
<version>${project.version}</version>
|
<version>${project.version}</version>
|
||||||
<scope>provided</scope>
|
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ class ExampleAnnotationProcessor : AbstractProcessor() {
|
|||||||
val simpleName = element.simpleName.toString()
|
val simpleName = element.simpleName.toString()
|
||||||
val generatedJavaClassName = generatedFilePrefix.capitalize() + simpleName.capitalize() + generatedFileSuffix
|
val generatedJavaClassName = generatedFilePrefix.capitalize() + simpleName.capitalize() + generatedFileSuffix
|
||||||
|
|
||||||
filer.createSourceFile(generatedJavaClassName).openWriter().use { with(it) {
|
filer.createSourceFile(packageName + '.' + generatedJavaClassName).openWriter().use { with(it) {
|
||||||
appendln("package $packageName;")
|
appendln("package $packageName;")
|
||||||
appendln("public final class $generatedJavaClassName {}")
|
appendln("public final class $generatedJavaClassName {}")
|
||||||
}}
|
}}
|
||||||
|
|||||||
@@ -72,8 +72,14 @@ abstract class BaseGradleIT {
|
|||||||
val androidHome: File? = null,
|
val androidHome: File? = null,
|
||||||
val androidGradlePluginVersion: String? = null)
|
val androidGradlePluginVersion: String? = null)
|
||||||
|
|
||||||
open inner class Project(val projectName: String, val wrapperVersion: String, val minLogLevel: LogLevel = LogLevel.DEBUG) {
|
open inner class Project(
|
||||||
open val resourcesRoot = File(resourcesRootFile, "testProject/$projectName")
|
val projectName: String,
|
||||||
|
val wrapperVersion: String,
|
||||||
|
directoryPrefix: String? = null,
|
||||||
|
val minLogLevel: LogLevel = LogLevel.DEBUG
|
||||||
|
) {
|
||||||
|
val resourceDirName = if (directoryPrefix != null) "$directoryPrefix/$projectName" else projectName
|
||||||
|
open val resourcesRoot = File(resourcesRootFile, "testProject/$resourceDirName")
|
||||||
val projectDir = File(workingDir.canonicalFile, projectName)
|
val projectDir = File(workingDir.canonicalFile, projectName)
|
||||||
|
|
||||||
open fun setupWorkingDir() {
|
open fun setupWorkingDir() {
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import kotlin.test.assertEquals
|
|||||||
|
|
||||||
abstract class BaseIncrementalGradleIT : BaseGradleIT() {
|
abstract class BaseIncrementalGradleIT : BaseGradleIT() {
|
||||||
|
|
||||||
inner class JpsTestProject(val buildLogFinder: BuildLogFinder, val resourcesBase: File, val relPath: String, wrapperVersion: String = "2.10", minLogLevel: LogLevel = LogLevel.DEBUG) : Project(File(relPath).name, wrapperVersion, minLogLevel) {
|
inner class JpsTestProject(val buildLogFinder: BuildLogFinder, val resourcesBase: File, val relPath: String, wrapperVersion: String = "2.10", minLogLevel: LogLevel = LogLevel.DEBUG) : Project(File(relPath).name, wrapperVersion, null, minLogLevel) {
|
||||||
override val resourcesRoot = File(resourcesBase, relPath)
|
override val resourcesRoot = File(resourcesBase, relPath)
|
||||||
val mapWorkingToOriginalFile = hashMapOf<File, File>()
|
val mapWorkingToOriginalFile = hashMapOf<File, File>()
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,142 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2016 JetBrains s.r.o.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.gradle
|
||||||
|
|
||||||
|
import org.junit.Test
|
||||||
|
import java.io.File
|
||||||
|
import java.io.FileFilter
|
||||||
|
|
||||||
|
class Kapt2IT: BaseGradleIT() {
|
||||||
|
companion object {
|
||||||
|
private const val GRADLE_VERSION = "2.10"
|
||||||
|
private const val ANDROID_GRADLE_PLUGIN_VERSION = "1.5.+"
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun androidBuildOptions() =
|
||||||
|
BuildOptions(withDaemon = true,
|
||||||
|
androidHome = File("../../../dependencies/android-sdk-for-tests"),
|
||||||
|
androidGradlePluginVersion = ANDROID_GRADLE_PLUGIN_VERSION)
|
||||||
|
|
||||||
|
override fun defaultBuildOptions(): BuildOptions =
|
||||||
|
super.defaultBuildOptions().copy(withDaemon = true)
|
||||||
|
|
||||||
|
private fun CompiledProject.assertKaptSuccessful() {
|
||||||
|
assertContains("Kapt: Annotation processing complete, 0 errors, 0 warnings")
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testSimple() {
|
||||||
|
val project = Project("simple", GRADLE_VERSION, directoryPrefix = "kapt2")
|
||||||
|
|
||||||
|
project.build("build") {
|
||||||
|
assertSuccessful()
|
||||||
|
assertKaptSuccessful()
|
||||||
|
assertContains(":compileKotlin")
|
||||||
|
assertContains(":compileJava")
|
||||||
|
assertFileExists("build/generated/source/kapt2/main/example/TestClassGenerated.java")
|
||||||
|
assertFileExists("build/classes/main/example/TestClass.class")
|
||||||
|
assertFileExists("build/classes/main/example/TestClassGenerated.class")
|
||||||
|
assertFileExists("build/classes/main/example/SourceAnnotatedTestClassGenerated.class")
|
||||||
|
assertFileExists("build/classes/main/example/BinaryAnnotatedTestClassGenerated.class")
|
||||||
|
assertFileExists("build/classes/main/example/RuntimeAnnotatedTestClassGenerated.class")
|
||||||
|
assertContains("example.JavaTest PASSED")
|
||||||
|
}
|
||||||
|
|
||||||
|
project.build("build") {
|
||||||
|
assertSuccessful()
|
||||||
|
assertContains(":compileKotlin UP-TO-DATE")
|
||||||
|
assertContains(":compileJava UP-TO-DATE")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testInheritedAnnotations() {
|
||||||
|
Project("inheritedAnnotations", GRADLE_VERSION, directoryPrefix = "kapt2").build("build") {
|
||||||
|
assertSuccessful()
|
||||||
|
assertKaptSuccessful()
|
||||||
|
assertFileExists("build/generated/source/kapt2/main/example/TestClassGenerated.java")
|
||||||
|
assertFileExists("build/generated/source/kapt2/main/example/AncestorClassGenerated.java")
|
||||||
|
assertFileExists("build/classes/main/example/TestClassGenerated.class")
|
||||||
|
assertFileExists("build/classes/main/example/AncestorClassGenerated.class")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testButterKnife() {
|
||||||
|
val project = Project("android-butterknife", GRADLE_VERSION, directoryPrefix = "kapt2")
|
||||||
|
val options = androidBuildOptions()
|
||||||
|
|
||||||
|
project.build("assembleRelease", options = options) {
|
||||||
|
assertSuccessful()
|
||||||
|
assertKaptSuccessful()
|
||||||
|
assertFileExists("app/build/generated/source/kapt2/release/org/example/kotlin/butterknife/SimpleActivity\$\$ViewBinder.java")
|
||||||
|
assertFileExists("app/build/intermediates/classes/release/org/example/kotlin/butterknife/SimpleActivity\$\$ViewBinder.class")
|
||||||
|
assertFileExists("app/build/intermediates/classes/release/org/example/kotlin/butterknife/SimpleAdapter\$ViewHolder.class")
|
||||||
|
}
|
||||||
|
|
||||||
|
project.build("assembleRelease", options = options) {
|
||||||
|
assertSuccessful()
|
||||||
|
assertContains(":compileReleaseKotlin UP-TO-DATE")
|
||||||
|
assertContains(":compileReleaseJavaWithJavac UP-TO-DATE")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testDagger() {
|
||||||
|
val project = Project("android-dagger", GRADLE_VERSION, directoryPrefix = "kapt2")
|
||||||
|
val options = androidBuildOptions()
|
||||||
|
|
||||||
|
project.build("assembleRelease", options = options) {
|
||||||
|
assertSuccessful()
|
||||||
|
assertKaptSuccessful()
|
||||||
|
assertFileExists("app/build/generated/source/kapt2/release/com/example/dagger/kotlin/DaggerApplicationComponent.java")
|
||||||
|
assertFileExists("app/build/generated/source/kapt2/release/com/example/dagger/kotlin/ui/HomeActivity_MembersInjector.java")
|
||||||
|
assertFileExists("app/build/intermediates/classes/release/com/example/dagger/kotlin/DaggerApplicationComponent.class")
|
||||||
|
assertFileExists("app/build/intermediates/classes/release/com/example/dagger/kotlin/AndroidModule.class")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testDbFlow() {
|
||||||
|
val project = Project("android-dbflow", GRADLE_VERSION, directoryPrefix = "kapt2")
|
||||||
|
val options = androidBuildOptions()
|
||||||
|
|
||||||
|
project.build("assembleRelease", options = options) {
|
||||||
|
assertSuccessful()
|
||||||
|
assertKaptSuccessful()
|
||||||
|
assertFileExists("app/build/generated/source/kapt2/release/com/raizlabs/android/dbflow/config/GeneratedDatabaseHolder.java")
|
||||||
|
assertFileExists("app/build/generated/source/kapt2/release/com/raizlabs/android/dbflow/config/AppDatabaseapp_Database.java")
|
||||||
|
assertFileExists("app/build/generated/source/kapt2/release/mobi/porquenao/poc/kotlin/core/Item_Table.java")
|
||||||
|
assertFileExists("app/build/generated/source/kapt2/release/mobi/porquenao/poc/kotlin/core/Item_Adapter.java")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testRealm() {
|
||||||
|
val project = Project("android-realm", GRADLE_VERSION, directoryPrefix = "kapt2")
|
||||||
|
val options = androidBuildOptions()
|
||||||
|
|
||||||
|
project.build("assembleRelease", options = options) {
|
||||||
|
assertSuccessful()
|
||||||
|
assertKaptSuccessful()
|
||||||
|
assertFileExists("build/generated/source/kapt2/release/io/realm/CatRealmProxy.java")
|
||||||
|
assertFileExists("build/generated/source/kapt2/release/io/realm/CatRealmProxyInterface.java")
|
||||||
|
assertFileExists("build/generated/source/kapt2/release/io/realm/DefaultRealmModule.java")
|
||||||
|
assertFileExists("build/generated/source/kapt2/release/io/realm/DefaultRealmModuleMediator.java")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -24,7 +24,7 @@ class KaptIT: BaseGradleIT() {
|
|||||||
assertContains(":compileKotlin")
|
assertContains(":compileKotlin")
|
||||||
assertContains(":compileJava")
|
assertContains(":compileJava")
|
||||||
assertFileExists("build/tmp/kapt/main/wrappers/annotations.main.txt")
|
assertFileExists("build/tmp/kapt/main/wrappers/annotations.main.txt")
|
||||||
assertFileExists("build/generated/source/kapt/main/TestClassGenerated.java")
|
assertFileExists("build/generated/source/kapt/main/example/TestClassGenerated.java")
|
||||||
assertFileExists("build/classes/main/example/TestClass.class")
|
assertFileExists("build/classes/main/example/TestClass.class")
|
||||||
assertFileExists("build/classes/main/example/TestClassGenerated.class")
|
assertFileExists("build/classes/main/example/TestClassGenerated.class")
|
||||||
assertNoSuchFile("build/classes/main/example/SourceAnnotatedTestClassGenerated.class")
|
assertNoSuchFile("build/classes/main/example/SourceAnnotatedTestClassGenerated.class")
|
||||||
@@ -162,8 +162,8 @@ class KaptIT: BaseGradleIT() {
|
|||||||
fun testInheritedAnnotations() {
|
fun testInheritedAnnotations() {
|
||||||
Project("kaptInheritedAnnotations", GRADLE_VERSION).build("build") {
|
Project("kaptInheritedAnnotations", GRADLE_VERSION).build("build") {
|
||||||
assertSuccessful()
|
assertSuccessful()
|
||||||
assertFileExists("build/generated/source/kapt/main/TestClassGenerated.java")
|
assertFileExists("build/generated/source/kapt/main/example/TestClassGenerated.java")
|
||||||
assertFileExists("build/generated/source/kapt/main/AncestorClassGenerated.java")
|
assertFileExists("build/generated/source/kapt/main/example/AncestorClassGenerated.java")
|
||||||
assertFileExists("build/classes/main/example/TestClassGenerated.class")
|
assertFileExists("build/classes/main/example/TestClassGenerated.class")
|
||||||
assertFileExists("build/classes/main/example/AncestorClassGenerated.class")
|
assertFileExists("build/classes/main/example/AncestorClassGenerated.class")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,37 @@
|
|||||||
|
apply plugin: 'android-sdk-manager'
|
||||||
|
apply plugin: 'com.android.application'
|
||||||
|
apply plugin: 'kotlin-android'
|
||||||
|
apply plugin: 'kotlin-kapt'
|
||||||
|
|
||||||
|
android {
|
||||||
|
compileSdkVersion 23
|
||||||
|
buildToolsVersion "23.0.1"
|
||||||
|
|
||||||
|
defaultConfig {
|
||||||
|
applicationId "org.example.kotlin.butterknife"
|
||||||
|
minSdkVersion 15
|
||||||
|
targetSdkVersion 23
|
||||||
|
versionCode 1
|
||||||
|
versionName "1.0"
|
||||||
|
}
|
||||||
|
|
||||||
|
buildTypes {
|
||||||
|
release {
|
||||||
|
minifyEnabled false
|
||||||
|
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sourceSets {
|
||||||
|
main.java.srcDirs += 'src/main/kotlin'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
compile fileTree(dir: 'libs', include: ['*.jar'])
|
||||||
|
|
||||||
|
compile 'com.android.support:appcompat-v7:23.3.0'
|
||||||
|
compile 'com.jakewharton:butterknife:8.0.1'
|
||||||
|
kapt 'com.jakewharton:butterknife-compiler:8.0.1'
|
||||||
|
compile "org.jetbrains.kotlin:kotlin-stdlib:0.1-SNAPSHOT"
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
# Add project specific ProGuard rules here.
|
||||||
|
# By default, the flags in this file are appended to flags specified
|
||||||
|
# in /Users/yan/Library/Android/sdk/tools/proguard/proguard-android.txt
|
||||||
|
# You can edit the include path and order by changing the proguardFiles
|
||||||
|
# directive in build.gradle.
|
||||||
|
#
|
||||||
|
# For more details, see
|
||||||
|
# http://developer.android.com/guide/developing/tools/proguard.html
|
||||||
|
|
||||||
|
# Add any project specific keep options here:
|
||||||
|
|
||||||
|
# If your project uses WebView with JS, uncomment the following
|
||||||
|
# and specify the fully qualified class name to the JavaScript interface
|
||||||
|
# class:
|
||||||
|
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
|
||||||
|
# public *;
|
||||||
|
#}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
|
||||||
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
package="org.example.kotlin.butterknife">
|
||||||
|
|
||||||
|
<application
|
||||||
|
android:label="@string/app_name"
|
||||||
|
android:name=".SimpleApp">
|
||||||
|
|
||||||
|
<activity
|
||||||
|
android:label="@string/app_name"
|
||||||
|
android:name=".SimpleActivity">
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="android.intent.action.MAIN"/>
|
||||||
|
<category android:name="android.intent.category.LAUNCHER"/>
|
||||||
|
<category android:name="android.intent.category.DEFAULT"/>
|
||||||
|
</intent-filter>
|
||||||
|
</activity>
|
||||||
|
</application>
|
||||||
|
</manifest>
|
||||||
@@ -0,0 +1,84 @@
|
|||||||
|
package org.example.kotlin.butterknife
|
||||||
|
|
||||||
|
import android.app.Activity
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.view.View
|
||||||
|
import android.view.animation.AlphaAnimation
|
||||||
|
import android.widget.Button
|
||||||
|
import android.widget.ListView
|
||||||
|
import android.widget.TextView
|
||||||
|
import android.widget.Toast
|
||||||
|
|
||||||
|
import android.widget.Toast.LENGTH_SHORT
|
||||||
|
import butterknife.*
|
||||||
|
|
||||||
|
class SimpleActivity : Activity() {
|
||||||
|
|
||||||
|
@BindView(R.id.title)
|
||||||
|
lateinit var title: TextView
|
||||||
|
|
||||||
|
@BindView(R.id.subtitle)
|
||||||
|
lateinit var subtitle: TextView
|
||||||
|
|
||||||
|
@BindView(R.id.hello)
|
||||||
|
lateinit var hello: Button
|
||||||
|
|
||||||
|
@BindView(R.id.list_of_things)
|
||||||
|
lateinit var listOfThings: ListView
|
||||||
|
|
||||||
|
@BindView(R.id.footer)
|
||||||
|
lateinit var footer: TextView
|
||||||
|
|
||||||
|
@BindViews(R.id.title, R.id.subtitle, R.id.hello)
|
||||||
|
lateinit var headerViews: MutableList<View>
|
||||||
|
|
||||||
|
@JvmField
|
||||||
|
@BindColor(R.color.blue)
|
||||||
|
var titleTextColor: Int = 0
|
||||||
|
|
||||||
|
private lateinit var adapter: SimpleAdapter
|
||||||
|
|
||||||
|
@OnClick(R.id.hello)
|
||||||
|
fun sayHello() {
|
||||||
|
Toast.makeText(this, "Hello, views!", LENGTH_SHORT).show()
|
||||||
|
ButterKnife.apply(headerViews.toList(), ALPHA_FADE)
|
||||||
|
}
|
||||||
|
|
||||||
|
@OnLongClick(R.id.hello)
|
||||||
|
fun sayGetOffMe(): Boolean {
|
||||||
|
Toast.makeText(this, "Let go of me!", LENGTH_SHORT).show()
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
@OnItemClick(R.id.list_of_things)
|
||||||
|
fun onItemClick(position: Int) {
|
||||||
|
Toast.makeText(this, "You clicked: " + adapter.getItem(position), LENGTH_SHORT).show()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
super.onCreate(savedInstanceState)
|
||||||
|
setContentView(R.layout.simple_activity)
|
||||||
|
ButterKnife.bind(this)
|
||||||
|
|
||||||
|
title.text = "Butter Knife"
|
||||||
|
subtitle.text = "Field and method binding for Android views."
|
||||||
|
footer.text = "by Jake Wharton"
|
||||||
|
hello.text = "Say Hello"
|
||||||
|
|
||||||
|
title.setTextColor(titleTextColor)
|
||||||
|
|
||||||
|
adapter = SimpleAdapter(this)
|
||||||
|
listOfThings.adapter = adapter
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private val ALPHA_FADE = ButterKnife.Action<View> { view, index ->
|
||||||
|
with (AlphaAnimation(0f, 1f)) {
|
||||||
|
fillBefore = true
|
||||||
|
duration = 500
|
||||||
|
startOffset = (index * 100).toLong()
|
||||||
|
view.startAnimation(this)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,57 @@
|
|||||||
|
package org.example.kotlin.butterknife
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.View
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import android.widget.BaseAdapter
|
||||||
|
import android.widget.TextView
|
||||||
|
import butterknife.ButterKnife
|
||||||
|
import butterknife.BindView
|
||||||
|
|
||||||
|
class SimpleAdapter(context: Context) : BaseAdapter() {
|
||||||
|
|
||||||
|
private val inflater = LayoutInflater.from(context)
|
||||||
|
|
||||||
|
override fun getCount() = CONTENTS.size
|
||||||
|
override fun getItem(position: Int) = CONTENTS[position]
|
||||||
|
override fun getItemId(position: Int) = position.toLong()
|
||||||
|
|
||||||
|
override fun getView(position: Int, v: View?, parent: ViewGroup): View {
|
||||||
|
var view = v
|
||||||
|
val holder: ViewHolder
|
||||||
|
if (view != null) {
|
||||||
|
holder = view.tag as ViewHolder
|
||||||
|
} else {
|
||||||
|
view = inflater.inflate(R.layout.simple_list_item, parent, false)
|
||||||
|
holder = ViewHolder(view)
|
||||||
|
view!!.tag = holder
|
||||||
|
}
|
||||||
|
|
||||||
|
val word = getItem(position)
|
||||||
|
holder.word.text = "Word: $word"
|
||||||
|
holder.length.text = "Length: ${word.length}"
|
||||||
|
holder.position.text = "Position: $position"
|
||||||
|
|
||||||
|
return view
|
||||||
|
}
|
||||||
|
|
||||||
|
class ViewHolder(view: View) {
|
||||||
|
@BindView(R.id.word)
|
||||||
|
lateinit var word: TextView
|
||||||
|
|
||||||
|
@BindView(R.id.length)
|
||||||
|
lateinit var length: TextView
|
||||||
|
|
||||||
|
@BindView(R.id.position)
|
||||||
|
lateinit var position: TextView
|
||||||
|
|
||||||
|
init {
|
||||||
|
ButterKnife.bind(this, view)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private val CONTENTS = "The quick brown fox jumps over the lazy dog".split(" ")
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
package org.example.kotlin.butterknife
|
||||||
|
|
||||||
|
import android.app.Application
|
||||||
|
import butterknife.ButterKnife
|
||||||
|
|
||||||
|
class SimpleApp : Application() {
|
||||||
|
override fun onCreate() {
|
||||||
|
super.onCreate()
|
||||||
|
ButterKnife.setDebug(BuildConfig.DEBUG)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:padding="8dp">
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/title"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:gravity="center"
|
||||||
|
android:textSize="50sp"
|
||||||
|
/>
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/subtitle"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:gravity="center"
|
||||||
|
android:textSize="20sp"
|
||||||
|
/>
|
||||||
|
<Button
|
||||||
|
android:id="@+id/hello"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="0dp"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:layout_margin="10dp"
|
||||||
|
/>
|
||||||
|
<ListView
|
||||||
|
android:id="@+id/list_of_things"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="0dp"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:layout_margin="10dp"
|
||||||
|
/>
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/footer"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:gravity="center"
|
||||||
|
android:textSize="17sp"
|
||||||
|
android:textStyle="italic"
|
||||||
|
/>
|
||||||
|
</LinearLayout>
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:orientation="vertical">
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/word"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
/>
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/length"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
/>
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/position"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
/>
|
||||||
|
</LinearLayout>
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources>
|
||||||
|
<color name="blue">#3366ee</color>
|
||||||
|
</resources>
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
|
||||||
|
<resources>
|
||||||
|
<string name="app_name">Butter Knife</string>
|
||||||
|
</resources>
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
// Top-level build file where you can add configuration options common to all sub-projects/modules.
|
||||||
|
|
||||||
|
buildscript {
|
||||||
|
repositories {
|
||||||
|
maven {
|
||||||
|
url 'file://' + pathToKotlinPlugin
|
||||||
|
}
|
||||||
|
jcenter()
|
||||||
|
}
|
||||||
|
dependencies {
|
||||||
|
classpath 'com.android.tools.build:gradle:1.5.+'
|
||||||
|
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:0.1-SNAPSHOT"
|
||||||
|
classpath "com.jakewharton.sdkmanager:gradle-plugin:0.12.+"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
allprojects {
|
||||||
|
repositories {
|
||||||
|
maven {
|
||||||
|
url 'file://' + pathToKotlinPlugin
|
||||||
|
}
|
||||||
|
mavenCentral()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
kapt.verbose=true
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
include ':app'
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
apply plugin: 'android-sdk-manager'
|
||||||
|
apply plugin: 'com.android.application'
|
||||||
|
apply plugin: 'kotlin-android'
|
||||||
|
apply plugin: 'kotlin-kapt'
|
||||||
|
apply plugin: 'kotlin-android-extensions'
|
||||||
|
|
||||||
|
android {
|
||||||
|
compileSdkVersion 23
|
||||||
|
buildToolsVersion "23.0.1"
|
||||||
|
|
||||||
|
defaultConfig {
|
||||||
|
applicationId "com.example.dagger.kotlin"
|
||||||
|
minSdkVersion 14
|
||||||
|
targetSdkVersion 23
|
||||||
|
versionCode 1
|
||||||
|
versionName "1.0"
|
||||||
|
}
|
||||||
|
buildTypes {
|
||||||
|
release {
|
||||||
|
minifyEnabled false
|
||||||
|
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sourceSets {
|
||||||
|
main.java.srcDirs += 'src/main/kotlin'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
compile fileTree(dir: 'libs', include: ['*.jar'])
|
||||||
|
compile 'com.android.support:appcompat-v7:23.3.0'
|
||||||
|
compile "org.jetbrains.kotlin:kotlin-stdlib:0.1-SNAPSHOT"
|
||||||
|
|
||||||
|
compile 'com.google.dagger:dagger:2.2'
|
||||||
|
kapt 'com.google.dagger:dagger-compiler:2.2'
|
||||||
|
provided 'org.glassfish:javax.annotation:10.0-b28'
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
# Add project specific ProGuard rules here.
|
||||||
|
# By default, the flags in this file are appended to flags specified
|
||||||
|
# in /Users/yan/Library/Android/sdk/tools/proguard/proguard-android.txt
|
||||||
|
# You can edit the include path and order by changing the proguardFiles
|
||||||
|
# directive in build.gradle.
|
||||||
|
#
|
||||||
|
# For more details, see
|
||||||
|
# http://developer.android.com/guide/developing/tools/proguard.html
|
||||||
|
|
||||||
|
# Add any project specific keep options here:
|
||||||
|
|
||||||
|
# If your project uses WebView with JS, uncomment the following
|
||||||
|
# and specify the fully qualified class name to the JavaScript interface
|
||||||
|
# class:
|
||||||
|
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
|
||||||
|
# public *;
|
||||||
|
#}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
|
||||||
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.dagger.kotlin">
|
||||||
|
|
||||||
|
<application
|
||||||
|
android:allowBackup="true"
|
||||||
|
android:label="app_name"
|
||||||
|
android:name=".DemoApplication">
|
||||||
|
<activity
|
||||||
|
android:label="app_name"
|
||||||
|
android:name=".ui.HomeActivity">
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="android.intent.action.MAIN"/>
|
||||||
|
<category android:name="android.intent.category.LAUNCHER"/>
|
||||||
|
<category android:name="android.intent.category.DEFAULT"/>
|
||||||
|
</intent-filter>
|
||||||
|
</activity>
|
||||||
|
</application>
|
||||||
|
</manifest>
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2013 Square, Inc.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package com.example.dagger.kotlin
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.content.Context.LOCATION_SERVICE
|
||||||
|
import android.location.LocationManager
|
||||||
|
import dagger.Module
|
||||||
|
import dagger.Provides
|
||||||
|
import javax.inject.Singleton
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A module for Android-specific dependencies which require a [Context] or
|
||||||
|
* [android.app.Application] to create.
|
||||||
|
*/
|
||||||
|
@Module class AndroidModule(private val application: BaseApplication) {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allow the application context to be injected but require that it be annotated with
|
||||||
|
* [@Annotation][ForApplication] to explicitly differentiate it from an activity context.
|
||||||
|
*/
|
||||||
|
@Provides @Singleton @ForApplication
|
||||||
|
fun provideApplicationContext(): Context {
|
||||||
|
return application
|
||||||
|
}
|
||||||
|
|
||||||
|
@Provides @Singleton
|
||||||
|
fun provideLocationManager(): LocationManager {
|
||||||
|
return application.getSystemService(LOCATION_SERVICE) as LocationManager
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
package com.example.dagger.kotlin
|
||||||
|
|
||||||
|
import com.example.dagger.kotlin.ui.HomeActivity
|
||||||
|
import dagger.Component
|
||||||
|
import javax.inject.Singleton
|
||||||
|
|
||||||
|
@Singleton
|
||||||
|
@Component(modules = arrayOf(AndroidModule::class))
|
||||||
|
interface ApplicationComponent {
|
||||||
|
fun inject(application: BaseApplication)
|
||||||
|
fun inject(homeActivity: HomeActivity)
|
||||||
|
fun inject(demoActivity: DemoActivity)
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
package com.example.dagger.kotlin
|
||||||
|
|
||||||
|
import android.app.Application
|
||||||
|
|
||||||
|
abstract class BaseApplication : Application() {
|
||||||
|
|
||||||
|
protected fun initDaggerComponent(): ApplicationComponent {
|
||||||
|
return DaggerApplicationComponent.builder().androidModule(AndroidModule(this)).build()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
package com.example.dagger.kotlin
|
||||||
|
|
||||||
|
import android.app.Activity
|
||||||
|
import android.os.Bundle
|
||||||
|
|
||||||
|
abstract class DemoActivity : Activity() {
|
||||||
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
super.onCreate(savedInstanceState)
|
||||||
|
// Perform injection so that when this call returns all dependencies will be available for use.
|
||||||
|
(application as DemoApplication).component.inject(this)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
package com.example.dagger.kotlin
|
||||||
|
|
||||||
|
class DemoApplication : BaseApplication() {
|
||||||
|
lateinit var component: ApplicationComponent
|
||||||
|
|
||||||
|
override fun onCreate() {
|
||||||
|
super.onCreate()
|
||||||
|
val component = initDaggerComponent()
|
||||||
|
component.inject(this) // As of now, LocationManager should be injected into this.
|
||||||
|
this.component = component
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
package com.example.dagger.kotlin
|
||||||
|
|
||||||
|
import javax.inject.Qualifier
|
||||||
|
|
||||||
|
@Qualifier
|
||||||
|
annotation class ForApplication
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2013 Square, Inc.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package com.example.dagger.kotlin.ui
|
||||||
|
|
||||||
|
import android.location.LocationManager
|
||||||
|
import android.os.Bundle
|
||||||
|
import com.example.dagger.kotlin.DemoActivity
|
||||||
|
import com.example.dagger.kotlin.DemoApplication
|
||||||
|
import com.example.dagger.kotlin.R
|
||||||
|
import kotlinx.android.synthetic.main.activity_main.locationInfo
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
class HomeActivity : DemoActivity() {
|
||||||
|
@Inject
|
||||||
|
lateinit var locationManager: LocationManager
|
||||||
|
|
||||||
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
super.onCreate(savedInstanceState)
|
||||||
|
setContentView(R.layout.activity_main)
|
||||||
|
(application as DemoApplication).component.inject(this)
|
||||||
|
|
||||||
|
// TODO do something with the injected dependencies here!
|
||||||
|
locationInfo.text = "Injected LocationManager:\n$locationManager"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent" tools:context=".ui.HomeActivity">
|
||||||
|
|
||||||
|
<TextView android:id="@+id/locationInfo"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:padding="16dp" />
|
||||||
|
|
||||||
|
</RelativeLayout>
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
<resources>
|
||||||
|
<string name="app_name">kotlin</string>
|
||||||
|
</resources>
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
<resources>
|
||||||
|
|
||||||
|
<!-- Base application theme. -->
|
||||||
|
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
|
||||||
|
<!-- Customize your theme here. -->
|
||||||
|
</style>
|
||||||
|
|
||||||
|
</resources>
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
// Top-level build file where you can add configuration options common to all sub-projects/modules.
|
||||||
|
|
||||||
|
buildscript {
|
||||||
|
repositories {
|
||||||
|
maven {
|
||||||
|
url 'file://' + pathToKotlinPlugin
|
||||||
|
}
|
||||||
|
mavenCentral()
|
||||||
|
}
|
||||||
|
dependencies {
|
||||||
|
classpath 'com.android.tools.build:gradle:1.5.+'
|
||||||
|
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:0.1-SNAPSHOT"
|
||||||
|
classpath "com.jakewharton.sdkmanager:gradle-plugin:0.12.+"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
allprojects {
|
||||||
|
repositories {
|
||||||
|
maven {
|
||||||
|
url 'file://' + pathToKotlinPlugin
|
||||||
|
}
|
||||||
|
mavenCentral()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
kapt.verbose=true
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
include ':app'
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
apply plugin: 'android-sdk-manager'
|
||||||
|
apply plugin: 'com.android.application'
|
||||||
|
apply plugin: 'kotlin-android'
|
||||||
|
apply plugin: 'kotlin-android-extensions'
|
||||||
|
apply plugin: 'kotlin-kapt'
|
||||||
|
|
||||||
|
android {
|
||||||
|
compileSdkVersion 23
|
||||||
|
buildToolsVersion '23.0.1'
|
||||||
|
|
||||||
|
defaultConfig {
|
||||||
|
minSdkVersion 14
|
||||||
|
targetSdkVersion 23
|
||||||
|
versionCode 1
|
||||||
|
versionName '1.0'
|
||||||
|
}
|
||||||
|
sourceSets {
|
||||||
|
main.java.srcDirs += 'src/main/kotlin'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def dbflow_version = "3.1.1"
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
// Android Support Libraries
|
||||||
|
compile 'com.android.support:appcompat-v7:23.3.0'
|
||||||
|
compile 'com.android.support:cardview-v7:23.3.0'
|
||||||
|
compile 'com.android.support:recyclerview-v7:23.3.0'
|
||||||
|
|
||||||
|
// DBFlow
|
||||||
|
kapt "com.github.Raizlabs.DBFlow:dbflow-processor:${dbflow_version}"
|
||||||
|
compile "com.github.Raizlabs.DBFlow:dbflow-core:${dbflow_version}"
|
||||||
|
compile "com.github.Raizlabs.DBFlow:dbflow:${dbflow_version}"
|
||||||
|
compile "com.github.Raizlabs.DBFlow:dbflow-kotlinextensions:${dbflow_version}"
|
||||||
|
|
||||||
|
// Kotlin
|
||||||
|
compile "org.jetbrains.kotlin:kotlin-stdlib:0.1-SNAPSHOT"
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<manifest
|
||||||
|
package="mobi.porquenao.poc.kotlin"
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
|
||||||
|
<application
|
||||||
|
android:name=".DatabaseApplication"
|
||||||
|
android:allowBackup="false"
|
||||||
|
android:icon="@drawable/ic_launcher"
|
||||||
|
android:label="@string/app_name"
|
||||||
|
android:theme="@style/AppTheme">
|
||||||
|
|
||||||
|
<activity
|
||||||
|
android:name=".ui.MainActivity">
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="android.intent.action.MAIN"/>
|
||||||
|
<category android:name="android.intent.category.LAUNCHER"/>
|
||||||
|
</intent-filter>
|
||||||
|
</activity>
|
||||||
|
|
||||||
|
</application>
|
||||||
|
|
||||||
|
</manifest>
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
package mobi.porquenao.poc.kotlin
|
||||||
|
|
||||||
|
import android.app.Application
|
||||||
|
import com.raizlabs.android.dbflow.config.FlowConfig
|
||||||
|
|
||||||
|
import com.raizlabs.android.dbflow.config.FlowManager
|
||||||
|
|
||||||
|
class DatabaseApplication : Application() {
|
||||||
|
override fun onCreate() {
|
||||||
|
super.onCreate()
|
||||||
|
FlowManager.init(FlowConfig.Builder(this).build())
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onTerminate() {
|
||||||
|
super.onTerminate()
|
||||||
|
FlowManager.destroy()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
package mobi.porquenao.poc.kotlin.core
|
||||||
|
|
||||||
|
import com.raizlabs.android.dbflow.annotation.Database
|
||||||
|
|
||||||
|
@Database(name = AppDatabase.NAME, version = AppDatabase.VERSION, generatedClassSeparator = "_")
|
||||||
|
object AppDatabase {
|
||||||
|
const val NAME: String = "app"
|
||||||
|
const val VERSION: Int = 1
|
||||||
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
package mobi.porquenao.poc.kotlin.core
|
||||||
|
|
||||||
|
import com.raizlabs.android.dbflow.converter.TypeConverter
|
||||||
|
import java.util.*
|
||||||
|
import com.raizlabs.android.dbflow.annotation.TypeConverter as TypeConverterAnnotation
|
||||||
|
|
||||||
|
@TypeConverterAnnotation
|
||||||
|
class CalendarConverter : TypeConverter<Long, Calendar>() {
|
||||||
|
|
||||||
|
override fun getDBValue(model: Calendar): Long? {
|
||||||
|
return model.timeInMillis
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getModelValue(data: Long?): Calendar {
|
||||||
|
val calendar = Calendar.getInstance()
|
||||||
|
calendar.timeInMillis = data!!
|
||||||
|
return calendar
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
package mobi.porquenao.poc.kotlin.core
|
||||||
|
|
||||||
|
import com.raizlabs.android.dbflow.annotation.Column
|
||||||
|
import com.raizlabs.android.dbflow.annotation.PrimaryKey
|
||||||
|
import com.raizlabs.android.dbflow.annotation.Table
|
||||||
|
import com.raizlabs.android.dbflow.structure.BaseModel
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
|
@Table(name = "items", database = AppDatabase::class)
|
||||||
|
class Item : BaseModel() {
|
||||||
|
|
||||||
|
@PrimaryKey(autoincrement = true)
|
||||||
|
@Column(name = "id")
|
||||||
|
var id: Long = 0
|
||||||
|
|
||||||
|
@Column(name = "updated_at", typeConverter = CalendarConverter::class)
|
||||||
|
var updatedAt: Calendar = Calendar.getInstance()
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
package mobi.porquenao.poc.kotlin.core
|
||||||
|
|
||||||
|
import com.raizlabs.android.dbflow.sql.language.Select
|
||||||
|
|
||||||
|
object ItemRepository {
|
||||||
|
|
||||||
|
fun getAll(): MutableList<Item> {
|
||||||
|
return Select()
|
||||||
|
.from(Item::class.java)
|
||||||
|
.where()
|
||||||
|
.orderBy(Item_Table.updated_at, false)
|
||||||
|
.queryList()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
package mobi.porquenao.poc.kotlin.ui
|
||||||
|
|
||||||
|
import android.app.ActivityManager
|
||||||
|
import android.graphics.BitmapFactory
|
||||||
|
import android.os.Build
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.support.v7.app.AppCompatActivity
|
||||||
|
import kotlinx.android.synthetic.main.activity_main.*
|
||||||
|
import mobi.porquenao.poc.kotlin.R
|
||||||
|
|
||||||
|
abstract class BaseActivity : AppCompatActivity() {
|
||||||
|
|
||||||
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
super.onCreate(savedInstanceState)
|
||||||
|
prepareTaskDescription()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun setContentView(layoutResID: Int) {
|
||||||
|
super.setContentView(layoutResID)
|
||||||
|
setSupportActionBar(toolbar)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun prepareTaskDescription() {
|
||||||
|
if (Build.VERSION.SDK_INT >= 21) {
|
||||||
|
if (sTaskDescription == null) {
|
||||||
|
val label = getString(R.string.app_name)
|
||||||
|
val icon = BitmapFactory.decodeResource(resources, R.drawable.ic_task)
|
||||||
|
val colorPrimary = resources.getColor(R.color.app_primary_500)
|
||||||
|
sTaskDescription = ActivityManager.TaskDescription(label, icon, colorPrimary)
|
||||||
|
}
|
||||||
|
setTaskDescription(sTaskDescription)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private var sTaskDescription: ActivityManager.TaskDescription? = null
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
package mobi.porquenao.poc.kotlin.ui
|
||||||
|
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.support.v7.widget.LinearLayoutManager
|
||||||
|
import android.view.Menu
|
||||||
|
import android.view.MenuItem
|
||||||
|
import kotlinx.android.synthetic.main.activity_main.*
|
||||||
|
import mobi.porquenao.poc.kotlin.R
|
||||||
|
|
||||||
|
class MainActivity : BaseActivity() {
|
||||||
|
lateinit var listAdapter: MainAdapter
|
||||||
|
|
||||||
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
super.onCreate(savedInstanceState)
|
||||||
|
setContentView(R.layout.activity_main)
|
||||||
|
|
||||||
|
with (list) {
|
||||||
|
setHasFixedSize(true)
|
||||||
|
layoutManager = LinearLayoutManager(this@MainActivity)
|
||||||
|
listAdapter = MainAdapter()
|
||||||
|
adapter = listAdapter
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onCreateOptionsMenu(menu: Menu?): Boolean {
|
||||||
|
menuInflater.inflate(R.menu.main, menu)
|
||||||
|
return super.onCreateOptionsMenu(menu)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onOptionsItemSelected(item: MenuItem?): Boolean {
|
||||||
|
listAdapter.add()
|
||||||
|
list.smoothScrollToPosition(0)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,67 @@
|
|||||||
|
package mobi.porquenao.poc.kotlin.ui
|
||||||
|
|
||||||
|
import android.graphics.Color
|
||||||
|
import android.support.v7.widget.RecyclerView
|
||||||
|
import android.text.format.DateFormat
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.View
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import kotlinx.android.synthetic.main.main_item.view.*
|
||||||
|
import mobi.porquenao.poc.kotlin.R
|
||||||
|
import mobi.porquenao.poc.kotlin.core.Item
|
||||||
|
import mobi.porquenao.poc.kotlin.core.ItemRepository
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
|
class MainAdapter : RecyclerView.Adapter<MainAdapter.ViewHolder>() {
|
||||||
|
|
||||||
|
private val mItems: MutableList<Item>
|
||||||
|
private val mOnClickListener: View.OnClickListener
|
||||||
|
|
||||||
|
init {
|
||||||
|
mItems = ItemRepository.getAll()
|
||||||
|
mOnClickListener = View.OnClickListener { v ->
|
||||||
|
val item = v.tag as Item
|
||||||
|
item.updatedAt = Calendar.getInstance()
|
||||||
|
item.save()
|
||||||
|
notifyDataSetChanged()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
|
||||||
|
val layoutInflater = LayoutInflater.from(parent.context)
|
||||||
|
return ViewHolder(layoutInflater.inflate(R.layout.main_item, parent, false))
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
|
||||||
|
val item = mItems[position]
|
||||||
|
val date = item.updatedAt.timeInMillis
|
||||||
|
|
||||||
|
val color = "#" + date.toString().substring(7)
|
||||||
|
holder.card.setCardBackgroundColor(Color.parseColor(color))
|
||||||
|
holder.title.text = color
|
||||||
|
holder.date.text = DateFormat.format("hh:mm:ss", Date(date))
|
||||||
|
|
||||||
|
with (holder.container) {
|
||||||
|
tag = item
|
||||||
|
setOnClickListener(mOnClickListener)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getItemCount(): Int {
|
||||||
|
return mItems.size
|
||||||
|
}
|
||||||
|
|
||||||
|
fun add() {
|
||||||
|
val item = Item()
|
||||||
|
mItems.add(0, item)
|
||||||
|
item.save()
|
||||||
|
notifyItemInserted(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
class ViewHolder(view: View) : RecyclerView.ViewHolder(view) {
|
||||||
|
val card = view.card
|
||||||
|
val container = view.container
|
||||||
|
val title = view.title
|
||||||
|
val date = view.date
|
||||||
|
}
|
||||||
|
}
|
||||||
|
After Width: | Height: | Size: 1.3 KiB |
|
After Width: | Height: | Size: 427 B |
|
After Width: | Height: | Size: 704 B |
|
After Width: | Height: | Size: 272 B |
|
After Width: | Height: | Size: 1.3 KiB |
|
After Width: | Height: | Size: 498 B |
|
After Width: | Height: | Size: 2.3 KiB |
|
After Width: | Height: | Size: 871 B |
|
After Width: | Height: | Size: 3.1 KiB |
|
After Width: | Height: | Size: 1.5 KiB |
@@ -0,0 +1,7 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
|
||||||
|
<item android:drawable="?android:attr/selectableItemBackground" android:state_pressed="true"/>
|
||||||
|
<item android:drawable="@android:color/transparent"/>
|
||||||
|
|
||||||
|
</selector>
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<android.support.v7.widget.Toolbar
|
||||||
|
android:id="@+id/toolbar"
|
||||||
|
style="@style/AppToolbar"/>
|
||||||
|
|
||||||
|
<android.support.v7.widget.RecyclerView
|
||||||
|
android:id="@+id/list"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:paddingBottom="8dp"
|
||||||
|
android:paddingTop="8dp"
|
||||||
|
android:scrollbars="vertical"/>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<android.support.v7.widget.CardView
|
||||||
|
android:id="@+id/card"
|
||||||
|
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="100dp"
|
||||||
|
android:layout_marginBottom="8dp"
|
||||||
|
android:layout_marginLeft="16dp"
|
||||||
|
android:layout_marginRight="16dp"
|
||||||
|
android:layout_marginTop="8dp"
|
||||||
|
app:cardBackgroundColor="@color/app_primary_500"
|
||||||
|
app:cardCornerRadius="2dp"
|
||||||
|
tools:ignore="RtlHardcoded,RtlSymmetry">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/container"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:gravity="center_vertical"
|
||||||
|
android:padding="16dip"
|
||||||
|
android:background="?android:attr/selectableItemBackground"
|
||||||
|
android:clickable="true">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/title"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:textColor="@android:color/white"
|
||||||
|
android:textSize="30sp"
|
||||||
|
tools:text="#2196F3"/>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/date"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:textColor="@android:color/white"
|
||||||
|
android:textSize="18sp"
|
||||||
|
android:text="01:23:45"
|
||||||
|
tools:ignore="HardcodedText" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</android.support.v7.widget.CardView>
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||||
|
|
||||||
|
<item
|
||||||
|
android:id="@+id/action_event"
|
||||||
|
android:icon="@drawable/abc_ic_menu_copy_mtrl_am_alpha"
|
||||||
|
android:title="@string/menu_add"
|
||||||
|
app:showAsAction="always"/>
|
||||||
|
|
||||||
|
</menu>
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources>
|
||||||
|
|
||||||
|
<color name="app_primary_500">#2196F3</color>
|
||||||
|
<color name="app_primary_700">#0087e9</color>
|
||||||
|
<color name="app_accent_200">#FF3D00</color>
|
||||||
|
|
||||||
|
</resources>
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources>
|
||||||
|
|
||||||
|
<string name="app_name">POC Kotlin</string>
|
||||||
|
<string name="menu_add">Add</string>
|
||||||
|
|
||||||
|
</resources>
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources>
|
||||||
|
|
||||||
|
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
|
||||||
|
<item name="colorAccent">@color/app_accent_200</item>
|
||||||
|
<item name="colorPrimary">@color/app_primary_500</item>
|
||||||
|
<item name="colorPrimaryDark">@color/app_primary_700</item>
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<style name="AppToolbar" parent="ThemeOverlay.AppCompat.Dark.ActionBar">
|
||||||
|
<item name="android:layout_width">match_parent</item>
|
||||||
|
<item name="android:layout_height">wrap_content</item>
|
||||||
|
<item name="android:background">?attr/colorPrimary</item>
|
||||||
|
<item name="android:minHeight">?attr/actionBarSize</item>
|
||||||
|
<item name="popupTheme">@style/ThemeOverlay.AppCompat.Light</item>
|
||||||
|
<item name="theme">@style/ThemeOverlay.AppCompat.Dark.ActionBar</item>
|
||||||
|
</style>
|
||||||
|
|
||||||
|
</resources>
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
// Top-level build file where you can add configuration options common to all sub-projects/modules.
|
||||||
|
|
||||||
|
buildscript {
|
||||||
|
repositories {
|
||||||
|
maven {
|
||||||
|
url 'file://' + pathToKotlinPlugin
|
||||||
|
}
|
||||||
|
mavenCentral()
|
||||||
|
}
|
||||||
|
dependencies {
|
||||||
|
classpath 'com.android.tools.build:gradle:1.5.+'
|
||||||
|
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:0.1-SNAPSHOT"
|
||||||
|
classpath "com.jakewharton.sdkmanager:gradle-plugin:0.12.+"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
allprojects {
|
||||||
|
repositories {
|
||||||
|
maven {
|
||||||
|
url 'file://' + pathToKotlinPlugin
|
||||||
|
}
|
||||||
|
mavenCentral()
|
||||||
|
maven { url "https://jitpack.io" }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
kapt.verbose=true
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
include ':app'
|
||||||
@@ -0,0 +1,63 @@
|
|||||||
|
buildscript {
|
||||||
|
ext.realm_version = '1.1.1'
|
||||||
|
|
||||||
|
repositories {
|
||||||
|
maven {
|
||||||
|
url 'file://' + pathToKotlinPlugin
|
||||||
|
}
|
||||||
|
jcenter()
|
||||||
|
}
|
||||||
|
dependencies {
|
||||||
|
classpath 'com.android.tools.build:gradle:1.5.+'
|
||||||
|
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:0.1-SNAPSHOT"
|
||||||
|
classpath("io.realm:realm-gradle-plugin:$realm_version") {
|
||||||
|
exclude group: 'com.android.tools.build', module: 'gradle'
|
||||||
|
}
|
||||||
|
classpath "com.jakewharton.sdkmanager:gradle-plugin:0.12.+"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
apply plugin: 'android-sdk-manager'
|
||||||
|
apply plugin: 'com.android.application'
|
||||||
|
apply plugin: 'kotlin-android'
|
||||||
|
apply plugin: 'kotlin-kapt'
|
||||||
|
apply plugin: 'kotlin-android-extensions'
|
||||||
|
apply plugin: 'realm-android'
|
||||||
|
|
||||||
|
android {
|
||||||
|
compileSdkVersion 23
|
||||||
|
buildToolsVersion "23.0.1"
|
||||||
|
defaultConfig {
|
||||||
|
applicationId 'io.realm.examples.kotlin'
|
||||||
|
minSdkVersion 14
|
||||||
|
targetSdkVersion 23
|
||||||
|
versionCode 1
|
||||||
|
versionName "1.0"
|
||||||
|
}
|
||||||
|
|
||||||
|
buildTypes {
|
||||||
|
release {
|
||||||
|
minifyEnabled false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dexOptions {
|
||||||
|
incremental false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
repositories {
|
||||||
|
maven {
|
||||||
|
url 'file://' + pathToKotlinPlugin
|
||||||
|
}
|
||||||
|
maven {
|
||||||
|
url 'http://oss.jfrog.org/artifactory/oss-snapshot-local'
|
||||||
|
}
|
||||||
|
mavenCentral()
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
compile "org.jetbrains.kotlin:kotlin-stdlib:0.1-SNAPSHOT"
|
||||||
|
compile "org.jetbrains.kotlin:kotlin-reflect:0.1-SNAPSHOT"
|
||||||
|
compile 'org.jetbrains.anko:anko-common:0.9'
|
||||||
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
kapt.verbose=true
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
# Add project specific ProGuard rules here.
|
||||||
|
# By default, the flags in this file are appended to flags specified
|
||||||
|
# in /usr/local/Cellar/android-sdk/22.6.2/tools/proguard/proguard-android.txt
|
||||||
|
# You can edit the include path and order by changing the proguardFiles
|
||||||
|
# directive in build.gradle.
|
||||||
|
#
|
||||||
|
# For more details, see
|
||||||
|
# http://developer.android.com/guide/developing/tools/proguard.html
|
||||||
|
|
||||||
|
# Add any project specific keep options here:
|
||||||
|
|
||||||
|
# If your project uses WebView with JS, uncomment the following
|
||||||
|
# and specify the fully qualified class name to the JavaScript interface
|
||||||
|
# class:
|
||||||
|
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
|
||||||
|
# public *;
|
||||||
|
#}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
<manifest package="io.realm.examples.kotlin"
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
|
||||||
|
<application
|
||||||
|
android:allowBackup="true"
|
||||||
|
android:icon="@mipmap/ic_launcher"
|
||||||
|
android:label="@string/app_name"
|
||||||
|
android:theme="@style/AppTheme">
|
||||||
|
<activity
|
||||||
|
android:name=".KotlinExampleActivity"
|
||||||
|
android:label="@string/app_name">
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="android.intent.action.MAIN"/>
|
||||||
|
|
||||||
|
<category android:name="android.intent.category.LAUNCHER"/>
|
||||||
|
</intent-filter>
|
||||||
|
</activity>
|
||||||
|
</application>
|
||||||
|
|
||||||
|
</manifest>
|
||||||
@@ -0,0 +1,219 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2015 Realm Inc.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.realm.examples.kotlin
|
||||||
|
|
||||||
|
import android.app.Activity
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.util.Log
|
||||||
|
import android.widget.LinearLayout
|
||||||
|
import android.widget.TextView
|
||||||
|
import io.realm.Realm
|
||||||
|
import io.realm.Sort
|
||||||
|
import io.realm.RealmConfiguration
|
||||||
|
import io.realm.examples.kotlin.model.Cat
|
||||||
|
import io.realm.examples.kotlin.model.Dog
|
||||||
|
import io.realm.examples.kotlin.model.Person
|
||||||
|
import org.jetbrains.anko.doAsync
|
||||||
|
import org.jetbrains.anko.uiThread
|
||||||
|
import kotlin.properties.Delegates
|
||||||
|
|
||||||
|
|
||||||
|
class KotlinExampleActivity : Activity() {
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
val TAG: String = KotlinExampleActivity::class.qualifiedName as String
|
||||||
|
}
|
||||||
|
|
||||||
|
private var rootLayout: LinearLayout by Delegates.notNull()
|
||||||
|
private var realm: Realm by Delegates.notNull()
|
||||||
|
private var realmConfig: RealmConfiguration by Delegates.notNull()
|
||||||
|
|
||||||
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
super.onCreate(savedInstanceState)
|
||||||
|
setContentView(R.layout.activity_realm_basic_example)
|
||||||
|
rootLayout = findViewById(R.id.container) as LinearLayout
|
||||||
|
rootLayout.removeAllViews()
|
||||||
|
|
||||||
|
// These operations are small enough that
|
||||||
|
// we can generally safely run them on the UI thread.
|
||||||
|
|
||||||
|
// Create configuration and reset Realm.
|
||||||
|
realmConfig = RealmConfiguration.Builder(this).build()
|
||||||
|
Realm.deleteRealm(realmConfig)
|
||||||
|
|
||||||
|
// Open the realm for the UI thread.
|
||||||
|
realm = Realm.getInstance(realmConfig)
|
||||||
|
|
||||||
|
basicCRUD(realm)
|
||||||
|
basicQuery(realm)
|
||||||
|
basicLinkQuery(realm)
|
||||||
|
|
||||||
|
// Delete all persons
|
||||||
|
// Using executeTransaction with a lambda reduces code size and makes it impossible
|
||||||
|
// to forget to commit the transaction.
|
||||||
|
realm.executeTransaction {
|
||||||
|
realm.delete(Person::class.java)
|
||||||
|
}
|
||||||
|
|
||||||
|
// More complex operations can be executed on another thread, for example using
|
||||||
|
// Anko's async extension method.
|
||||||
|
doAsync() {
|
||||||
|
var info: String
|
||||||
|
info = complexReadWrite()
|
||||||
|
info += complexQuery()
|
||||||
|
|
||||||
|
uiThread {
|
||||||
|
showStatus(info)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onDestroy() {
|
||||||
|
super.onDestroy()
|
||||||
|
realm.close() // Remember to close Realm when done.
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun showStatus(txt: String) {
|
||||||
|
Log.i(TAG, txt)
|
||||||
|
val tv = TextView(this)
|
||||||
|
tv.text = txt
|
||||||
|
rootLayout.addView(tv)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun basicCRUD(realm: Realm) {
|
||||||
|
showStatus("Perform basic Create/Read/Update/Delete (CRUD) operations...")
|
||||||
|
|
||||||
|
// All writes must be wrapped in a transaction to facilitate safe multi threading
|
||||||
|
realm.executeTransaction {
|
||||||
|
// Add a person
|
||||||
|
var person = realm.createObject(Person::class.java)
|
||||||
|
person.id = 1
|
||||||
|
person.name = "Young Person"
|
||||||
|
person.age = 14
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find the first person (no query conditions) and read a field
|
||||||
|
var person = realm.where(Person::class.java).findFirst()
|
||||||
|
showStatus(person.name + ": " + person.age)
|
||||||
|
|
||||||
|
// Update person in a transaction
|
||||||
|
realm.executeTransaction {
|
||||||
|
person.name = "Senior Person"
|
||||||
|
person.age = 99
|
||||||
|
showStatus(person.name + " got older: " + person.age)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun basicQuery(realm: Realm) {
|
||||||
|
showStatus("\nPerforming basic Query operation...")
|
||||||
|
showStatus("Number of persons: ${realm.where(Person::class.java).count()}")
|
||||||
|
|
||||||
|
val results = realm.where(Person::class.java).equalTo("age", 99).findAll()
|
||||||
|
|
||||||
|
showStatus("Size of result set: " + results.size)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun basicLinkQuery(realm: Realm) {
|
||||||
|
showStatus("\nPerforming basic Link Query operation...")
|
||||||
|
showStatus("Number of persons: ${realm.where(Person::class.java).count()}")
|
||||||
|
|
||||||
|
val results = realm.where(Person::class.java).equalTo("cats.name", "Tiger").findAll()
|
||||||
|
|
||||||
|
showStatus("Size of result set: ${results.size}")
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun complexReadWrite(): String {
|
||||||
|
var status = "\nPerforming complex Read/Write operation..."
|
||||||
|
|
||||||
|
// Open the default realm. All threads must use it's own reference to the realm.
|
||||||
|
// Those can not be transferred across threads.
|
||||||
|
val realm = Realm.getInstance(realmConfig)
|
||||||
|
|
||||||
|
// Add ten persons in one transaction
|
||||||
|
realm.executeTransaction {
|
||||||
|
val fido = realm.createObject(Dog::class.java)
|
||||||
|
fido.name = "fido"
|
||||||
|
for (i in 0..9) {
|
||||||
|
val person = realm.createObject(Person::class.java)
|
||||||
|
person.id = i.toLong()
|
||||||
|
person.name = "Person no. $i"
|
||||||
|
person.age = i
|
||||||
|
person.dog = fido
|
||||||
|
|
||||||
|
// The field tempReference is annotated with @Ignore.
|
||||||
|
// This means setTempReference sets the Person tempReference
|
||||||
|
// field directly. The tempReference is NOT saved as part of
|
||||||
|
// the RealmObject:
|
||||||
|
person.tempReference = 42
|
||||||
|
|
||||||
|
for (j in 0..i - 1) {
|
||||||
|
val cat = realm.createObject(Cat::class.java)
|
||||||
|
cat.name = "Cat_$j"
|
||||||
|
person.cats.add(cat)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Implicit read transactions allow you to access your objects
|
||||||
|
status += "\nNumber of persons: ${realm.where(Person::class.java).count()}"
|
||||||
|
|
||||||
|
// Iterate over all objects
|
||||||
|
for (person in realm.where(Person::class.java).findAll()) {
|
||||||
|
val dogName: String = person?.dog?.name ?: "None"
|
||||||
|
|
||||||
|
status += "\n${person.name}: ${person.age} : $dogName : ${person.cats.size}"
|
||||||
|
|
||||||
|
// The field tempReference is annotated with @Ignore
|
||||||
|
// Though we initially set its value to 42, it has
|
||||||
|
// not been saved as part of the Person RealmObject:
|
||||||
|
check(person.tempReference == 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sorting
|
||||||
|
val sortedPersons = realm.where(Person::class.java).findAllSorted("age", Sort.DESCENDING);
|
||||||
|
check(realm.where(Person::class.java).findAll().last().name == sortedPersons.first().name)
|
||||||
|
status += "\nSorting ${sortedPersons.last().name} == ${realm.where(Person::class.java).findAll().first().name}"
|
||||||
|
|
||||||
|
realm.close()
|
||||||
|
return status
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun complexQuery(): String {
|
||||||
|
var status = "\n\nPerforming complex Query operation..."
|
||||||
|
|
||||||
|
// Realm implements the Closable interface, therefore we can make use of Kotlin's built-in
|
||||||
|
// extension method 'use' (pun intended).
|
||||||
|
Realm.getInstance(realmConfig).use {
|
||||||
|
// 'it' is the implicit lambda parameter of type Realm
|
||||||
|
status += "\nNumber of persons: ${it.where(Person::class.java).count()}"
|
||||||
|
|
||||||
|
// Find all persons where age between 7 and 9 and name begins with "Person".
|
||||||
|
val results = it
|
||||||
|
.where(Person::class.java)
|
||||||
|
.between("age", 7, 9) // Notice implicit "and" operation
|
||||||
|
.beginsWith("name", "Person")
|
||||||
|
.findAll()
|
||||||
|
|
||||||
|
status += "\nSize of result set: ${results.size}"
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return status
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2015 Realm Inc.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.realm.examples.kotlin.model
|
||||||
|
|
||||||
|
import io.realm.RealmObject
|
||||||
|
|
||||||
|
open class Cat : RealmObject() {
|
||||||
|
open var name: String? = null
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2015 Realm Inc.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.realm.examples.kotlin.model
|
||||||
|
|
||||||
|
import io.realm.RealmObject
|
||||||
|
|
||||||
|
open class Dog : RealmObject() {
|
||||||
|
open var name: String? = null
|
||||||
|
}
|
||||||
@@ -0,0 +1,51 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2015 Realm Inc.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.realm.examples.kotlin.model
|
||||||
|
|
||||||
|
import io.realm.RealmList
|
||||||
|
import io.realm.RealmObject
|
||||||
|
import io.realm.annotations.Ignore
|
||||||
|
import io.realm.annotations.PrimaryKey
|
||||||
|
|
||||||
|
// Your model has to extend RealmObject. Furthermore, the class and all of the
|
||||||
|
// properties must be annotated with open (Kotlin classes and methods are final
|
||||||
|
// by default).
|
||||||
|
open class Person(
|
||||||
|
// You can put properties in the constructor as long as all of them are initialized with
|
||||||
|
// default values. This ensures that an empty constructor is generated.
|
||||||
|
// All properties are by default persisted.
|
||||||
|
// Properties can be annotated with PrimaryKey or Index.
|
||||||
|
// If you use non-nullable types, properties must be initialized with non-null values.
|
||||||
|
@PrimaryKey open var name: String = "",
|
||||||
|
|
||||||
|
open var age: Int = 0,
|
||||||
|
|
||||||
|
// Other objects in a one-to-one relation must also subclass RealmObject
|
||||||
|
open var dog: Dog? = null,
|
||||||
|
|
||||||
|
// One-to-many relations is simply a RealmList of the objects which also subclass RealmObject
|
||||||
|
open var cats: RealmList<Cat> = RealmList(),
|
||||||
|
|
||||||
|
// You can instruct Realm to ignore a field and not persist it.
|
||||||
|
@Ignore open var tempReference: Int = 0,
|
||||||
|
|
||||||
|
open var id: Long = 0
|
||||||
|
) : RealmObject() {
|
||||||
|
// The Kotlin compiler generates standard getters and setters.
|
||||||
|
// Realm will overload them and code inside them is ignored.
|
||||||
|
// So if you prefer you can also just have empty abstract methods.
|
||||||
|
}
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
<ScrollView
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:paddingLeft="@dimen/activity_horizontal_margin"
|
||||||
|
android:paddingRight="@dimen/activity_horizontal_margin"
|
||||||
|
android:paddingTop="@dimen/activity_vertical_margin"
|
||||||
|
android:paddingBottom="@dimen/activity_vertical_margin"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
tools:keep="@layout/activity_realm_basic_example">
|
||||||
|
<LinearLayout
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content">
|
||||||
|
<TextView
|
||||||
|
android:gravity="center_horizontal"
|
||||||
|
android:text="@string/status_output"
|
||||||
|
android:textStyle="bold"
|
||||||
|
android:textSize="18sp"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"/>
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/container"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:paddingTop="10sp"
|
||||||
|
android:orientation="vertical"
|
||||||
|
tools:context=".RealmIntroExample"/>
|
||||||
|
</LinearLayout>
|
||||||
|
</ScrollView>
|
||||||
|
After Width: | Height: | Size: 4.8 KiB |
|
After Width: | Height: | Size: 2.9 KiB |
|
After Width: | Height: | Size: 6.9 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 16 KiB |
@@ -0,0 +1,6 @@
|
|||||||
|
<resources>
|
||||||
|
<!-- Example customization of dimensions originally defined in res/values/dimens.xml
|
||||||
|
(such as screen margins) for screens with more than 820dp of available width. This
|
||||||
|
would include 7" and 10" devices in landscape (~960dp and ~1280dp respectively). -->
|
||||||
|
<dimen name="activity_horizontal_margin">64dp</dimen>
|
||||||
|
</resources>
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
<resources>
|
||||||
|
<!-- Default screen margins, per the Android Design guidelines. -->
|
||||||
|
<dimen name="activity_horizontal_margin">16dp</dimen>
|
||||||
|
<dimen name="activity_vertical_margin">16dp</dimen>
|
||||||
|
</resources>
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources>
|
||||||
|
<string name="app_name">Kotlin example</string>
|
||||||
|
<string name="status_output">Status Output…</string>
|
||||||
|
</resources>
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
<resources>
|
||||||
|
|
||||||
|
<!-- Base application theme. -->
|
||||||
|
<style name="AppTheme" parent="android:Theme.Holo.Light.DarkActionBar">
|
||||||
|
<!-- Customize your theme here. -->
|
||||||
|
</style>
|
||||||
|
|
||||||
|
</resources>
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
buildscript {
|
||||||
|
repositories {
|
||||||
|
mavenCentral()
|
||||||
|
maven {
|
||||||
|
url 'file://' + pathToKotlinPlugin
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dependencies {
|
||||||
|
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:0.1-SNAPSHOT"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
apply plugin: "java"
|
||||||
|
apply plugin: "kotlin"
|
||||||
|
apply plugin: "kotlin-kapt"
|
||||||
|
|
||||||
|
repositories {
|
||||||
|
maven {
|
||||||
|
url 'file://' + pathToKotlinPlugin
|
||||||
|
}
|
||||||
|
mavenCentral()
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
compile "org.jetbrains.kotlin:kotlin-stdlib:0.1-SNAPSHOT"
|
||||||
|
compile "org.jetbrains.kotlin:annotation-processor-example:0.1-SNAPSHOT"
|
||||||
|
kapt "org.jetbrains.kotlin:annotation-processor-example:0.1-SNAPSHOT"
|
||||||
|
}
|
||||||
|
|
||||||
|
task show << {
|
||||||
|
buildscript.configurations.classpath.each { println it }
|
||||||
|
}
|
||||||
|
|
||||||
|
kapt {
|
||||||
|
generateStubs = true
|
||||||
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
kapt.verbose=true
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2015 JetBrains s.r.o.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package example
|
||||||
|
|
||||||
|
@example.ExampleAnnotation
|
||||||
|
open class TestClass
|
||||||
|
|
||||||
|
class AncestorClass : TestClass()
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
buildscript {
|
||||||
|
repositories {
|
||||||
|
mavenCentral()
|
||||||
|
maven {
|
||||||
|
url 'file://' + pathToKotlinPlugin
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dependencies {
|
||||||
|
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:0.1-SNAPSHOT"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
apply plugin: "java"
|
||||||
|
apply plugin: "kotlin"
|
||||||
|
apply plugin: "kotlin-kapt"
|
||||||
|
|
||||||
|
repositories {
|
||||||
|
maven {
|
||||||
|
url 'file://' + pathToKotlinPlugin
|
||||||
|
}
|
||||||
|
mavenCentral()
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
compile "org.jetbrains.kotlin:kotlin-stdlib:0.1-SNAPSHOT"
|
||||||
|
compile "org.jetbrains.kotlin:annotation-processor-example:0.1-SNAPSHOT"
|
||||||
|
kapt "org.jetbrains.kotlin:annotation-processor-example:0.1-SNAPSHOT"
|
||||||
|
testCompile 'junit:junit:4.12'
|
||||||
|
}
|
||||||
|
|
||||||
|
task show << {
|
||||||
|
buildscript.configurations.classpath.each { println it }
|
||||||
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
kapt.verbose=true
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
package foo
|
||||||
|
|
||||||
|
internal class InternalDummy {
|
||||||
|
internal val x = "InternalDummy.x"
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
package foo
|
||||||
|
|
||||||
|
internal class InternalDummyUser {
|
||||||
|
internal fun use(dummy: InternalDummy) {
|
||||||
|
if (dummy.x != "InternalDummy.x") throw AssertionError("dummy.x = ${dummy.x}")
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2015 JetBrains s.r.o.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package javaPackage;
|
||||||
|
|
||||||
|
public class JavaClass {
|
||||||
|
|
||||||
|
public void test() {
|
||||||
|
System.out.println(example.TestClassGenerated.class.getName());
|
||||||
|
System.out.println(example.SourceAnnotatedTestClassGenerated.class.getName());
|
||||||
|
System.out.println(example.BinaryAnnotatedTestClassGenerated.class.getName());
|
||||||
|
System.out.println(example.RuntimeAnnotatedTestClassGenerated.class.getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
package example
|
||||||
|
|
||||||
|
@example.ExampleAnnotation
|
||||||
|
@example.ExampleSourceAnnotation
|
||||||
|
@example.ExampleBinaryAnnotation
|
||||||
|
@example.ExampleRuntimeAnnotation
|
||||||
|
public class TestClass {
|
||||||
|
|
||||||
|
@example.ExampleAnnotation
|
||||||
|
public val testVal: String = "text"
|
||||||
|
|
||||||
|
@example.ExampleAnnotation
|
||||||
|
public fun testFunction(): TestClassGenerated = TestClassGenerated()
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
package example;
|
||||||
|
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
public class JavaTest {
|
||||||
|
@Test
|
||||||
|
public void test() {
|
||||||
|
TestClass testClass = new TestClass();
|
||||||
|
Assert.assertEquals("text", testClass.getTestVal());
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
package foo
|
||||||
|
|
||||||
|
import org.junit.Test
|
||||||
|
|
||||||
|
class InternalDummyTest {
|
||||||
|
@Test
|
||||||
|
fun testDummy() {
|
||||||
|
val dummy = InternalDummy()
|
||||||
|
val dummyUser = InternalDummyUser()
|
||||||
|
dummyUser.use(dummy)
|
||||||
|
}
|
||||||
|
}
|
||||||