Introducció
L'arquitectura Model-View-ViewModel (MVVM) és un patró de disseny que separa la lògica de la interfície d'usuari (UI) de la lògica de negoci i de les dades. Això facilita la mantenibilitat, la testabilitat i la modularitat del codi. En aquest tema, aprendrem a implementar l'arquitectura MVVM en una aplicació Android utilitzant Android Jetpack.
Conceptes Clau
Model
- Descripció: Representa les dades de l'aplicació i la lògica de negoci.
- Funció: Gestiona les dades, ja sigui des d'una base de dades local o una API remota.
View
- Descripció: Representa la interfície d'usuari.
- Funció: Mostra les dades i rep les interaccions de l'usuari.
ViewModel
- Descripció: Actua com a intermediari entre el Model i la View.
- Funció: Proporciona dades a la View i gestiona la lògica de presentació.
Estructura del Projecte
| Component | Descripció |
|---|---|
Model |
Conté les classes de dades i la lògica de negoci. |
View |
Conté les activitats i fragments que mostren la interfície d'usuari. |
ViewModel |
Conté les classes que gestionen la lògica de presentació i proporcionen dades a la View. |
Implementació Pas a Pas
- Configuració del Projecte
Assegura't de tenir les següents dependències en el teu build.gradle:
dependencies {
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.3.1"
implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.3.1"
implementation "androidx.room:room-runtime:2.3.0"
kapt "androidx.room:room-compiler:2.3.0"
}
- Creació del Model
Crea una classe de dades i una interfície DAO per gestionar les operacions de la base de dades.
// User.kt
@Entity(tableName = "users")
data class User(
@PrimaryKey(autoGenerate = true) val id: Int,
val name: String,
val email: String
)
// UserDao.kt
@Dao
interface UserDao {
@Query("SELECT * FROM users")
fun getAllUsers(): LiveData<List<User>>
@Insert
suspend fun insert(user: User)
}
- Creació del ViewModel
Crea una classe ViewModel per gestionar la lògica de presentació.
// UserViewModel.kt
class UserViewModel(application: Application) : AndroidViewModel(application) {
private val userDao: UserDao = AppDatabase.getDatabase(application).userDao()
val allUsers: LiveData<List<User>> = userDao.getAllUsers()
fun insert(user: User) = viewModelScope.launch {
userDao.insert(user)
}
}
- Creació de la View
Crea una activitat o fragment per mostrar la interfície d'usuari.
// MainActivity.kt
class MainActivity : AppCompatActivity() {
private lateinit var userViewModel: UserViewModel
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
userViewModel = ViewModelProvider(this).get(UserViewModel::class.java)
val userAdapter = UserAdapter()
recyclerView.adapter = userAdapter
userViewModel.allUsers.observe(this, Observer { users ->
users?.let { userAdapter.submitList(it) }
})
addButton.setOnClickListener {
val user = User(name = "John Doe", email = "john.doe@example.com")
userViewModel.insert(user)
}
}
}
- Creació del Layout
Defineix el layout XML per la teva activitat o fragment.
<!-- activity_main.xml -->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<Button
android:id="@+id/addButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Add User" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>Exercici Pràctic
Objectiu
Implementar una aplicació senzilla que utilitzi l'arquitectura MVVM per gestionar una llista de tasques.
Passos
- Crea una classe
Taskamb els campsid,titleidescription. - Defineix una interfície
TaskDaoamb les operacions CRUD. - Implementa un
TaskViewModelper gestionar les dades de les tasques. - Crea una activitat
TaskActivityper mostrar la llista de tasques i afegir-ne de noves. - Defineix el layout XML per
TaskActivity.
Solució
// Task.kt
@Entity(tableName = "tasks")
data class Task(
@PrimaryKey(autoGenerate = true) val id: Int,
val title: String,
val description: String
)
// TaskDao.kt
@Dao
interface TaskDao {
@Query("SELECT * FROM tasks")
fun getAllTasks(): LiveData<List<Task>>
@Insert
suspend fun insert(task: Task)
}
// TaskViewModel.kt
class TaskViewModel(application: Application) : AndroidViewModel(application) {
private val taskDao: TaskDao = AppDatabase.getDatabase(application).taskDao()
val allTasks: LiveData<List<Task>> = taskDao.getAllTasks()
fun insert(task: Task) = viewModelScope.launch {
taskDao.insert(task)
}
}
// TaskActivity.kt
class TaskActivity : AppCompatActivity() {
private lateinit var taskViewModel: TaskViewModel
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_task)
taskViewModel = ViewModelProvider(this).get(TaskViewModel::class.java)
val taskAdapter = TaskAdapter()
recyclerView.adapter = taskAdapter
taskViewModel.allTasks.observe(this, Observer { tasks ->
tasks?.let { taskAdapter.submitList(it) }
})
addButton.setOnClickListener {
val task = Task(title = "New Task", description = "Task Description")
taskViewModel.insert(task)
}
}
}
// activity_task.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<Button
android:id="@+id/addButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Add Task" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>Conclusió
En aquest tema, hem après a implementar l'arquitectura MVVM en una aplicació Android. Hem separat la lògica de la interfície d'usuari de la lògica de negoci i de les dades, facilitant així la mantenibilitat i la testabilitat del codi. Aquesta estructura modular ens permet desenvolupar aplicacions més robustes i escalables.
Curs d'Android Studio
Mòdul 1: Introducció a Android Studio
- Introducció a Android Studio
- Configuració d'Android Studio
- Comprensió de la Interfície d'Android Studio
- Creació del teu Primer Projecte Android
Mòdul 2: Desenvolupament Bàsic d'Android
- Comprensió de l'Estructura del Projecte Android
- Introducció als Dissenys XML
- Components Bàsics de la Interfície d'Usuari
- Introducció a les Activitats
- Executar la teva Aplicació en un Emulador
Mòdul 3: Desenvolupament Intermedi d'Android
- Introducció als Intents
- Treballar amb Fragments
- Gestió de l'Entrada de l'Usuari
- Ús de RecyclerView
- Xarxes en Android
Mòdul 4: Desenvolupament Avançat d'Android
- Persistència de Dades amb SQLite
- Ús de Room per a la Gestió de Bases de Dades
- Components Avançats de la Interfície d'Usuari
- Vistes Personalitzades i Canvas
- Treballar amb Tasques en Segon Pla
Mòdul 5: Desenvolupament Professional d'Android
- Implementació de l'Arquitectura MVVM
- Injecció de Dependències amb Dagger
- Proves Unitàries i Proves de la Interfície d'Usuari
- Publicació de la teva Aplicació a Google Play
- Optimització del Rendiment
