android & kotlin - the code awakens #02

37
Android & Kotlin The code awakens #02

Upload: omar-miatello

Post on 05-Apr-2017

66 views

Category:

Software


0 download

TRANSCRIPT

Page 1: Android & Kotlin - The code awakens #02

Android & KotlinThe code awakens #02

Page 2: Android & Kotlin - The code awakens #02

Omar MiatelloMember of GDG Milano (Italy)Android Developer @ Satispay

Personal profilegoogle.com/+OmarMiatelloGoogle+ Community: Kotlin for Androidgoo.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

Page 3: Android & Kotlin - The code awakens #02

Previously on Android & Kotlin #01: goo.gl/0jHLmEProperties

val a: Int = 1 // val = READ ONLY (getter)var b: Int = 1 // var = READ/WRITE (getter/setter)

String templates"My name is $name $surname"

Lambdasview.setOnClickListener { Log.d("TAG", "Item clicked!") }

Delegated properties (example: lazy)val item by lazy { MyItem() }

Page 4: Android & Kotlin - The code awakens #02

dummy/HeroAdapter.javapublic 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)

Page 5: Android & Kotlin - The code awakens #02

Kotlin vs Java - Part 2Null-safety

Elvis OperatorSmart-castCollections

Page 6: Android & Kotlin - The code awakens #02

