Mi Camino hacia
Kotlin
#kotlinstgo
Armando Picón
@devpicon
Slide 2
Slide 2 text
/DevPicon
Armando Picón
Android Developer at CornerShop
https://www.linkedin.com/in/armandopicon/
¿Quién soy?
Slide 3
Slide 3 text
¿Qué es Kotlin?
● Lenguaje de programación
● Desarrollo por JetBrains
● Busca superar las limitaciones de Java
● Su desarrollo llevó 6 años, antes de la versión 1.0
Slide 4
Slide 4 text
Hitos
2010 - Kotlin Hello World
Febrero 2016 - Kotlin 1.0
Marzo 2017 - Kotlin 1.1
Mayo 2017 - Android soportará Kotlin
Slide 5
Slide 5 text
¿Por qué usar Kotlin?
● Interoperabilidad con Java
● Null safety
● Functional programming features
● Ligero
● Poca curva de aprendizaje
● Open Source
¿Qué necesito?
● Android Studio 2.x y Plugin de Kotlin para IntelliJ IDEA
● Android Studio 3.x
Slide 12
Slide 12 text
...show me the code!!
Slide 13
Slide 13 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 14
Slide 14 text
class Person(name: String, age: Int){
val name = name
var age = age
}
Person.kt
Slide 15
Slide 15 text
class Person(val name: String, var age: Int)
Person.k
t
Slide 16
Slide 16 text
data class Person(val name: String, var age: Int)
Person.k
t
Slide 17
Slide 17 text
Data class
•Accessors (getters & setters)
•Equal / HashCode
•toString
•copy
Slide 18
Slide 18 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 19
Slide 19 text
val people = listOf(
Person("Armando", 36),
Person("Ronald", 24),
Person("Alberto", 58))
val person = people.find { it.name == "Ronald" }
return person
Slide 20
Slide 20 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 21
Slide 21 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.jav
a
Slide 22
Slide 22 text
Utilities.k
t
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 23
Slide 23 text
Utilities.k
t
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 24
Slide 24 text
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}
MainActivity.jav
a
Slide 25
Slide 25 text
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
}
}
MainActivity.k
t
Slide 26
Slide 26 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.k
t
Slide 27
Slide 27 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.k
t
Slide 28
Slide 28 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.k
t
import kotlinx.android.synthetic.main.activity_main.*
Slide 29
Slide 29 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.k
t
import kotlinx.android.synthetic.main.activity_main.*
Slide 30
Slide 30 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.k
t
Slide 31
Slide 31 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.k
t
Extensions.k
t
Slide 32
Slide 32 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.k
t
Extensions.k
t
Slide 33
Slide 33 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.k
t
Extensions.k
t
Slide 34
Slide 34 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.k
t
Slide 35
Slide 35 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.k
t
class MainController(view: MainView) {
val view = view
}
MainController.k
t
Slide 36
Slide 36 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.k
t
class MainController(view: MainView) {
val view = view
}
MainController.k
t
Slide 37
Slide 37 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.k
t
class MainController(view: MainView) {
val view = view
}
MainController.k
t
interface MainView {
}
MainView.k
t
Slide 38
Slide 38 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.k
t
class MainController(view: MainView) {
val view = view
}
MainController.k
t
interface MainView {
}
MainView.k
t
Slide 39
Slide 39 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.k
t
class MainController(view: MainView) {
val view = view
}
MainController.k
t
interface MainView {
}
MainView.k
t
Slide 40
Slide 40 text
MyFragment.k
t
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 41
Slide 41 text
MyFragment.k
t
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.k
t
fun ViewGroup.inflate(layoutId: Int, attachToRoot: Boolean = false): View {
val inflater = LayoutInflater.from(context)
return inflater.inflate(layoutId, this, attachToRoot)
}
Slide 42
Slide 42 text
MyFragment.k
t
Extensions.k
t
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 43
Slide 43 text
MyFragment.k
t
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 44
Slide 44 text
MyFragment.k
t
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 45
Slide 45 text
MyFragment.k
t
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 46
Slide 46 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.k
t
Slide 47
Slide 47 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.k
t
Slide 48
Slide 48 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.k
t
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.k
t