Lesson 8 App Architecture (UI Layer)
Lesson 8 App Architecture (UI Layer)
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
Android Development with Kotlin This work is licensed under the Apache 2 license. 4
Examples of short-term hacks
Android Development with Kotlin This work is licensed under the Apache 2 license. 5
Why you need good app architecture
Android Development with Kotlin This work is licensed under the Apache 2 license. 6
Android Jetpack
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
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
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()
Android Development with Kotlin This work is licensed under the Apache 2 license. 17
Using a ViewModel
Within MainActivity onCreate():
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 with
(defined in XML layout)
click listeners)
Android Development with Kotlin This work is licensed under the Apache 2 license. 20
Data binding in XML revisited
Android Development with Kotlin This work is licensed under the Apache 2 license. 21
Attaching a ViewModel to a data binding
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
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
Android Development with Kotlin This work is licensed under the Apache 2 license. 26
Observer design pattern diagram
Observable
Observer Observer
Android Development with Kotlin This work is licensed under the Apache 2 license. 27
LiveData
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)
Android Development with Kotlin This work is licensed under the Apache 2 license. 29
Use LiveData in ViewModel
class ScoreViewModel : ViewModel() {
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)
}
Android Development with Kotlin This work is licensed under the Apache 2 license. 31
Two-way data binding
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
Android Development with Kotlin This work is licensed under the Apache 2 license. 37
Example LiveData with transformations
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-concerns
principle to make apps more maintainable and reduce technical debt
Android Development with Kotlin This work is licensed under the Apache 2 license. 40
Learn More
Android Development with Kotlin This work is licensed under the Apache 2 license. 41
Pathway
Android Development with Kotlin This work is licensed under the Apache 2 license. 42