Kapt: Gradle integration tests for the new kapt
@@ -26,7 +26,6 @@
|
||||
<groupId>org.jetbrains.kotlin</groupId>
|
||||
<artifactId>kotlin-stdlib</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
|
||||
@@ -45,7 +45,7 @@ class ExampleAnnotationProcessor : AbstractProcessor() {
|
||||
val simpleName = element.simpleName.toString()
|
||||
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("public final class $generatedJavaClassName {}")
|
||||
}}
|
||||
|
||||
@@ -72,8 +72,14 @@ abstract class BaseGradleIT {
|
||||
val androidHome: File? = null,
|
||||
val androidGradlePluginVersion: String? = null)
|
||||
|
||||
open inner class Project(val projectName: String, val wrapperVersion: String, val minLogLevel: LogLevel = LogLevel.DEBUG) {
|
||||
open val resourcesRoot = File(resourcesRootFile, "testProject/$projectName")
|
||||
open inner class Project(
|
||||
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)
|
||||
|
||||
open fun setupWorkingDir() {
|
||||
|
||||
@@ -10,7 +10,7 @@ import kotlin.test.assertEquals
|
||||
|
||||
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)
|
||||
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(":compileJava")
|
||||
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/TestClassGenerated.class")
|
||||
assertNoSuchFile("build/classes/main/example/SourceAnnotatedTestClassGenerated.class")
|
||||
@@ -160,8 +160,8 @@ class KaptIT: BaseGradleIT() {
|
||||
fun testInheritedAnnotations() {
|
||||
Project("kaptInheritedAnnotations", GRADLE_VERSION).build("build") {
|
||||
assertSuccessful()
|
||||
assertFileExists("build/generated/source/kapt/main/TestClassGenerated.java")
|
||||
assertFileExists("build/generated/source/kapt/main/AncestorClassGenerated.java")
|
||||
assertFileExists("build/generated/source/kapt/main/example/TestClassGenerated.java")
|
||||
assertFileExists("build/generated/source/kapt/main/example/AncestorClassGenerated.java")
|
||||
assertFileExists("build/classes/main/example/TestClassGenerated.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)
|
||||
}
|
||||
}
|
||||