Kotlin for Android Developers - DevFest Chicago / DC

Kotlin for Android Developers - DevFest Chicago / DC

48fd642048ccd225ddaffcada7a6d407?s=128

Michael Evans

September 24, 2016
Tweet

Transcript

  1. 8.

    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. 9.

    Why Kotlin? • Type inference • Lambdas • Null safety

    • Smart casts • String templates • Higher order functions • Extension functions • Data classes • Default Values
  3. 11.

    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. 12.

    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. 13.
  6. 20.

    Defining Variables val a: Int = 1
 val b =

    1
 
 var x = 5
 x += 1 final int a = 1;
 
 
 int x = 5;
  7. 21.

    Defining Variables val a: Int = 1
 val b =

    1
 
 var x = 5
 x += 1 final int a = 1;
 
 
 int x = 5;
  8. 22.

    Properties public class Person {
 
 private String name;
 


    public String getName() {
 return name;
 }
 
 public void setName(String name) {
 this.name = name;
 }
 }
  9. 23.

    Properties var person = Person()
 person.name = "Mike"
 val name

    = person.name class Person {
 
 var name: String = "Ryan"
 }
  10. 26.

    val string: String = "Mike"
 val another: String = null

    // does not compile
 
 val nullable: String? = null // ok Nullability
  11. 28.

    Nullability println(person?.name)
 
 val email = data["email"] ?: "foo@bar.com"
 


    data?.let {
 // execute this block if not null
 
 println(files!!.size)
  12. 29.

    Nullability println(person?.name?.length)
 
 val email = data["email"] ?: "foo@bar.com"
 


    data?.let {
 // execute this block if not null
 
 println(files!!.size)
  13. 30.

    Nullability println(person?.name?.length)
 
 val email = data["email"] ?: "foo@bar.com"
 


    data?.let {
 // execute this block if not null
 
 println(files!!.size)
  14. 33.

    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
  15. 34.

    Extension Functions fun List.swap(index1: Int, index2: Int) {
 val tmp

    = this[index1]
 this[index1] = this[index2]
 this[index2] = tmp
 }
  16. 35.

    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
  17. 36.

    { it.isEmpty() } 
 { it.length == 10 } 


    { isPalindrome(it) } Function Expressions
  18. 37.

    { it.isEmpty() } 
 { it.length == 10 } 


    { isPalindrome(it) } Function Expressions
  19. 38.

    { it.isEmpty() } 
 { it.length == 10 } 


    { isPalindrome(it) } Function Expressions
  20. 39.

    val isEmpty: (String) -> Boolean = { it.isEmpty() } 


    val exactly10: (String) -> Boolean = { it.length == 10 } 
 val palindrome: (String) -> Boolean = { isPalindrome(it) } Function Expressions
  21. 41.

    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
 }
  22. 42.

    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"]
  23. 43.
  24. 47.

    inline fun supportsLollipop(code: () -> Unit) {
 if (Build.VERSION.SDK_INT >=

    Build.VERSION_CODES.LOLLIPOP) {
 code.invoke()
 }
 } Inline Functions
  25. 48.

    supportsLollipop {
 getWindow().setStatusBarColor(Color.BLACK)
 } inline fun supportsLollipop(code: () -> Unit)

    {
 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
 code.invoke()
 }
 } Inline Functions
  26. 50.

    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) {
 
 }
 }));
  27. 51.

    recycler.adapter = ContactsAdapter(contacts) {
 navigateToDetail(it)
 }
 
 class ContactsAdapter(val contacts:

    List<Contact>,
 val listener: (Contact) -> Unit)
 
 itemView.setOnClickListener { listener(contact) }
  28. 52.

    recycler.adapter = ContactsAdapter(contacts) {
 navigateToDetail(it)
 }
 
 class ContactsAdapter(val contacts:

    List<Contact>,
 val listener: (Contact) -> Unit)
 
 itemView.setOnClickListener { listener(contact) }
  29. 53.

    recycler.adapter = ContactsAdapter(contacts) {
 navigateToDetail(it)
 }
 
 class ContactsAdapter(val contacts:

    List<Contact>,
 val listener: (Contact) -> Unit)
 
 itemView.setOnClickListener { listener(contact) }
  30. 56.

    inline fun SharedPreferences.edit( func: SharedPreferences.Editor.() -> Unit) {
 val editor

    = edit()
 editor.func()
 editor.apply()
 }
 
 Extension Function Expressions
  31. 57.

    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
  32. 58.

    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
  33. 60.
  34. 61.

    verticalLayout {
 padding = dip(30)
 editText {
 hint = "Name"


    textSize = 24f
 }
 editText {
 hint = "Password"
 textSize = 24f
 }
 button("Login") {
 textSize = 26f
 }
 } Anko
  35. 65.

    Java Interoperability class Person {
 private String name;
 
 public

    void setName(String name) {
 this.name = name;
 }
 }
  36. 66.

    var person = Person()
 person.name = "name" Java Interoperability class

    Person {
 private String name;
 
 public void setName(String name) {
 this.name = name;
 }
 }
  37. 68.

    // 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
  38. 69.

    // 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
  39. 70.

    // 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
  40. 72.

    Data Classes class Person {
 private String name;
 private int

    age;
 
 public String getName() {
 return name;
 }
 
 public int getAge() {
 return age;
 }
 }
  41. 73.

    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();
 }
 }