Slide 1

Slide 1 text

Kotlin for Android Developers Antonio Leiva @lime_cl

Slide 2

Slide 2 text

http://plex.tv

Slide 3

Slide 3 text

http://antonioleiva.com

Slide 4

Slide 4 text

No content

Slide 5

Slide 5 text

Kotlin features

Slide 6

Slide 6 text

What is Kotlin? • JVM based • Object-oriented functional language • Created by JetBrains (IntelliJ, Android Studio) • Simple,lightweight, interoperable

Slide 7

Slide 7 text

Kotlin features Title Text Null safety

Slide 8

Slide 8 text

Null safety Artist artist = null;
 artist.print(); JAVA Null Pointer Exception

Slide 9

Slide 9 text

Null safety KOTLIN var artist: Artist? = null
 artist.print() var artist: Artist? = null
 artist?.print() won´t compile will do nothing if (artist != null) {
 artist.print()
 } Smart cast var artist: Artist? = null
 artist!!.print() will crash

Slide 10

Slide 10 text

Kotlin features Title Text Properties

Slide 11

Slide 11 text

Properties private String field = “”;
 
 public String getField() {
 return field;
 }
 
 public void setField(String field) {
 this.field = field;
 } JAVA

Slide 12

Slide 12 text

Properties var property: String = "" KOTLIN

Slide 13

Slide 13 text

Properties var property: String = ""
 get(){
 return "property is $field"
 }
 set(value: String){
 if (value != "")
 field = value
 }

Slide 14

Slide 14 text

Kotlin features Title Text Data Classes

Slide 15

Slide 15 text

Data Classes public class Artist {
 private long id;
 private String name;
 private String url;
 private String mbid;
 
 public long getId() {
 return id;
 }
 
 public void setId(long id) {
 this.id = id;
 }
 
 public String getName() {
 return name;
 }
 
 public void setName(String name) {
 this.name = name;
 }
 
 public String getUrl() {
 return url;
 }
 
 public void setUrl(String url) {
 this.url = url;
 }
 
 public String getMbid() {
 return mbid;
 }
 
 public void setMbid(String mbid) {
 this.mbid = mbid;
 }
 
 @Override public String toString() {
 return "Artist{" +
 "id=" + id +
 ", name='" + name + '\'' +
 ", url='" + url + '\'' +
 ", mbid='" + mbid + '\'' +
 '}';
 }
 }
 JAVA

Slide 16

Slide 16 text

Data Classes data class Artist(
 var id: Long,
 var name: String,
 var url: String,
 var mbid: String) KOTLIN

Slide 17

Slide 17 text

Kotlin is functional

Slide 18

Slide 18 text

Kotlin is functional (kind of)

Slide 19

Slide 19 text

Kotlin is functional Lambdas

Slide 20

Slide 20 text

Lambdas function: (T) -> R

Slide 21

Slide 21 text

Lambdas public interface Callback {
 void invoke(T result);
 }
 
 public void asyncOperation(int value, Callback callback){
 ...
 callback.invoke(true);
 } JAVA asyncOperation(5, new Callback() {
 @Override public void invoke(Boolean result) {
 System.out.println("Result: " + result);
 }
 });

Slide 22

Slide 22 text

Lambdas fun asyncOperation(value: Int, callback: (Boolean) -> Unit) {
 ...
 callback(true)
 } asyncOperation(5) { result ->
 println("result: $result")
 }

Slide 23

Slide 23 text

Lambdas fun asyncOperation(value: Int, callback: (Boolean) -> Unit) {
 ...
 callback(true)
 } asyncOperation(5) { result ->
 println("result: $result")
 } asyncOperation(5) { println("result: $it") }

Slide 24

Slide 24 text

Lambdas asyncOperation(5) { println("result: $it") } asyncOperation(5, new Callback() {
 @Override public void invoke(Boolean result) {
 System.out.println("Result: " + result);
 }
 });

Slide 25

Slide 25 text

Kotlin is functional Collections

Slide 26

Slide 26 text

Collections • Iterable • Collection • List • Set • Map filter sort map zip dropWhile first firstOrNull last lastOrNull fold …

Slide 27

Slide 27 text

