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

Kotlin on Android by Svetlana Isakova

Riga Dev Day
March 13, 2016
56

Kotlin on Android by Svetlana Isakova

Riga Dev Day

March 13, 2016
Tweet

Transcript

  1. public class Person {
 private final String name;
 private final

    int age;
 
 public Person(String name, int age) {
 this.name = name;
 this.age = age;
 }
 
 public String getName() {
 return name;
 }
 
 public int getAge() {
 return age;
 }
 }
  2. - equals - hashCode - toString 
 data 
 class

    Person(val name: String, val age: Int)
  3. Nullable types in Kotlin val s1: String = "always not

    null” 
 val s2: String? = null s1.length ✓ ✗ s2.length
  4. val s: String? if (s != null) {
 s.length
 }

    smart cast if (s == null) fail()
 s.length Dealing with Nullable Types the result has type Int? s!! throws NPE if s is null s?.length ?: 0
  5. you can avoid any repetition you can make the code

    look nicer you can create API looking like DSL expressive
  6. import com.example.util.lastChar import com.example.util.* Extension Functions val c: Char =

    "abc".lastChar() fun String.lastChar() = get(length - 1) ✳
  7. fun String.lastChar() = get(length - 1) Calling Extension Functions from

    Java code StringExtensions.kt char c = StringExtensionsKt.lastChar("abc"); JavaClass.java import static StringExtensionsKt.lastChar; char c = lastChar("abc");
  8. val employees: List<Employee> employees.filter { it.city == City.PRAGUE }.map(Employee::age).average() employees.filter

    { it.city == City.MUNICH }.map(Employee::age).average() Avoiding Duplication (I) employees.averageAgeFor(City.PRAGUE) employees.averageAgeFor(City.MUNICH) add an extension function averageAgeFor
  9. Working with collections with Lambdas & Member References { employee

    -> employee.age } { employee: Employee -> employee.city == City.PRAGUE } employees.filter { it.city == City.PRAGUE }.map(Employee::age).average()
  10. button.setOnClickListener(new View.OnClickListener() {
 @Override
 public void onClick(View v) {
 Toast.makeText(MainActivity.this,

    "Thank you!", Toast.LENGTH_SHORT).show();
 }
 }); Lambdas vs anonymous classes button.setOnClickListener {
 toast("Thank you!")
 }
  11. val sb = StringBuilder()
 with (sb) {
 appendln("Alphabet: ")
 for

    (c in 'a'..'z') {
 append(c)
 } toString()
 } The with function with is a function val sb = StringBuilder()
 sb.appendln("Alphabet: ")
 for (c in 'a'..'z') {
 sb.append(c)
 }
 sb.toString()

  12. lambda is its second argument val sb = StringBuilder()
 with

    (sb) {
 this.appendln(“Alphabet: ")
 for (c in 'a'..'z') {
 this.append(c)
 } this.toString()
 } val sb = StringBuilder()
 with (sb, {
 this.appendln(“Alphabet: ")
 for (c in 'a'..'z') {
 this.append(c)
 } this.toString()
 }) lambda is its second argument Lambda with receiver with is a function this is an implicit receiver in the lambda val sb = StringBuilder()
 with (sb) {
 appendln("Alphabet: ")
 for (c in 'a'..'z') {
 append(c)
 } toString()
 } this can be omitted
  13. buildString {
 appendln("Alphabet: ")
 for (c in 'a'..'z') {
 append(c)


    }
 } Make it even more simple val sb = StringBuilder()
 with (sb) {
 appendln("Alphabet: ")
 for (c in 'a'..'z') {
 append(c)
 } toString()
 }
  14. buildString {
 appendln("Alphabet: ")
 for (c in 'a'..'z') {
 append(c)


    }
 } Lambda with receiver buildString {
 appendln("Alphabet: ")
 for (c in 'a'..'z') {
 this.append(c)
 }
 } lambda with implicit this this can be omitted ✳
  15. val db: SQLiteDatabase = … db.beginTransaction()
 try {
 db.delete("users", "first_name

    = ?", arrayOf("Jake"))
 db.setTransactionSuccessful()
 } finally {
 db.endTransaction()
 } db.inTransaction {
 delete("users", "first_name = ?", arrayOf("Jake"))
 } Avoiding Duplication (II)
  16. db.beginTransaction()
 try {
 db.delete("users", "first_name = ?", arrayOf("Jake"))
 db.setTransactionSuccessful()
 }

    finally {
 db.endTransaction()
 } db.inTransaction {
 delete("users", "first_name = ?", arrayOf("Jake"))
 } Inline functions is declared as inline function generated bytecode is similar to:
  17. Alerts fun Activity.showAreYouSureAlert(process: () -> Unit) {
 alert(title = "Are

    you sure?",
 message = "Are you really sure?") {
 positiveButton("Yes") { process() }
 negativeButton("No") { }
 }.show()
 } Are you sure? Are you really sure? No Yes
  18. customView {
 verticalLayout {
 val email = editText {
 hint

    = "Email"
 }
 
 val password = editText {
 hint = "Password"
 transformationMethod = PasswordTransformationMethod.getInstance()
 }
 
 positiveButton("Log In") {
 logIn(email.text, password.text)
 }
 }
 } Password Log In Email Custom layouts
  19. Kotlin Android Extensions <Button
 android:id="@+id/click_me_button"
 />
 class KotlinActivity : Activity()

    {
 override fun onCreate(savedInstanceState: Bundle?) {
 
 click_me_button.setOnClickListener { }
 }
 } import kotlinx.android.synthetic.activity_buttons.click_me_button
  20. class KotlinActivity : Activity() {
 
 
 
 
 


    override fun onCreate(savedInstanceState: Bundle?) {
 Button click_me_button.setOnClickListener { }
 }
 } How it works var cachedView: HashMap<Int, View>?
 
 fun getCachedViewById(id: Int): View this code is generated by compiler var click_me_button = 
 getCachedViewById(R.id.click_me_button) as Button