Slide 1

Slide 1 text

#io17extended #kotlin #devreactor Armando Picón @devpicon Kotlin/Android para Java Haters…

Slide 2

Slide 2 text

Kotlin para Android Developers Kotlin para Java Lovers… y Haters también Armando Picón

Slide 3

Slide 3 text

¿Qué es Kotlin? • Lenguaje de programación

Slide 4

Slide 4 text

¿Qué es Kotlin? • Lenguaje de programación • Desarrollado por JetBrains

Slide 5

Slide 5 text

¿Qué es Kotlin? • Lenguaje de programación • Desarrollado por JetBrains • Busca superar las limitaciones de Java

Slide 6

Slide 6 text

¿Qué es Kotlin? • Lenguaje de programación • Desarrollado por JetBrains • Busca superar las limitaciones de Java • Su desarrollo llevó 6 años antes de la versión 1.0

Slide 7

Slide 7 text

Kotlin Hello World! 2010 Kotlin 1.0 Febrero 2016 Kotlin 1.1 Marzo 2017

Slide 8

Slide 8 text

¿Qué es Kotlin? • Lenguaje de programación • Desarrollado por JetBrains • Busca superar las limitaciones de Java • Su desarrollo llevó 6 años antes de la versión 1.0 • Google le brinda soporte como segundo lenguaje para Android

Slide 9

Slide 9 text

Características • Interoperabilidad con Java

Slide 10

Slide 10 text

Características • Interoperabilidad con Java • NPE safety

Slide 11

Slide 11 text

Características • Interoperabilidad con Java • NPE safety • Características de programación funcional

Slide 12

Slide 12 text

Características • Interoperabilidad con Java • NPE safety • Características de programación funcional • Ligero

Slide 13

Slide 13 text

Características • Interoperabilidad con Java • NPE safety • Características de programación funcional • Ligero • Poca curva de aprendizaje

Slide 14

Slide 14 text

Características • Interoperabilidad con Java • NPE safety • Características de programación funcional • Ligero • Poca curva de aprendizaje • Open Source

Slide 15

Slide 15 text

¿Cómo funciona? Código Java Código Kotlin javac kotlinc bytecode Dalvik ART Android

Slide 16

Slide 16 text

No content

Slide 17

Slide 17 text

No content

Slide 18

Slide 18 text

No content

Slide 19

Slide 19 text

No content

Slide 20

Slide 20 text

¿Qué necesito para empezar? • Plugin de Kotlin para IntelliJ IDEA y Android Studio 2.x • Android Studio 3.x

Slide 21

Slide 21 text

MainActivity.java public class Person { private final String name; private int age; public Person(String name, int age) { this.name = name; this.age = age; } public String getName() { return name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } } Person.java

Slide 22

Slide 22 text

class Person(name: String, age: Int){ val name = name var age = age } Person.kt

Slide 23

Slide 23 text

class Person(val name: String, var age: Int) Person.kt

Slide 24

Slide 24 text

data class Person(val name: String, var age: Int) Person.kt

Slide 25

Slide 25 text

Data class • Accessors (getters & setters) • Equal / HashCode • toString • copy

Slide 26

Slide 26 text

List people = new ArrayList<>(); people.add(new Person("Armando", 36)); people.add(new Person("Ronald", 24)); people.add(new Person("Alberto", 58)); for (Person person : people) { if (person.getName().equals("Ronald")) { return person; } }

Slide 27

Slide 27 text

val people = listOf( Person("Armando", 36), Person("Ronald", 24), Person("Alberto", 58)) val person = people.find { it.name == "Ronald" } return person

Slide 28

Slide 28 text

val numberList = listOf(1, 2, 3, 4, 5, 6, 7) val squared = numberList.map { i -> i * i } squared.forEach { println(it) } // result: 1, 4, 9, 16, 25, 36, 49

Slide 29

Slide 29 text

public class Utilities { public Locale getDefaultLocale(String deliveryArea){ String deliveryAreaLower = deliveryArea.toLowerCase(); if(deliveryAreaLower == "mexico" || deliveryAreaLower == "bolivia" || deliveryAreaLower == "peru"){ return MyLocale.SPANISH; } if (deliveryAreaLower == "brazil"){ return MyLocale.PORTUGUESE; } if (deliveryAreaLower == "usa"){ return MyLocale.ENGLISH; } return MyLocale.SPANISH; } } Utilities.java

Slide 30

Slide 30 text

Utilities.kt class Utilities { fun getDefaultLocale(deliveryArea: String): Locale { val deliveryAreaLower = deliveryArea.toLowerCase() if (deliveryAreaLower === "mexico" || deliveryAreaLower === "bolivia" || deliveryAreaLower === "peru") { return MyLocale.SPANISH } if (deliveryAreaLower === "brazil") { return MyLocale.PORTUGUESE } if (deliveryAreaLower === "usa") { return MyLocale.ENGLISH } return MyLocale.SPANISH } }

