A series of 3 events for building apps with Kotlin on Android.
Introduction to Kotlin, a modern language, developed by JetBrains (those who developed the IDE on which is based Android Studio) that compared to Java is more concise, versatile and with better error handling. The code is 100% interoperable with Java, and can be used to write native Android apps or small component.
4. dummy/HeroAdapter.java
public 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)
5. Previously on Android & Kotlin #01: goo.gl/0jHLmE
Properties
val a: Int = 1 // val = READ ONLY (getter)
var b: Int = 1 // var = READ/WRITE (getter/setter)
String templates
"My name is $name $surname"
Lambdas
view.setOnClickListener { Log.d("TAG", "Item clicked!") }
Delegated properties (example: lazy)
val item by lazy { MyItem() }
6. // val = READ ONLY (getter)
// var = READ/WRITE (getter/setter)
val onlyRead = 1
var writable = 2
var nullable: Int? = 3
fun test() {
onlyRead = 3 // Error at compile time
writable = 3
writable = "test" // Error at compile time
writable = null // Error at compile time
nullable = null
}
// Customize getter/setter
val p1: Int = 1
get() {
// add some logic
return field
}
var p2: Int = 2
get() {
return field
}
set(value) {
// add some logic
field = value
}
Properties // More examples
7. var name = "Omar"
fun test() {
var str: String
str = "My name is $name"
str = "My name is $name (${name.length} chars)"
str = "$name == ${name}"
str = "$name.length != ${name.length}" // IS NOT THE SAME
str = "Time is: ${System.currentTimeMillis()}ms since 1970"
}
String templates // More examples
8. "qwerty | 123 | abc".filter { char ->
char.isDigit() // return is implicit in lambda expressions
}
"qwerty | 123 | abc".filter {
it.isDigit() // we can use "it" with 1 parameter
}
"qwerty | 123 | abc".filterIndexed { index: Int, c: Char ->
index > 3 && c.isLetterOrDigit()
}
Lambdas // More examples
9. val startTime by lazy { System.currentTimeMillis() }
var test by Delegates.observable(3) {
prop, old, new ->
if (new > old) Log.w("TEST", "$new > $old")
}
fun test() {
startTime
test = 5
test = 1
test = 2
val finish = System.currentTimeMillis() - startTime
}
Delegated properties // More examples
10. Previously on Android & Kotlin #02: goo.gl/h3uG8M
Null safety
var a: String = null // Error at compile time
var b: String? = null
Elvis Operator
val example: String = b ?: "Default" // b may be null
Smart-cast
if (myView is TextView) { myView.setText("Ciao") }
Collections
listOf("Android", "iOS", null).filterNotNull().map { it.toUpperCase() }
11. var test: String? = null
fun test() {
test = "new string"
test.length // Error at compile time
test?.length // if (test != null) test.length else null
test!!.length // test MUST exist or throw NullPointerException
val len = test?.length ?: 0 // default value = 0
test?.length ?: throw IllegalStateException("Missing the main string!")
}
Null safety & Elvis Operator // More examples
12. var test: Any? = "My new value"
fun test() {
val _test: Any? = test
if (_test != null) {
val checkEqual =
_test.equals("My new value")
if (_test is String) {
val checkLen = _test.length
_test.capitalize()
_test.substring(1)
}
}
when (_test) {
is Int -> {
val sum = _test + 1
}
is String -> {
val len = _test.length
}
}
}
Smart-cast // More examples
19. class Hero(val power: Int) class Hero {
private final int power;
public Hero(int power) {
this.power = power;
}
}
#10 Kotlin - Infix Notation
http://kotlinlang.org/docs/reference/functions.html#infix-notation
vs
20. class Hero(val power: Int) {
infix fun vs(opponent: Hero): Hero {
return if (power > opponent.power) {
this
} else {
opponent
}
}
}
#10 Kotlin - Infix Notation
http://kotlinlang.org/docs/reference/functions.html#infix-notation
vs
21. class Hero(val power: Int) {
infix fun vs(opponent: Hero): Hero {
return if (power > opponent.power) {
this
} else {
opponent
}
}
}
fun example() {
val thor = Hero(7)
val ironman = Hero(8)
val spiderman = Hero(4)
}
// Skip Java version of Hero class,
// we use Kotlin class
class MyJavaClass {
void example() {
Hero thor = new Hero(7);
Hero ironman = new Hero(8);
Hero spiderman = new Hero(4);
}
}
#10 Kotlin - Infix Notation
http://kotlinlang.org/docs/reference/functions.html#infix-notation
vs
22. class Hero(val power: Int) {
infix fun vs(opponent: Hero): Hero {
return if (power > opponent.power) {
this
} else {
opponent
}
}
}
fun example() {
val thor = Hero(7)
val ironman = Hero(8)
val spiderman = Hero(4)
val theBest = thor vs ironman vs spiderman
}
// Skip Java version of Hero class,
// we use Kotlin class
class MyJavaClass {
void example() {
Hero thor = new Hero(7);
Hero ironman = new Hero(8);
Hero spiderman = new Hero(4);
Hero theBest =
thor.vs(ironman).vs(spiderman);
}
}
#10 Kotlin - Infix Notation
http://kotlinlang.org/docs/reference/functions.html#infix-notation
vs
23. class Hero(val power: Int) {
infix fun vs(opponent: Hero): Hero {
return if (power > opponent.power) {
this
} else {
opponent
}
}
}
fun example() {
val thor = Hero(7)
val ironman = Hero(8)
val spiderman = Hero(4)
val theBest = thor vs ironman vs spiderman
}
// Skip Java version of Hero class,
// we use Kotlin class
class MyJavaClass {
void example() {
Hero thor = new Hero(7);
Hero ironman = new Hero(8);
Hero spiderman = new Hero(4);
Hero theBest =
thor.vs(ironman).vs(spiderman);
}
}
#10 Kotlin - Infix Notation
http://kotlinlang.org/docs/reference/functions.html#infix-notation
vs
24. class Male(val eyes: String)
class Female(val hair: String)
class Male {
private String eyes;
public Male(String eyes) {
this.eyes = eyes;
}
}
class Female {
private String hair;
public Female(String hair) {
this.hair = hair;
}
}
#11 Kotlin - Operator Overloading
http://kotlinlang.org/docs/reference/operator-overloading.html
vs
25. class Male(val eyes: String)
class Female(val hair: String)
class Baby(val eyes: String, val hair: String)
// Skip Java version of Male, Female and Baby
// class, there is not enough space!
#11 Kotlin - Operator Overloading
http://kotlinlang.org/docs/reference/operator-overloading.html
vs
26. class Male(val eyes: String) {
operator fun plus(her: Female): Baby {
return Baby(this.eyes, her.hair)
}
}
class Female(val hair: String)
class Baby(val eyes: String, val hair: String)
// Skip Java version of Male, Female and Baby
// class, there is not enough space!
#11 Kotlin - Operator Overloading
http://kotlinlang.org/docs/reference/operator-overloading.html
vs
27. class Male(val eyes: String) {
operator fun plus(her: Female): Baby {
return Baby(this.eyes, her.hair)
}
}
class Female(val hair: String)
class Baby(val eyes: String, val hair: String)
fun example() {
val myBaby = Male("green") + Female("blond")
}
// Skip Java version of Male, Female and Baby
// class, there is not enough space!
class MyJavaClass {
void example() {
Baby myBaby = new Male("green").plus(
new Female("blond"));
}
}
#11 Kotlin - Operator Overloading
http://kotlinlang.org/docs/reference/operator-overloading.html
vs
28. class Male(val eyes: String) {
operator fun plus(her: Female): Baby {
return Baby(this.eyes, her.hair)
}
}
class Female(val hair: String)
class Baby(val eyes: String, val hair: String)
fun example() {
val myBaby = Male("green") + Female("blond")
}
// Skip Java version of Male, Female and Baby
// class, there is not enough space!
class MyJavaClass {
void example() {
Baby myBaby =
new Male("green").plus(new Female("blond"));
}
}
#11 Kotlin - Operator Overloading
http://kotlinlang.org/docs/reference/operator-overloading.html
vs
30. Extensions // More examples (1)
fun String.encodeUrl(charsetName: String = "UTF-8") = URLEncoder.encode(this, charsetName)
fun String.isValidEmail() = Patterns.EMAIL_ADDRESS.matcher(this).matches()
// INFO: https://en.wikipedia.org/wiki/Non-breaking_space
fun String.useNonBreakingSpace() = replace(' ', 'u00A0')
// http://developer.android.com/reference/android/content/Intent.html#ACTION_VIEW
fun Uri.viewIntent() = Intent(Intent.ACTION_VIEW).setData(this)
fun <T : View> T.onClick(onClick: (T) -> Unit) = setOnClickListener(onClick as (View) -> Unit)
fun View.postDelayed(delayMillis: Long, action: () -> Unit) = postDelayed(action, delayMillis)
val EditText.string: String
get() = text.toString()
31. Extensions // More examples (2)
fun View.hideSoftInput() {
val imm = context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
imm.hideSoftInputFromWindow(windowToken, 0)
}
/**
* Kotlin version of method Utils.isViewInBounds(container, view) by Alex Lockwood
* URL: https://github.com/alexjlockwood/activity-
transitions/blob/c4fa3a21c941691fb6bbe53e37cf3965842ee254/app/src/main/java/com/alexjlockwood/activity/transi
tions/Utils.java
*
* Returns true if {@param view} is contained within {@param container}'s bounds.
*/
fun View.isInBounds(container: View): Boolean {
val containerBounds = Rect()
container.getHitRect(containerBounds)
return getLocalVisibleRect(containerBounds)
}
32. Extensions + Infix Notation // More examples
infix fun String?.orNotNull(defaultValue: String): String =
if (!this.isNullOrBlank()) this!! else defaultValue
infix fun String?.or(defaultValue: String?): String? =
if (!this.isNullOrBlank()) this else defaultValue
// val a: String? = null
// val b: String? = null
// val c: String? = "test"
// val myText = a or b or c orNotNull "default"
33. Extensions + Operator Overloading // More examples
operator fun StringBuilder.plusAssign(s: String) { appendln(s) }
// val sb = StringBuilder()
// sb += "test"
// sb += "test2"
34. Questions?
Developers playground - #EX3
- In KotlinExample use: Extensions, Infix Notation, Operator Overloading
Start with: https://github.com/jacklt/KotlinExample/tree/ex2
Solution: https://github.com/jacklt/KotlinExample/tree/ex3 (at some point maybe …) :P