#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
¿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