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

Android & Kotlin: The code awakens (episode 03)...

Android & Kotlin: The code awakens (episode 03) - 3/3

Kotlin vs Java - Part 3
Extensions
Infix Notation
Operator Overloading

Avatar for Omar Miatello

Omar Miatello

March 30, 2016
Tweet

More Decks by Omar Miatello

Other Decks in Technology

Transcript

  1. Omar Miatello Member of GDG Milano (Italy) Android Developer @

    Satispay Personal profile google.com/+OmarMiatello Google+ Community: Kotlin for Android goo.gl/mUKF1w Google Presentation #01 goo.gl/0jHLmE #02 goo.gl/h3uG8M #03 goo.gl/hnwvqu Google Photo #01 goo.gl/photos/cKP9L6zqZcxDRGzQ8 #02 goo.gl/photos/sXdpkbihCi5xAAnx7 #03 goo.gl/photos/P6kGhLE8yrWYnhAW6
  2. dummy/HeroAdapter.java public class HeroAdapter extends RecyclerView.Adapter<HeroAdapter.ViewHolder> { private final List<HeroItem>

    mValues; private final HeroOnClickListener mListener; public HeroAdapter(List<HeroItem> items, HeroOnClickListener listener) { mValues = items; mListener = listener; } @Override public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_hero, parent, false); return new ViewHolder(view); } @Override public void onBindViewHolder(final ViewHolder holder, int position) { HeroItem item = mValues.get(position); “Convert Java File to Kotlin File” CTRL + ALT + SHIFT + K (or CMD + ALT + SHIFT + K)
  3. Previously on Android & Kotlin #01: goo.gl/0jHLmE • Properties val

    a: Int = 1 // val = READ ONLY (getter) var b: Int = 1 // var = READ/WRITE (getter/setter) • String templates "My name is $name $surname" • Lambdas view.setOnClickListener { Log.d("TAG", "Item clicked!") } • Delegated properties (example: lazy) val item by lazy { MyItem() }
  4. // val = READ ONLY (getter) // var = READ/WRITE

    (getter/setter) val onlyRead = 1 var writable = 2 var nullable: Int? = 3 fun test() { onlyRead = 3 // Error at compile time writable = 3 writable = "test" // Error at compile time writable = null // Error at compile time nullable = null } // Customize getter/setter val p1: Int = 1 get() { // add some logic return field } var p2: Int = 2 get() { return field } set(value) { // add some logic field = value } Properties // More examples
  5. var name = "Omar" fun test() { var str: String

    str = "My name is $name" str = "My name is $name (${name.length} chars)" str = "$name == ${name}" str = "$name.length != ${name.length}" // IS NOT THE SAME str = "Time is: ${System.currentTimeMillis()}ms since 1970" } String templates // More examples
  6. "qwerty | 123 | abc".filter { char -> char.isDigit() //

    return is implicit in lambda expressions } "qwerty | 123 | abc".filter { it.isDigit() // we can use "it" with 1 parameter } "qwerty | 123 | abc".filterIndexed { index: Int, c: Char -> index > 3 && c.isLetterOrDigit() } Lambdas // More examples
  7. val startTime by lazy { System.currentTimeMillis() } var test by

    Delegates.observable(3) { prop, old, new -> if (new > old) Log.w("TEST", "$new > $old") } fun test() { startTime test = 5 test = 1 test = 2 val finish = System.currentTimeMillis() - startTime } Delegated properties // More examples
  8. Previously on Android & Kotlin #02: goo.gl/h3uG8M • Null safety

    var a: String = null // Error at compile time var b: String? = null • Elvis Operator val example: String = b ?: "Default" // b may be null • Smart-cast if (myView is TextView) { myView.setText("Ciao") } • Collections listOf("Android", "iOS", null).filterNotNull().map { it.toUpperCase() }
  9. var test: String? = null fun test() { test =

    "new string" test.length // Error at compile time test?.length // if (test != null) test.length else null test!!.length // test MUST exist or throw NullPointerException val len = test?.length ?: 0 // default value = 0 test?.length ?: throw IllegalStateException("Missing the main string!") } Null safety & Elvis Operator // More examples
  10. var test: Any? = "My new value" fun test() {

    val _test: Any? = test if (_test != null) { val checkEqual = _test.equals("My new value") if (_test is String) { val checkLen = _test.length _test.capitalize() _test.substring(1) } } when (_test) { is Int -> { val sum = _test + 1 } is String -> { val len = _test.length } } } Smart-cast // More examples
  11. val stringList = listOf("my", "items", "list") fun test() { stringList.first()

    stringList.filterNotNull() stringList.filter { it.length > 3 } stringList.first { it.length > 4 } stringList.firstOrNull() { it.length > 10 } stringList.findLast { it.startsWith("m") } stringList.sorted() stringList.indexOfLast { it.startsWith("i") } stringList.map { it.length } stringList.maxBy { it.length } // ... } Collections // More examples
  12. fun String.isBig(): Boolean { return length() > 10 } #9

    Kotlin - Extensions http://kotlinlang.org/docs/reference/extensions.html vs
  13. fun String.isBig(): Boolean { return length() > 10 } fun

    example() { "why?!".isBig() // false! "harder, better, ...".isBig() // true! } #9 Kotlin - Extensions http://kotlinlang.org/docs/reference/extensions.html vs
  14. fun String.isBig(): Boolean { return length() > 10 } fun

    example() { "why?!".isBig() // false! "harder, better, ...".isBig() // true! } // file MyUtils.java class MyUtils { static boolean isBig(String str) { return str.length() > 10; } } // file MyJavaClass.java class MyJavaClass { void example() { MyUtils.isBig("why?!"); MyUtils.isBig("harder, better, ..."); } } #9 Kotlin - Extensions http://kotlinlang.org/docs/reference/extensions.html vs
  15. fun String.isBig(): Boolean { return length() > 10 } fun

    example() { "why?!".isBig() "harder, better, ...".isBig() } // file MyUtils.java class MyUtils { static boolean isBig(String str) { return str.length() > 10; } } // file MyJavaClass.java class MyJavaClass { void example() { MyUtils.isBig("why?!"); MyUtils.isBig("harder, better, ..."); } } #9 Kotlin - Extensions http://kotlinlang.org/docs/reference/extensions.html vs
  16. class Hero(val power: Int) class Hero { private final int

    power; public Hero(int power) { this.power = power; } } #10 Kotlin - Infix Notation http://kotlinlang.org/docs/reference/functions.html#infix-notation vs
  17. class Hero(val power: Int) { infix fun vs(opponent: Hero): Hero

    { return if (power > opponent.power) { this } else { opponent } } } #10 Kotlin - Infix Notation http://kotlinlang.org/docs/reference/functions.html#infix-notation vs
  18. class Hero(val power: Int) { infix fun vs(opponent: Hero): Hero

    { return if (power > opponent.power) { this } else { opponent } } } fun example() { val thor = Hero(7) val ironman = Hero(8) val spiderman = Hero(4) } // Skip Java version of Hero class, // we use Kotlin class class MyJavaClass { void example() { Hero thor = new Hero(7); Hero ironman = new Hero(8); Hero spiderman = new Hero(4); } } #10 Kotlin - Infix Notation http://kotlinlang.org/docs/reference/functions.html#infix-notation vs
  19. class Hero(val power: Int) { infix fun vs(opponent: Hero): Hero

    { return if (power > opponent.power) { this } else { opponent } } } fun example() { val thor = Hero(7) val ironman = Hero(8) val spiderman = Hero(4) val theBest = thor vs ironman vs spiderman } // Skip Java version of Hero class, // we use Kotlin class class MyJavaClass { void example() { Hero thor = new Hero(7); Hero ironman = new Hero(8); Hero spiderman = new Hero(4); Hero theBest = thor.vs(ironman).vs(spiderman); } } #10 Kotlin - Infix Notation http://kotlinlang.org/docs/reference/functions.html#infix-notation vs
  20. class Hero(val power: Int) { infix fun vs(opponent: Hero): Hero

    { return if (power > opponent.power) { this } else { opponent } } } fun example() { val thor = Hero(7) val ironman = Hero(8) val spiderman = Hero(4) val theBest = thor vs ironman vs spiderman } // Skip Java version of Hero class, // we use Kotlin class class MyJavaClass { void example() { Hero thor = new Hero(7); Hero ironman = new Hero(8); Hero spiderman = new Hero(4); Hero theBest = thor.vs(ironman).vs(spiderman); } } #10 Kotlin - Infix Notation http://kotlinlang.org/docs/reference/functions.html#infix-notation vs
  21. class Male(val eyes: String) class Female(val hair: String) class Male

    { private String eyes; public Male(String eyes) { this.eyes = eyes; } } class Female { private String hair; public Female(String hair) { this.hair = hair; } } #11 Kotlin - Operator Overloading http://kotlinlang.org/docs/reference/operator-overloading.html vs
  22. class Male(val eyes: String) class Female(val hair: String) class Baby(val

    eyes: String, val hair: String) // Skip Java version of Male, Female and Baby // class, there is not enough space! #11 Kotlin - Operator Overloading http://kotlinlang.org/docs/reference/operator-overloading.html vs
  23. class Male(val eyes: String) { operator fun plus(her: Female): Baby

    { return Baby(this.eyes, her.hair) } } class Female(val hair: String) class Baby(val eyes: String, val hair: String) // Skip Java version of Male, Female and Baby // class, there is not enough space! #11 Kotlin - Operator Overloading http://kotlinlang.org/docs/reference/operator-overloading.html vs
  24. class Male(val eyes: String) { operator fun plus(her: Female): Baby

    { return Baby(this.eyes, her.hair) } } class Female(val hair: String) class Baby(val eyes: String, val hair: String) fun example() { val myBaby = Male("green") + Female("blond") } // Skip Java version of Male, Female and Baby // class, there is not enough space! class MyJavaClass { void example() { Baby myBaby = new Male("green").plus( new Female("blond")); } } #11 Kotlin - Operator Overloading http://kotlinlang.org/docs/reference/operator-overloading.html vs
  25. class Male(val eyes: String) { operator fun plus(her: Female): Baby

    { return Baby(this.eyes, her.hair) } } class Female(val hair: String) class Baby(val eyes: String, val hair: String) fun example() { val myBaby = Male("green") + Female("blond") } // Skip Java version of Male, Female and Baby // class, there is not enough space! class MyJavaClass { void example() { Baby myBaby = new Male("green").plus(new Female("blond")); } } #11 Kotlin - Operator Overloading http://kotlinlang.org/docs/reference/operator-overloading.html vs
  26. Extensions // More examples (1) fun String.encodeUrl(charsetName: String = "UTF-8")

    = URLEncoder.encode(this, charsetName) fun String.isValidEmail() = Patterns.EMAIL_ADDRESS.matcher(this).matches() // INFO: https://en.wikipedia.org/wiki/Non-breaking_space fun String.useNonBreakingSpace() = replace(' ', '\u00A0') // http://developer.android.com/reference/android/content/Intent.html#ACTION_VIEW fun Uri.viewIntent() = Intent(Intent.ACTION_VIEW).setData(this) fun <T : View> T.onClick(onClick: (T) -> Unit) = setOnClickListener(onClick as (View) -> Unit) fun View.postDelayed(delayMillis: Long, action: () -> Unit) = postDelayed(action, delayMillis) val EditText.string: String get() = text.toString()
  27. Extensions // More examples (2) fun View.hideSoftInput() { val imm

    = context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager imm.hideSoftInputFromWindow(windowToken, 0) } /** * Kotlin version of method Utils.isViewInBounds(container, view) by Alex Lockwood * URL: https://github.com/alexjlockwood/activity-transitions/blob/c4fa3a21c941691fb6bbe53e37cf3965842ee254/app/src/ main/java/com/alexjlockwood/activity/transitions/Utils.java * * Returns true if {@param view} is contained within {@param container}'s bounds. */ fun View.isInBounds(container: View): Boolean { val containerBounds = Rect() container.getHitRect(containerBounds) return getLocalVisibleRect(containerBounds) }
  28. Extensions + Infix Notation // More examples infix fun String?.orNotNull(defaultValue:

    String): String = if (!this.isNullOrBlank()) this!! else defaultValue infix fun String?.or(defaultValue: String?): String? = if (!this.isNullOrBlank()) this else defaultValue // val a: String? = null // val b: String? = null // val c: String? = "test" // val myText = a or b or c orNotNull "default"
  29. Extensions + Operator Overloading // More examples operator fun StringBuilder.plusAssign(s:

    String) { appendln(s) } // val sb = StringBuilder() // sb += "test" // sb += "test2"
  30. Questions? Developers playground - #EX3 - In KotlinExample use: Extensions,

    Infix Notation, Operator Overloading Start with: https://github.com/jacklt/KotlinExample/tree/ex2 Solution: https://github.com/jacklt/KotlinExample/tree/ex3 (at some point maybe …) :P