[go: up one dir, main page]

0% found this document useful (0 votes)
44 views650 pages

Android HUST

Lesson 1 covers the basics of Kotlin, including getting started with project setup, operators, data types, variables, conditionals, lists, arrays, and null safety. It emphasizes Kotlin's features such as type inference, immutability, and safe handling of null values. The lesson provides practical examples and explanations to help learners understand the foundational concepts of Kotlin programming.

Uploaded by

Hoang Nguyen Huy
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
44 views650 pages

Android HUST

Lesson 1 covers the basics of Kotlin, including getting started with project setup, operators, data types, variables, conditionals, lists, arrays, and null safety. It emphasizes Kotlin's features such as type inference, immutability, and safe handling of null values. The lesson provides practical examples and explanations to help learners understand the foundational concepts of Kotlin programming.

Uploaded by

Hoang Nguyen Huy
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 650

Lesson 1:

Kotlin basics

Android Development with Kotlin v1.0 This work is licensed under the Apache 2 license. 1
About this lesson
Lesson 1: Kotlin basics
○ Get started
○ Operators
○ Data types
○ Variables
○ Conditionals
○ Lists and arrays
○ Null safety
○ Summary
Android Development with Kotlin This work is licensed under the Apache 2 license. 2
Get started

Android Development with Kotlin This work is licensed under the Apache 2 license. 3
Open IntelliJ IDEA

Android Development with Kotlin This work is licensed under the Apache 2 license. 4
Create a new project

Android Development with Kotlin This work is licensed under the Apache 2 license. 5
Name the project

Android Development with Kotlin This work is licensed under the Apache 2 license. 6
Open REPL (Read-Eval-Print-Loop)

It may take a few


moments before
the Kotlin menu
appears under
Tools.
Android Development with Kotlin This work is licensed under the Apache 2 license. 7
Create a printHello() function

Press
Control+Enter
(Command+Enter
on a Mac) to
execute.

Android Development with Kotlin This work is licensed under the Apache 2 license. 8
Operators

Android Development with Kotlin This work is licensed under the Apache 2 license. 9
Operators
● Mathematical operators + - * / %

● Increment and decrement operators ++ --


< <= > >=
● Comparison operators

● Assignment operator =

● Equality operators == !=

Android Development with Kotlin This work is licensed under the Apache 2 license. 10
Math operators with integers
1 + 1 => 2

53 - 3 => 50

50 / 10 => 5

9 % 3 => 0

Android Development with Kotlin This work is licensed under the Apache 2 license. 11
Math operators with doubles

1.0 / 2.0 => 0.5

2.0 * 3.5 => 7.0

Android Development with Kotlin This work is licensed under the Apache 2 license. 12
Math operators

1+1 1.0/2.0
⇒ kotlin.Int = 2 ⇒ kotlin.Double = 0.5

53-3 2.0*3.5 ⇒ indicates output


⇒ kotlin.Int = 50 ⇒ kotlin.Double = 7.0 from your code.

Result includes the


50/10 type
⇒ kotlin.Int = 5 (kotlin.Int).

Android Development with Kotlin This work is licensed under the Apache 2 license. 13
Numeric operator methods
Kotlin keeps numbers as primitives, but lets you call methods on
numbers as if they were objects.

2.times(3)
⇒ kotlin.Int = 6

3.5.plus(4)
⇒ kotlin.Double = 7.5

2.4.div(2)
⇒ kotlin.Double = 1.2

Android Development with Kotlin This work is licensed under the Apache 2 license. 14
Data types

Android Development with Kotlin This work is licensed under the Apache 2 license. 15
Integer types
Type Bits Notes

Long 64 From -263 to 263-1

Int 32 From -231 to 231-1

Short 16 From -32768 to 32767

Byte 8 From -128 to 127

Android Development with Kotlin This work is licensed under the Apache 2 license. 16
Floating-point and other numeric
types
Type Bits Notes

Double 64 16 - 17 significant digits

Float 32 6 - 7 significant digits

Char 16 16-bit Unicode character

Boolean 8 True or false. Operations include:


|| - lazy disjunction, && - lazy conjunction,
! - negation

Android Development with Kotlin This work is licensed under the Apache 2 license. 17
Operand types
Results of operations keep the types of the operands

6*50 1/2
⇒ kotlin.Int = 300 ⇒ kotlin.Int = 0

6.0*50.0 1.0*2.0
⇒ kotlin.Double = 300.0 ⇒ kotlin.Double = 0.5

6.0*50
⇒ kotlin.Double = 300.0

Android Development with Kotlin This work is licensed under the Apache 2 license. 18
Type casting
Assign an Int to a Byte
val i: Int = 6
val b: Byte = i
println(b)

⇒ error: type mismatch: inferred type is Int but Byte was expected
Convert Int to Byte with casting
val i: Int = 6
println(i.toByte())

⇒ 6

Android Development with Kotlin This work is licensed under the Apache 2 license. 19
Underscores for long numbers

Use underscores to make long numeric constants more readable.

val oneMillion = 1_000_000

val idNumber = 999_99_9999L

val hexBytes = 0xFF_EC_DE_5E

val bytes = 0b11010010_01101001_10010100_10010010

Android Development with Kotlin This work is licensed under the Apache 2 license. 20
Strings

Strings are any sequence of characters enclosed by double quotes.


val s1 = "Hello world!"

String literals can contain escape characters


val s2 = "Hello world!\n"

