KAI KOENIG (@AGENTK) ANKO THE ULTIMATE NINJA OF KOTLIN LIBRARIES?
AGENDA ▸ What are Kotlin and Anko? ▸ Anko-related idioms and language concepts ▸ Anko DSL ▸ The hidden parts of Anko ▸ Anko VS The Rest ▸ Final thoughts
WHAT ARE KOTLIN AND ANKO?
WHAT ARE KOTLIN AND ANKO? SOME KOTLIN FUNDAMENTALS ▸ Statically typed programming language for the JVM and Android ▸ Started as internal language “Project Kotlin” at Jetbrains in 2010 ▸ Now: Open-Source, Apache License ▸ Kotlin SDK plus tool support for IntelliJ, Android Studio, Eclipse ▸ Named after an island in the Gulf of Finland
WHAT ARE KOTLIN AND ANKO? MOTIVATION FOR KOTLIN ▸ The Java platform is awesome, but it has its issues: ▸ sometimes tied to backwards/legacy compatibility ▸ can be a very verbose language and produce bloated code ▸ type system has various flaws ▸ Kotlin aims to fix a lot of those issues, in particular when you have to use Java 6 or 7 (if we’re lucky…) and you can’t use all the new, shiny features from Java 8 and soon Java 9 and 10
WHAT ARE KOTLIN AND ANKO? HOW DOES A SIMPLE CONVERSION LOOK LIKE? public String listConvert(Collection<Integer> collection) { fun listConvert(collection: Collection< Int >): String { StringBuilder sb = new StringBuilder(); val sb = StringBuilder() sb.append("{"); sb.append("{") Iterator<Integer> iterator = collection.iterator(); val iterator = collection.iterator() while (iterator.hasNext()) { while (iterator.hasNext()) { Integer element = iterator.next(); val element = iterator.next() sb.append(element); sb.append(element) if (iterator.hasNext()) { if (iterator.hasNext()) { sb.append(", "); sb.append(", ") } } } } sb.append("}"); sb.append("}") return sb.toString(); return sb.toString() } } fun listConvertKt(collection: Collection< Int >): String { return collection.joinToString(prefix = "{",postfix = "}") }
WHAT ARE KOTLIN AND ANKO? WHAT IS ANKO? ▸ Library to make Android development with Kotlin faster and easier ▸ Created by Jetbrains ▸ Best-known feature is Anko’s Layout DSL ▸ Some other functionality: ▸ intent and service wrappers ▸ async call handling ▸ SQLite
ANKO-RELATED IDIOMS & LANGUAGE PATTERNS https://www.flickr.com/photos/geraldford/6976818221/
ANKO-RELATED IDIOMS & LANGUAGE PATTERNS IDIOM AND LANGUAGE OVERVIEW ▸ Immutability ▸ Syntactic sugar (loops, ranges etc) ▸ String templates & Enum classes ▸ Extension functions ▸ Null safety ▸ Lambdas ▸ Properties and Fields ▸ Collection API ▸ Type inference and casts ▸ Type-safe builders ▸ Data classes ▸ Java-Kotlin-Interop
ANKO-RELATED IDIOMS & LANGUAGE PATTERNS DATA CLASSES ▸ The POJOs or Beans of other languages data class ChromeEncryptedPayload( val encryptedPayload: String , val encryptionHeader: String , ▸ Data classes implicitly create: val cryptoKeyHeader: String ) ▸ getters/setters (non-data classes have those too) - recommended to use val as often as possible. ▸ proper and useful implementations for equals(), hashCode(), toString(), copy() ▸ copy() has default parameters and can be used to alter a copy
ANKO-RELATED IDIOMS & LANGUAGE PATTERNS PROPERTIES AND FIELDS var counter = 0 ▸ Kotlin classes have mutable or set(value) { immutable properties if (value >= 0) field = value } ▸ An automated backing field can be provided by the compiler (if required) ▸ Default getter/setters for properties, can be customised
ANKO-RELATED IDIOMS & LANGUAGE PATTERNS EXTENSION FUNCTIONS fun Int .sum(otherInt: Int ): Int = this + ▸ Allow adding new functionality to a otherInt class without inheritance or decorators 3.sum(7) ▸ Kotlin has extension functions as well fun Activity.toast(message: CharSequence, as extension properties duration: Int = TOAST.LENGTH_SHORT) { Toast.makeText( this , message, ▸ Resolved statically, don’t actually duration).show() } modify the class (excellent example why this has to be the case at http:// // In onCreate of an Activity override fun onCreate(...) { goo.gl/EN6bTs) ... toast("Hi there") ... }
ANKO-RELATED IDIOMS & LANGUAGE PATTERNS TYPE-SAFE BUILDERS (I) ▸ Builders are a very popular approach in JsonBuilder builder = new JsonBuilder() Groovy to define data in a declarative builder.records { car { way name 'HSV Maloo' make 'Holden' ▸ Often used for: year 2006 country 'Australia' } ▸ generating XML or JSON } String json = JsonOutput.prettyPrint ▸ UI layout (Swing components) etc (builder.toString()) ▸ In Kotlin, builders even can be type- checked
ANKO-RELATED IDIOMS & LANGUAGE PATTERNS TYPE-SAFE BUILDERS (II) ▸ html() is a function with a lambda as an fun result(args: Array<String>) = html { argument (init) head { title {”HTML in Kotlin"} } ▸ init’s type is a function type with body { ... receiver, this allows you to: } } ▸ pass receiver (of type HTML) to function fun html(init: HTML.() -> Unit): HTML { val html = HTML() html.init() return html ▸ call members of instance inside the } function
ANKO-RELATED IDIOMS & LANGUAGE PATTERNS TYPE-SAFE BUILDERS (III) ▸ Html class has functions to build the class Html { ... head and the body elements of the fun head(headBuilder: Head.() -> Unit) { DSL. head = Head() head?.headBuilder() } ▸ Not shown: classes further down in the hierachy: fun body(bodyBuilder: Body.() -> Unit) { body = Body() body?.bodyBuilder() ▸ Head, Body etc. } } ▸ Complete HTML builder example at: http://goo.gl/TndcC9
ANKO-RELATED IDIOMS & LANGUAGE PATTERNS IDIOM AND LANGUAGE OVERVIEW ▸ Immutability ▸ Syntactic sugar (loops, ranges etc) ▸ String templates & Enum classes ▸ Extension functions ▸ Null safety ▸ Lambdas ▸ Properties and Fields ▸ Collection API ▸ Type inference and casts ▸ Type-safe builders ▸ Data classes ▸ Java-Kotlin-Interop
ANKO DSL
ANKO DSL WHAT IS A DSL? ▸ D omain- S pecific L anguage ▸ Computer programming language ▸ Limited expressiveness: ▸ DSLs are usually not general-purpose languages ▸ strongly focussed on a particular domain ▸ examples: SQL, Ant XML, XSLT, Gradle etc.
ANKO DSL MORE ON DSL CONCEPTS ▸ Increased level of abstraction ▸ What vs. How ▸ Common discussion: are DSLs code or data? ▸ Interpretation vs. code generation
ANKO DSL A DSL FOR LAYOUTS ▸ The most important element of Anko is the Layout DSL ▸ Idea: replace XML layout definitions by Kotlin code - without having to build the layout in a fully programmatic sense ▸ Modular: as we’re talking about UI/Layout, it’s very important to select the right library for your minSDKVersion ▸ Extensible: you can add your own DSL elements for custom UI controls
ANKO DSL LAYOUT XML <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent" > <EditText android:layout_width="match_parent" android:gravity="center" android:text="@string/empty_todos_message" android:layout_weight="7" android:layout_height="wrap_content" /> <Button android:layout_width="match_parent" android:layout_weight="1" android:text="Say Hello" android:layout_height="0dp" /> </LinearLayout>
ANKO DSL PROGRAMMATIC LAYOUT IN KOTLIN val act = this val layout = LinearLayout(act) layout.orientation = LinearLayout.VERTICAL val name = EditText(act) val button = Button(act) button.text = "Say Hello" button.setOnClickListener { Toast.makeText(act, "Hello, ${name.text}!", Toast.LENGTH_SHORT).show() } layout.addView(name) layout.addView(button)
ANKO DSL ANKO DSL verticalLayout { val name = editText() button("Say Hello") { onClick { toast("Hello, ${name.text}!") } } }
ANKO DSL ANKO DSL INTERNALS ▸ Anko DSL example from previous slide looks very similar to the earlier HTML builder example ▸ Anko uses extension functions arranged into type-safe builders and lambdas ▸ You don’t have to write all those extensions by hand though - Anko generates them based on the Android SDK’s android.jar
ANKO DSL GETTING STARTED WITH ANKO DSL (I) ▸ Depending on minSdkVersion of project, import: compile "org.jetbrains.anko:anko-sdk{15|19|21|23}:0.9" ▸ If the project uses an Android Support library, import matching Anko library: compile “org.jetbrains.anko:anko-recyclerview-v7:0.9"
ANKO DSL GETTING STARTED WITH ANKO DSL (II) ▸ General approach: override fun onCreate(savedInstanceState: Bundle?) { super .onCreate(savedInstanceState) ▸ Anko DSL automatically becomes verticalLayout { padding = dip(30) available in onCreate() in an Activity editText { hint = "Name" textSize = 24f ▸ no need for setContentView(), Anko } editText { DSL also automatically sets the hint = "Password" content view for activities textSize = 24f } button("Login") { textSize = 26f } } }
Recommend
More recommend