0% found this document useful (0 votes)
19 views

Lesson 8 - App Architecture (UI Layer)

You should probably get to work!

Uploaded by

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

Lesson 8 - App Architecture (UI Layer)

You should probably get to work!

Uploaded by

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

Lesson 8:

App architecture
(UI layer)

This work is licensed under the


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

This work is licensed under the


Android Development with Kotlin Apache 2 license. 2
Android app
architecture

This work is licensed under the


Android Development with Kotlin 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.

This work is licensed under the


Android Development with Kotlin 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

This work is licensed under the


Android Development with Kotlin 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
This work is licensed under the
Android Development with Kotlin 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

This work is licensed under the


Android Development with Kotlin Apache 2 license. 7
Separation of concerns

res/
layout
UI Controller
(Activity/Fragment
ViewModel
)

LiveData Data
Layer

This work is licensed under the


Android Development with Kotlin 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.

This work is licensed under the


Android Development with Kotlin Apache 2 license. 9
ViewModel

This work is licensed under the


Android Development with Kotlin 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"

This work is licensed under the


Android Development with Kotlin 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

This work is licensed under the


Android Development with Kotlin Apache 2 license. 12
Lifetime of a ViewModel

This work is licensed under the


Android Development with Kotlin Apache 2 license. 13
Kabaddi Kounter

This work is licensed under the


Android Development with Kotlin Apache 2 license. 14
ViewModel class
abstract class ViewModel

This work is licensed under the


Android Development with Kotlin 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++
}
}
}
This work is licensed under the
Android Development with Kotlin 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()

}
This work is licensed under the
Android Development with Kotlin 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()
}

This work is licensed under the


Android Development with Kotlin Apache 2 license. 18
Data binding

This work is licensed under the


Android Development with Kotlin Apache 2 license. 19
ViewModels and data binding
● App architecture without data binding
UI Controller
ViewMode Views
(activity/fragment
(defined in XML
l with click
layout)
listeners)

● ViewModels can work in concert with data


binding
ViewMode Views
(defined in XML
l layout)

This work is licensed under the


Android Development with Kotlin 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>

This work is licensed under the


Android Development with Kotlin 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
...

This work is licensed under the


Android Development with Kotlin 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()}" />

...

This work is licensed under the


Android Development with Kotlin 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()
}
}

This work is licensed under the


Android Development with Kotlin Apache 2 license. 24
LiveData

This work is licensed under the


Android Development with Kotlin 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.

This work is licensed under the


Android Development with Kotlin Apache 2 license. 26
Observer design pattern
diagram
Observable

notify observe() notify observe()

Observer Observer

This work is licensed under the


Android Development with Kotlin 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)

This work is licensed under the


Android Development with Kotlin 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.

This work is licensed under the


Android Development with Kotlin 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
}
...

This work is licensed under the


Android Development with Kotlin 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)

This work is licensed under the


Android Development with Kotlin 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.

This work is licensed under the


Android Development with Kotlin 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>
This work is licensed under the
Android Development with Kotlin 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)
}
...
This work is licensed under the
Android Development with Kotlin 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
}
}
}
This work is licensed under the
Android Development with Kotlin Apache 2 license. 35
Transform LiveData

This work is licensed under the


Android Development with Kotlin Apache 2 license. 36
Manipulating LiveData with
transformations

LiveData can be transformed into a new LiveData object.


● map()
● switchMap()

This work is licensed under the


Android Development with Kotlin Apache 2 license. 37
Example LiveData with
transformations

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


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

This work is licensed under the


Android Development with Kotlin Apache 2 license. 38
Summary

This work is licensed under the


Android Development with Kotlin Apache 2 license. 39
Summary
In Lesson 8, you learned how to:
● Follow good app architecture design, and the separation-of-c
oncerns principle to make apps more maintainable and reduc
e technical 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
This work is licensed under the
Android Development with Kotlin 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

This work is licensed under the


Android Development with Kotlin Apache 2 license. 41
Pathway

Practice what you’ve learned by


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

This work is licensed under the


Android Development with Kotlin Apache 2 license. 42

You might also like