class MyKotlinClass { val a: String = "ciao" val b: String = null // Error at compile time}

#5 Kotlin - Null Safetyhttp://kotlinlang.org/docs/reference/null-safety.html

vs

Page 7: Android & Kotlin - The code awakens #02

class MyKotlinClass { val a: String = "ciao" val b: String = null // Error at compile time val c: String? = null val d: String? = "ok"}

#5 Kotlin - Null Safetyhttp://kotlinlang.org/docs/reference/null-safety.html

vs

Page 8: Android & Kotlin - The code awakens #02

class MyKotlinClass { val a: String = "ciao" val b: String = null // Error at compile time val c: String? = null val d: String? = "ok"

fun example(e: String, f: String?) { e.length() f.length() // Error at compile time }}

static class MyUtils { void example(String e, String f) { e.length(); // throw NullPointerException? f.length(); // throw NullPointerException? }}

#5 Kotlin - Null Safetyhttp://kotlinlang.org/docs/reference/null-safety.html

vs

Page 9: Android & Kotlin - The code awakens #02

class MyKotlinClass { val a: String = "ciao" val b: String = null // Error at compile time val c: String? = null val d: String? = "ok"

fun example(e: String, f: String?) { e.length() f.length() // Error at compile time f?.length() }}

static class MyUtils { void example(String e, String f) { e.length(); // throw NullPointerException? f.length(); // throw NullPointerException? }}

#5 Kotlin - Null Safetyhttp://kotlinlang.org/docs/reference/null-safety.html

vs

Page 10: Android & Kotlin - The code awakens #02

class MyKotlinClass { val a: String = "ciao" val b: String = null // Error at compile time val c: String? = null val d: String? = "ok"

fun example(e: String, f: String?) { e.length() f.length() // Error at compile time f?.length()

if (f != null) { f.length() } }}

static class MyUtils { void example(String e, String f) { e.length(); // throw NullPointerException? f.length(); // throw NullPointerException?

if (e != null) { e.length(); }

if (f != null) { e.length(); } }}

#5 Kotlin - Null Safetyhttp://kotlinlang.org/docs/reference/null-safety.html

vs

Page 11: Android & Kotlin - The code awakens #02

val map = mapOf( "dog" to "woof", "cat" to "meow", "bird" to "tweet", "mouse" to "squeek")

fun sound(animal: String): String? { return map.get(animal)}

class MyUtils { static Map<String, String> map = // ...

static String sound(String animal) { return map.get(animal); }}

#6 Kotlin - Elvis Operatorhttp://kotlinlang.org/docs/reference/idioms.html#if-not-null-and-else-shorthand

vs

Page 12: Android & Kotlin - The code awakens #02

val map = mapOf( "dog" to "woof", "cat" to "meow", "bird" to "tweet", "mouse" to "squeek")

fun sound(animal: String): String? { return map.get(animal)}

fun example() { val foxSay = sound("fox") ?: "No one knows"}

class MyUtils { static Map<String, String> map = // ...

static String sound(String animal) { return map.get(animal); }

static void example() { String s = sound("fox"); String foxSay = s != null ? s : "No one knows";

}}

#6 Kotlin - Elvis Operatorhttp://kotlinlang.org/docs/reference/idioms.html#if-not-null-and-else-shorthand

vs

Page 13: Android & Kotlin - The code awakens #02

val map = mapOf( "dog" to "woof", "cat" to "meow", "bird" to "tweet", "mouse" to "squeek")

fun sound(animal: String): String? { return map.get(animal)}

fun example() { val foxSay = sound("fox") ?: "No one knows"}

class MyUtils { static Map<String, String> map = // ...

static String sound(String animal) { return map.get(animal); }

static void example() { String s = sound("fox"); String foxSay = s != null ? s : "No one knows";

}}

#6 Kotlin - Elvis Operatorhttp://kotlinlang.org/docs/reference/idioms.html#if-not-null-and-else-shorthand

vs

Page 14: Android & Kotlin - The code awakens #02

class MyUtils {

static void example(View myView) { if (myView instanceof ImageView) {

} }

}

#7 Kotlin - Smart Casthttp://kotlinlang.org/docs/reference/typecasts.html#smart-casts

vs

Page 15: Android & Kotlin - The code awakens #02

class MyUtils {

static void example(View myView) { if (myView instanceof ImageView) { ImageView imageView = (ImageView) myView; } }

}

#7 Kotlin - Smart Casthttp://kotlinlang.org/docs/reference/typecasts.html#smart-casts

vs

Page 16: Android & Kotlin - The code awakens #02

class MyUtils {

static void example(View myView) { if (myView instanceof ImageView) { ImageView imageView = (ImageView) myView; imageView.setImageAlpha(10); } }

}

#7 Kotlin - Smart Casthttp://kotlinlang.org/docs/reference/typecasts.html#smart-casts

vs

Page 17: Android & Kotlin - The code awakens #02

class MyUtils {

static void example(View myView) { if (myView instanceof ImageView) { ImageView imageView = (ImageView) myView; imageView.setImageAlpha(10); } else if (myView instanceof TextView) { TextView textView = (TextView) myView; textView.setText("Ciao"); } }

}

#7 Kotlin - Smart Casthttp://kotlinlang.org/docs/reference/typecasts.html#smart-casts

vs

Page 18: Android & Kotlin - The code awakens #02

fun example1(myView: View) { if (myView is ImageView) { myView.setImageAlpha(10) } else if (myView is TextView) { myView.setText("Ciao") }}

class MyUtils {

static void example(View myView) { if (myView instanceof ImageView) { ImageView imageView = (ImageView) myView; imageView.setImageAlpha(10); } else if (myView instanceof TextView) { TextView textView = (TextView) myView; textView.setText("Ciao"); } }

}

#7 Kotlin - Smart Casthttp://kotlinlang.org/docs/reference/typecasts.html#smart-casts

vs

Page 19: Android & Kotlin - The code awakens #02

fun example1(myView: View) { if (myView is ImageView) { myView.setImageAlpha(10) } else if (myView is TextView) { myView.setText("Ciao") }}

fun example2(myView: View) { when (myView) { is ImageView -> myView.imageAlpha = 10 is TextView -> myView.text = "Ciao" }}

class MyUtils {

static void example(View myView) { if (myView instanceof ImageView) { ImageView imageView = (ImageView) myView; imageView.setImageAlpha(10); } else if (myView instanceof TextView) { TextView textView = (TextView) myView; textView.setText("Ciao"); } }

}

#7 Kotlin - Smart Casthttp://kotlinlang.org/docs/reference/typecasts.html#smart-casts

vs

Page 20: Android & Kotlin - The code awakens #02

fun example() { val os = listOf("Android", "iOS", null, "Windows Phone")

}

class MyUtils { static void example() { List<String> os = Arrays.asList("Android", "iOS", null, "Windows Phone"); }}

#8 Kotlin - Using collectionshttp://kotlinlang.org/docs/reference/basic-syntax.html#using-collections

vs

Page 21: Android & Kotlin - The code awakens #02

fun example() { val os = listOf("Android", "iOS", null, "Windows Phone")

os.filterNotNull()

}

class MyUtils { static void example() { List<String> os = Arrays.asList("Android", "iOS", null, "Windows Phone"); List<String> osNotNull = new ArrayList<>(); for (String name : os) { if (name != null) osNotNull.add(name); } }}

#8 Kotlin - Using collectionshttp://kotlinlang.org/docs/reference/basic-syntax.html#using-collections

vs

Page 22: Android & Kotlin - The code awakens #02

fun example() { val os = listOf("Android", "iOS", null, "Windows Phone")

os.filterNotNull().sortedBy { it.length() }

}

class MyUtils { static void example() { List<String> os = Arrays.asList("Android", "iOS", null, "Windows Phone"); List<String> osNotNull = new ArrayList<>(); for (String name : os) { if (name != null) osNotNull.add(name); } Collections.sort(osNotNull, new Comparator<String>() { @Override public int compare(String l, String r) { return r.length() - l.length(); } }); }}

#8 Kotlin - Using collectionshttp://kotlinlang.org/docs/reference/basic-syntax.html#using-collections

vs

Page 23: Android & Kotlin - The code awakens #02

fun example() { val os = listOf("Android", "iOS", null, "Windows Phone")

os.filterNotNull().sortedBy { it.length() } .map { it.toUpperCase() }

}

class MyUtils { static void example() { List<String> os = Arrays.asList("Android", "iOS", null, "Windows Phone"); List<String> osNotNull = new ArrayList<>(); for (String name : os) { if (name != null) osNotNull.add(name); } Collections.sort(osNotNull, new Comparator<String>() { @Override public int compare(String l, String r) { return l.length() - r.length(); } }); for (String name : osNotNull) { String value = name.toUpperCase(); } }}

#8 Kotlin - Using collectionshttp://kotlinlang.org/docs/reference/basic-syntax.html#using-collections

vs

Page 24: Android & Kotlin - The code awakens #02

fun example() { val os = listOf("Android", "iOS", null, "Windows Phone")

os.filterNotNull().sortedBy { it.length() } .map { it.toUpperCase() } .forEach { print(it) }

}

class MyUtils { static void example() { List<String> os = Arrays.asList("Android", "iOS", null, "Windows Phone"); List<String> osNotNull = new ArrayList<>(); for (String name : os) { if (name != null) osNotNull.add(name); } Collections.sort(osNotNull, new Comparator<String>() { @Override public int compare(String l, String r) { return l.length() - r.length(); } }); for (String name : osNotNull) { String value = name.toUpperCase(); print(value); }} }

#8 Kotlin - Using collectionshttp://kotlinlang.org/docs/reference/basic-syntax.html#using-collections

vs

Page 25: Android & Kotlin - The code awakens #02

Android ExampleFrom Java to Kotlin!

https://github.com/jacklt/KotlinExample/tree/ex1

Page 26: Android & Kotlin - The code awakens #02

dummy/Items.ktdata class HeroItem(val name: String, val gender: String, val power: Int)

Page 27: Android & Kotlin - The code awakens #02

dummy/HeroDummyContent.ktobject HeroDummyContent { private val MALE = "Male" private val FEMALE = "Female"

val ITEMS = listOf( HeroItem("Hulk", MALE, 9), HeroItem("Iron Man", MALE, 8), HeroItem("Thor", MALE, 8), HeroItem("Jessica Jones", FEMALE, 2), HeroItem("Spiderman", MALE, 4) )}

Page 28: Android & Kotlin - The code awakens #02

dummy/HeroDummyContent.kt > object vs classobject HeroDummyContent { private val MALE = "Male" private val FEMALE = "Female"

val ITEMS = listOf( HeroItem("Hulk", MALE, 9), HeroItem("Iron Man", MALE, 8), HeroItem("Thor", MALE, 8), HeroItem("Jessica Jones", FEMALE, 2), HeroItem("Spiderman", MALE, 4) )}

Page 29: Android & Kotlin - The code awakens #02

dummy/HeroDummyContent.kt > listOf(...)object HeroDummyContent { private val MALE = "Male" private val FEMALE = "Female"

val ITEMS = listOf( HeroItem("Hulk", MALE, 9), HeroItem("Iron Man", MALE, 8), HeroItem("Thor", MALE, 8), HeroItem("Jessica Jones", FEMALE, 2), HeroItem("Spiderman", MALE, 4) )}

Page 30: Android & Kotlin - The code awakens #02

dummy/HeroAdapter.ktclass HeroAdapter(val mValues: List<HeroItem>, val mListener: Function1<HeroItem, Unit>?) : RecyclerView.Adapter<HeroAdapter.ViewHolder>() {

// ... override fun onBindViewHolder(holder: ViewHolder, position: Int) { val hero = mValues[position] holder.item = hero holder.nameView.text = "${hero.name} (Power: ${hero.power})" holder.genderView.text = hero.gender

holder.itemView.setOnClickListener { mListener?.invoke(hero) } } // ...

}

Page 31: Android & Kotlin - The code awakens #02

dummy/HeroAdapter.kt > String templateclass HeroAdapter(val mValues: List<HeroItem>, val mListener: Function1<HeroItem, Unit>?) : RecyclerView.Adapter<HeroAdapter.ViewHolder>() {

// ... override fun onBindViewHolder(holder: ViewHolder, position: Int) { val hero = mValues[position] holder.item = hero holder.nameView.text = "${hero.name} (Power: ${hero.power})" holder.genderView.text = hero.gender

holder.itemView.setOnClickListener { mListener?.invoke(hero) } } // ...

}

Page 32: Android & Kotlin - The code awakens #02

MainActivity.ktclass MainActivity : AppCompatActivity() {

private var currentHero: HeroItem? = null

private val adapter by lazy { HeroAdapter(HeroDummyContent.ITEMS) { // onItemClick ... } } // ...}

Page 33: Android & Kotlin - The code awakens #02

MainActivity.kt > adapter (lazy)HeroAdapter(HeroDummyContent.ITEMS) { // onClick val previousHero = currentHero if (previousHero != null) { // fight val conclusion = if (previousHero.power == it.power) { "It's a draw" } else if (previousHero.power > it.power) { "${previousHero.name} wins!" } else { "${it.name} wins!" } Snackbar.make(fab, "${previousHero.name} vs ${it.name}!\n$conclusion", Snackbar.LENGTH_LONG).show() currentHero = null } else { // assign current hero Snackbar.make(fab, "Choose: ${it.name}", Snackbar.LENGTH_SHORT).show() currentHero = it }}

Page 34: Android & Kotlin - The code awakens #02

MainActivity.kt > adapter (lazy) > Smart castHeroAdapter(HeroDummyContent.ITEMS) { // onClick val previousHero = currentHero if (previousHero != null) { // fight val conclusion = if (previousHero.power == it.power) { "It's a draw" } else if (previousHero.power > it.power) { "${previousHero.name} wins!" } else { "${it.name} wins!" } Snackbar.make(fab, "${previousHero.name} vs ${it.name}!\n$conclusion", Snackbar.LENGTH_LONG).show() currentHero = null } else { // assign current hero Snackbar.make(fab, "Choose: ${it.name}", Snackbar.LENGTH_SHORT).show() currentHero = it }}

Page 35: Android & Kotlin - The code awakens #02

MainActivity.kt > adapter (lazy) > return if expressionHeroAdapter(HeroDummyContent.ITEMS) { // onClick val previousHero = currentHero if (previousHero != null) { // fight val conclusion = if (previousHero.power == it.power) { "It's a draw" } else if (previousHero.power > it.power) { "${previousHero.name} wins!" } else { "${it.name} wins!" } Snackbar.make(fab, "${previousHero.name} vs ${it.name}!\n$conclusion", Snackbar.LENGTH_LONG).show() currentHero = null } else { // assign current hero Snackbar.make(fab, "Choose: ${it.name}", Snackbar.LENGTH_SHORT).show() currentHero = it }}

Page 36: Android & Kotlin - The code awakens #02

Questions?Developers playground - #EX2- Aggiungere le proprietà a HeroItem: hair (String?), eyes (String?)- Mostrarle (se presenti) nella lista- Se vengono scelti 2 eroi di sesso opposto, viene creato un nuovo eroe- Si possono usare le proprietà dei genitori, oppure dei valori di default se

mancano

Start with: https://github.com/jacklt/KotlinExample/tree/ex1

Solution: https://github.com/jacklt/KotlinExample/tree/ex2

Page 37: Android & Kotlin - The code awakens #02

THANKS!Omar Miatello, Member of GDG Milano (Italy)

Android Developer @ Satispay