Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Kotlin for Android Developers - DevFest Chicago / DC

Michael Evans
September 24, 2016

Kotlin for Android Developers - DevFest Chicago / DC

Michael Evans

September 24, 2016
Tweet

More Decks by Michael Evans

Other Decks in Programming

Transcript

  1. Nullability I call it my billion-dollar mistake. It was the

    invention of the null reference in 1965 […] This has led to innumerable errors, vulnerabilities, and system crashes, which have probably caused a billion dollars of pain and damage in the last forty years.
  2. Why Kotlin? • Type inference • Lambdas • Null safety

    • Smart casts • String templates • Higher order functions • Extension functions • Data classes • Default Values
  3. Getting Started buildscript {
 repositories {
 mavenCentral()
 }
 dependencies {


    classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.0.3"
 }
 }
 
 apply plugin: 'kotlin'
 
 dependencies {
 compile "org.jetbrains.kotlin:kotlin-stdlib:1.0.3" }

  4. Getting Started buildscript {
 repositories {
 mavenCentral()
 }
 dependencies {


    classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.0.3"
 }
 }
 
 apply plugin: 'kotlin'
 
 dependencies {
 compile "org.jetbrains.kotlin:kotlin-stdlib:1.0.3" }

  5. Defining Variables val a: Int = 1
 val b =

    1
 
 var x = 5
 x += 1 final int a = 1;
 
 
 int x = 5;
  6. Defining Variables val a: Int = 1
 val b =

    1
 
 var x = 5
 x += 1 final int a = 1;
 
 
 int x = 5;
  7. Properties public class Person {
 
 private String name;
 


    public String getName() {
 return name;
 }
 
 public void setName(String name) {
 this.name = name;
 }
 }
  8. Properties var person = Person()
 person.name = "Mike"
 val name

    = person.name class Person {
 
 var name: String = "Ryan"
 }
  9. val string: String = "Mike"
 val another: String = null

    // does not compile
 
 val nullable: String? = null // ok Nullability
  10. Nullability println(person?.name)
 
 val email = data["email"] ?: "[email protected]"
 


    data?.let {
 // execute this block if not null
 
 println(files!!.size)
  11. Nullability println(person?.name?.length)
 
 val email = data["email"] ?: "[email protected]"
 


    data?.let {
 // execute this block if not null
 
 println(files!!.size)
  12. Nullability println(person?.name?.length)
 
 val email = data["email"] ?: "[email protected]"
 


    data?.let {
 // execute this block if not null
 
 println(files!!.size)
  13. fun toast(message: String, length: Int = Toast.LENGTH_SHORT) {
 Toast.makeText(this, message,

    length).show()
 } toast("Hello")
 toast("Hello", Toast.LENGTH_LONG)
 toast("Hello", length = Toast.LENGTH_LONG) Default Values
  14. Extension Functions fun List.swap(index1: Int, index2: Int) {
 val tmp

    = this[index1]
 this[index1] = this[index2]
 this[index2] = tmp
 }
  15. fun Activity.toast(message: CharSequence, duration: Int = Toast.LENGTH_SHORT) {
 Toast.makeText(this, message,

    duration).show()
 } fun List.swap(index1: Int, index2: Int) {
 val tmp = this[index1]
 this[index1] = this[index2]
 this[index2] = tmp
 } Extension Functions
  16. { it.isEmpty() } 
 { it.length == 10 } 


    { isPalindrome(it) } Function Expressions
  17. { it.isEmpty() } 
 { it.length == 10 } 


    { isPalindrome(it) } Function Expressions
  18. { it.isEmpty() } 
 { it.length == 10 } 


    { isPalindrome(it) } Function Expressions
  19. val isEmpty: (String) -> Boolean = { it.isEmpty() } 


    val exactly10: (String) -> Boolean = { it.length == 10 } 
 val palindrome: (String) -> Boolean = { isPalindrome(it) } Function Expressions
  20. Higher order functions fun <T> List<T>.filter(predicate: (T) -> Boolean): List<T>

    {
 val newList = ArrayList<T>()
 for (item in this) {
 if(predicate(item)) {
 newList.add(item)
 }
 }
 return newList
 }
  21. fun <T> List<T>.filter(predicate: (T) -> Boolean): List<T> {
 // ...


    } Higher order functions val names = listOf("Mike", "John", "Bob")
 names.filter { it == "Mike" } // ["Mike"]
 names.filter(palindrome) // ["Bob"]
  22. inline fun supportsLollipop(code: () -> Unit) {
 if (Build.VERSION.SDK_INT >=

    Build.VERSION_CODES.LOLLIPOP) {
 code.invoke()
 }
 } Inline Functions
  23. supportsLollipop {
 getWindow().setStatusBarColor(Color.BLACK)
 } inline fun supportsLollipop(code: () -> Unit)

    {
 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
 code.invoke()
 }
 } Inline Functions
  24. public class ContactsAdapter extends RecyclerView.Adapter {
 interface ContactClickListener {
 void

    onContactClicked(Contact contact);
 } recycler.setAdapter(new ContactsAdapter(contacts, new ContactsAdapter.ContactClickListener() {
 @Override
 public void onContactClicked(ContactsAdapter.Contact contact) {
 
 }
 }));
  25. recycler.adapter = ContactsAdapter(contacts) {
 navigateToDetail(it)
 }
 
 class ContactsAdapter(val contacts:

    List<Contact>,
 val listener: (Contact) -> Unit)
 
 itemView.setOnClickListener { listener(contact) }
  26. recycler.adapter = ContactsAdapter(contacts) {
 navigateToDetail(it)
 }
 
 class ContactsAdapter(val contacts:

    List<Contact>,
 val listener: (Contact) -> Unit)
 
 itemView.setOnClickListener { listener(contact) }
  27. recycler.adapter = ContactsAdapter(contacts) {
 navigateToDetail(it)
 }
 
 class ContactsAdapter(val contacts:

    List<Contact>,
 val listener: (Contact) -> Unit)
 
 itemView.setOnClickListener { listener(contact) }
  28. inline fun SharedPreferences.edit( func: SharedPreferences.Editor.() -> Unit) {
 val editor

    = edit()
 editor.func()
 editor.apply()
 }
 
 Extension Function Expressions
  29. inline fun SharedPreferences.edit( func: SharedPreferences.Editor.() -> Unit) {
 val editor

    = edit()
 editor.func()
 editor.apply()
 }
 
 preferences.edit {
 putString("foo", "bar")
 putString("fizz", "buzz")
 remove("username")
 } Extension Function Expressions
  30. inline fun SharedPreferences.edit( func: SharedPreferences.Editor.() -> Unit) {
 val editor

    = edit()
 editor.func()
 editor.apply()
 }
 
 fun SharedPreferences.Editor.set(pair: Pair<String, String>) =
 putString(pair.first, pair.second) Extension Function Expressions
  31. verticalLayout {
 padding = dip(30)
 editText {
 hint = "Name"


    textSize = 24f
 }
 editText {
 hint = "Password"
 textSize = 24f
 }
 button("Login") {
 textSize = 26f
 }
 } Anko
  32. Java Interoperability class Person {
 private String name;
 
 public

    void setName(String name) {
 this.name = name;
 }
 }
  33. var person = Person()
 person.name = "name" Java Interoperability class

    Person {
 private String name;
 
 public void setName(String name) {
 this.name = name;
 }
 }
  34. // com/example/util/DateExtensions.kt
 fun Date.isTuesday() = day == 2
 
 //

    com/example/util/DateExtensionsKt.java
 static boolean isTuesday(Date date) {
 return date.getDay() == 2;
 } Java Interoperability - Extensions
  35. // com/example/util/DateExtensions.kt
 fun Date.isTuesday() = day == 2
 
 //

    com/example/util/DateExtensionsKt.java
 static boolean isTuesday(Date date) {
 return date.getDay() == 2;
 } Java Interoperability - Extensions
  36. // com/example/util/DateExtensions.kt @file:JvmName("DateUtils") fun Date.isTuesday() = day == 2
 


    // com/example/util/DateUtils.java
 static boolean isTuesday(Date date) {
 return date.getDay() == 2;
 } Java Interoperability - Extensions
  37. Data Classes class Person {
 private String name;
 private int

    age;
 
 public String getName() {
 return name;
 }
 
 public int getAge() {
 return age;
 }
 }
  38. Data Classes @Override public boolean equals(Object o) {
 if (this

    == o) return true;
 if (o == null || getClass() != o.getClass()) return false;
 
 Person person = (Person) o;
 
 if (age != person.age) return false;
 return name != null ? name.equals(person.name) : person.name == null;
 }
 
 @Override public int hashCode() {
 int result = name != null ? name.hashCode() : 0;
 result = 31 * result + age;
 return result;
 }
 
 @Override public String toString() {
 return super.toString();
 }
 }