Collections parsedContacts .filter { it.name != null && it.image != null }
 .sortedBy { it.name }
 .map { Contact(it.id, it.name!!, it.image!!) }

Slide 28

Slide 28 text

Kotlin is functional Extending language

Slide 29

Slide 29 text

Extending language inline fun supportsLollipop(code:() -> Unit) {
 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP){
 code.invoke()
 }
 } supportsLollipop {
 getWindow().setStatusBarColor(Color.BLACK)
 }

Slide 30

Slide 30 text

More awesome features!

Slide 31

Slide 31 text

More awesome features! Extension functions

Slide 32

Slide 32 text

Extension functions fun Context.toast(message: CharSequence){
 Toast.makeText(this, message, duration).show()
 }

Slide 33

Slide 33 text

Extension functions fun Context.toast(message: CharSequence){
 Toast.makeText(this, message, duration).show()
 } context.toast("I'm a context")
 activity.toast("I'm an activity")
 service.toast("I'm a service")

Slide 34

Slide 34 text

Extension functions fun Long.toDateString(dateFormat: Int = DateFormat.MEDIUM): String {
 val df = DateFormat.getDateInstance(dateFormat, Locale.getDefault())
 return df.format(this)
 }

Slide 35

Slide 35 text

More awesome features! Default arguments

Slide 36

Slide 36 text

Default arguments fun Long.toDateString(dateFormat: Int = DateFormat.MEDIUM): String {
 val df = DateFormat.getDateInstance(dateFormat, Locale.getDefault())
 return df.format(this)
 }

Slide 37

Slide 37 text

Default arguments fun Long.toDateString(dateFormat: Int = DateFormat.MEDIUM): String {
 val df = DateFormat.getDateInstance(dateFormat, Locale.getDefault())
 return df.format(this)
 } dateLong.toDateString()
 dateLong.toDateString(DateFormat.FULL)

Slide 38

Slide 38 text

Default arguments fun Activity.toast(message: CharSequence, duration: Int = Toast.LENGTH_SHORT){
 Toast.makeText(this, message, duration).show()
 } toast(“Short Toast!!”) toast("Long Toast!!", Toast.LENGTH_LONG)

Slide 39

Slide 39 text

More awesome features! Interfaces

Slide 40

Slide 40 text

Interfaces • Can contain code (but not state) interface ToolbarManager {
 
 val toolbar: Toolbar
 
 fun initToolbar() {
 toolbar.inflateMenu(R.menu.menu_main)
 toolbar.setOnMenuItemClickListener {
 when (it.itemId) {
 R.id.action_settings -> App.instance.toast("Settings")
 else -> App.instance.toast("Unknown option")
 }
 true
 }
 }
 }

Slide 41

Slide 41 text

Interfaces class MainActivity : AppCompatActivity(), ToolbarManager {
 
 override val toolbar by lazy { find(R.id.toolbar) }
 
 override fun onCreate(savedInstanceState: Bundle?) {
 super.onCreate(savedInstanceState)
 setContentView(R.layout.activity_main)
 initToolbar()
 ...
 }
 }


Slide 42

Slide 42 text

More awesome features! Property delegation

Slide 43

Slide 43 text

Property delegation val toolbar by lazy { find(R.id.toolbar) } • Lazy var p by Delegates.observable("") { d, old, new -> db.saveChanges(this, new) } • Observable • Not Null • Vetoable • Values from map • Custom

Slide 44

Slide 44 text

More awesome features! Flow control

Slide 45

Slide 45 text

Flow control • If • When • For • While

Slide 46

Slide 46 text

Flow control • If val z = if (condition) x else y

Slide 47

Slide 47 text

Flow control • When val cost = when(x) {
 in 1..10 -> "cheap"
 in 10..100 -> "regular"
 in 100..1000 -> "expensive"
 in specialValues -> "special value!"
 else -> "not rated"
 }

Slide 48

Slide 48 text

Flow control • When val res = when {
 x in 1..10 -> "cheap"
 s.contains("hello") -> "it's a welcome!"
 v is ViewGroup -> "child count: ${v.getChildCount()}"
 else -> ""
 }

Slide 49

Slide 49 text

More awesome features! Title Text Interoperability

Slide 50

Slide 50 text