Slide 31

Slide 31 text

Utilities.kt class Utilities { fun getDefaultLocale(deliveryArea: String): Locale = when (deliveryArea.toLowerCase()) { "mexico", "bolivia", "peru" -> MyLocale.SPANISH "brazil" -> MyLocale.PORTUGUESE "usa" -> MyLocale.ENGLISH else -> MyLocale.SPANISH } }

Slide 32

Slide 32 text

public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } } MainActivity.java

Slide 33

Slide 33 text

class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) } } MainActivity.kt

Slide 34

Slide 34 text

class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) val name = "GDG La Paz" val textView = findViewById(R.id.txt_hello_world) as TextView textView.text = "¡Hola $name!" } } MainActivity.kt

Slide 35

Slide 35 text

class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) val name = "GDG La Paz" txt_hello_world.text = "¡Hola $name!" } } MainActivity.kt

Slide 36

Slide 36 text

class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) val name = "GDG La Paz" txt_hello_world.text = "¡Hola $name!" } } MainActivity.kt import kotlinx.android.synthetic.main.activity_main.*

Slide 37

Slide 37 text

class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) val name = "GDG La Paz" txt_hello_world.text = "¡Hola $name!" } } MainActivity.kt import kotlinx.android.synthetic.main.activity_main.*

Slide 38

Slide 38 text

class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) val name = "GDG La Paz" txt_hello_world.text = "¡Hola $name!" Glide.with(this).load("http://cdm.devpicon.com/avatar.jpg").into(img_profile) } } MainActivity.kt

Slide 39

Slide 39 text

class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) val name = "GDG La Paz" txt_hello_world.text = "¡Hola $name!" Glide.with(this).load("http://cdm.devpicon.com/avatar.jpg").into(img_profile) } } fun ImageView.loadImage(imageUrl: String?) { if (imageUrl != null) { Glide.with(this.context).load(imageUrl).into(this) } } MainActivity.kt Extensions.kt

Slide 40

Slide 40 text

class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) val name = "GDG La Paz" txt_hello_world.text = "¡Hola $name!" Glide.with(this).load("http://cdm.devpicon.com/avatar.jpg").into(img_profile) } } fun ImageView.loadImage(imageUrl: String?) { if (imageUrl != null) { Glide.with(this.context).load(imageUrl).into(this) } } MainActivity.kt Extensions.kt

Slide 41

Slide 41 text

fun ImageView.loadImage(imageUrl: String?) { if (imageUrl != null) { Glide.with(this.context).load(imageUrl).into(this) } } class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) val name = "GDG La Paz" txt_hello_world.text = "¡Hola $name!" img_profile.loadImage("http://cdm.devpicon.com/avatar.jpg") } } MainActivity.kt Extensions.kt

Slide 42

Slide 42 text

class MainActivity : AppCompatActivity(), MainView { var controller : MainController? = null override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) controller = MainController(this) } } MainActivity.kt

Slide 43

Slide 43 text

class MainActivity : AppCompatActivity(), MainView { var controller : MainController? = null override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) controller = MainController(this) } } MainActivity.kt class MainController(view: MainView) { val view = view } MainController.kt

Slide 44

Slide 44 text

class MainActivity : AppCompatActivity(), MainView { var controller : MainController? = null override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) controller = MainController(this) } } MainActivity.kt class MainController(view: MainView) { val view = view } MainController.kt

Slide 45

Slide 45 text

class MainActivity : AppCompatActivity(), MainView { var controller : MainController? = null override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) controller = MainController(this) } } MainActivity.kt class MainController(view: MainView) { val view = view } MainController.kt interface MainView { } MainView.kt

Slide 46

Slide 46 text

class MainActivity : AppCompatActivity(), MainView { var controller : MainController? = null override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) controller = MainController(this) } } MainActivity.kt class MainController(view: MainView) { val view = view } MainController.kt interface MainView { } MainView.kt

Slide 47

Slide 47 text

class MainActivity : AppCompatActivity(), MainView { lateinit var controller : MainController override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) controller = MainController(this) } } MainActivity.kt class MainController(view: MainView) { val view = view } MainController.kt interface MainView { } MainView.kt

Slide 48

Slide 48 text

MyFragment.kt class MyFragment : Fragment() { override fun onCreateView(inflater: LayoutInflater?, container: ViewGroup?, savedInstanceState: Bundle?): View? { val myView: View? = inflater?.inflate(R.layout.my_fragment_layout, container, false) return myView } }

Slide 49

Slide 49 text