Or any arbitrary text delimited by a triple quote (""")


val text = """
var bikes = 50
"""

Android Development with Kotlin This work is licensed under the Apache 2 license. 21
String concatenation

val numberOfDogs = 3
val numberOfCats = 2

"I have $numberOfDogs dogs" + " and $numberOfCats cats"

=> I have 3 dogs and 2 cats

Android Development with Kotlin This work is licensed under the Apache 2 license. 22
String templates
A template expression starts with a dollar sign ($) and can be a simple value:

val i = 10
println("i = $i")
=> i = 10

Or an expression inside curly braces:

val s = "abc"
println("$s.length is ${s.length}")
=> abc.length is 3
Android Development with Kotlin This work is licensed under the Apache 2 license. 23
String template expressions

val numberOfShirts = 10
val numberOfPants = 5

"I have ${numberOfShirts + numberOfPants} items of clothing"

=> I have 15 items of clothing

Android Development with Kotlin This work is licensed under the Apache 2 license. 24
Variables

Android Development with Kotlin This work is licensed under the Apache 2 license. 25
Variables
● Powerful type inference
● Let the compiler infer the type
● You can explicitly declare the type if
neededand immutable variables
● Mutable
● Immutability not enforced, but
recommended
Kotlin is a statically-typed language. The type is resolved at compile time
and never changes.

Android Development with Kotlin This work is licensed under the Apache 2 license. 26
Specifying the variable type

Colon Notation
var width: Int = 12
var length: Double = 2.5

Important: Once a type has been assigned by you or the compiler, you
can't change the type or you get an error.

Android Development with Kotlin This work is licensed under the Apache 2 license. 27
Mutable and immutable variables
● Mutable (Changeable)

var score = 10

● Immutable (Unchangeable)

val name = "Jennifer"

Although not strictly enforced, using immutable variables is


recommended in most cases.

Android Development with Kotlin This work is licensed under the Apache 2 license. 28
var and val

var count = 1
count = 2

val size = 1
size = 2

=> Error: val cannot be reassigned

Android Development with Kotlin This work is licensed under the Apache 2 license. 29
Conditionals

Android Development with Kotlin This work is licensed under the Apache 2 license. 30
Control flow

Kotlin features several ways to implement conditional logic:

● If/Else statements
● When statements
● For loops
● While loops

Android Development with Kotlin This work is licensed under the Apache 2 license. 31
if/else statements
val numberOfCups = 30
val numberOfPlates = 50

if (numberOfCups > numberOfPlates) {


println("Too many cups!")
} else {
println("Not enough cups!")
}
=> Not enough cups!

Android Development with Kotlin This work is licensed under the Apache 2 license. 32
if statement with multiple cases
val guests = 30
if (guests == 0) {
println("No guests")
} else if (guests < 20) {
println("Small group of people")
} else {
println("Large group of people!")
}
⇒ Large group of people!

Android Development with Kotlin This work is licensed under the Apache 2 license. 33
Ranges

● Data type containing a span of comparable values (e.g.,


integers from 1 to 100 inclusive)
● Ranges are bounded
● Objects within a range can be mutable or immutable

Android Development with Kotlin This work is licensed under the Apache 2 license. 34
Ranges in if/else statements

val numberOfStudents = 50
if (numberOfStudents in 1..100) {
println(numberOfStudents)

}
=> 50

Note: There are no spaces around the "range to" operator (1..100)

Android Development with Kotlin This work is licensed under the Apache 2 license. 35
when statement
when (results) {
0 -> println("No results")
in 1..39 -> println("Got results!")
else -> println("That's a lot of results!")
}
⇒ That's a lot of results!

As well as a when statement, you can also define a when expression


that provides a return value.

Android Development with Kotlin This work is licensed under the Apache 2 license. 36
for loops

val pets = arrayOf("dog", "cat", "canary")


for (element in pets) {
print(element + " ")
}
⇒ dog cat canary

You don’t need to define an iterator variable and increment it for each
pass.

Android Development with Kotlin This work is licensed under the Apache 2 license. 37
for loops: elements and indexes

for ((index, element) in pets.withIndex()) {


println("Item at $index is $element\n")

}
⇒ Item at 0 is dog
Item at 1 is cat
Item at 2 is canary

Android Development with Kotlin This work is licensed under the Apache 2 license. 38
for loops: step sizes and ranges

for (i in 1..5) print(i)


⇒ 12345

for (i in 5 downTo 1) print(i)


⇒ 54321

for (i in 3..6 step 2) print(i)


⇒ 35

for (i in 'd'..'g') print (i)


⇒ defg

Android Development with Kotlin This work is licensed under the Apache 2 license. 39
while loops
var bicycles = 0
while (bicycles < 50) {
bicycles++
}
println("$bicycles bicycles in the bicycle rack\n")
⇒ 50 bicycles in the bicycle rack

do {
bicycles--
} while (bicycles > 50)
println("$bicycles bicycles in the bicycle rack\n")
⇒ 49 bicycles in the bicycle rack

Android Development with Kotlin This work is licensed under the Apache 2 license. 40
repeat loops

repeat(2) {
print("Hello!")
}
⇒ Hello!Hello!

Android Development with Kotlin This work is licensed under the Apache 2 license. 41
Lists and arrays

Android Development with Kotlin This work is licensed under the Apache 2 license. 42
Lists

● Lists are ordered collections of elements


● List elements can be accessed programmatically through
their indices
● Elements can occur more than once in a list

An example of a list is a sentence: it's a group of words, their order is


important, and they can repeat.

Android Development with Kotlin This work is licensed under the Apache 2 license. 43
Immutable list using listOf()

Declare a list using listOf() and print it out.

val instruments = listOf("trumpet", "piano", "violin")


println(instruments)
⇒ [trumpet, piano, violin]

Android Development with Kotlin This work is licensed under the Apache 2 license. 44
Mutable list using mutableListOf()

Lists can be changed using mutableListOf()

val myList = mutableListOf("trumpet", "piano", "violin")


myList.remove("violin")

⇒ kotlin.Boolean = true

With a list defined with val, you can't change which list the variable refers
to, but you can still change the contents of the list.

Android Development with Kotlin This work is licensed under the Apache 2 license. 45
Arrays

● Arrays store multiple items

● Array elements can be accessed programmatically


through their indices

● Array elements are mutable


● Array size is fixed

Android Development with Kotlin This work is licensed under the Apache 2 license. 46
Array using arrayOf()

An array of strings can be created using arrayOf()


val pets = arrayOf("dog", "cat", "canary")
println(java.util.Arrays.toString(pets))
⇒ [dog, cat, canary]

With an array defined with val, you can't change which array the variable
refers to, but you can still change the contents of the array.

Android Development with Kotlin This work is licensed under the Apache 2 license. 47
Arrays with mixed or single types

An array can contain different types.


val mix = arrayOf("hats", 2)

An array can also contain just one type (integers in this case).
val numbers = intArrayOf(1, 2, 3)

Android Development with Kotlin This work is licensed under the Apache 2 license. 48
Combining arrays

Use the + operator.


val numbers = intArrayOf(1,2,3)
val numbers2 = intArrayOf(4,5,6)
val combined = numbers2 + numbers
println(Arrays.toString(combined))

=> [4, 5, 6, 1, 2, 3]

Android Development with Kotlin This work is licensed under the Apache 2 license. 49
Null safety

Android Development with Kotlin This work is licensed under the Apache 2 license. 50
Null safety

● In Kotlin, variables cannot be null by default


● You can explicitly assign a variable to null using the safe
call operator
● Allow null-pointer exceptions using the !! operator
● You can test for null using the elvis (?:) operator

Android Development with Kotlin This work is licensed under the Apache 2 license. 51
Variables cannot be null

In Kotlin, null variables are not allowed by default.

Declare an Int and assign null to it.


var numberOfBooks: Int = null

⇒ error: null can not be a value of a non-null type Int

Android Development with Kotlin This work is licensed under the Apache 2 license. 52
Safe call operator

The safe call operator (?), after the type indicates that a variable can be
null.
Declare an Int? as nullable
var numberOfBooks: Int? = null

In general, do not set a variable to null as it may have unwanted


consequences.
Android Development with Kotlin This work is licensed under the Apache 2 license. 53
Testing for null
Check whether the numberOfBooks variable is not null. Then decrement
that variable.
var numberOfBooks = 6
if (numberOfBooks != null) {
numberOfBooks = numberOfBooks.dec()
}

Now look at the Kotlin way of writing it, using the safe call operator.
var numberOfBooks = 6
numberOfBooks = numberOfBooks?.dec()

Android Development with Kotlin This work is licensed under the Apache 2 license. 54
The !! operator
If you’re certain a variable won’t be null, use !! to force the variable into a
non-null type. Then you can call methods/properties on it.

val len = s!!.length

throws NullPointerException if s is null

Warning: Because !! will throw an exception, it should only be used


when it would be exceptional to hold a null value.

Android Development with Kotlin This work is licensed under the Apache 2 license. 55
Elvis operator

Chain null tests with the ?: operator.


numberOfBooks = numberOfBooks?.dec() ?: 0

The ?: operator is sometimes called the "Elvis operator," because it's like a
smiley on its side with a pompadour hairstyle, like Elvis Presley styled his hair.

Android Development with Kotlin This work is licensed under the Apache 2 license. 56
Summary

Android Development with Kotlin This work is licensed under the Apache 2 license. 57
Summary
In Lesson 1, you learned how to:

● Create an IntelliJ IDEA project, opening REPL, and execute a functi


on
● Use operators and numeric operator methods
● Use data types, type casting, strings, and string templates
● Use v
ariables and type inference, and mutable and immutable variable
s
● Use conditionals, control flow, and looping structures
● Use lists and arrays
Android Development with Kotlin This work is licensed under the Apache 2 license. 58
Pathway

Practice what you’ve learned by


completing the pathway:
Lesson 1: Kotlin basics

Android Development with Kotlin This work is licensed under the Apache 2 license. 59
Lesson 2:
Functions

Android Development with Kotlin v1.0 This work is licensed under the Apache 2 license. 1
About this lesson
Lesson 2: Functions
○ Programs in Kotlin
○ (Almost) Everything has a value
○ Functions in Kotlin
○ Compact functions
○ Lambdas and higher-order functions
○ List filters
○ Summary

Android Development with Kotlin This work is licensed under the Apache 2 license. 2
Programs in Kotlin

Android Development with Kotlin This work is licensed under the Apache 2 license. 3
Setting up
Before you can write code and run programs, you need to:

● Create a file in your project


● Create a main() function
● Pass arguments to main()(Optional)
● Use any passed arguments in function calls (Optional)
● Run your program

Android Development with Kotlin This work is licensed under the Apache 2 license. 4
Create a new Kotlin file
In IntelliJ IDEA's Project pane, under Hello World, right-click the src folder.
● Select New > Kotlin File/Class.
● Select File, name the file Hello, and press Enter.

Android Development with Kotlin This work is licensed under the Apache 2 license. 5
Create a Kotlin file
You should now see a file in the src folder called Hello.kt.

Android Development with Kotlin This work is licensed under the Apache 2 license. 6
Create a main() function
main() is the entry point for execution for a Kotlin program.

In the Hello.kt file:


fun main(args: Array<String>) {
println("Hello, world!")
}

The args in the main() function are optional.

Android Development with Kotlin This work is licensed under the Apache 2 license. 7
Run your Kotlin program
To run your program, click the Run icon ( ) to the left of the main() function.

IntelliJ IDEA runs the program, and displays the results in the console.

Android Development with Kotlin This work is licensed under the Apache 2 license. 8
Pass arguments to main()

Select Run > Edit Configurations to open the Run/Debug Configurations


window.

Android Development with Kotlin This work is licensed under the Apache 2 license. 9
Use arguments in main()

Use args[0] to access the first input argument passed to main().

fun main(args: Array<String>) {


println("Hello, ${args[0]}")
}

⇒ Hello, Kotlin!

Android Development with Kotlin This work is licensed under the Apache 2 license. 10
(Almost) Everything has a
value

Android Development with Kotlin This work is licensed under the Apache 2 license. 11
(Almost) Everything is an expression

In Kotlin, almost everything is an expression and has a value. Even an if


expression has a value.

val temperature = 20
val isHot = if (temperature > 40) true else false
println(isHot)
⇒ false

Android Development with Kotlin This work is licensed under the Apache 2 license. 12
Expression values

Sometimes, that value is kotlin.Unit.

val isUnit = println("This is an expression")


println(isUnit)

⇒ This is an expression
kotlin.Unit

Android Development with Kotlin This work is licensed under the Apache 2 license. 13
Functions in Kotlin

Android Development with Kotlin This work is licensed under the Apache 2 license. 14
About functions

● A block of code that performs a specific task

● Breaks a large program into smaller modular chunks

● Declared using the fun keyword

● Can take arguments with either named or default values

15
Android Development with Kotlin This work is licensed under the Apache 2 license.
Parts of a function

Earlier, you created a simple function that printed "Hello World".

fun printHello() {
println("Hello World")
}

printHello()

Android Development with Kotlin This work is licensed under the Apache 2 license. 16
Unit returning functions

If a function does not return any useful value, its return type is Unit.

fun printHello(name: String?): Unit {


println("Hi there!")
}

Unit is a type with only one value: Unit.

Android Development with Kotlin This work is licensed under the Apache 2 license. 17
Unit returning functions
The Unit return type declaration is optional.
fun printHello(name: String?): Unit {
println("Hi there!")
}

is equivalent to:
fun printHello(name: String?) {
println("Hi there!")
}

Android Development with Kotlin This work is licensed under the Apache 2 license. 18
Function arguments

Functions may have:


● Default parameters
● Required parameters
● Named arguments

Android Development with Kotlin This work is licensed under the Apache 2 license. 19
Default parameters
Default values provide a fallback if no parameter value is passed.

fun drive(speed: String = "fast") {


println("driving $speed")
}
Use "=" after the type
to define default values
drive() ⇒ driving fast
drive("slow") ⇒ driving slowly
drive(speed = "turtle-like") ⇒ driving turtle-like

Android Development with Kotlin This work is licensed under the Apache 2 license. 20
Required parameters

If no default is specified for a parameter, the corresponding argument is


required.
Required
parameters
fun tempToday(day: String, temp: Int) {
println("Today is $day and it's $temp degrees.")
}

Android Development with Kotlin This work is licensed under the Apache 2 license. 21
Default versus required parameters
Functions can have a mix of default and required parameters.

fun reformat(str: String,


divideByCamelHumps: Boolean,
wordSeparator: Char, Has default
value
normalizeCase: Boolean = true){

Pass in required arguments.

reformat("Today is a day like no other day", false, '_')

Android Development with Kotlin This work is licensed under the Apache 2 license. 22
Named arguments

To improve readability, use named arguments for required arguments.

reformat(str, divideByCamelHumps = false, wordSeparator = '_')

It's considered good style to put default arguments after positional


arguments, that way callers only have to specify the required arguments.

Android Development with Kotlin This work is licensed under the Apache 2 license. 23
Compact functions

Android Development with Kotlin This work is licensed under the Apache 2 license. 24
Single-expression functions

Compact functions, or single-expression functions, make your code more


concise and readable.

fun double(x: Int): Int { Complete


x * 2 version
}

fun double(x: Int):Int = x * 2 Compact


version

Android Development with Kotlin This work is licensed under the Apache 2 license. 25
Lambdas and higher-order
functions

Android Development with Kotlin This work is licensed under the Apache 2 license. 26
Kotlin functions are first-class

● Kotlin functions can be stored in variables and data


structures
● They can be passed as arguments to, and returned from,
other higher-order functions

● You can use higher-order functions to create new "built-in"


functions

Android Development with Kotlin This work is licensed under the Apache 2 license. 27
Lambda functions
A lambda is an expression that makes a function that has no name.

Parameter and
type Function
var dirtLevel = 20
arrow
val waterFilter = {level: Int -> level / 2}
println(waterFilter(dirtLevel))
⇒ 10
Code to
execute

Android Development with Kotlin This work is licensed under the Apache 2 license. 28
Syntax for function types
Kotlin's syntax for function types is closely related to its syntax for lambdas.
Declare a variable that holds a function.

val waterFilter: (Int) -> Int = {level -> level / 2}

Variable nameData type of variable Function


(function type)

Android Development with Kotlin This work is licensed under the Apache 2 license. 29
Higher-order functions
Higher-order functions take functions as parameters, or return a function.

fun encodeMsg(msg: String, encode: (String) -> String): String {​


return encode(msg)
}

The body of the code calls the function that was passed as the second
argument, and passes the first argument along to it.

Android Development with Kotlin This work is licensed under the Apache 2 license. 30
Higher-order functions
To call this function, pass it a string and a function.

val enc1: (String) -> String = { input -> input.toUpperCase() }


println(encodeMsg("abc", enc1))

Using a function type separates its implementation from its usage.

Android Development with Kotlin This work is licensed under the Apache 2 license. 31
Passing a function reference
Use the :: operator to pass a named function as an argument to another
function.

fun enc2(input:String): String = input.reversed()


encodeMessage("abc", ::enc2) Passing a named function,
not a lambda

The :: operator lets Kotlin know that you are passing the function reference
as an argument, and not trying to call the function.

Android Development with Kotlin This work is licensed under the Apache 2 license. 32
Last parameter call syntax
Kotlin prefers that any parameter that takes a function is the last parameter.

encodeMessage("acronym", { input -> input.toUpperCase() })

You can pass a lambda as a function parameter without putting it inside the
parentheses.

encodeMsg("acronym") { input -> input.toUpperCase() }

Android Development with Kotlin This work is licensed under the Apache 2 license. 33
Using higher-order functions

Many Kotlin built-in functions are defined using last parameter call syntax.

inline fun repeat(times: Int, action: (Int) -> Unit)

repeat(3) {
println("Hello")
}

Android Development with Kotlin This work is licensed under the Apache 2 license. 34
List filters

Android Development with Kotlin This work is licensed under the Apache 2 license. 35
List filters
Get part of a list based on some condition

bright
red red-orange dark red orange saffron
orange

Apply filter() on list


Condition: element contains “red”

red red-orange dark red

Android Development with Kotlin This work is licensed under the Apache 2 license. 36
Iterating through lists
If a function literal has only one parameter, you can omit its declaration and
the "->". The parameter is implicitly declared under the name it.

val ints = listOf(1, 2, 3)


ints.filter { it > 0 }

Filter iterates through a collection, where it is the value of the element


during the iteration. This is equivalent to:

ints.filter { n: Int -> n > 0 } ints.filter { n -> n > 0 }


OR

Android Development with Kotlin This work is licensed under the Apache 2 license. 37
List filters

The filter condition in curly braces {} tests each item as the filter loops
through. If the expression returns true, the item is included.

val books = listOf("nature", "biology", "birds")


println(books.filter { it[0] == 'b' })

⇒ [biology, birds]

Android Development with Kotlin This work is licensed under the Apache 2 license. 38
Eager and lazy filters
Evaluation of expressions in lists:

● Eager: occurs regardless of whether the result is ever used

● Lazy: occurs only if necessary at runtime

Lazy evaluation of lists is useful if you don't need the entire result, or if the
list is exceptionally large and multiple copies wouldn't wouldn't fit into RAM.

Android Development with Kotlin This work is licensed under the Apache 2 license. 39
Eager filters

Filters are eager by default. A new list is created each time you use a filter.

val instruments = listOf("viola", "cello", "violin")


val eager = instruments.filter { it [0] == 'v' }
println("eager: " + eager)
⇒ eager: [viola, violin]

Android Development with Kotlin This work is licensed under the Apache 2 license. 40
Lazy filters
Sequences are data structures that use lazy evaluation, and can be used with
filters to make them lazy.

val instruments = listOf("viola", "cello", "violin")


val filtered = instruments.asSequence().filter { it[0] == 'v'}
println("filtered: " + filtered)
⇒ filtered: kotlin.sequences.FilteringSequence@386cc1c4

Android Development with Kotlin This work is licensed under the Apache 2 license. 41
Sequences -> lists
Sequences can be turned back into lists using toList().

val filtered = instruments.asSequence().filter { it[0] == 'v'}


val newList = filtered.toList()
println("new list: " + newList)

⇒ new list: [viola, violin]

Android Development with Kotlin This work is licensed under the Apache 2 license. 42
Other list transformations
● map() performs the same transform on every item and returns the list.

val numbers = setOf(1, 2, 3)


println(numbers.map { it * 3 })
=> [3, 6, 9]

● flatten() returns a single list of all the elements of nested collections.


val numberSets = listOf(setOf(1, 2, 3), setOf(4, 5), setOf(1, 2))
println(numberSets.flatten())
=> [1, 2, 3, 4, 5, 1, 2]

Android Development with Kotlin This work is licensed under the Apache 2 license. 43
Summary

Android Development with Kotlin This work is licensed under the Apache 2 license. 44
Summary
In Lesson 2, you learned how to:

● Create a file and a main()


function in your project, and run a program
● Pass arguments to the main() function
● Use the returned value of an expression
● Use default arguments to replace multiple versions of a function
● Use compact functions, to make code more readable
● Use lambdas and higher-order functions
● Use eager andAndroid
lazyDevelopment
list filters
with Kotlin This work is licensed under the Apache 2 license. 45
Pathway

Practice what you’ve learned by


completing the pathway:
Lesson 2: Functions

Android Development with Kotlin This work is licensed under the Apache 2 license. 46
Lesson 3:
Classes and
objects

Android Development with Kotlin v1.0 This work is licensed under the Apache 2 license. 1
About this lesson
Lesson 3: Classes and objects
○ Classes
○ Inheritance
○ Extension functions
○ Special classes
○ Organizing your code
○ Summary

Android Development with Kotlin This work is licensed under the Apache 2 license. 2
Classes

Android Development with Kotlin This work is licensed under the Apache 2 license. 3
Class

Object
● Classes are blueprints for objects instances
● Classes define methods that operate
on their object instances

Class

Android Development with Kotlin This work is licensed under the Apache 2 license. 4
Class versus object instance
House Class Object Instances
Data
● House color (String)
● Number of windows (Int)
● Is for sale (Boolean)
Behavior
● updateColor()
● putOnSale() FOR SALE

Android Development with Kotlin This work is licensed under the Apache 2 license. 5
Define and use a class
Class Definition Create New Object Instance

class House { val myHouse = House()


val color: String = "white" println(myHouse)
val numberOfWindows: Int = 2
val isForSale: Boolean = false

fun updateColor(newColor: String){...}


...
}

Android Development with Kotlin This work is licensed under the Apache 2 license. 6
Constructors
When a constructor is defined in the class header, it can contain:
● No parameters
class A

● Parameters
○ Not marked with var or val → copy exists only within scope of the
constructor
class B(x: Int)
○ Marked var or val → copy exists in all instances of the class
class C(val y: Int)
Android Development with Kotlin This work is licensed under the Apache 2 license. 7
Constructor examples
class A val aa = A()

class B(x: Int) val bb = B(12)


println(bb.x)
=> compiler error unresolved
reference

class C(val y: Int) val cc = C(42)


println(cc.y)
=> 42

Android Development with Kotlin This work is licensed under the Apache 2 license. 8
Default parameters
Class instances can have default values.
● Use default values to reduce the number of constructors needed
● Default parameters can be mixed with required parameters
● More concise (don’t need to have multiple constructor versions)
class Box(val length: Int, val width:Int = 20, val height:Int = 40)
val box1 = Box(100, 20, 40)
val box2 = Box(length = 100)
val box3 = Box(length = 100, width = 20, height = 40)

Android Development with Kotlin This work is licensed under the Apache 2 license. 9
Primary constructor
Declare the primary constructor within the class header.
class Circle(i: Int) {
init {
...
}
}
This is technically equivalent to:
class Circle {
constructor(i: Int) {
...
}
}
Android Development with Kotlin This work is licensed under the Apache 2 license. 10
Initializer block

● Any required initialization code is run in a special init


block
● Multiple init blocks are allowed
● init blocks become the body of the primary constructor

Android Development with Kotlin This work is licensed under the Apache 2 license. 11
Initializer block example
Use the init keyword:

class Square(val side: Int) {


init {
println(side * 2)
}
}

val s = Square(10)
=> 20

Android Development with Kotlin This work is licensed under the Apache 2 license. 12
Multiple constructors
● Use the constructor keyword to define secondary constructors
● Secondary constructors must call:
○ The primary constructor using this keyword

OR
○ Another secondary constructor that calls the primary
constructor
● Secondary constructor body is not required

Android Development with Kotlin This work is licensed under the Apache 2 license. 13
Multiple constructors example
class Circle(val radius:Double) {
constructor(name:String) : this(1.0)
constructor(diameter:Int) : this(diameter / 2.0) {
println("in diameter constructor")
}
init {
println("Area: ${Math.PI * radius * radius}")
}
}
val c = Circle(3)

Android Development with Kotlin This work is licensed under the Apache 2 license. 14
Properties

● Define properties in a class using val or var


● Access these properties using
dot . notation with property name
● Set these properties using
dot . notation with property name (only if declared a var)

Android Development with Kotlin This work is licensed under the Apache 2 license. 15
Person class with name property
class Person(var name: String)
fun main() {
val person = Person("Alex")
println(person.name) Access with .<property name>
person.name = "Joey" Set with .<property name>
println(person.name)
}

Android Development with Kotlin This work is licensed under the Apache 2 license. 16
Custom getters and setters
If you don’t want the default get/set behavior:

● Override get() for a property


● Override set() for a property (if defined as a var)

Format: var propertyName: DataType = initialValue


get() = ...
set(value) {
...
}

Android Development with Kotlin This work is licensed under the Apache 2 license. 17
Custom getter
class Person(val firstName: String, val lastName:String) {
val fullName:String
get() {
return "$firstName $lastName"
}
}

val person = Person("John", "Doe")


println(person.fullName)
=> John Doe

Android Development with Kotlin This work is licensed under the Apache 2 license. 18
Custom setter
var fullName:String = ""
get() = "$firstName $lastName"
set(value) {
val components = value.split(" ")
firstName = components[0]
lastName = components[1]
field = value
}

person.fullName = "Jane Smith"

Android Development with Kotlin This work is licensed under the Apache 2 license. 19
Member functions

● Classes can also contain functions


● Declare functions as shown in Functions in Lesson 2
○ fun keyword
○ Can have default or required parameters
○ Specify return type (if not Unit)

Android Development with Kotlin This work is licensed under the Apache 2 license. 20
Inheritance

Android Development with Kotlin This work is licensed under the Apache 2 license. 21
Inheritance

● Kotlin has single-parent class inheritance


● Each class has exactly one parent class, called a superclass
● Each subclass inherits all members of its superclass
including ones that the superclass itself has inherited

If you don't want to be limited by only inheriting a single class, you can
define an interface since you can implement as many of those as you want.

Android Development with Kotlin This work is licensed under the Apache 2 license. 22
Interfaces

● Provide a contract all implementing classes must adhere to

● Can contain method signatures and property names

● Can derive from other interfaces

Format: interface NameOfInterface { interfaceBody }

Android Development with Kotlin This work is licensed under the Apache 2 license. 23
Interface example
interface Shape {
fun computeArea() : Double
}
class Circle(val radius:Double) : Shape {
override fun computeArea() = Math.PI * radius * radius
}

val c = Circle(3.0)
println(c.computeArea())
=> 28.274333882308138

Android Development with Kotlin This work is licensed under the Apache 2 license. 24
Extending classes

To extend a class:
● Create a new class that uses an existing class as its core
(subclass)
● Add functionality to a class without creating a new one
(extension functions)

Android Development with Kotlin This work is licensed under the Apache 2 license. 25
Creating a new class

● Kotlin classes by default are not subclassable

● Use open keyword to allow subclassing

● Properties and functions are redefined with the override


keyword

Android Development with Kotlin This work is licensed under the Apache 2 license. 26
Classes are final by default
Declare a class
class A

Try to subclass A
class B : A

=>Error: A is final and cannot be inherited from

Android Development with Kotlin This work is licensed under the Apache 2 license. 27
Use open keyword
Use open to declare a class so that it can be subclassed.

Declare a class

open class C

Subclass from C
class D : C()

Android Development with Kotlin This work is licensed under the Apache 2 license. 28
Overriding

● Must use open for properties and methods that can be


overridden (otherwise you get compiler error)

● Must use override when overriding properties and methods

● Something marked override can be overridden in subclasses


(unless marked final)

Android Development with Kotlin This work is licensed under the Apache 2 license. 29
Abstract classes

● Class is marked as abstract


● Cannot be instantiated, must be subclassed
● Similar to an interface with the added the ability to store
state
● Properties and functions marked with abstract must be
overridden
● Can include non-abstract properties and functions
Android Development with Kotlin This work is licensed under the Apache 2 license. 30
Example abstract classes
abstract class Food {
abstract val kcal : Int
abstract val name : String
fun consume() = println("I'm eating ${name}")
}
class Pizza() : Food() {
override val kcal = 600
override val name = "Pizza"
}
fun main() {
Pizza().consume() // "I'm eating Pizza"
}
Android Development with Kotlin This work is licensed under the Apache 2 license. 31
When to use each
● Defining a broad spectrum of behavior or types? Consider an
interface.

● Will the behavior be specific to that type? Consider a class.

● Need to inherit from multiple classes? Consider refactoring code to


see if some behavior can be isolated into an interface.

● Want to leave some properties / methods abstract to be defined by


subclasses? Consider an abstract class.

● You can extend only one class, but implement one or more
Android Development with Kotlin This work is licensed under the Apache 2 license.
interfaces. 32
Extension functions

Android Development with Kotlin This work is licensed under the Apache 2 license. 33
Extension functions
Add functions to an existing class that you cannot modify
directly.
● Appears as if the implementer added it

● Not actually modifying the existing class

● Cannot access private instance variables

Format: fun ClassName.functionName( params ) { body }

Android Development with Kotlin This work is licensed under the Apache 2 license. 34
Why use extension functions?

● Add functionality to classes that are not open

● Add functionality to classes you don’t own

● Separate out core API from helper methods for classes you
own

Define extension functions in an easily discoverable place such as in the


same file as the class, or a well-named function.

Android Development with Kotlin This work is licensed under the Apache 2 license. 35
Extension function example
Add isOdd() to Int class:

fun Int.isOdd(): Boolean { return this % 2 == 1 }

Call isOdd() on an Int:

3.isOdd()

Extension functions are very powerful in Kotlin!

Android Development with Kotlin This work is licensed under the Apache 2 license. 36
Special classes

Android Development with Kotlin This work is licensed under the Apache 2 license. 37
Data class

● Special class that exists just to store a set of data

● Mark the class with the data keyword

● Generates getters for each property (and setters for vars


too)
● Generates toString(), equals(), hashCode(), copy()
methods, and destructuring operators

Format: data class <NameOfClass>( parameterList )


Android Development with Kotlin This work is licensed under the Apache 2 license. 38
Data class example
Define the data class:

data class Player(val name: String, val score: Int)

Use the data class:


val firstPlayer = Player("Lauren", 10)
println(firstPlayer)
=> Player(name=Lauren, score=10)

Data classes make your code much more concise!

Android Development with Kotlin This work is licensed under the Apache 2 license. 39
Pair and Triple

● Pair and Triple are predefined data classes that store


2 or 3 pieces of data respectively

● Access variables with .first, .second, .third


respectively

● Usually named data classes are a better option


(more meaningful names for your use case)

Android Development with Kotlin This work is licensed under the Apache 2 license. 40
Pair and Triple examples
val bookAuthor = Pair("Harry Potter", "J.K. Rowling")

println(bookAuthor)
=> (Harry Potter, J.K. Rowling)

val bookAuthorYear = Triple("Harry Potter", "J.K. Rowling", 1997)


println(bookAuthorYear)

println(bookAuthorYear.third)
=> (Harry Potter, J.K. Rowling, 1997)
1997

Android Development with Kotlin This work is licensed under the Apache 2 license. 41
Pair to
Pair's special to variant lets you omit parentheses and periods (infix
function).
It allows for more readable code
val bookAuth1 = "Harry Potter".to("J. K. Rowling")
val bookAuth2 = "Harry Potter" to "J. K. Rowling"
=> bookAuth1 and bookAuth2 are Pair (Harry Potter, J. K. Rowling)
Also used in collections like Map and HashMap

val map = mapOf(1 to "x", 2 to "y", 3 to "zz")


=> map of Int to String {1=x, 2=y, 3=zz}

Android Development with Kotlin This work is licensed under the Apache 2 license. 42
Enum class
User-defined data type for a set of named values

● Use this to require instances be one of several constant values


● The constant value is, by default, not visible to you
● Use enum before the class keyword

Format: enum class EnumName { NAME1, NAME2, … NAMEn }


Referenced via EnumName.<ConstantName>

Android Development with Kotlin This work is licensed under the Apache 2 license. 43
Enum class example
Define an enum with red, green, and blue colors.

enum class Color(val r: Int, val g: Int, val b: Int) {


RED(255, 0, 0), GREEN(0, 255, 0), BLUE(0, 0, 255)
}

println("" + Color.RED.r + " " + Color.RED.g + " " + Color.RED.b)


=> 255 0 0

Android Development with Kotlin This work is licensed under the Apache 2 license. 44
Object/singleton

● Sometimes you only want one instance of a class to ever


exist

● Use the object keyword instead of the class keyword

● Accessed with NameOfObject.<function or variable>

Android Development with Kotlin This work is licensed under the Apache 2 license. 45
Object/singleton example
object Calculator {
fun add(n1: Int, n2: Int): Int {
return n1 + n2
}
}

println(Calculator.add(2,4))
=> 6

Android Development with Kotlin This work is licensed under the Apache 2 license. 46
Companion objects

● Lets all instances of a class share a single instance of a set


of variables or functions

● Use companion keyword

● Referenced via ClassName.PropertyOrFunction

Android Development with Kotlin This work is licensed under the Apache 2 license. 47
Companion object example
class PhysicsSystem {
companion object WorldConstants {
val gravity = 9.8
val unit = "metric"
fun computeForce(mass: Double, accel: Double): Double {
return mass * accel
}
}
}
println(PhysicsSystem.WorldConstants.gravity)
println(PhysicsSystem.WorldConstants.computeForce(10.0, 10.0))
=> 9.8100.0
Android Development with Kotlin This work is licensed under the Apache 2 license. 48
Organizing your code

Android Development with Kotlin This work is licensed under the Apache 2 license. 49
Single file, multiple entities

● Kotlin DOES NOT enforce a single entity (class/interface)


per file convention

● You can and should group related structures in the same


file
● Be mindful of file length and clutter

Android Development with Kotlin This work is licensed under the Apache 2 license. 50
Packages

● Provide means for organization

● Identifiers are generally lower case words separated by


periods

● Declared in the first non-comment line of code in a file


following the package keyword

package org.example.game

Android Development with Kotlin This work is licensed under the Apache 2 license. 51
Example class hierarchy
org.example.vehi
cle
Vehicle

org.example.vehicle.mo
org.example.vehicle.car
ped
Moped Car
Moped50cc Sedan
Moped100cc Hatchback

Android Development with Kotlin This work is licensed under the Apache 2 license. 52
Visibility modifiers
Use visibility modifiers to limit what information you expose.

● public means visible outside the class. Everything is public by default,


including variables and methods of the class.
● private means it will only be visible in that class (or source file if you
are working with functions).
● protected is the same as private, but it will also be visible to any
subclasses.

Android Development with Kotlin This work is licensed under the Apache 2 license. 53
Summary

Android Development with Kotlin This work is licensed under the Apache 2 license. 54
Summary
In Lesson 3, you learned about:

● Classes, constructors, and getters and setters


● Inheritance, interfaces, and how to extend classes
● Extension functions
● Special classes: data classes, enums, object/singletons, companio
n objects
● Packages
● Visibility modifiers
Android Development with Kotlin This work is licensed under the Apache 2 license. 55
Pathway

Practice what you’ve learned by


completing the pathway:
Lesson 3: Classes and objects

Android Development with Kotlin This work is licensed under the Apache 2 license. 56
Lesson 4:
Build your first
Android app

Android Development with Kotlin v1.0 This work is licensed under the Apache 2 license. 1
About this lesson
Lesson 4: Build your first Android app
● Your first app
● Anatomy of an Android app
● Layouts and resources in Android
● Activities
● Make an app interactive
● Gradle: Building an Android app
● Accessibility
● Summary
Android Development with Kotlin This work is licensed under the Apache 2 license. 2
Android Studio
Official IDE for building Android apps

Android Development with Kotlin This work is licensed under the Apache 2 license. 3
Your first app

Android Development with Kotlin This work is licensed under the Apache 2 license. 4
Open Android Studio

Android Development with Kotlin This work is licensed under the Apache 2 license. 5
Create new project

Android Development with Kotlin This work is licensed under the Apache 2 license. 6
Enter your project details

Android Development with Kotlin This work is licensed under the Apache 2 license. 7
Android releases and API levels

Android Development with Kotlin This work is licensed under the Apache 2 license. 8
Choose API levels for your app

● Minimum SDK: Device needs at least this API level to install


● Target SDK: API version and highest Android version tested
● Compile SDK: Android OS library version compiled with
minSdkVersion <= targetSdkVersion <= compileSdkVersion

The API level identifies the framework API version of the Android SDK.

Android Development with Kotlin This work is licensed under the Apache 2 license. 9
Tour of Android Studio

Android Development with Kotlin This work is licensed under the Apache 2 license. 10
Run your app

● Android device (phone,


tablet)
● Emulator on your computer

Android Development with Kotlin This work is licensed under the Apache 2 license. 11
Android Virtual Device (AVD)
Manager

Android Development with Kotlin This work is licensed under the Apache 2 license. 12
Anatomy of an Android
App
project

Android Development with Kotlin This work is licensed under the Apache 2 license. 13
Anatomy of a basic app project

● Activity
● Resources (layout files, images, audio files, themes, and
colors)
● Gradle files

Android Development with Kotlin This work is licensed under the Apache 2 license. 14
Android app project structure
MyApplication
├── app
│ ├── libs
│ └── src
│ ├── androidTest
│ ├── main
│ │ ├── java
│ │ ├── res
│ │ └── AndroidManifest.xml
│ └── test
├── build.gradle
└── gradlew

Android Development with Kotlin This work is licensed under the Apache 2 license. 15
Browse files in Android Studio

Android Development with Kotlin This work is licensed under the Apache 2 license. 16
Layouts and resources in
Android

Android Development with Kotlin This work is licensed under the Apache 2 license. 17
Views

● Views are the user interface building blocks in Android


○ Bounded by a rectangular area on the screen
○ Responsible for drawing and event handling
○ Examples: TextView, ImageView, Button
● Can be grouped to form more complex user interfaces

Android Development with Kotlin This work is licensed under the Apache 2 license. 18
Layout Editor

Android Development with Kotlin This work is licensed under the Apache 2 license. 19
XML Layouts

You can also edit your layout in XML.


● Android uses XML to specify the layout of user interfaces
(including View attributes)

● Each View in XML corresponds to a class in Kotlin that


controls how that View functions

Android Development with Kotlin This work is licensed under the Apache 2 license. 20
XML for a TextView

<TextView
android:layout_width="wrap_content"
Hello World!
android:layout_height="wrap_content"
android:text="Hello World!"/>

Android Development with Kotlin This work is licensed under the Apache 2 license. 21
Size of a View
● wrap_content
android:layout_width="wrap_content"
● match_parent
android:layout_width="match_parent"
● Fixed value (use dp units)
android:layout_width="48dp"

Android Development with Kotlin This work is licensed under the Apache 2 license. 22
ViewGroups
A ViewGroup is a container that determines how views are displayed.
FrameLayout LinearLayout ConstraintLayout

TextView TextVie TextVie


w w
TextView TextView
Button
Button

The ViewGroup is the parent and the views inside it are its children.

Android Development with Kotlin This work is licensed under the Apache 2 license. 23
FrameLayout example
A FrameLayout generally holds a single child View.

<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="match_parent" TextView
android:layout_height="match_parent"
android:text="Hello World!"/>
</FrameLayout>

Android Development with Kotlin This work is licensed under the Apache 2 license. 24
LinearLayout example
● Aligns child views in a row or column
● Set android:orientation to horizontal or vertical

<LinearLayout
android:layout_width="match_parent"
TextView
android:layout_height="match_parent"
android:orientation="vertical">
TextView
<TextView ... />
<TextView ... />
Button
<Button ... />
</LinearLayout>

Android Development with Kotlin This work is licensed under the Apache 2 license. 25
View hierarchy

LinearLayo
ut ImageView

ImageVie LinearLayo TextView


TextView
w ut

Butto Butto
n n
Button Button

Android Development with Kotlin This work is licensed under the Apache 2 license. 26
App resources
Static content or additional files that your code uses
● Layout files
● Images
● Audio files
● User interface strings
● App icon

Android Development with Kotlin This work is licensed under the Apache 2 license. 27
Common resource directories
Add resources to your app by including them in the appropriate resource
directory under the parent res folder.

main
├── java
└── res
├── drawable
├── layout
├── mipmap
└── values

Android Development with Kotlin This work is licensed under the Apache 2 license. 28
Resource IDs
● Each resource has a resource ID to access it.
● When naming resources, the convention is to use all lowercase with
underscores (for example, activity_main.xml).
● Android autogenerates a class file named R.java with references to all
resources in the app.
● Individual items are referenced with:
R.<resource_type>.<resource_name>
Examples: R.drawable.ic_launcher (res/drawable/ic_launcher.xml)
R.layout.activity_main (res/layout/activity_main.xml)

Android Development with Kotlin This work is licensed under the Apache 2 license. 29
Resource IDs for views
Individual views can also have resource IDs.

Add the android:id attribute to the View in XML. Use @+id/name syntax.
<TextView
android:id="@+id/helloTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"/>

Within your app, you can now refer to this specific TextView using:
R.id.helloTextView

Android Development with Kotlin This work is licensed under the Apache 2 license. 30
Activities

Android Development with Kotlin This work is licensed under the Apache 2 license. 31
What’s an Activity?
● An Activity is a means for the user to
accomplish one main goal.
● An Android app is composed of one or more
activities.

Android Development with Kotlin This work is licensed under the Apache 2 license. 32
MainActivity.kt

class MainActivity : AppCompatActivity() {

override fun onCreate(savedInstanceState: Bundle?) {


super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
}
}

Android Development with Kotlin This work is licensed under the Apache 2 license. 33
How an Activity runs
Activity
launched

onCreate()

App is running

Activity shut
down

Android Development with Kotlin This work is licensed under the Apache 2 license. 34
Implement the onCreate() callback

Called when the system creates your Activity


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

Android Development with Kotlin This work is licensed under the Apache 2 license. 35
Layout inflation
Activity

ViewGroup

Layout files LayoutInflate


View1
layout1 layout2 layout3 r ViewGroup

View2 View3

Android Development with Kotlin This work is licensed under the Apache 2 license. 36
Make an app interactive

Android Development with Kotlin This work is licensed under the Apache 2 license. 37
Define app behavior in Activity
Modify the Activity so the app responds to user input, such as a button tap.

Android Development with Kotlin This work is licensed under the Apache 2 license. 38
Modify a View dynamically

Within MainActivity.kt:

Get a reference to the View in the view hierarchy:


val resultTextView: TextView = findViewById(R.id.textView)

Change properties or call methods on the View instance:


resultTextView.text = "Goodbye!"

Android Development with Kotlin This work is licensed under the Apache 2 license. 39
Set up listeners for specific events
User interacts with a View

An event is fired

Did developer register a


callback?
No Yes

Ignore the Execute the


event callback
Android Development with Kotlin This work is licensed under the Apache 2 license. 40
View.OnClickListener
class MainActivity : AppCompatActivity(), View.OnClickListener {

override fun onCreate(savedInstanceState: Bundle?) {


...
val button: Button = findViewById(R.id.button)
button.setOnClickListener(this)
}

override fun onClick(v: View?) {


TODO("not implemented")
}
}

Android Development with Kotlin This work is licensed under the Apache 2 license. 41
SAM (single abstract method)
Converts a function into an implementation of an interface
Format: InterfaceName { lambda body }

val runnable = Runnable { println("Hi there") }


is equivalent to
val runnable = (object: Runnable {
override fun run() {
println("Hi there")
}
})

Android Development with Kotlin This work is licensed under the Apache 2 license. 42
View.OnClickListener as a SAM
A more concise way to declare a click listener
class MainActivity : AppCompatActivity() {

override fun onCreate(savedInstanceState: Bundle?) {


...

val button: Button = findViewById(R.id.button)


button.setOnClickListener({ view -> /* do something*/ })
}
}

Android Development with Kotlin This work is licensed under the Apache 2 license. 43
Late initialization

class Student(val id: String) {

lateinit var records: HashSet<Any>

init {
// retrieve records given an id
}
}

Android Development with Kotlin This work is licensed under the Apache 2 license. 44
Lateinit example in Activity

class MainActivity : AppCompatActivity() {

lateinit var result: TextView

override fun onCreate(savedInstanceState: Bundle?) {


...
result = findViewById(R.id.result_text_view)
}
}

Android Development with Kotlin This work is licensed under the Apache 2 license. 45
Gradle: Building an
Android app

Android Development with Kotlin This work is licensed under the Apache 2 license. 46
What is Gradle?

● Builds automation system


● Manages the build cycle via a series of tasks (for example,
compiles Kotlin sources, runs tests, installs app to device)
● Determines the proper order of tasks to run
● Manages dependencies between projects and third-party
libraries

Android Development with Kotlin This work is licensed under the Apache 2 license. 47
Gradle build file

● Declare plugins
● Define Android properties
● Handle dependencies
● Connect to repositories

Android Development with Kotlin This work is licensed under the Apache 2 license. 48
Plugins

Provide libraries and infrastructure needed by your app


apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'

Android Development with Kotlin This work is licensed under the Apache 2 license. 49
Android configuration
android {
compileSdkVersion 30
buildToolsVersion "30.0.2"

defaultConfig {
applicationId "com.example.sample"
minSdkVersion 19
targetSdkVersion 30
}
}

Android Development with Kotlin This work is licensed under the Apache 2 license. 50
Dependencies

dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-
jdk7:$kotlin_version"
implementation 'androidx.core:core-ktx:1.3.2'
implementation 'androidx.appcompat:appcompat:1.2.0'
implementation 'com.google.android.material:material:1.2.1'
...
}

Android Development with Kotlin This work is licensed under the Apache 2 license. 51
Repositories

repositories {
google()
jcenter()
maven {
url "https://maven.example.com"
}
}

Android Development with Kotlin This work is licensed under the Apache 2 license. 52
Common Gradle tasks

● Clean
● Tasks
● InstallDebug

Android Development with Kotlin This work is licensed under the Apache 2 license. 53
Accessibility

Android Development with Kotlin This work is licensed under the Apache 2 license. 54
Accessibility

● Refers to improving the design and functionality of


your app to make it easier for more people, including
those with disabilities, to use
● Making your app more accessible leads to an overall
better user experience and benefits all your users

Android Development with Kotlin This work is licensed under the Apache 2 license. 55
Make apps more accessible
● Increase text visibility with foreground and background color
contrast ratio:
○ At least 4.5:1 for small text against the background
○ At least 3.0:1 for large text against the background
● Use large, simple controls
○ Touch target size should be at least 48dp x 48dp
● Describe each UI element
○ Set content description on images and controls

Android Development with Kotlin This work is licensed under the Apache 2 license.
Accessibility Scanner

Tool that scans your screen and suggests


improvements to make your app more
accessible, based on:
● Content labels
● Touch target sizes
● Clickable views
● Text and image contrast

Android Development with Kotlin This work is licensed under the Apache 2 license. 57
Accessibility Scanner example

Android Development with Kotlin This work is licensed under the Apache 2 license. 58
Add content labels
● Set contentDescription attribute → read aloud by screen
reader

<ImageView
...
android:contentDescription="@string/stop_sign" />

● Text in TextView already provided to accessibility services,


no additional label needed

Android Development with Kotlin This work is licensed under the Apache 2 license. 59
No content label needed

● For graphical elements that are purely for decorative


purposes, you can set
android:importantForAccessibility="no"

● Removing unnecessary announcements is better for the


user

Android Development with Kotlin This work is licensed under the Apache 2 license. 60
TalkBack

● Google screen reader included on Android devices


● Provides spoken feedback so you don’t have to look at the
screen to use your device
● Lets you navigate the device using gestures
● Includes braille keyboard for Unified English Braille

Android Development with Kotlin This work is licensed under the Apache 2 license. 61
TalkBack example
Reads text
aloud as user
navigates the
screen

Android Development with Kotlin This work is licensed under the Apache 2 license. 62
Switch access

● Allows for controlling the device using one or more switches


instead of the touchscreen
● Scans your app UI and highlights each item until you make
a selection
● Use with external switch, external keyboard, or buttons on
the Android device (e.g., volume buttons)

Android Development with Kotlin This work is licensed under the Apache 2 license. 63
Android Accessibility Suite
Collection of accessibility apps that help you
use your Android device eyes-free, or with a
switch device. It includes:

● Talkback screen reader


● Switch Access
● Accessibility Menu
● Select to Speak

Android Development with Kotlin This work is licensed under the Apache 2 license. 64
Accessibility Resources

● Build more accessible apps


● Principles for improving app accessibility
● Basic Android Accessibility codelab
● Material Design best practices on accessibility

Android Development with Kotlin This work is licensed under the Apache 2 license. 65
Summary

Android Development with Kotlin This work is licensed under the Apache 2 license. 66
Summary
In Lesson 4, you learned how to:

● Use Views and ViewGroups


to build the user interface of your app
● Access resources in your app from
R.<resource_type>.<resource_name>
● Define app behavior in the Activity (for example, register
OnClickListener)
● Use Gradle as the build system to build your app
● Follow best practices to make
Android Development your apps This
with Kotlin more accessible
work is licensed under the Apache 2 license. 67
Learn more
● Layouts
● LinearLayout
● Input events overview
● View
● ViewGroup

Android Development with Kotlin This work is licensed under the Apache 2 license. 68
Pathway

Practice what you’ve learned by


completing the pathway:
Lesson 4: Build your first Android app

Android Development with Kotlin This work is licensed under the Apache 2 license. 69
Lesson 5:
Layouts

Android Development with Kotlin v1.0 This work is licensed under the Apache 2 license. 1
About this lesson
Lesson 5: Layouts
● Layouts in Android
● ConstraintLayout
● Additional topics for ConstraintLayout
● Data binding
● Displaying lists with RecyclerView
● Summary

Android Development with Kotlin This work is licensed under the Apache 2 license. 2
Layouts in Android

Android Development with Kotlin This work is licensed under the Apache 2 license. 3
Android devices
● Android devices come in
many different form factors.
● More and more pixels per
inch are being packed into
device screens.
● Developers need the ability
to specify layout dimensions
that are consistent across
devices.

Android Development with Kotlin This work is licensed under the Apache 2 license. 4
Density-independent pixels (dp)
Use dp when specifying sizes in your layout, such as the width or height of
views.
● Density-independent pixels (dp)
take screen density into account.

Hell
80d
● Android views are measured in p

density-independent pixels.
● dp = (width in pixels * 160)
o 160d
p
screen density

Android Development with Kotlin This work is licensed under the Apache 2 license. 5
Screen-density buckets
Density qualifier Description DPI estimate

ldpi (mostly unused) Low density ~120dpi

mdpi (baseline density) Medium density ~160dpi

hdpi High density ~240dpi

xhdpi Extra-high density ~320dpi

xxhdpi Extra-extra-high density ~480dpi

xxxhdpi Extra-extra-extra-high density ~640dpi

Android Development with Kotlin This work is licensed under the Apache 2 license. 6
Android View rendering cycle
Measure

Layout

Draw

Android Development with Kotlin This work is licensed under the Apache 2 license. 7
Drawing region

What we see:

How it's drawn:

Android Development with Kotlin This work is licensed under the Apache 2 license. 8
View margins and padding

View with margin View with margin and padding

View View

Android Development with Kotlin This work is licensed under the Apache 2 license. 9
ConstraintLayout

Android Development with Kotlin This work is licensed under the Apache 2 license. 10
Deeply nested layouts are costly

● Deeply nested ViewGroups require more computation


● Views may be measured multiple times
● Can cause UI slowdown and lack of responsiveness

Use ConstraintLayout to avoid some of these issues!

Android Development with Kotlin This work is licensed under the Apache 2 license. 11
What is ConstraintLayout?

● Recommended default layout for Android


● Solves costly issue of too many nested layouts, while
allowing complex behavior
● Position and size views within it using a set of constraints

Android Development with Kotlin This work is licensed under the Apache 2 license. 12
What is a constraint?

A restriction or limitation on the


properties of a View that the layout
attempts to respect

Android Development with Kotlin This work is licensed under the Apache 2 license. 13
Relative positioning constraints
Can set up a constraint relative to the parent container
Format:
layout_constraint<SourceConstraint>_to<TargetConstraint>Of

Example attributes on a TextView:


app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toLeftOf="parent"

Android Development with Kotlin This work is licensed under the Apache 2 license. 14
Relative positioning constraints

Top

Hello!
Baseline
Bottom

Android Development with Kotlin This work is licensed under the Apache 2 license. 15
Relative positioning constraints

Left Hello! Right

Start End

Android Development with Kotlin This work is licensed under the Apache 2 license. 16
Simple ConstraintLayout example
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">

<TextView
...

app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>
Android Development with Kotlin This work is licensed under the Apache 2 license. 17
Layout Editor in Android Studio
You can click and drag to add constraints to a View.

Android Development with Kotlin This work is licensed under the Apache 2 license. 18
Constraint Widget in Layout Editor

Fixed

Wrap content

Match constraints

Android Development with Kotlin This work is licensed under the Apache 2 license. 19
Wrap content for width and height

Android Development with Kotlin This work is licensed under the Apache 2 license. 20
Wrap content for width, fixed height

Android Development with Kotlin This work is licensed under the Apache 2 license. 21
Center a view horizontally

Android Development with Kotlin This work is licensed under the Apache 2 license. 22
Use match_constraint
Can’t use match_parent on a child view, use match_constraint instead

Android Development with Kotlin This work is licensed under the Apache 2 license. 23
Chains

● Let you position views in relation to each other


● Can be linked horizontally or vertically
● Provide much of LinearLayout functionality

Android Development with Kotlin This work is licensed under the Apache 2 license. 24
Create a Chain in Layout Editor

1. Select the objects you want to be


in the chain.
2. Right-click and select Chains.
3. Create a horizontal or vertical
chain.

Android Development with Kotlin This work is licensed under the Apache 2 license. 25
Chain styles
Adjust space between views with these different chain styles.

Spread Chain

Spread Inside Chain

Weighted Chain

Packed Chain

Android Development with Kotlin This work is licensed under the Apache 2 license. 26
Additional topics for
ConstraintLayout

Android Development with Kotlin This work is licensed under the Apache 2 license. 27
Guidelines

● Let you position multiple views relative to a single guide


● Can be vertical or horizontal
● Allow for greater collaboration with design/UX teams
● Aren't drawn on the device

Android Development with Kotlin This work is licensed under the Apache 2 license. 28
Guidelines in Android Studio

Android Development with Kotlin This work is licensed under the Apache 2 license. 29
Example Guideline
<ConstraintLayout>
<androidx.constraintlayout.widget.Guideline
android:id="@+id/start_guideline"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_begin="16dp" />
<TextView ...
app:layout_constraintStart_toEndOf="@id/start_guideline" />
</ConstraintLayout>

Android Development with Kotlin This work is licensed under the Apache 2 license. 30
Creating Guidelines

● layout_constraintGuide_begin
● layout_constraintGuide_end
● layout_constraintGuide_percent

Android Development with Kotlin This work is licensed under the Apache 2 license. 31
Groups

● Control the visibility of a set of widgets


● Group visibility can be toggled in code

Android Development with Kotlin This work is licensed under the Apache 2 license. 32
Example group

<androidx.constraintlayout.widget.Group
android:id="@+id/group"
android:layout_width="wrap_content"
android:layout_height="wrap_content"

app:constraint_referenced_ids="locationLabel,locationDetails"/>

Android Development with Kotlin This work is licensed under the Apache 2 license. 33
Groups app code
override fun onClick(v: View?) {
if (group.visibility == View.GONE) {
group.visibility = View.VISIBLE
button.setText(R.string.hide_details)
} else {
group.visibility = View.GONE
button.setText(R.string.show_details)
}

}
Android Development with Kotlin This work is licensed under the Apache 2 license. 34
Data binding

Android Development with Kotlin This work is licensed under the Apache 2 license. 35
Current approach: findViewById()
Traverses the View hierarchy each time
MainActivity.kt activity_main.xml
<ConstraintLayout … >
findViewById <TextView
val name = findViewById(...)
val age = findViewById(...)
findViewById android:id="@+id/name"/>
val loc = findViewById(...)
<TextView
name.text = … android:id="@+id/age"/>
findViewById
age.text = … <TextView
loc.text = … android:id="@+id/loc"/>
</ConstraintLayout>

Android Development with Kotlin This work is licensed under the Apache 2 license. 36
Use data binding instead
Bind UI components in your layouts to data sources in your app.

MainActivity.kt activity_main.xml
<layout>
<ConstraintLayout … >
Val binding:ActivityMainBinding initialize
<TextView
binding
android:id="@+id/name"/>
binding.name.text = … <TextView
binding.age.text = … android:id="@+id/age"/>
binding.loc.text = … <TextView
android:id="@+id/loc"/>
</ConstraintLayout>
</layout>

Android Development with Kotlin This work is licensed under the Apache 2 license. 37
Modify build.gradle file

android {
...
buildFeatures {
dataBinding true
}
}

Android Development with Kotlin This work is licensed under the Apache 2 license. 38
Add layout tag

<layout>
<androidx.constraintlayout.widget.ConstraintLayout>
<TextView ... android:id="@+id/username" />
<EditText ... android:id="@+id/password" />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>

Android Development with Kotlin This work is licensed under the Apache 2 license. 39
Layout inflation with data binding

Replace this
setContentView(R.layout.activity_main)

with this
val binding: ActivityMainBinding = DataBindingUtil.setContentView(
this, R.layout.activity_main)

binding.username = "Melissa"

Android Development with Kotlin This work is licensed under the Apache 2 license. 40
Data binding layout variables
<layout>
<data>
<variable name="name" type="String"/>
</data>
<androidx.constraintlayout.widget.ConstraintLayout>
<TextView
android:id="@+id/textView"
android:text="@{name}" />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
In MainActivity.kt:
binding.name = "John"

Android Development with Kotlin This work is licensed under the Apache 2 license. 41
Data binding layout expressions
<layout>
<data>
<variable name="name" type="String"/>
</data>

<androidx.constraintlayout.widget.ConstraintLayout>
<TextView
android:id="@+id/textView"
android:text="@{name.toUpperCase()}" />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>

Android Development with Kotlin This work is licensed under the Apache 2 license. 42
Displaying lists with
RecyclerView

Android Development with Kotlin This work is licensed under the Apache 2 license. 43
RecyclerView

● Widget for displaying lists of data


● "Recycles" (reuses) item views to make scrolling more
performant
● Can specify a list item layout for each item in the dataset
● Supports animations and transitions

Android Development with Kotlin This work is licensed under the Apache 2 license. 44
RecyclerView.Adapter

● Supplies data and layouts that the RecyclerView displays


● A custom Adapter extends from RecyclerView.Adapter and
overrides these three functions:
● getItemCount
● onCreateViewHolder
● onBindViewHolder

Android Development with Kotlin This work is licensed under the Apache 2 license. 45
View recycling in RecyclerView
Boston, If item is scrolled
Massachusetts offscreen, it isn’t
Chicago, Illinois
destroyed. Item is put in
Mountain View, a pool to be recycled.
California
Miami, Florida
Seattle, Washington
Reno, Nevada
onBindViewHolder
Nashville, Tennessee binds the view with the
new values, and then
Little Rock, Arkansas the view gets reinserted
in the list.
Android Development with Kotlin This work is licensed under the Apache 2 license. 46
Add RecyclerView to your layout

<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv"
android:scrollbars="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"/>

Android Development with Kotlin This work is licensed under the Apache 2 license. 47
Create a list item layout
res/layout/item_view.xml
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/number"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</FrameLayout>

Android Development with Kotlin This work is licensed under the Apache 2 license. 48
Create a list adapter
class MyAdapter(val data: List<Int>) : RecyclerView.Adapter<MyAdapter.MyViewHolder>()
{
class MyViewHolder(val row: View) : RecyclerView.ViewHolder(row) {
val textView = row.findViewById<TextView>(R.id.number)
}

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {


val layout = LayoutInflater.from(parent.context).inflate(R.layout.item_view,
parent, false)
return MyViewHolder(layout)
}
override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
holder.textView.text = data.get(position).toString()
}
override fun getItemCount(): Int = data.size

Android Development with Kotlin This work is licensed under the Apache 2 license. 49
Set the adapter on the RecyclerView
In MainActivity.kt:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)

val rv: RecyclerView = findViewById(R.id.rv)


rv.layoutManager = LinearLayoutManager(this)

rv.adapter = MyAdapter(IntRange(0, 100).toList())


}

Android Development with Kotlin This work is licensed under the Apache 2 license. 50
Summary

Android Development with Kotlin This work is licensed under the Apache 2 license. 51
Summary

In Lesson 5, you learned how to:


● Specify lengths in dp for your layout
● Work with screen densities for different Android devices
● Render Views to the screen of your app
● Layout views within a ConstraintLayout using constraints
● Simplify getting View references from layout with data binding
● Display a list of text items using a RecyclerView
and custom adapter This work is licensed under the Apache 2 license.
Android Development with Kotlin 52
Learn more

● Pixel density on Android


● Spacing
● Device metrics
● Type scale
● Build a Responsive UI with ConstraintLayout
● Data Binding Library
● Create dynamic lists with RecyclerView

Android Development with Kotlin This work is licensed under the Apache 2 license. 53
Pathway

Practice what you’ve learned by


completing the pathway:
Lesson 5: Layouts

Android Development with Kotlin This work is licensed under the Apache 2 license. 54
Lesson 6:
App navigation

Android Development with Kotlin v1.0 This work is licensed under the Apache 2 license. 1
About this lesson
Lesson 6: App navigation
● Multiple activities and intents
● App bar, navigation drawer, and menus
● Fragments
● Navigation in an app
● More custom navigation behavior
● Navigation UI
● Summary

Android Development with Kotlin This work is licensed under the Apache 2 license. 2
Multiple activities and
intents

Android Development with Kotlin This work is licensed under the Apache 2 license. 3
Multiple screens in an app
Sometimes app functionality may be separated into multiple screens.

Examples:
● View details of a single item (for example, product in a shopping app)
● Create a new item (for example, new email)
● Show settings for an app
● Access services in other apps (for example, photo gallery or browse
documents)

Android Development with Kotlin This work is licensed under the Apache 2 license. 4
Intent

Requests an action from another app component, such as another


Activity

● An Intent usually has two primary pieces of information:


○ Action to be performed (for example, ACTION_VIEW,
ACTION_EDIT, ACTION_MAIN)
○ Data to operate on (for example, a person’s record in the
contacts database)
● Commonly used to specify a request to transition to another
Activity Android Development with Kotlin This work is licensed under the Apache 2 license. 5
Explicit intent

● Fulfills a request using a specific component


● Navigates internally to an Activity in your app
● Navigates to a specific third-party app or another app
you've written

Android Development with Kotlin This work is licensed under the Apache 2 license. 6
Explicit intent examples
Navigate between activities in your app:
fun viewNoteDetail() {
val intent = Intent(this, NoteDetailActivity::class.java)
intent.putExtra(NOTE_ID, note.id)
startActivity(intent)
}
Navigate to a specific external app:
fun openExternalApp() {
val intent = Intent("com.example.workapp.FILE_OPEN")
if (intent.resolveActivity(packageManager) != null) {
startActivity(intent)
}
}
Android Development with Kotlin This work is licensed under the Apache 2 license. 7
Implicit intent

● Provides generic action the app can perform


● Resolved using mapping of the data type and action to
known components
● Allows any app that matches the criteria to handle the
request

Android Development with Kotlin This work is licensed under the Apache 2 license. 8
Implicit intent example

fun sendEmail() {
val intent = Intent(Intent.ACTION_SEND)
intent.type = "text/plain"
intent.putExtra(Intent.EXTRA_EMAIL, emailAddresses)
intent.putExtra(Intent.EXTRA_TEXT, "How are you?")

if (intent.resolveActivity(packageManager) != null) {
startActivity(intent)
}
}

Android Development with Kotlin This work is licensed under the Apache 2 license. 9
App bar, navigation
drawer, and menus

Android Development with Kotlin This work is licensed under the Apache 2 license. 10
App bar

Android Development with Kotlin This work is licensed under the Apache 2 license. 11
Navigation drawer

Android Development with Kotlin This work is licensed under the Apache 2 license. 12
Menu
Define menu items in XML menu resource (located in res/menu folder)

<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/action_settings"
android:orderInCategory="100"
android:title="@string/action_settings"
app:showAsAction="never" />
</menu>

Android Development with Kotlin This work is licensed under the Apache 2 license. 13
More menu options
<menu>
<group android:checkableBehavior="single">
<item
android:id="@+id/nav_home"
android:icon="@drawable/ic_menu_camera"
android:title="@string/menu_home" />
<item
android:id="@+id/nav_gallery"
android:icon="@drawable/ic_menu_gallery"
android:title="@string/menu_gallery" />
<item
android:id="@+id/nav_slideshow"
android:icon="@drawable/ic_menu_slideshow"
android:title="@string/menu_slideshow" />
</group>
</menu>
Android Development with Kotlin This work is licensed under the Apache 2 license. 14
Options menu example
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">

<item android:id="@+id/action_intent"
android:title="@string/action_intent" />

<item
android:id="@+id/action_settings"
android:orderInCategory="100"
android:title="@string/action_settings"
app:showAsAction="never" />
</menu>

Android Development with Kotlin This work is licensed under the Apache 2 license. 15
Inflate options menu

override fun onCreateOptionsMenu(menu: Menu): Boolean {


menuInflater.inflate(R.menu.main, menu)
return true
}

Android Development with Kotlin This work is licensed under the Apache 2 license. 16
Handle menu options selected
override fun onOptionsItemSelected(item: MenuItem): Boolean {

when (item.itemId) {
R.id.action_intent -> {
val intent = Intent(Intent.ACTION_WEB_SEARCH)
intent.putExtra(SearchManager.QUERY, "pizza")
if (intent.resolveActivity(packageManager) != null) {
startActivity(intent)
}
}
else -> Toast.makeText(this, item.title, Toast.LENGTH_LONG).show()
...

Android Development with Kotlin This work is licensed under the Apache 2 license. 17
Fragments

Android Development with Kotlin This work is licensed under the Apache 2 license. 18
Fragments for tablet layouts

Android Development with Kotlin This work is licensed under the Apache 2 license. 19
Fragment

● Represents a behavior or portion of the UI in an activity


("microactivity")
● Must be hosted in an activity
● Lifecycle tied to host activity's lifecycle
● Can be added or removed at runtime

Android Development with Kotlin This work is licensed under the Apache 2 license. 20
Note about fragments

Use the AndroidX version of the Fragment class.


(androidx.fragment.app.Fragment).

Don't use the platform version of the Fragment class


(android.app.Fragment), which was deprecated.

Android Development with Kotlin This work is licensed under the Apache 2 license. 21
Navigation within an
app

Android Development with Kotlin This work is licensed under the Apache 2 license. 22
Navigation component
● Collection of libraries and tooling, including an integrated editor,
for creating navigation paths through an app
● Assumes one Activity per graph with many Fragment
destinations
● Consists of three major parts:
○ Navigation graph
○ Navigation Host (NavHost)
○ Navigation Controller (NavController)

Android Development with Kotlin This work is licensed under the Apache 2 license. 23
Add dependencies

In build.gradle, under
dependencies:
implementation "androidx.navigation:navigation-fragment-ktx:$nav_version"

implementation "androidx.navigation:navigation-ui-ktx:$nav_version"

Android Development with Kotlin This work is licensed under the Apache 2 license. 24
Navigation host (NavHost)

<fragment
android:id="@+id/nav_host"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:defaultNavHost="true"
app:navGraph="@navigation/nav_graph_name"/>

Android Development with Kotlin This work is licensed under the Apache 2 license. 25
Navigation graph
New resource type located in res/navigation
directory
● XML file containing all of your navigation
destinations and actions
● Lists all the (Fragment/Activity) destinations
that can be navigated to
● Lists the associated actions to traverse
between them
● Optionally lists animations for entering or
exiting
Android Development with Kotlin This work is licensed under the Apache 2 license. 26
Navigation Editor in Android Studio

Android Development with Kotlin This work is licensed under the Apache 2 license. 27
Creating a Fragment
● Extend Fragment class
● Override onCreateView()
● Inflate a layout for the Fragment that you have defined in XML

class DetailFragment : Fragment() {

override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,


savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.detail_fragment, container, false)
}
}

Android Development with Kotlin This work is licensed under the Apache 2 license. 28
Specifying Fragment destinations

● Fragment destinations are denoted by the action tag in the


navigation graph.
● Actions can be defined in XML directly or in the Navigation
Editor by dragging from source to destination.
● Autogenerated action IDs take the form of
action_<sourceFragment>_to_<destinationFragment>.

Android Development with Kotlin This work is licensed under the Apache 2 license. 29
Example fragment destination
<fragment
android:id="@+id/welcomeFragment"
android:name="com.example.android.navigation.WelcomeFragment"
android:label="fragment_welcome"
tools:layout="@layout/fragment_welcome" >

<action
android:id="@+id/action_welcomeFragment_to_detailFragment"
app:destination="@id/detailFragment" />

</fragment>

Android Development with Kotlin This work is licensed under the Apache 2 license. 30
Navigation Controller
(NavController)
NavController manages UI navigation in a navigation host.
● Specifying a destination path only names the action, but it
doesn’t execute it.
● To follow a path, use NavController.

Android Development with Kotlin This work is licensed under the Apache 2 license. 31
Example NavController

class MainActivity : AppCompatActivity() {

override fun onCreate(savedInstanceState: Bundle?) {


...
val navController = findNavController(R.id.myNavHostFragment)
}
fun navigateToDetail() {
navController.navigate(R.id.action_welcomeFragment_to_detailFragment)
}
}

Android Development with Kotlin This work is licensed under the Apache 2 license. 32
More custom navigation
behavior

Android Development with Kotlin This work is licensed under the Apache 2 license. 33
Passing data between destinations
Using Safe Args:
● Ensures arguments have a valid type
● Lets you provide default values
● Generates a <SourceDestination>Directions class with methods for
every action in that destination
● Generates a class to set arguments for every named action
● Generates a <TargetDestination>Args class providing access to the
destination's arguments

Android Development with Kotlin This work is licensed under the Apache 2 license. 34
Setting up Safe Args
In the project build.gradle file:
buildscript {
repositories {
google()
}
dependencies {
classpath "androidx.navigation:navigation-safe-args-gradle-plugin:$nav_version"
}
}

In the app's or module's build.gradle file:


apply plugin: "androidx.navigation.safeargs.kotlin"

Android Development with Kotlin This work is licensed under the Apache 2 license. 35
Sending data to a Fragment

1. Create arguments the destination fragment will expect.


2. Create action to link from source to destination.
3. Set the arguments in the action method on
<Source>FragmentDirections.
4. Navigate according to that action using the Navigation Controller.
5. Retrieve the arguments in the destination fragment.

Android Development with Kotlin This work is licensed under the Apache 2 license. 36
Destination arguments
<fragment
android:id="@+id/multiplyFragment"
android:name="com.example.arithmetic.MultiplyFragment"
android:label="MultiplyFragment" >
<argument
android:name="number1"
app:argType="float"
android:defaultValue="1.0" />
<argument
android:name="number2"
app:argType="float"
android:defaultValue="1.0" />
</fragment>

Android Development with Kotlin This work is licensed under the Apache 2 license. 37
Supported argument types
Type Type Syntax Supports Default Supports
app:argType=<type> Values Null
Values

Integer "integer" Yes No

Float "float" Yes No

Long "long" Yes No

Boolean "boolean" Yes ("true" or No


"false")

String "string" Yes Yes

Array above type + "[]" Yes (only "@null") Yes


(for example, "string[]" "long[]")

Enum Fully qualified name of the enum Yes No


Android Development with Kotlin This work is licensed under the Apache 2 license. 38
Supported argument types: Custom
classes
Type Type Syntax Supports Default Supports Null
app:argType=<type> Values Values

Serializable Fully qualified class name Yes (only "@null") Yes

Parcelable Fully qualified class name Yes (only "@null") Yes

Android Development with Kotlin This work is licensed under the Apache 2 license. 39
Create action from source to
destination
In nav_graph.xml:
<fragment
android:id="@+id/fragment_input"
android:name="com.example.arithmetic.InputFragment">

<action
android:id="@+id/action_to_multiplyFragment"
app:destination="@id/multiplyFragment" />

</fragment>

Android Development with Kotlin This work is licensed under the Apache 2 license. 40
Navigating with actions
In InputFragment.kt:
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding.button.setOnClickListener {
val n1 = binding.number1.text.toString().toFloatOrNull() ?: 0.0
val n2 = binding.number2.text.toString().toFloatOrNull() ?: 0.0

val action = InputFragmentDirections.actionToMultiplyFragment(n1, n2)


view.findNavController().navigate(action)
}
}

Android Development with Kotlin This work is licensed under the Apache 2 license. 41
Retrieving Fragment arguments
class MultiplyFragment : Fragment() {
val args: MultiplyFragmentArgs by navArgs()
lateinit var binding: FragmentMultiplyBinding
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val number1 = args.number1
val number2 = args.number2
val result = number1 * number2
binding.output.text = "${number1} * ${number2} = ${result}"
}

}
Android Development with Kotlin This work is licensed under the Apache 2 license. 42
Navigation UI

Android Development with Kotlin This work is licensed under the Apache 2 license. 43
Menus revisited

override fun onOptionsItemSelected(item: MenuItem): Boolean {


val navController = findNavController(R.id.nav_host_fragment)
return item.onNavDestinationSelected(navController) ||
super.onOptionsItemSelected(item)

Android Development with Kotlin This work is licensed under the Apache 2 license. 44
DrawerLayout for navigation drawer
<androidx.drawerlayout.widget.DrawerLayout
android:id="@+id/drawer_layout" ...>

<fragment
android:name="androidx.navigation.fragment.NavHostFragment"
android:id="@+id/nav_host_fragment" ... />

<com.google.android.material.navigation.NavigationView
android:id="@+id/nav_view"
app:menu="@menu/activity_main_drawer" ... />

</androidx.drawerlayout.widget.DrawerLayout>

Android Development with Kotlin This work is licensed under the Apache 2 license. 45
Finish setting up navigation drawer
Connect DrawerLayout to navigation graph:

val appBarConfiguration = AppBarConfig(navController.graph, drawer)

Set up NavigationView for use with a NavController:


val navView = findViewById<NavigationView>(R.id.nav_view)
navView.setupWithNavController(navController)

Android Development with Kotlin This work is licensed under the Apache 2 license. 46
Understanding the back stack
State 1 State 2 State 3

Activity 3

Activity 2 Activity 2 Activity 2

Activity 1 Activity 1 Activity 1

Back stack Back stack Back stack

Android Development with Kotlin This work is licensed under the Apache 2 license.
Fragments and the back stack
State 1 State 2 State 3

Fragment 2

Fragment 1 Fragment 1 Fragment 1

Activity 2 Activity 2 Activity 2

Activity 1 Activity 1 Activity 1

Back stack Back stack Back stack

Android Development with Kotlin This work is licensed under the Apache 2 license.
Summary

Android Development with Kotlin This work is licensed under the Apache 2 license. 49
Summary
In Lesson 6, you learned how to:
● Use explicit and implicit intents to navigate between Activities
● S
tructure apps using fragments instead of putting all UI code in the Ac
tivity
● Handle navigation with NavGraph, NavHost, and NavController
● Use Safe Args to pass data between fragment destinations
● Use NavigationUI to hook up top app bar, navigation drawer, and bot
tom navigation
● Android keeps a back stack of all the destinations you’ve visited, with
each new destination beingwith
Android Development pushed
Kotlin onto the stack.
This work is licensed under the Apache 2 license. 50
Learn more
● Principles of navigation
● Navigation component
● Pass data between destinations
● NavigationUI

Android Development with Kotlin This work is licensed under the Apache 2 license. 51
Pathway

Practice what you’ve learned by


completing the pathway:
Lesson 6: App navigation

Android Development with Kotlin This work is licensed under the Apache 2 license. 52
Lesson 7:
Activity and
fragment lifecycles

Android Development with Kotlin v1.0 This work is licensed under the Apache 2 license. 1
About this lesson
Lesson 7: Activity and fragment lifecycles
● Activity lifecycle
● Logging
● Fragment lifecycle
● Lifecycle-aware components
● Tasks and back stack
● Summary

Android Development with Kotlin This work is licensed under the Apache 2 license. 2
Activity lifecycle

Android Development with Kotlin This work is licensed under the Apache 2 license. 3
Why it matters

● Preserve user data and state if:


○ User temporarily leaves app and then returns
○ User is interrupted (for example, a phone call)
○ User rotates device
● Avoid memory leaks and app crashes.

Android Development with Kotlin This work is licensed under the Apache 2 license. 4
Simplified activity lifecycle
Activity
launched

onCreate()

App is running

Activity shut
down

Android Development with Kotlin This work is licensed under the Apache 2 license. 5
Activity lifecycle
Activity
onCreate()
launched

onRestart() onStart()

onResume()

Activity
running

onPause()

onStop()

Activity shut
onDestroy()
down

Android Development with Kotlin This work is licensed under the Apache 2 license. 6
Activity states
CREATED

STARTED

RESUMED
Activity is
running
PAUSED

STOPPED
DESTROYE
D
Android Development with Kotlin This work is licensed under the Apache 2 license. 7
onCreate()

● Activity is created and other initialization work occurs


● You must implement this callback
● Inflate activity UI and perform other app startup logic

Android Development with Kotlin This work is licensed under the Apache 2 license. 8
onStart()

● Activity becomes visible to the user


● Called after activity:
○ onCreate()
or
○ onRestart() if activity was previously stopped

Android Development with Kotlin This work is licensed under the Apache 2 license. 9
onResume()

● Activity gains input focus:


○ User can interact with the activity
● Activity stays in resumed state until system triggers activity
to be paused

Android Development with Kotlin This work is licensed under the Apache 2 license. 10
onPause()

● Activity has lost focus (not in foreground)


● Activity is still visible, but user is not actively interacting with
it
● Counterpart to onResume()

Android Development with Kotlin This work is licensed under the Apache 2 license. 11
onStop()

● Activity is no longer visible to the user


● Release resources that aren’t needed anymore
● Save any persistent state that the user is in the process of
editing so they don’t lose their work

Android Development with Kotlin This work is licensed under the Apache 2 license. 12
onDestroy()

● Activity is about to be destroyed, which can be caused by:


○ Activity has finished or been dismissed by the user
○ Configuration change
● Perform any final cleanup of resources.
● Don’t rely on this method to save user data (do that earlier)

Android Development with Kotlin This work is licensed under the Apache 2 license. 13
Summary of activity states
State Callbacks Description

Created onCreate() Activity is being initialized.

Started onStart() Activity is visible to the user.

Resumed onResume() Activity has input focus.

Paused onPause() Activity does not have input focus.

Stopped onStop() Activity is no longer visible.

Destroyed onDestroy() Activity is destroyed.

Android Development with Kotlin This work is licensed under the Apache 2 license. 14
Save state
User expects UI state to stay the same after a config change or if the
app is terminated when in the background.
● Activity is destroyed and restarted, or app is terminated and
activity is started.
● Store user data needed to reconstruct app and activity Lifecycle
changes:
○ Use Bundle provided by onSaveInstanceState().
○ onCreate() receives the Bundle as an argument when
activity is created again.

Android Development with Kotlin This work is licensed under the Apache 2 license. 15
Logging

Android Development with Kotlin This work is licensed under the Apache 2 license. 16
Logging in Android

● Monitor the flow of events or state of your app.


● Use the built-in Log class or third-party library.
● Example Log method call: Log.d(TAG, "Message")

Android Development with Kotlin This work is licensed under the Apache 2 license. 17
Write logs

Priority level Log method

Verbose Log.v(String, String)


Debug Log.d(String, String)
Info Log.i(String, String)
Warning Log.w(String, String)
Error Log.e(String, String)

Android Development with Kotlin This work is licensed under the Apache 2 license. 18
Fragment lifecycle

Android Development with Kotlin This work is licensed under the Apache 2 license. 19
Fragment states
CREATED

STARTED

RESUMED
Fragment is
running
PAUSED

STOPPED
DESTROYE
D
Android Development with Kotlin This work is licensed under the Apache 2 license. 20
Fragment lifecycle diagram

Fragmen
onViewCreated(
t is onAttach() onCreate() onCreateView()
)
onStart() onResume()
added

Fragment
Fragment onDestroyView(
is active
onPause() onStop()
)
onDestroy() onDetach() is
destroyed

Android Development with Kotlin This work is licensed under the Apache 2 license. 21
onAttach()

● Called when a fragment is attached to a context


● Immediately precedes onCreate()

Android Development with Kotlin This work is licensed under the Apache 2 license. 22
onCreateView()

● Called to create the view hierarchy associated with the


fragment
● Inflate the fragment layout here and return the root view

Android Development with Kotlin This work is licensed under the Apache 2 license. 23
onViewCreated()

● Called when view hierarchy has already been created


● Perform any remaining initialization here (for example,
restore state from Bundle)

Android Development with Kotlin This work is licensed under the Apache 2 license. 24
onDestroyView() and onDetach()

● onDestroyView() is called when view hierarchy of


fragment is removed.
● onDetach() is called when fragment is no longer attached
to the host.

Android Development with Kotlin This work is licensed under the Apache 2 license. 25
Summary of fragment states
State Callbacks Description

Initialized onAttach() Fragment is attached to host.

Created onCreate(), onCreateView(), Fragment is created and layout is being


onViewCreated() initialized.

Started onStart() Fragment is started and visible.

Resumed onResume() Fragment has input focus.

Paused onPause() Fragment no longer has input focus.

Stopped onStop() Fragment is not visible.

Destroyed onDestroyView(), onDestroy(), Fragment is removed from host.


onDetach()

Android Development with Kotlin This work is licensed under the Apache 2 license. 26
Save fragment state across config
changes
Preserve UI state in fragments by storing state in Bundle:
● onSaveInstanceState(outState: Bundle)

Retrieve that data by receiving the Bundle in these fragment


callbacks:
● onCreate()
● onCreateView()
● onViewCreated()

Android Development with Kotlin This work is licensed under the Apache 2 license. 27
Lifecycle-aware
components

Android Development with Kotlin This work is licensed under the Apache 2 license. 28
Lifecycle-aware components

Adjust their behavior based on activity or fragment lifecycle


● Use the androidx.lifecycle library
● Lifecycle tracks the lifecycle state of an activity or
fragment
○ Holds current lifecycle state
○ Dispatches lifecycle events (when there are state
changes)
Android Development with Kotlin This work is licensed under the Apache 2 license. 29
LifecycleOwner

● Interface that says this class has a lifecycle


● Implementers must implement getLifecycle() method
Examples: Fragment and AppCompatActivity are
implementations of LifecycleOwner

Android Development with Kotlin This work is licensed under the Apache 2 license. 30
LifecycleObserver
Implement LifecycleObserver interface:

class MyObserver : LifecycleObserver {


@OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
fun connectListener() {
...
}

Add the observer to the lifecycle:

myLifecycleOwner.getLifecycle().addObserver(MyObserver())

Android Development with Kotlin This work is licensed under the Apache 2 license. 31
Tasks and back stack

Android Development with Kotlin This work is licensed under the Apache 2 license. 32
Back stack of activities

EmailActivity

Back stack

Android Development with Kotlin This work is licensed under the Apache 2 license. 33
Add to the back stack

ComposeActivity

EmailActivity

Back stack

Android Development with Kotlin This work is licensed under the Apache 2 license. 34
Add to the back stack again

AttachFileActivity

ComposeActivity

EmailActivity

Back stack

Android Development with Kotlin This work is licensed under the Apache 2 license. 35
Tap Back button

AttachFileActivity

popped off the stack

ComposeActivity

EmailActivity

Back stack

Android Development with Kotlin This work is licensed under the Apache 2 license. 36
Tap Back button again

ComposeActivity

popped off the stack

EmailActivity

Back stack

Android Development with Kotlin This work is licensed under the Apache 2 license. 37
First destination in the back stack

First
fragment

FirstFragment

Back stack

Android Development with Kotlin This work is licensed under the Apache 2 license. 38
Add a destination to the back stack

Second
fragment
SecondFragment

FirstFragment

Back stack

Android Development with Kotlin This work is licensed under the Apache 2 license. 39
Tap Back button

SecondFragmen
t
First
fragment popped off the stack

FirstFragment

Back stack

Android Development with Kotlin This work is licensed under the Apache 2 license. 40
Another back stack example
ResultFragment

Question3Fragment

Result Question2Fragment
fragment
Question1Fragment

WelcomeFragment

Back stack

Android Development with Kotlin This work is licensed under the Apache 2 license. 41
Modify Back button behavior
ResultFragment

pop additional destinations Question3Fragment


off the back stack
Welcome Question2Fragment
fragment
Question1Fragment

WelcomeFragment

Back stack

Android Development with Kotlin This work is licensed under the Apache 2 license. 42
Summary

Android Development with Kotlin This work is licensed under the Apache 2 license. 43
Summary
In Lesson 7, you learned how to:
● Understand how an activity instance transitions through different lifec
ycle states as the user interacts with or leaves your app
● Reserve UI state across configuration changes using a Bundle
● Fragment lifecycle callback methods similar to activity, but with additio
ns
● Use lifecycle-aware components help organize your app code
● Use default or custom back stack behavior
● Use logging to help debug and track the state of the app

Android Development with Kotlin This work is licensed under the Apache 2 license. 44
Learn more

● Understand the Activity Lifecycle


● Activity class
● Fragments guide and lifecycle
● Fragment class

Android Development with Kotlin This work is licensed under the Apache 2 license. 45
Pathway

Practice what you’ve learned by


completing the pathway:
Lesson 7: Activity and FragmentLifecycles

Android Development with Kotlin This work is licensed under the Apache 2 license. 46
Lesson 8:
App architecture
(UI layer)

Android Development with Kotlin v1.0 This work is licensed under the Apache 2 license. 1
About this lesson
Lesson 8: App architecture (UI layer)
● Android app architecture
● ViewModel
● Data binding
● LiveData
● Transform LiveData
● Summary

Android Development with Kotlin This work is licensed under the Apache 2 license. 2
Android app architecture

Android Development with Kotlin This work is licensed under the Apache 2 license. 3
Avoid short-term hacks

● External factors, such as tight deadlines, can lead to poor


decisions about app design and structure.
● Decisions have consequences for future work (app can be
harder to maintain long-term).
● Need to balance on-time delivery and future maintenance
burden.

Android Development with Kotlin This work is licensed under the Apache 2 license. 4
Examples of short-term hacks

● Tailoring your app to a specific device


● Blindly copying and pasting code into your files
● Placing all business logic in activity file
● Hardcoding user-facing strings in your code

Android Development with Kotlin This work is licensed under the Apache 2 license. 5
Why you need good app
architecture
● Clearly defines where specific business logic belongs
● Makes it easier for developers to collaborate
● Makes your code easier to test
● Lets you benefit from already-solved problems
● Saves time and reduces technical debt as you extend your
app

Android Development with Kotlin This work is licensed under the Apache 2 license. 6
Android Jetpack

● Android libraries that incorporate best practices and provide


backward compatibility in your apps
● Jetpack comprises the androidx.* package libraries

Android Development with Kotlin This work is licensed under the Apache 2 license. 7
Separation of concerns

res/
layout
UI Controller
(Activity/Fragment) ViewModel

LiveData Data
Layer

Android Development with Kotlin This work is licensed under the Apache 2 license. 8
Architecture components

● Architecture design patterns, like MVVM and MVI, describe


a loose template for what the structure of your app should
be.
● Jetpack architecture components help you design robust,
testable, and maintainable apps.

Android Development with Kotlin This work is licensed under the Apache 2 license. 9
ViewModel

Android Development with Kotlin This work is licensed under the Apache 2 license. 10
Gradle: lifecycle extensions

In app/build.gradle file:

dependencies {
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycle_version"
implementation "androidx.activity:activity-ktx:$activity_version"

Android Development with Kotlin This work is licensed under the Apache 2 license. 11
ViewModel

● Prepares data for the UI


● Must not reference activity, fragment, or views in view hierarchy
● Scoped to a lifecycle (which activity and fragment have)
● Enables data to survive configuration changes
● Survives as long as the scope is alive

Android Development with Kotlin This work is licensed under the Apache 2 license. 12
Lifetime of a ViewModel

Android Development with Kotlin This work is licensed under the Apache 2 license. 13
Kabaddi Kounter

Android Development with Kotlin This work is licensed under the Apache 2 license. 14
ViewModel class
abstract class ViewModel

Android Development with Kotlin This work is licensed under the Apache 2 license. 15
Implement a ViewModel
class ScoreViewModel : ViewModel() {
var scoreA : Int = 0
var scoreB : Int = 0
fun incrementScore(isTeamA: Boolean) {
if (isTeamA) {
scoreA++
}
else {
scoreB++
}
}
}

Android Development with Kotlin This work is licensed under the Apache 2 license. 16
Load and use a ViewModel
class MainActivity : AppCompatActivity() {
// Delegate provided by androidx.activity.viewModels
val viewModel: ScoreViewModel by viewModels()

override fun onCreate(savedInstanceState: Bundle?) {


...
val scoreViewA: TextView = findViewById(R.id.scoreA)
scoreViewA.text = viewModel.scoreA.toString()

Android Development with Kotlin This work is licensed under the Apache 2 license. 17
Using a ViewModel
Within MainActivity onCreate():

val scoreViewA: TextView = findViewById(R.id.scoreA)


val plusOneButtonA: Button = findViewById(R.id.plusOne_teamA)

plusOneButtonA.setOnClickListener {
viewModel.incrementScore(true)
scoreViewA.text = viewModel.scoreA.toString()
}

Android Development with Kotlin This work is licensed under the Apache 2 license. 18
Data binding

Android Development with Kotlin This work is licensed under the Apache 2 license. 19
ViewModels and data binding
● App architecture without data binding
UI Controller Views
ViewModel (activity/fragment (defined in XML
with click listeners) layout)

● ViewModels can work in concert with data binding


Views
ViewModel (defined in XML
layout)

Android Development with Kotlin This work is licensed under the Apache 2 license. 20
Data binding in XML revisited

Specify ViewModels in the data tag of a binding.


<layout>
<data>
<variable>
name="viewModel"
type="com.example.kabaddikounter.ScoreViewModel" />
</data>
<ConstraintLayout ../>
</layout>

Android Development with Kotlin This work is licensed under the Apache 2 license. 21
Attaching a ViewModel to a data
binding
class MainActivity : AppCompatActivity() {

val viewModel: ScoreViewModel by viewModels()

override fun onCreate(savedInstanceState: Bundle?) {


super.onCreate(savedInstanceState)
val binding: ActivityMainBinding = DataBindingUtil.setContentView(this,
R.layout.activity_main)

binding.viewModel = viewModel
...

Android Development with Kotlin This work is licensed under the Apache 2 license. 22
Using a ViewModel from a data
binding
In activity_main.xml:

<TextView
android:id="@+id/scoreViewA"
android:text="@{viewModel.scoreA.toString()}" />

...

Android Development with Kotlin This work is licensed under the Apache 2 license. 23
ViewModels and data binding

override fun onCreate(savedInstanceState: Bundle?) {


...
val binding: ActivityMainBinding = DataBindingUtil.setContentView(this,
R.layout.activity_main)

binding.plusOneButtonA.setOnClickListener {
viewModel.incrementScore(true)
binding.scoreViewA.text = viewModel.scoreA.toString()
}
}

Android Development with Kotlin This work is licensed under the Apache 2 license. 24
LiveData

Android Development with Kotlin This work is licensed under the Apache 2 license. 25
Observer design pattern

● Subject maintains list of observers to notify when state


changes.
● Observers receive state changes from subject and execute
appropriate code.
● Observers can be added or removed at any time.

Android Development with Kotlin This work is licensed under the Apache 2 license. 26
Observer design pattern diagram

Observable

notify observe() notify observe()

Observer Observer

Android Development with Kotlin This work is licensed under the Apache 2 license. 27
LiveData

● A lifecycle-aware data holder that can be observed


● Wrapper that can be used with any data including lists
(for example, LiveData<Int> holds an Int)
● Often used by ViewModels to hold individual data fields
● Observers (activity or fragment) can be added or removed
○ observe(owner: LifecycleOwner, observer: Observer)
removeObserver(observer: Observer)

Android Development with Kotlin This work is licensed under the Apache 2 license. 28
LiveData versus MutableLiveData

LiveData<T> MutableLiveData<T>

● getValue() ● getValue()
● postValue(value: T)
● setValue(value: T)

T is the type of data that’s stored in LiveData or


MutableLiveData.

Android Development with Kotlin This work is licensed under the Apache 2 license. 29
Use LiveData in ViewModel
class ScoreViewModel : ViewModel() {

private val _scoreA = MutableLiveData<Int>(0)


val scoreA: LiveData<Int>
get() = _scoreA

fun incrementScore(isTeamA: Boolean) {


if (isTeamA) {
_scoreA.value = _scoreA.value!! + 1
}
...

Android Development with Kotlin This work is licensed under the Apache 2 license. 30
Add an observer on LiveData
Set up click listener to increment ViewModel score:
binding.plusOneButtonA.setOnClickListener {
viewModel.incrementScore(true)
}

Create observer to update team A score on screen:


val scoreA_Observer = Observer<Int> { newValue ->
binding.scoreViewA.text = newValue.toString()
}

Add the observer onto scoreA LiveData in ViewModel:


viewModel.scoreA.observe(this, scoreA_Observer)

Android Development with Kotlin This work is licensed under the Apache 2 license. 31
Two-way data binding

● We already have two-way binding with ViewModel and


LiveData.
● Binding to LiveData in XML eliminates need for an
observer in code.

Android Development with Kotlin This work is licensed under the Apache 2 license. 32
Example layout XML
<layout>
<data>
<variable>
name="viewModel"
type="com.example.kabaddikounter.ScoreViewModel" />
</data>
<ConstraintLayout ..>
<TextView ...
android:id="@+id/scoreViewA"
android:text="@{viewModel.scoreA.toString()}" />
...
</ConstraintLayout>
</layout>

Android Development with Kotlin This work is licensed under the Apache 2 license. 33
Example Activity
class MainActivity : AppCompatActivity() {
val viewModel: ScoreViewModel by viewModels()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val binding: ActivityMainBinding = DataBindingUtil
.setContentView(this, R.layout.activity_main)
binding.viewModel = viewModel
binding.lifecycleOwner = this
binding.plusOneButtonA.setOnClickListener {
viewModel.incrementScore(true)
}
...

Android Development with Kotlin This work is licensed under the Apache 2 license. 34
Example ViewModel
class ScoreViewModel : ViewModel() {
private val _scoreA = MutableLiveData<Int>(0)
val scoreA : LiveData<Int>
get() = _scoreA
private val _scoreB = MutableLiveData<Int>(0)
val scoreB : LiveData<Int>
get() = _scoreB
fun incrementScore(isTeamA: Boolean) {
if (isTeamA) {
_scoreA.value = _scoreA.value!! + 1
} else {
_scoreB.value = _scoreB.value!! + 1
}
}
}
Android Development with Kotlin This work is licensed under the Apache 2 license. 35
Transform LiveData

Android Development with Kotlin This work is licensed under the Apache 2 license. 36
Manipulating LiveData with
transformations

LiveData can be transformed into a new LiveData object.


● map()
● switchMap()

Android Development with Kotlin This work is licensed under the Apache 2 license. 37
Example LiveData with
transformations

val result: LiveData<String> = Transformations.map(viewModel.scoreA) {


x -> if (x > 10) "A Wins" else ""
}

Android Development with Kotlin This work is licensed under the Apache 2 license. 38
Summary

Android Development with Kotlin This work is licensed under the Apache 2 license. 39
Summary
In Lesson 8, you learned how to:
● Follow good app architecture design, and the separation-of-conce
rns principle to make apps more maintainable and reduce technic
al debt

● Create a ViewModel to hold data separately from a UI controller


● Use ViewModel
with data binding to make a responsive UI with less code
● Use observers to automatically get updates from LiveData
Android Development with Kotlin This work is licensed under the Apache 2 license. 40
Learn More

● Guide to app architecture


● Android Jetpack
● ViewModel Overview
● Android architecture sample app
● ViewModelProvider
● Lifecycle Aware Data Loading with Architecture Components
● ViewModels and LiveData: Patterns + AntiPatterns

Android Development with Kotlin This work is licensed under the Apache 2 license. 41
Pathway

Practice what you’ve learned by


completing the pathway:
Lesson 8: App architecture (UI layer)

Android Development with Kotlin This work is licensed under the Apache 2 license. 42
Lesson 9:
App architecture
(persistence)

Android Development with Kotlin v1.0 This work is licensed under the Apache 2 license. 1
About this lesson
Lesson 9: App architecture (persistence)
● Storing data
● Room persistence library
● Asynchronous programming
● Coroutines
● Testing databases
● Summary

Android Development with Kotlin This work is licensed under the Apache 2 license. 2
Storing data

Android Development with Kotlin This work is licensed under the Apache 2 license. 3
Ways to store data in an Android
app
● App-specific storage
● Shared storage (files to be shared with other apps)
● Preferences
● Databases

Android Development with Kotlin This work is licensed under the Apache 2 license. 4
What is a database?

Collection of structured data that can be easily accessed,


searched, and organized, consisting of:
Example Database
● Tables
person car
● Rows
_id _id
name make
● Columns age model
email year

5
Android Development with Kotlin This work is licensed under the Apache 2 license.
Structured Query Language (SQL)
Use SQL to access and modify a relational database.

● Create new tables


● Query for data
● Insert new data
● Update data
● Delete data

Android Development with Kotlin This work is licensed under the Apache 2 license. 6
SQLite in Android

Store data

Your app

SQLite database

Android Development with Kotlin This work is licensed under the Apache 2 license. 7
Example SQLite commands

Create
INSERT INTO colors VALUES ("red", "#FF0000");

Read
SELECT * from colors;

Update
UPDATE colors SET hex="#DD0000" WHERE name="red";

Delete
DELETE FROM colors WHERE name = "red";

Android Development with Kotlin This work is licensed under the Apache 2 license. 8
Interacting directly with a database

● No compile-time verification of raw SQL queries


● Need lots of boilerplate code to convert between
SQL queries data objects

Android Development with Kotlin This work is licensed under the Apache 2 license. 9
Room persistence library

Android Development with Kotlin This work is licensed under the Apache 2 license. 10
Add Gradle dependencies
dependencies {
implementation "androidx.room:room-runtime:$room_version"
kapt "androidx.room:room-compiler:$room_version"

// Kotlin Extensions and Coroutines support for Room


implementation "androidx.room:room-ktx:$room_version"

// Test helpers
testImplementation "androidx.room:room-testing:$room_version"
}

Android Development with Kotlin This work is licensed under the Apache 2 license. 11
Room

Rest of the app code

Color("#FF0000", "red")
Room

Data access Color("#4CAF50",


Colors object "green")
database
Color("#1155CC",
"blue")

Android Development with Kotlin This work is licensed under the Apache 2 license. 12
ColorValue app

Android Development with Kotlin This work is licensed under the Apache 2 license. 13
Room

● Entity Color
● DAO ColorDao
● Database ColorDatabase

Android Development with Kotlin This work is licensed under the Apache 2 license. 14
Color class

data class Color {


val hex: String,
val name: String
}

Android Development with Kotlin This work is licensed under the Apache 2 license. 15
Annotations

● Provide extra information to the compiler


@Entity marks entity class, @Dao for DAO, @Database for database
● Can take parameters

@Entity(tableName = "colors")
● Can autogenerate code for you

Android Development with Kotlin This work is licensed under the Apache 2 license. 16
Entity

Class that maps to a SQLite database table


● @Entity
● @PrimaryKey
● @ColumnInfo

Android Development with Kotlin This work is licensed under the Apache 2 license. 17
Example entity

@Entity(tableName = "colors")
colors
data class Color {
_id
@PrimaryKey(autoGenerate = true) val _id: Int, hex_color
name
@ColumnInfo(name = "hex_color") val hex: String,
val name: String
}

Android Development with Kotlin This work is licensed under the Apache 2 license. 18
Data access object (DAO)

Work with DAO classes instead of accessing database directly:


● Define database interactions in the DAO.
● Declare DAO as an interface or abstract class.
● Room creates DAO implementation at compile time.
● Room verifies all of your DAO queries at compile-time.

Android Development with Kotlin This work is licensed under the Apache 2 license. 19
Example DAO
@Dao
interface ColorDao {
@Query("SELECT * FROM colors")
fun getAll(): Array<Color>
@Insert
fun insert(vararg color: Color)
@Update
fun update(color: Color)
@Delete
fun delete(color: Color)

Android Development with Kotlin This work is licensed under the Apache 2 license. 20
Query
@Dao
interface ColorDao {

@Query("SELECT * FROM colors")


fun getAll(): Array<Color>

@Query("SELECT * FROM colors WHERE name = :name")


fun getColorByName(name: String): LiveData<Color>

@Query("SELECT * FROM colors WHERE hex_color = :hex")


fun getColorByHex(hex: String): LiveData<Color>

Android Development with Kotlin This work is licensed under the Apache 2 license. 21
Insert

@Dao
interface ColorDao {
...

@Insert
fun insert(vararg color: Color)

...
}

Android Development with Kotlin This work is licensed under the Apache 2 license. 22
Update

@Dao
interface ColorDao {
...

@Update
fun update(color: Color)

...
}

Android Development with Kotlin This work is licensed under the Apache 2 license. 23
Delete

@Dao
interface ColorDao {
...

@Delete
fun delete(color: Color)

...
}

Android Development with Kotlin This work is licensed under the Apache 2 license. 24
Create a Room database

● Annotate class with @Database and include list of entities:


@Database(entities = [Color::class], version = 1)

● Declare abstract class that extends RoomDatabase:


abstract class ColorDatabase : RoomDatabase() {

○ Declare abstract method with no args that returns the


DAO:
abstract fun colorDao(): ColorDao
Android Development with Kotlin This work is licensed under the Apache 2 license. 25
Example Room database
@Database(entities = [Color::class], version = 1)
abstract class ColorDatabase : RoomDatabase() {
abstract fun colorDao(): ColorDao
companion object {
@Volatile
private var INSTANCE: ColorDatabase? = null
fun getInstance(context: Context): ColorDatabase {
...
}
}
...

Android Development with Kotlin This work is licensed under the Apache 2 license. 26
Create database instance
fun getInstance(context: Context): ColorDatabase {
return INSTANCE ?: synchronized(this) {
INSTANCE ?: Room.databaseBuilder(
context.applicationContext,
ColorDatabase::class.java, "color_database"
)
.fallbackToDestructiveMigration()
.build()
.also { INSTANCE = it }
}
}

Android Development with Kotlin This work is licensed under the Apache 2 license. 27
Get and use a DAO

Get the DAO from the database:


val colorDao = ColorDatabase.getInstance(application).colorDao()

Create new Color and use DAO to insert it into database:


val newColor = Color(hex = "#6200EE", name = "purple")
colorDao.insert(newColor)

Android Development with Kotlin This work is licensed under the Apache 2 license. 28
Asynchronous
programming

Android Development with Kotlin This work is licensed under the Apache 2 license. 29
Long-running tasks

● Download information
● Sync with a server
● Write to a file
● Heavy computation
● Read from, or write to, a database

Android Development with Kotlin This work is licensed under the Apache 2 license. 30
Need for async programming

● Limited time to do tasks and remain responsive


● Balanced with the need to execute long-running tasks
● Control over how and where tasks are executed

Android Development with Kotlin This work is licensed under the Apache 2 license. 31
Async programming on Android

● Threading
● Callbacks
● Plus many other options

What is the recommended way?

Android Development with Kotlin This work is licensed under the Apache 2 license. 32
Coroutines

Android Development with Kotlin This work is licensed under the Apache 2 license. 33
Coroutines

● Keep your app responsive while managing long-running


tasks.
● Simplify asynchronous code in your Android app.
● Write code in sequential way
● Handle exceptions with try/catch block

Android Development with Kotlin This work is licensed under the Apache 2 license. 34
Benefits of coroutines

● Lightweight
● Fewer memory leaks
● Built-in cancellation support
● Jetpack integration

Android Development with Kotlin This work is licensed under the Apache 2 license. 35
Suspend functions

● Add suspend modifier


● Must be called by other suspend functions or coroutines

Android Development with Kotlin This work is licensed under the Apache 2 license. 36
Suspend and resume

● suspend
Pauses execution of current coroutine and saves local
variables
● resume
Automatically loads saved state and continues execution
from the point the code was suspended

Android Development with Kotlin This work is licensed under the Apache 2 license. 37
Example

Android Development with Kotlin This work is licensed under the Apache 2 license. 38
Add suspend modifier to DAO
methods
@Dao
interface ColorDao {
@Query("SELECT * FROM colors")
suspend fun getAll(): Array<Color>
@Insert
suspend fun insert(vararg color: Color)
@Update
suspend fun update(color: Color)
@Delete
suspend fun delete(color: Color)

Android Development with Kotlin This work is licensed under the Apache 2 license. 39
Control where coroutines run

Dispatcher Description of work Examples of work


Dispatchers.Main UI and nonblocking Updating LiveData,
(short) tasks calling suspend
functions
Dispatchers.IO Network and disk tasks Database, file IO
Dispatchers.Default CPU intensive Parsing JSON

Android Development with Kotlin This work is licensed under the Apache 2 license. 40
withContext
suspend fun get(url: String) {

// Start on Dispatchers.Main

withContext(Dispatchers.IO) {
// Switches to Dispatchers.IO
// Perform blocking network IO here
}

// Returns to Dispatchers.Main
}

Android Development with Kotlin This work is licensed under the Apache 2 license. 41
CoroutineScope
Coroutines must run in a CoroutineScope:
● Keeps track of all coroutines started in it (even suspended ones)
● Provides a way to cancel coroutines in a scope
● Provides a bridge between regular functions and coroutines
Examples: GlobalScope
ViewModel has viewModelScope
Lifecycle has lifecycleScope

Android Development with Kotlin This work is licensed under the Apache 2 license. 42
Start new coroutines

● launch - no result needed


fun loadUI() {
launch {
fetchDocs()
}
}

● async - can return a result

Android Development with Kotlin This work is licensed under the Apache 2 license. 43
ViewModelScope

class MyViewModel: ViewModel() {

init {
viewModelScope.launch {
// Coroutine that will be canceled
// when the ViewModel is cleared
}
}
...

Android Development with Kotlin This work is licensed under the Apache 2 license. 44
Example viewModelScope

class ColorViewModel(val dao: ColorDao, application: Application)


: AndroidViewModel(application) {

fun save(color: Color) {


viewModelScope.launch {
colorDao.insert(color)
}
}

...

Android Development with Kotlin This work is licensed under the Apache 2 license. 45
Testing databases

Android Development with Kotlin This work is licensed under the Apache 2 license. 46
Add Gradle dependencies
android {
defaultConfig {
...
testInstrumentationRunner "androidx.test.runner
.AndroidJUnitRunner"
testInstrumentationRunnerArguments clearPackageData: 'true'
}
}
dependencies {
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test.ext:junit:1.1.0'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1'
}

Android Development with Kotlin This work is licensed under the Apache 2 license. 47
Testing Android code

● @RunWith(AndroidJUnit4::class)
● @Before
● @After
● @Test

Android Development with Kotlin This work is licensed under the Apache 2 license. 48
Create test class
@RunWith(AndroidJUnit4::class)
class DatabaseTest {

private lateinit val colorDao: ColorDao


private lateinit val db: ColorDatabase

private val red = Color(hex = "#FF0000", name = "red")


private val green = Color(hex = "#00FF00", name = "green")
private val blue = Color(hex = "#0000FF", name = "blue")

...

Android Development with Kotlin This work is licensed under the Apache 2 license. 49
Create and close database for each
test
In DatabaseTest.kt:
@Before
fun createDb() {
val context: Context = ApplicationProvider.getApplicationContext()
db = Room.inMemoryDatabaseBuilder(context, ColorDatabase::class.java)
.allowMainThreadQueries()
.build()
colorDao = db.colorDao()
}
@After
@Throws(IOException::class)
fun closeDb() = db.close()

Android Development with Kotlin This work is licensed under the Apache 2 license. 50
Test insert and retrieve from a
database
In DatabaseTest.kt:
@Test
@Throws(Exception::class)
fun insertAndRetrieve() {
colorDao.insert(red, green, blue)
val colors = colorDao.getAll()
assert(colors.size == 3)
}

Android Development with Kotlin This work is licensed under the Apache 2 license. 51
Summary

Android Development with Kotlin This work is licensed under the Apache 2 license. 52
Summary
In Lesson 9, you learned how to:
● Set up and configure a database using the Room library
● Use coroutines for asynchronous programming
● Use coroutines with Room
● Test a database

Android Development with Kotlin This work is licensed under the Apache 2 license. 53
Learn more
● 7 Pro-tips for Room
● Room Persistence Library
● SQLite Home Page
● Save data using SQLite
● Coroutines Guide
● Dispatchers - kotlinx-coroutines-core
● Coroutines on Android (part I): Getting the background
● Coroutines on Android (part II): Getting started
● Easy Coroutines in Android: viewModelScope
● Kotlin Coroutines
Android101
Development with Kotlin This work is licensed under the Apache 2 license. 54
Pathway

Practice what you’ve learned by


completing the pathway:
Lesson 9: App architecture(persistence)

Android Development with Kotlin This work is licensed under the Apache 2 license. 55
Lesson 10:
Advanced
RecyclerView
use cases
Android Development with Kotlin v1.0 This work is licensed under the Apache 2 license. 1
About this lesson
Lesson 10: Advanced RecyclerView use cases
● RecyclerView recap
● Advanced binding
● Multiple item view types
● Headers
● Grid layout
● Summary

Android Development with Kotlin This work is licensed under the Apache 2 license. 2
RecyclerView recap

Android Development with Kotlin This work is licensed under the Apache 2 license. 3
RecyclerView overview

● Widget for displaying lists of data


● "Recycles" (reuses) item views to make scrolling more
performant
● Can specify a list item layout for each item in the dataset
● Supports animations and transitions

Android Development with Kotlin This work is licensed under the Apache 2 license. 4
View recycling in RecyclerView
Boston, If item is scrolled
Massachusetts offscreen, it isn’t
Chicago, Illinois
destroyed. Item is put in
Mountain View, a pool to be recycled.
California
Miami, Florida
Seattle, Washington
Reno, Nevada
onBindViewHolder
Nashville, Tennessee binds the view with the
new values, and then
Little Rock, Arkansas the view gets reinserted
in the list.
Android Development with Kotlin This work is licensed under the Apache 2 license. 5
RecyclerViewDemo app

1
2
3
4
5
6
7
8
9
10
11
12
13

Android Development with Kotlin This work is licensed under the Apache 2 license. 6
Adapter for RecyclerViewDemo

class NumberListAdapter(var data: List<Int>):


RecyclerView.Adapter<NumberListAdapter.IntViewHolder>() {
class IntViewHolder(val row: View): RecyclerView.ViewHolder(row) {
val textView = row.findViewById<TextView>(R.id.number)

Android Development with Kotlin This work is licensed under the Apache 2 license. 7
Functions for RecyclerViewDemo

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int):


IntViewHolder {
val layout = LayoutInflater.from(parent.context)
.inflate(R.layout.item_view, parent, false)
return IntViewHolder(layout)
}

override fun onBindViewHolder(holder: IntViewHolder, position: Int) {


holder.textView.text = data.get(position).toString()
}

Android Development with Kotlin This work is licensed under the Apache 2 license. 8
Set the adapter onto the
RecyclerView
In MainActivity.kt:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)

val rv: RecyclerView = findViewById(R.id.rv)


rv.layoutManager = LinearLayoutManager(this)

rv.adapter = NumberListAdapter(IntRange(0,100).toList())
}

Android Development with Kotlin This work is licensed under the Apache 2 license. 9
Make items in the list clickable
In NumberListAdapter.kt:
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): IntViewHolder{
val layout = LayoutInflater.from(parent.context).inflate(R.layout.item_view,
parent, false)
val holder = IntViewHolder(layout)
holder.row.setOnClickListener {
// Do something on click
}
return holder
}

Android Development with Kotlin This work is licensed under the Apache 2 license. 10
ListAdapter

● RecyclerView.Adapter
○ Disposes UI data on every update
○ Can be costly and wasteful
● ListAdapter
○ Computes the difference between what is currently
shown and what needs to be shown
○ Changes are calculated on a background thread

Android Development with Kotlin This work is licensed under the Apache 2 license. 11
Sort using RecyclerView.Adapter
Starting state Ending state
1 1 1
5 2 2
2 3 3
6 4 4
3 5 5
8 8 16 actions:
7 6 6
deletions insertions 8 deletions
4 7 8 insertions 7
8 8 8

Android Development with Kotlin This work is licensed under the Apache 2 license. 12
Sort using ListAdapter
Starting state 1 Ending state
5
1 1
2
5 6 2
2 3 3
6 7 4
3 4 5
3 insertions 6 actions:
5
7 3 deletions 3 insertions 6
6 3 deletions
4 7
7
8 8 8

Android Development with Kotlin This work is licensed under the Apache 2 license. 13
ListAdapter example

class NumberListAdapter: ListAdapter<Int,


NumberListAdapter.IntViewHolder>(RowItemDiffCallback()) {

class IntViewHolder(val row: View):RecyclerView.ViewHolder(row) {


val textView = row.findViewById<TextView>(R.id.number)
}

...

Android Development with Kotlin This work is licensed under the Apache 2 license. 14
DiffUtil.ItemCallback

Determines the transformations needed to translate one list into


another
● areContentsTheSame(oldItem: T, newItem: T): Boolean
● areItemsTheSame(oldItem: T, newItem: T): Boolean

Android Development with Kotlin This work is licensed under the Apache 2 license. 15
DiffUtil.ItemCallback example

class RowItemDiffCallback : DiffUtil.ItemCallback<Int>() {

override fun areItemsTheSame(oldItem: Int, newItem: Int): Boolean {


return oldItem == newItem
}

override fun areContentsTheSame(oldItem: Int, newItem: Int): Boolean {


return oldItem == newItem
}
}

Android Development with Kotlin This work is licensed under the Apache 2 license. 16
Advanced binding

Android Development with Kotlin This work is licensed under the Apache 2 license. 17
ViewHolders and data binding
class IntViewHolder private constructor(val binding: ItemViewBinding):
RecyclerView.ViewHolder(binding.root) {
companion object {
fun from(parent: ViewGroup): IntViewHolder {
val layoutInflater = LayoutInflater.from(parent.context)
val binding = ItemViewBinding.inflate(layoutInflater,
parent, false)
return IntViewHolder(binding)
}
}
}

Android Development with Kotlin This work is licensed under the Apache 2 license. 18
Using the ViewHolder in a
ListAdapter
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int):
IntViewHolder {
return IntViewHolder.from(parent)
}

override fun onBindViewHolder(holder: NumberListAdapter.IntViewHolder,


position: Int) {
holder.binding.num = getItem(position)
}

Android Development with Kotlin This work is licensed under the Apache 2 license. 19
Binding adapters

Let you map a function to an attribute in your XML

● Override existing framework behavior:


android:text = "foo" → TextView.setText("foo") is called

● Create your own custom attributes:


app:base2Number = "5" → TextView.setBase2Number("5") is called

Android Development with Kotlin This work is licensed under the Apache 2 license. 20
Custom attribute

Add another TextView in the list item layout that uses a custom attribute:
<TextView
android:id="@+id/base2_number" Example list item
android:layout_width="wrap_content"
android:layout_height="wrap_content" 5 101
android:textSize="24sp"
app:base2Number="@{num}"/> @id/number @id/base2_number

Android Development with Kotlin This work is licensed under the Apache 2 license. 21
Add a binding adapter
Declare binding adapter:
@BindingAdapter("base2Number")
fun TextView.setBase2Number(item: Int) {
text = Integer.toBinaryString(item)
}
In NumberListAdapter.kt:
override fun onBindViewHolder(holder: NumberListAdapter.IntViewHolder,
position: Int) {
holder.binding.num = getItem(position)
holder.binding.executePendingBindings()
}

Android Development with Kotlin This work is licensed under the Apache 2 license. 22
Updated RecyclerViewDemo app

Android Development with Kotlin This work is licensed under the Apache 2 license. 23
Multiple item view types

Android Development with Kotlin This work is licensed under the Apache 2 license. 24
Add a new item view type

1. Create a new list item layout XML file.


2. Modify underlying adapter to hold the new type.
3. Override getItemViewType in adapter.
4. Create a new ViewHolder class.
5. Add conditional code in onCreateViewHolder and
onBindViewHolder to handle the new type.

Android Development with Kotlin This work is licensed under the Apache 2 license. 25
Declare new color item layout
<layout ...>
<data>
<variable
name="color"
type="android.graphics.Color" />
</data>
<androidx.constraintlayout.widget.ConstraintLayout ...>
<TextView
...
android:backgroundColor="@{color.toArgb()}" />
<TextView
...
android:text="@{color.toString()}" />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
Android Development with Kotlin This work is licensed under the Apache 2 license. 26
New view type
● Adapter should know about two item view types:
○ Item that displays a number
○ Item that displays a color
enum class ITEM_VIEW_TYPE { NUMBER, COLOR }

● Modify getItemViewType() to return the appropriate type (as


Int):
override fun getItemViewType(position: Int): Int

Android Development with Kotlin This work is licensed under the Apache 2 license. 27
Override getItemViewType

In NumberListAdapter.kt:
override fun getItemViewType(position: Int): Int {
return when(getItem(position)) {
is Int -> ITEM_VIEW_TYPE.NUMBER.ordinal
else -> ITEM_VIEW_TYPE.COLOR.ordinal
}
}

Android Development with Kotlin This work is licensed under the Apache 2 license. 28
Define new ViewHolder
class ColorViewHolder private constructor(val binding: ColorItemViewBinding):

RecyclerView.ViewHolder(binding.root) {

companion object {
fun from(parent: ViewGroup): ColorViewHolder {
val layoutInflater = LayoutInflater.from(parent.context)
val binding = ColorItemViewBinding.inflate(layoutInflater,
parent, false)
return ColorViewHolder(binding)
}
}
}
Android Development with Kotlin This work is licensed under the Apache 2 license. 29
Update onCreateViewHolder()

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int):


RecyclerView.ViewHolder {

return when(viewType) {
ITEM_VIEW_TYPE.NUMBER.ordinal -> IntViewHolder.from(parent)
else -> ColorViewHolder.from(parent)
}
}

Android Development with Kotlin This work is licensed under the Apache 2 license. 30
Update onBindViewHolder()
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
when (holder) {
is IntViewHolder -> {
holder.binding.num = getItem(position) as Int
holder.binding.executePendingBindings()
}
is ColorViewHolder -> {
holder.binding.color = getItem(position) as Color
holder.binding.executePendingBindings()
}
}
}

Android Development with Kotlin This work is licensed under the Apache 2 license. 31
Headers

Android Development with Kotlin This work is licensed under the Apache 2 license. 32
Headers Example
Entrees ● 2 item view types:
Burger $5.00 ○ header item
Salad $3.00 Drinks
Sandwich $4.00
○ food menu item
Drinks
Coffee $2.00
Coffee $2.00

Soda $1.00

Android Development with Kotlin This work is licensed under the Apache 2 license. 33
Grid layout

Android Development with Kotlin This work is licensed under the Apache 2 license. 34
List versus grid

Android Development with Kotlin This work is licensed under the Apache 2 license. 35
Specifying a LayoutManager
In MainActivity onCreate(), once you have a reference to the
RecyclerView
● Display a list with LinearLayoutManager:
recyclerView.layoutManager = LinearLayoutManager(this)
● Display a grid with GridLayoutManager:
recyclerView.layoutManager = GridLayoutManager(this, 2)

● Use a different layout manager (or create your own)

Android Development with Kotlin This work is licensed under the Apache 2 license. 36
GridLayoutManager

● Arranges items in a grid as a table of rows and columns.


● Orientation can be vertically or horizontally scrollable.
● By default, each item occupies 1 span.
● You can vary the number of spans an item takes up (span
size).

Android Development with Kotlin This work is licensed under the Apache 2 license. 37
Set span size for an item
Create SpanSizeLookup instance and override getSpanSize(position):

val manager = GridLayoutManager(this, 2)


manager.spanSizeLookup = object : GridLayoutManager.SpanSizeLookup() {
override fun getSpanSize(position: Int): Int {
return when (position) {
0,1,2 -> 2
else -> 1
}
}
}

Android Development with Kotlin This work is licensed under the Apache 2 license. 38
Summary

Android Development with Kotlin This work is licensed under the Apache 2 license. 39
Summary
In Lesson 10, you learned how to:
● Use ListAdapter to make RecyclerView
more efficient at updating lists
● Create a binding adapter with custom logic to set View values fro
m an XML attribute
● Handle multiple ViewHolders in the same RecyclerView
to show multiple item types
● Use GridLayoutManager to display items as a grid
● Specify span size for an item in a grid with
Android Development with Kotlin
SpanSizeLookup
This work is licensed under the Apache 2 license. 40
Learn More

● Create a List with RecyclerView


● RecyclerView
● ListAdapter
● Binding adapters
● GridLayoutManager
● DiffUtil and ItemCallback

Android Development with Kotlin This work is licensed under the Apache 2 license. 41
Pathway

Practice what you’ve learned by


completing the pathway:
Lesson 10: Advanced RecyclerViewuse cases

Android Development with Kotlin This work is licensed under the Apache 2 license. 42
Lesson 11:
Connect to the
internet

Android Development with Kotlin v1.0 This work is licensed under the Apache 2 license. 1
About this lesson
Lesson 11: Connect to the internet
● Android permissions
● Connect to, and use, network resources
● Connect to a web service
● Display images
● Summary

Android Development with Kotlin This work is licensed under the Apache 2 license. 2
Android permissions

Android Development with Kotlin This work is licensed under the Apache 2 license. 3
Permissions

● Protect the privacy of an Android user


● Declared with the <uses-permission> tag in the
AndroidManifest.xml

Android Development with Kotlin This work is licensed under the Apache 2 license. 4
Permissions granted to your app

● Permissions can be granted during installation or runtime,


depending on protection level.
● Each permission has a protection level: normal, signature,
or dangerous.
● For permissions granted during runtime, prompt users to
explicitly grant or deny access to your app.

Android Development with Kotlin This work is licensed under the Apache 2 license. 5
Permission protection levels

Protection Level Granted when? Must prompt Examples


before use?
Normal Install time No ACCESS_WIFI_STATE,
BLUETOOTH, VIBRATE,
INTERNET

Signature Install time No N/A

Dangerous Runtime Yes GET_ACCOUNTS, CAMERA,


CALL_PHONE

Android Development with Kotlin This work is licensed under the Apache 2 license. 6
Add permissions to the manifest
In AndroidManifest.xml:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.sampleapp">
<uses-permission android:name="android.permission.USE_BIOMETRIC" />
<application>
<activity
android:name=".MainActivity" ... >
...
</activity>
</application>
</manifest>

Android Development with Kotlin This work is licensed under the Apache 2 license. 7
Internet access permissions

In AndroidManifest.xml:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

Android Development with Kotlin This work is licensed under the Apache 2 license. 8
Request dangerous permissions

● Prompt the user to grant the permission when they try to


access functionality that requires a dangerous permission.
● Explain to the user why the permission is needed.
● Fall back gracefully if the user denies the permission (app
should still function).

Android Development with Kotlin This work is licensed under the Apache 2 license. 9
Prompt for dangerous permission

Android Development with Kotlin This work is licensed under the Apache 2 license. 10
App permissions best practices

● Only use the permissions necessary for your app to work.


● Pay attention to permissions required by libraries.
● Be transparent.
● Make system accesses explicit.

Android Development with Kotlin This work is licensed under the Apache 2 license. 11
Connect to, and use,
network resources

Android Development with Kotlin This work is licensed under the Apache 2 license. 12
Retrofit

● Networking library that turns your HTTP API into a Kotlin


and Java interface
● Enables processing of requests and responses into objects
for use by your apps
○ Provides base support for parsing common response
types, such as XML and JSON
○ Can be extended to support other response types

Android Development with Kotlin This work is licensed under the Apache 2 license. 13
Why use Retrofit?

● Builds on industry standard libraries, like OkHttp, that


provide:
○ HTTP/2 support
○ Connection pooling
○ Response caching and enhanced security
● Frees the developer from the scaffolding setup needed to
run a request

Android Development with Kotlin This work is licensed under the Apache 2 license. 14
Add Gradle dependencies

implementation "com.squareup.retrofit2:retrofit:2.9.0"
implementation "com.squareup.retrofit2:converter-moshi:2.9.0"

implementation "com.squareup.moshi:moshi:$moshi_version"
implementation "com.squareup.moshi:moshi-kotlin:$moshi_version"
kapt "com.squareup.moshi:moshi-kotlin-codegen:$moshi_version"

Android Development with Kotlin This work is licensed under the Apache 2 license. 15
Connect to a web service

Android Development with Kotlin This work is licensed under the Apache 2 license. 16
HTTP methods

● GET

● POST

● PUT

● DELETE

Android Development with Kotlin This work is licensed under the Apache 2 license. 17
Example web service API

URL DESCRIPTION METHO


D
example.com/posts Get a list of all GET
posts
example.com/posts/username Get a list of posts GET
by user
example.com/posts/search?filter=queryterm Search posts using GET
a filter
example.com/posts/new Create a new post POST
Android Development with Kotlin This work is licensed under the Apache 2 license. 18
Define a Retrofit service
interface SimpleService {
@GET("posts")
suspend fun listAll(): List<Post>

@GET("posts/{userId}")
suspend fun listByUser(@Path("userId") userId:String): List<Post>

@GET("posts/search") // becomes post/search?filter=query


suspend fun search(@Query("filter") search: String): List<Post>

@POST("posts/new")
suspend fun create(@Body post : Post): Post
}

Android Development with Kotlin This work is licensed under the Apache 2 license. 19
Create a Retrofit object for network
access
val retrofit = Retrofit.Builder()
.baseUrl("https://example.com")
.addConverterFactory(...)
.build()

val service = retrofit.create(SimpleService::class.java)

Android Development with Kotlin This work is licensed under the Apache 2 license. 20
End-to-end diagram

Retrofit
Service HTTP Request
App UI
Server
ViewMod HTTP
Web API
el Response
Converter (JSON)

Moshi

Android Development with Kotlin This work is licensed under the Apache 2 license. 21
Converter.Factory

Helps convert from a response type into class objects


● JSON (Gson or Moshi)
● XML (Jackson, SimpleXML, JAXB)
● Protocol buffers
● Scalars (primitives, boxed, and Strings)

Android Development with Kotlin This work is licensed under the Apache 2 license. 22
Moshi

● JSON library for parsing JSON into objects and back


● Add Moshi library dependencies to your app’s Gradle file.
● Configure your Moshi builder to use with Retrofit.

List of JSON
Moshi
Post objects response

Android Development with Kotlin This work is licensed under the Apache 2 license. 23
Moshi JSON encoding

@JsonClass(generateAdapter = true)
data class Post (
val title: String,
val description: String,
val url: String,
val updated: String,
val thumbnail: String,
val closedCaptions: String?)

Android Development with Kotlin This work is licensed under the Apache 2 license. 24
JSON code

{
"title":"Android Jetpack: EmojiCompat",
"description":"Android Jetpack: EmojiCompat",
"url":"https://www.youtube.com/watch?v=sYGKUtM2ga8",
"updated":"2018-06-07T17:09:43+00:00",
"thumbnail":"https://i4.ytimg.com/vi/sYGKUtM2ga8/hqdefault.jpg"
}

Android Development with Kotlin This work is licensed under the Apache 2 license. 25
Set up Retrofit and Moshi
private val moshi = Moshi.Builder()
.add(KotlinJsonAdapterFactory())
.build()
val retrofit = Retrofit.Builder()
.addConverterFactory(MoshiConverterFactory.create(moshi))
.baseUrl(BASE_URL)
.build()
object API {
val retrofitService : SimpleService by lazy {
retrofit.create(SimpleService::class.java)
}
}

Android Development with Kotlin This work is licensed under the Apache 2 license. 26
Use Retrofit with coroutines

Launch a new coroutine in the view model:

viewModelScope.launch {
Log.d("posts", API.retrofitService.searchPosts("query"))
}

Android Development with Kotlin This work is licensed under the Apache 2 license. 27
Display images

Android Development with Kotlin This work is licensed under the Apache 2 license. 28
Glide

● Third-party image-loading library in Android


● Focused on performance for smoother scrolling
● Supports images, video stills, and animated GIFs

Android Development with Kotlin This work is licensed under the Apache 2 license. 29
Add Gradle dependency

implementation "com.github.bumptech.glide:glide:$glide_version"

Android Development with Kotlin This work is licensed under the Apache 2 license. 30
Load an image

Glide.with(fragment)
.load(url)
.into(imageView);

Android Development with Kotlin This work is licensed under the Apache 2 license. 31
Customize a request with
RequestOptions

● Apply a crop to an image


● Apply transitions
● Set options for placeholder image or error image
● Set caching policies

Android Development with Kotlin This work is licensed under the Apache 2 license. 32
RequestOptions example
@BindingAdapter("imageUrl")
fun bindImage(imgView: ImageView, imgUrl: String?) {
imgUrl?.let {
val imgUri = imgUrl.toUri().buildUpon().scheme("https").build()

Glide.with(imgView)
.load(imgUri)
.apply(RequestOptions()
.placeholder(R.drawable.loading_animation)
.error(R.drawable.ic_broken_image))
.into(imgView)
}
}

Android Development with Kotlin This work is licensed under the Apache 2 license. 33
Summary

Android Development with Kotlin This work is licensed under the Apache 2 license. 34
Summary
In Lesson 11, you learned how to:
● Declare permissions your app needs in AndroidManifest.xml
● Use t
he three protection levels for permissions: normal, signature, and
dangerous (prompt the user at runtime for dangerous permissio
ns)
● Use the Retrofit library to make web service API calls from your ap
p
● Use the Moshi library to parse JSON response into class objects
● Load and display images
Android Developmentfrom the internet
with Kotlin using the Glide
This work is licensed under the Apache 2 license. 35
Learn More

● App permissions best practices


● Retrofit
● Moshi
● Glide

Android Development with Kotlin This work is licensed under the Apache 2 license. 36
Pathway

Practice what you’ve learned by


completing the pathway:
Lesson 11: Connect to the internet

Android Development with Kotlin This work is licensed under the Apache 2 license. 37
Lesson 12:
Repository
pattern and
WorkManager

Android Development with Kotlin v1.0 This work is licensed under the Apache 2 license. 1
About this lesson
Lesson 12: Repository pattern and WorkManager
● Repository pattern
● WorkManager
● Work input and output
● WorkRequest constraints
● Summary

Android Development with Kotlin This work is licensed under the Apache 2 license. 2
Repository pattern

Android Development with Kotlin This work is licensed under the Apache 2 license. 3
Existing app architecture

UI Controller

ViewModel

Room

Android Development with Kotlin This work is licensed under the Apache 2 license. 4
Relative data speeds

Operation Relative speed

Reading from LiveData FAST

Reading from Room database SLOW

Reading from network SLOWEST

Android Development with Kotlin This work is licensed under the Apache 2 license. 5
Cache network responses

● Account for long network request times and still be


responsive to the user
● Use Room locally when retrieval from the network may be
costly or difficult
● Can cache based on the least recently used (LRU) value,
frequently accessed (FRU) values, or other algorithm

Android Development with Kotlin This work is licensed under the Apache 2 license. 6
Repository pattern

● Can abstract away multiple data sources from the caller


● Supports fast retrieval using local database while sending
network request for data refresh (which can take longer)
● Can test data sources separately from other aspects of your app

Android Development with Kotlin This work is licensed under the Apache 2 license. 7
App architecture with repository
pattern UI
Controller

ViewModel

Repository

Remote data
Room Mock backend
source

Android Development with Kotlin This work is licensed under the Apache 2 license. 8
Implement a repository class

● Provide a common interface to access data:


○ Expose functions to query and modify the underlying
data
● Depending on your data sources, the repository can:
○ Hold a reference to the DAO, if your data is in a
database
○ Make network requests if you connect to a web service

Android Development with Kotlin This work is licensed under the Apache 2 license. 9
WorkManager

Android Development with Kotlin This work is licensed under the Apache 2 license. 10
WorkManager

● Android Jetpack architecture component


● Recommended solution to execute background work
(immediate or deferred)
● Opportunistic and guaranteed execution
● Execution can be based on certain conditions

Android Development with Kotlin This work is licensed under the Apache 2 license. 11
When to use WorkManager

Task

Yes Requires active No


user

Requires active
Immediate user
Yes No

Exact Deferred

Android Development with Kotlin This work is licensed under the Apache 2 license. 12
Declare WorkManager
dependencies

implementation "androidx.work:work-runtime-ktx:$work_version"

Android Development with Kotlin This work is licensed under the Apache 2 license. 13
Important classes to know

● Worker - does the work on a background thread, override


doWork() method
● WorkRequest - request to do some work
● Constraint - conditions on when the work can run
● WorkManager - schedules the WorkRequest to be run

Android Development with Kotlin This work is licensed under the Apache 2 license. 14
Define the work
class UploadWorker(appContext: Context, workerParams: WorkerParameters) :
Worker(appContext, workerParams) {

override fun doWork(): Result {

// Do the work here. In this case, upload the images.


uploadImages()

// Indicate whether work finished successfully with the Result


return Result.success()
}
}

Android Development with Kotlin This work is licensed under the Apache 2 license. 15
Extend CoroutineWorker instead of
Worker
class UploadWorker(appContext: Context, workerParams: WorkerParameters) :
CoroutineWorker(appContext, workerParams) {

override suspend fun doWork(): Result {

// Do the work here (in this case, upload the images)


uploadImages()

// Indicate whether work finished successfully with the Result


return Result.success()
}
}

Android Development with Kotlin This work is licensed under the Apache 2 license. 16
WorkRequests

● Can be scheduled to run once or repeatedly


○ OneTimeWorkRequest
○ PeriodicWorkRequest
● Persisted across device reboots
● Can be chained to run sequentially or in parallel
● Can have constraints under which they will run

Android Development with Kotlin This work is licensed under the Apache 2 license. 17
Schedule a OneTimeWorkRequest
Create WorkRequest:
val uploadWorkRequest: WorkRequest =
OneTimeWorkRequestBuilder<UploadWorker>()
.build()

Add the work to the WorkManager queue:

WorkManager.getInstance(myContext)
.enqueue(uploadWorkRequest)

Android Development with Kotlin This work is licensed under the Apache 2 license. 18
Schedule a PeriodicWorkRequest
● Set a repeat interval
● Set a flex interval (optional)
Flex period Flex period Flex period
can run can run can run
work work work

...
Interval 1 Interval 2 Interval N

Specify an interval using TimeUnit (e.g., TimeUnit.HOURS, TimeUnit.DAYS)

Android Development with Kotlin This work is licensed under the Apache 2 license. 19
Flex interval
And then
Work could
again
happen here
soon after
Example
1
Day 1 Day 2

1 hr 1 hr
Example
2
11 PM 12 AM 11 PM 12 AM
Day 1 Day 2

Android Development with Kotlin This work is licensed under the Apache 2 license. 20
PeriodicWorkRequest example

val repeatingRequest = PeriodicWorkRequestBuilder<RefreshDataWorker>(


1, TimeUnit.HOURS, // repeatInterval
15, TimeUnit.MINUTES // flexInterval
).build()

Android Development with Kotlin This work is licensed under the Apache 2 license. 21
Enqueue periodic work

WorkManager.getInstance().enqueueUniquePeriodicWork(
"Unique Name",
ExistingPeriodicWorkPolicy.KEEP, // or REPLACE
repeatingRequest
)

Android Development with Kotlin This work is licensed under the Apache 2 license. 22
Work input and output

Android Development with Kotlin This work is licensed under the Apache 2 license. 23
Define Worker with input and
output
class MathWorker(context: Context, params: WorkerParameters):
CoroutineWorker(context, params) {

override suspend fun doWork(): Result {


val x = inputData.getInt(KEY_X_ARG, 0)
val y = inputData.getInt(KEY_Y_ARG, 0)
val result = computeMathFunction(x, y)
val output: Data = workDataOf(KEY_RESULT to result)
return Result.success(output)
}
}

Android Development with Kotlin This work is licensed under the Apache 2 license. 24
Result output from doWork()

Result status Result status with output

Result.success() Result.success(output)

Result.failure() Result.failure(output)

Result.retry()

Android Development with Kotlin This work is licensed under the Apache 2 license. 25
Send input data to Worker

val complexMathWork = OneTimeWorkRequest<MathWorker>()


.setInputData(
workDataOf(
"X_ARG" to 42,
"Y_ARG" to 421,
)
).build()

WorkManager.getInstance(myContext).enqueue(complexMathWork)

Android Development with Kotlin This work is licensed under the Apache 2 license. 26
WorkRequest constraints

Android Development with Kotlin This work is licensed under the Apache 2 license. 27
Constraints

● setRequiredNetworkType
● setRequiresBatteryNotLow
● setRequiresCharging
● setTriggerContentMaxDelay
● requiresDeviceIdle

Android Development with Kotlin This work is licensed under the Apache 2 license. 28
Constraints example
val constraints = Constraints.Builder()
.setRequiredNetworkType(NetworkType.UNMETERED)
.setRequiresCharging(true)
.setRequiresBatteryNotLow(true)
.setRequiresDeviceIdle(true)
.build()

val myWorkRequest: WorkRequest = OneTimeWorkRequestBuilder<MyWork>()


.setConstraints(constraints)
.build()

Android Development with Kotlin This work is licensed under the Apache 2 license. 29
Summary

Android Development with Kotlin This work is licensed under the Apache 2 license. 30
Summary
In Lesson 12, you learned how to:
● Use a repository to abstract the data layer from the rest of the ap
p
● Schedule background tasks efficiently and optimize them using
WorkManager
● Create custom Worker classes to specify the work to be done
● Create and enqueue one-time or periodic work requests

Android Development with Kotlin This work is licensed under the Apache 2 license. 31
Learn more

● Fetch data
● Schedule tasks with WorkManager
● Define work requests
● Connect ViewModel and the repository
● Use WorkManager for immediate background executio
n

Android Development with Kotlin This work is licensed under the Apache 2 license. 32
Pathway

Practice what you’ve learned by


completing the pathway:
Lesson 12: Repository pattern andWorkManager

Android Development with Kotlin This work is licensed under the Apache 2 license. 33
Lesson 13:
App UI design

Android Development with Kotlin v1.0 This work is licensed under the Apache 2 license. 1
About this lesson
Lesson 13: App UI design
● Android styling
● Typography
● Material Design
● Material Components
● Localization
● Example apps
● Summary

Android Development with Kotlin This work is licensed under the Apache 2 license. 2
Android styling

Android Development with Kotlin This work is licensed under the Apache 2 license. 3
Android styling system

● Used to specify the visual design of your app


● Helps you maintain a consistent look across your app
● Hierarchical (you can inherit from parent styles and override
specific attributes)

Android Development with Kotlin This work is licensed under the Apache 2 license. 4
Precedence of each method of
styling

View
attributes Overrides this

Style
Overrides this

Theme

Android Development with Kotlin This work is licensed under the Apache 2 license. 5
Themes

● Collection of named resources, useful broadly across the app


● Named resources are known as theme attributes
● Examples:
○ Use a theme to define primary & secondary colors in the app
○ Use a theme to set the default font for all text within an
activity

Android Development with Kotlin This work is licensed under the Apache 2 license. 6
Declare a theme
In res/values/themes.xml:
<style name="Theme.MyApp" parent="Theme.MaterialComponents.Light">
<item name="colorPrimary">@color/orange_500</item>
<item name="colorPrimaryVariant">@color/orange_700</item>
<item name="colorSecondary">@color/pink_200</item>
<item name="colorSecondaryVariant">@color/pink_700</item>
...
</style>

Android Development with Kotlin This work is licensed under the Apache 2 license. 7
Apply a theme
In AndroidManifest.xml:
<manifest ... >
<application ... >
<activity android:theme="@style/Theme.MyApp" ... >
</activity>
</application>
</manifest>

In layout file:
<ConstraintLayout …
android:theme="@style/Theme.MyApp">

Android Development with Kotlin This work is licensed under the Apache 2 license. 8
Refer to theme attribute in a layout
In layout file:

<LinearLayout …
android:background="?attr/colorSurface">

Use ?attr/themeAttributeName syntax.


Examples: ?attr/colorPrimary
?attr/colorPrimaryVariant

Android Development with Kotlin This work is licensed under the Apache 2 license. 9
Styles

● A style is a collection of view attributes, specific to a


type of view
● Use a style to create a collection of reusable styling
information, such as font size or colors
● Good for declaring small sets of common designs used
throughout your app

Android Development with Kotlin This work is licensed under the Apache 2 license. 10
Declare a style
In res/values/styles.xml:
<style name="DescriptionStyle">
<item name="android:textColor">#00FF00</item>
<item name="android:textSize">16sp</item>
...
</style>

Android Development with Kotlin This work is licensed under the Apache 2 license. 11
Apply a style

On a view in a layout file:

<TextView
style="@style/DescriptionStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/description_text" />

Android Development with Kotlin This work is licensed under the Apache 2 license. 12
Refer to theme attribute in a style
In res/values/styles.xml:

<style name="DescriptionStyle">
<item name="android:textColor">?attr/colorOnSurface</item>
<item name="android:textSize">16sp</item>
...
</style>

Android Development with Kotlin This work is licensed under the Apache 2 license. 13
View attributes

● Use view attributes to set attributes explicitly for each view


● You can use every property that can be set via styles or
themes
● Use for custom or one-off designs such as margins,
paddings, or constraints

Android Development with Kotlin This work is licensed under the Apache 2 license. 14
Resources directory
└── res
├── drawable
├── drawable-*
├── layout
├── menu
├── mipmap-*
├── navigation
├── values
│ ├── colors.xml
│ ├── dimens.xml
│ ├── strings.xml
│ ├── styles.xml
│ └── themes.xml
└── values-*

Android Development with Kotlin This work is licensed under the Apache 2 license. 15
Provide alternative resources
└── res
├── values
│ ├── colors.xml
│ ├── strings.xml
│ ├── styles.xml
│ └── themes.xml
└── values-b+es
│ ├── strings.xml Use when device locale is set to Spanish
└── values-night
└── themes.xml Use when night mode is turned on

Android Development with Kotlin This work is licensed under the Apache 2 license. 16
Color resources
A way to name and standardize colors throughout your app
In res/values/colors.xml:
<resources>
<color name="purple_200">#FFBB86FC</color>
<color name="purple_500">#FF6200EE</color>
<color name="purple_700">#FF3700B3</color>
<color name="teal_200">#FF03DAC5</color>
<color name="teal_700">#FF018786</color>
...
</resources>
Specified as hexadecimal colors in form of #AARRGGBB

Android Development with Kotlin This work is licensed under the Apache 2 license. 17
Dimension resources
A way to name and standardize dimension values in your layouts
● Declare your dimension values in res/values/dimens.xml:
<resources>
<dimen name="top_margin">16dp</dimen>
</resources>

● Refer to them as @dimen/<name> in layouts or R.dimen.<name> in


code:
<TextView …
android:layout_marginTop="@dimen/top_margin" />

Android Development with Kotlin This work is licensed under the Apache 2 license. 18
Typography

Android Development with Kotlin This work is licensed under the Apache 2 license. 19
Scale-independent pixels (sp)

● The textual equivalent to density-


independent pixels (dp)
● Specify text sizes in sp
(takes into account user preferences)
● Users can adjust Font and Display
sizes in the Settings app (after
Display)

Android Development with Kotlin This work is licensed under the Apache 2 license. 20
Type scale

● A set of styles designed to


work together in a cohesive
manner for your app and
content
● Contains reusable categories
of text with intended purpose
for each (for example,
headline, subtitle, caption)

Android Development with Kotlin This work is licensed under the Apache 2 license. 21
TextAppearance
A TextAppearance style often alters one or more of these attributes:

● typeface (android:fontFamily)
● weight (android:textStyle)
● text size (android:textSize)
● capitalization (android:textAllCaps)
● letter spacing (android:letterSpacing)

Android Development with Kotlin This work is licensed under the Apache 2 license. 22
Examples using TextAppearance
<TextView
...
android:textAppearance="@style/TextAppearance.MaterialComponents.Headline1"
android:text="@string/title" />

<TextView
...
android:textAppearance="@style/TextAppearance.MaterialComponents.Body1"
android:text="@string/body_text" />

Android Development with Kotlin This work is licensed under the Apache 2 license. 23
Customize your own
TextAppearance
<style name="TextAppearance.MyApp.Headline1"
parent="TextAppearance.MaterialComponents.Headline1">
...
<item name="android:textStyle">normal</item>
<item name="android:textAllCaps">false</item>
<item name="android:textSize">64sp</item>
<item name="android:letterSpacing">0</item>
...
</style>

Android Development with Kotlin This work is licensed under the Apache 2 license. 24
Use a custom TextAppearance in a
theme

<style name="Theme.MyApp" parent="Theme.MaterialComponents.Light">


...
<item name="textAppearanceHeadline1">@style/TextAppearance.MyApp.Headline1</item>
...
</style>

Android Development with Kotlin This work is licensed under the Apache 2 license. 25
Material Design

Android Development with Kotlin This work is licensed under the Apache 2 license. 26
Intro to Material

Adaptable system of
guidelines, components,
and tools that support best
practices for UI design
Material Design homepage

Android Development with Kotlin This work is licensed under the Apache 2 license. 27
Material Components

Interactive building blocks


for creating a user
interface

Android Development with Kotlin This work is licensed under the Apache 2 license. 28
Material color tool

Android Development with Kotlin This work is licensed under the Apache 2 license. 29
Baseline Material color theme

Android Development with Kotlin This work is licensed under the Apache 2 license. 30
Material Components for Android
Library

implementation 'com.google.android.material:material:<version>'

Android Development with Kotlin This work is licensed under the Apache 2 license. 31
Material Themes
● Theme.MaterialComponents
● Theme.MaterialComponents.NoActionBar
● Theme.MaterialComponents.Light
● Theme.MaterialComponents.Light.NoActionBar
● Theme.MaterialComponents.Light.DarkActionBar
● Theme.MaterialComponents.DayNight
● Theme.MaterialComponents.DayNight.NoActionBar
● Theme.MaterialComponents.DayNight.DarkActionBar

Android Development with Kotlin This work is licensed under the Apache 2 license. 32
Material theme example
Theme.MaterialComponents.DayNight.DarkActionBar

Light mode Dark mode

Android Development with Kotlin This work is licensed under the Apache 2 license. 33
Dark theme
A low-light UI that displays mostly dark
surfaces
● Replaces light-tinted surfaces and dark
text with dark-tinted surfaces and light
text
● Makes it easier for anyone to use a
device in lower-light environments
● Improves visibility for users with low
vision
and those sensitive to bright light
● Can significantlyAndroid
reduce power
Development withusage
Kotlin This work is licensed under the Apache 2 license. 34
Support dark theme
In values/themes.xml:
<style name="AppTheme" parent="Theme.MaterialComponents.DayNight">
<item name="colorPrimary">@color/orange_500</item>
...

In values-night/themes.xml:
<style name="AppTheme" parent="Theme.MaterialComponents.DayNight">
<item name="colorPrimary">@color/orange_200</item>
...

Android Development with Kotlin This work is licensed under the Apache 2 license. 35
Material Components

Android Development with Kotlin This work is licensed under the Apache 2 license. 36
Material Components
Component library provided for Android and design guidelines

● Text fields ● App bars (top and bottom)

● Buttons ● Floating Action Button (FAB)

● Menus ● Navigation Drawer

● Cards ● Bottom navigation

● Chips ● Snackbar ...and more!


Android Development with Kotlin This work is licensed under the Apache 2 license. 37
Text field
● Composed of TextInputLayout with child view
TextInputEditText
● Shows a floating label or a text hint before the user enters
text
● Two types:

Filled text field Outlined text field

Android Development with Kotlin This work is licensed under the Apache 2 license. 38
Text field example
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/textField"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/label"
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox">

<com.google.android.material.textfield.TextInputEditText
android:layout_width="match_parent"
android:layout_height="wrap_content" />

</com.google.android.material.textfield.TextInputLayout>

Android Development with Kotlin This work is licensed under the Apache 2 license. 39
Bottom navigation

● Allows movement between top level


destinations in your app
● Alternate design pattern to a
navigation drawer
● Limited to 5 locations max

Android Development with Kotlin This work is licensed under the Apache 2 license. 40
Bottom navigation example

<LinearLayout …>

...

<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="@+id/bottom_navigation"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:menu="@menu/bottom_navigation_menu" />

</LinearLayout>

Android Development with Kotlin This work is licensed under the Apache 2 license. 41
Bottom navigation listener
bottomNav.setOnNavigationItemSelectedListener { item ->
when(item.itemId) {
R.id.item1 -> {
// Respond to navigation item 1 click
true
}
R.id.item2 -> {
true
}
else -> false
}
}

Android Development with Kotlin This work is licensed under the Apache 2 license. 42
Snackbar

● Display short messages within the app


● Messages have a duration (SHORT,
LONG, or INDEFINITE)
● May contain an optional action
● Works best in a CoordinatorLayout
● Shown at bottom of enclosing container

Android Development with Kotlin This work is licensed under the Apache 2 license. 43
Snackbar examples
Show a simple message:
Snackbar.make(view, R.string.text_label, Snackbar.LENGTH_SHORT)
.show()

Add an action to a Snackbar:


Snackbar.make(view, R.string.text_label, Snackbar.LENGTH_LONG)
.setAction(R.string.action_text) {
// Responds to click on the action
}
.show()

Android Development with Kotlin This work is licensed under the Apache 2 license. 44
Floating Action Button (FAB)
● Perform the most-common action for a screen (for example, creating a
new email)
● Come in multiple sizes (regular, mini, and extended)

Android Development with Kotlin This work is licensed under the Apache 2 license. 45
CoordinatorLayout

● Acts as top-level container in an app


● Manages interaction of its child views, such as
gestures
● Recommended for use with views like a Snackbar or
FAB

Android Development with Kotlin This work is licensed under the Apache 2 license. 46
FAB example
<androidx.coordinatorlayout.widget.CoordinatorLayout ...>
....
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/floating_action_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|end"
android:layout_margin="16dp"
android:contentDescription="@string/fab_content_desc"
app:fabSize="normal" <!-- or mini or auto -->
app:srcCompat="@drawable/ic_plus"/>

</androidx.coordinatorlayout.widget.CoordinatorLayout>

Android Development with Kotlin This work is licensed under the Apache 2 license. 47
Cards

● A card holds content and


actions for a single item.
● Cards are often arranged in a
list, grid, or dashboard.
● Use MaterialCardView.

Android Development with Kotlin This work is licensed under the Apache 2 license. 48
MaterialCardView example
<com.google.android.material.card.MaterialCardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="8dp">

<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<ImageView .../>
<TextView .../>
</LinearLayout>
</com.google.android.material.card.MaterialCardView>

Android Development with Kotlin This work is licensed under the Apache 2 license. 49
Localization

Android Development with Kotlin This work is licensed under the Apache 2 license. 50
Localize your app

● Separate the localized aspects of your app (for example, text,


audio files, currency, and numbers) as much as possible from the
core Kotlin functionality of the app.
Example: Extract the user facing strings into strings.xml.
● When a user runs your app, the Android system selects which
resources to load based on the device's locale.
● If locale-specific resources are not found, Android falls back to
default resources you defined.

Android Development with Kotlin This work is licensed under the Apache 2 license. 51
Support different languages and
cultures
● Decide which locales to support.
● Create locale-specific directories in res directory:
<resource type>-b+<language code>
[+<country code>]
Examples: layout-b+en+US
values-b+es
● Provide locale-specific resources (such as strings
and drawables) in those directories.

Android Development with Kotlin This work is licensed under the Apache 2 license. 52
Support languages that use RTL
scripts
● Users can choose a language that uses right-to-left (RTL) scripts.
● Add android:supportsRtl="true" to app tag in manifest.
● Convert left and right to start and end, respectively, in your
layout files (change android:paddingLeft to
android:paddingStart).
● Localize strings and format text in messages.
● Optionally, use -ldrtl resource qualifier to provide alternate
resources.
Android Development with Kotlin This work is licensed under the Apache 2 license. 53
Example apps

Android Development with Kotlin This work is licensed under the Apache 2 license. 54
Check out other apps

Sunflowe Google
r app I/O app

Android Development with Kotlin This work is licensed under the Apache 2 license. 55
Summary

Android Development with Kotlin This work is licensed under the Apache 2 license. 56
Summary

In Lesson 13, you learned how to:


● Customize the visual look of your app using styles and themes
● Choose from predefined type scales for the text in your app (or cr
eate your own text appearance)
● Select theme colors for your app using Material color tool
● Use Material Components library to speed up UI development
● Localize your app to support different languages and cultures

Android Development with Kotlin This work is licensed under the Apache 2 license. 57
Learn more
● Material Design
● Material Components
● Tools for picking colors
● Dark theme
● Localize your app
● Blog posts: Themes vs Styles, Common Theme Attributes,
Prefer Theme Attributes, Themes Overlay
● Sample code: Sunflower app, Google I/O app, Android GitHub repo

Android Development with Kotlin This work is licensed under the Apache 2 license. 58
Pathway

Practice what you’ve learned by


completing the pathway:
Lesson 13: App UI Design

Android Development with Kotlin This work is licensed under the Apache 2 license. 59

You might also like