Interoperability Palette.generateAsync(bitmap, new Palette.PaletteAsyncListener() {
 @Override public void onGenerated(Palette palette) {
 …
 }
 }); JAVA

Slide 51

Slide 51 text

Interoperability Palette.generateAsync(bitmap, new Palette.PaletteAsyncListener() {
 @Override public void onGenerated(Palette palette) {
 …
 }
 }); Palette.generateAsync(bitmap) { palette ->
 …
 } JAVA KOTLIN

Slide 52

Slide 52 text

Interoperability view.setOnClickListener(object : View.OnClickListener{
 override fun onClick(v: View) {
 toast("Click")
 }
 }) Regular anonymous class (similar to Java)

Slide 53

Slide 53 text

Interoperability If interface only has a function, substitute by function view.setOnClickListener({ view ->
 toast("Click")
 })

Slide 54

Slide 54 text

Interoperability view.setOnClickListener({
 toast("Click")
 }) If interface only has a function, substitute by function view.setOnClickListener({ view ->
 toast("Click")
 })

Slide 55

Slide 55 text

Interoperability view.setOnClickListener() {
 toast("Click")
 } If last parameter is a function, can go out of parenthesis

Slide 56

Slide 56 text

Interoperability view.setOnClickListener() {
 toast("Click")
 } If last parameter is a function, can go out of parenthesis view.setOnClickListener {
 toast("Click")
 }

Slide 57

Slide 57 text

Interoperability view.setOnClickListener(object : View.OnClickListener{
 override fun onClick(v: View) {
 toast("Click")
 }
 }) view.setOnClickListener { toast("Click") }

Slide 58

Slide 58 text

Interoperability Getter (+Setter) -> Property supportActionBar.title = title
 textView.text = title contactsList.adapter = ContactsAdapter()

Slide 59

Slide 59 text

Kotlin Android Extensions

Slide 60

Slide 60 text

Kotlin Android Extensions Direct access to XML views using its id as property name main.xml 
 
 
 


Slide 61

Slide 61 text

Kotlin Android Extensions Import synthetic properties import kotlinx.android.synthetic.main.* Use the properties override fun onCreate(savedInstanceState: Bundle?) {
 super.onCreate(savedInstanceState) setContentView(R.id.main)
 frameLayout.setVisibility(View.VISIBLE)
 welcomeText.setText("I´m a welcome text!!")
 }

Slide 62

Slide 62 text

Anko

Slide 63

Slide 63 text

Anko UI declaration DSL

Slide 64

Slide 64 text

UI declaration DSL verticalLayout {
 val name = editText()
 button("Say Hello") {
 onClick { toast("Hello, ${name.text}!") }
 }
 }

Slide 65

Slide 65 text

Anko Useful extensions

Slide 66

Slide 66 text

Useful extensions startActivity("id" to res.id, "name" to res.name) Start an activity Access to system services context.layoutInflater context.notificationManager
 context.sensorManager
 context.vibrator

Slide 67

Slide 67 text

Useful extensions Toasts and Alert dialogs toast(R.string.message)
 longToast("Wow, such a duration")
 
 alert("Yes /no Alert") {
 positiveButton("Yes") { submit() }
 negativeButton("No") {}
 }.show()

Slide 68

Slide 68 text

Anko Easy asynchrony

Slide 69

Slide 69 text

Easy asynchrony async {
 val result = longRequest()
 uiThread { bindForecast(result) }
 }

Slide 70

Slide 70 text

Anko SQLite helpers

Slide 71

Slide 71 text

SQLite helpers ManagedSQLiteOpenHelper dbHelper.use {
 select("TABLE_NAME").where("_id = {id}", "id" to 20)
 } db.createTable("TABLE_NAME", true,
 "_id" to INTEGER + PRIMARY_KEY,
 "name" to TEXT) parseList / parseOpt / classParser…

Slide 72

Slide 72 text

Conclusion

Slide 73

Slide 73 text

Conclusion • Lightweight, simple and powerful • Simplifies Android Development • Version 1.0 -> soon!

Slide 74

Slide 74 text

http://antonioleiva.com/book/ Kotlin for Android Developers • Create App from scratch • Step by step • Complete Kotlin coverage • Updated to latest version

Slide 75

Slide 75 text

http://antonioleiva.com/book/ ?