MyFragment.kt class MyFragment : Fragment() { override fun onCreateView(inflater: LayoutInflater?, container: ViewGroup?, savedInstanceState: Bundle?): View? { val myView: View? = inflater?.inflate(R.layout.my_fragment_layout, container, false) return myView } } Extensions.kt fun ViewGroup.inflate(layoutId: Int, attachToRoot: Boolean = false): View { val inflater = LayoutInflater.from(context) return inflater.inflate(layoutId, this, attachToRoot) }

Slide 50

Slide 50 text

MyFragment.kt Extensions.kt fun ViewGroup.inflate(layoutId: Int, attachToRoot: Boolean = false): View { val inflater = LayoutInflater.from(context) return inflater.inflate(layoutId, this, attachToRoot) } class MyFragment : Fragment() { override fun onCreateView(inflater: LayoutInflater?, container: ViewGroup?, savedInstanceState: Bundle?): View? { val myView: View? = container?.inflate(R.layout.my_fragment_layout) return myView } }

Slide 51

Slide 51 text

MyFragment.kt class MyFragment : Fragment() { override fun onCreateView(inflater: LayoutInflater?, container: ViewGroup?, savedInstanceState: Bundle?): View? { val myView: View? = container?.inflate(R.layout.my_fragment_layout) return myView } override fun onViewCreated(view: View?, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) val txtMyName: TextView = view?.findViewById(R.id.txtMyName) as TextView txtMyName.text = "Carlos" } }

Slide 52

Slide 52 text

MyFragment.kt class MyFragment : Fragment() { override fun onCreateView(inflater: LayoutInflater?, container: ViewGroup?, savedInstanceState: Bundle?): View? { val myView: View? = container?.inflate(R.layout.my_fragment_layout) return myView } override fun onViewCreated(view: View?, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) txtMyName.text = "Carlos" } }

Slide 53

Slide 53 text

MyFragment.kt class MyFragment : Fragment() { override fun onCreateView(inflater: LayoutInflater?, container: ViewGroup?, savedInstanceState: Bundle?): View? { val myView: View? = container?.inflate(R.layout.my_fragment_layout) return myView } override fun onViewCreated(view: View?, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) txtMyName.text = "Carlos" } } import kotlinx.android.synthetic.main.my_fragment_layout.*

Slide 54

Slide 54 text

sealed class Posts { class Header(val title: String, val imageUrl: String) : Posts() class Reshare(val title: String, val imageUrl: String, val sourceUrl: String): Posts() class News(val title: String, val imageUrl: String, val body: String): Posts() } Posts.kt

Slide 55

Slide 55 text

class MyAdapter(val posts: MutableList) : RecyclerView.Adapter override fun getItemCount(): Int = posts.size override fun onBindViewHolder(holder: PostViewHolder?, position: Int) { val post = posts[position] holder?.bind(post) } override fun onCreateViewHolder(parent: ViewGroup?, viewType: Int): PostViewHolder { val itemView = parent?.inflate(R.layout.item_post) return PostViewHolder(itemView) } } MyAdapter.kt

Slide 56

Slide 56 text

class PostViewHolder(itemView: View?): RecyclerView.ViewHolder(itemView) { fun bind(post: Posts) { when(post){ is Header -> { itemView.txtHeader.text = post.title itemView.imgHeader.loadImage(post.imageUrl) } is Reshare -> { itemView.txtHeader.text = post.title itemView.imgHeader.loadImage(post.imageUrl) itemView.txtSource.text = post.sourceUrl } is News -> { itemView.txtHeader.text = post.title itemView.imgHeader.loadImage(post.imageUrl) itemView.txtBody.text = post.body } } }} PostViewHolder.kt sealed class Posts { class Header(val title: String, val imageUrl: String) : Posts() class Reshare(val title: String, val imageUrl: String, val sourceUrl: String): Posts() class News(val title: String, val imageUrl: String, val body: String): Posts() } Posts.kt

Slide 57

Slide 57 text

No content

Slide 58

Slide 58 text

Recursos

Slide 59

Slide 59 text

kotlinlang.org

Slide 60

Slide 60 text

developer.android.com/kotlin

Slide 61

Slide 61 text

Recursos • DevCode.la - Curso de Fundamentos de Kotlin http://devcode.la/cursos/kotlin • Kotlin Dev Reactor https://medium.com/kotlin-dev-reactor

Slide 62

Slide 62 text

Artículos • How we made Basecamp 3’s Android app 100% Kotlin Dan Kim (Android Programmer at BaseCamp) https://goo.gl/JnXp4C • Kotlin in Production: Should you stay or should you go? Danny Preussler (GDE Android) https://goo.gl/SqxzzF

Slide 63

Slide 63 text

Libros • Kotlin for Android Developers Autor: Antonio Leiva http://a.co/ctlomXs

Slide 64

Slide 64 text

Libros • Kotlin in Action Autor: Dmitry Jemerov / Svetlana Isakova http://a.co/bP4fpLc

Slide 65

Slide 65 text

/DevPicon