В середине 2024 года, как глухой независимый разработчик, я часто размышляю о прогрессе и достижениях, достигнутых за последние шесть месяцев. В этой статье я расскажу, как использовать Jetpack Compose、Material3 объединить MVI(Model-View-Intent) Архитектурно спроектируйте модульное приложение для Android. Независимо от того, являетесь ли вы новичком или опытным разработчиком Android, я уверен, что эта статья будет вам полезна.
MVI да Model-View-Intent аббревиатура, МВИ Архитектура в основном состоит из трех основных частей:
Проект разделен на следующие модули:
Архитектура принята MVI(Model-View-Intent),состояние существования в приложении да неизменяемое,Поток данных является односторонним,позволять UI Изменения предсказуемы.
Проект основан на модульной конструкции и разделен на следующие категории:
com.nim.mviapp/
├── data/ # уровень данных
│ ├── repository/ # логика хранилища данных
│ ├── model/ # модель данных
│ └── database/ # База данных номеров
│
├── ui/ # Уровень пользовательского интерфейса
│ ├── theme/ # Material3 тема
│ ├── component/ # многоразовый UI компоненты
│ └── screen/ # Определение страницы, например HomeScreen и т. д.
│
├── viewmodel/ # уровень бизнес-логики (Intent + ViewModel)
│ └── WishViewModel.kt # Управлять бизнес-логикой и управлением статусами
│
└── MainApplication.kt # Вход в приложение
Внедрение уровня данных Repository Pattern,Единое управление источниками данных. проходить Room Для локального хранилища используйте Flow Обработка потоков данных для удобства MVI Однонаправленный поток данных остается прежним.
class WishRepository(private val wishDao: WishDao) {
fun getWishes(): Flow<List<Wish>> = wishDao.getAllWishes()
suspend fun addWish(wish: Wish) {
wishDao.addAWish(wish)
}
suspend fun updateWishLikedStatus(wish: Wish, isLiked: Boolean) {
wish.isLiked = isLiked
wishDao.updateWish(wish)
}
// Другие операции CRUD...
}
существовать MVI , каждая пользовательская операция будет упакована в Intent,Затемпроходить ViewModel иметь дело с。ViewModel Управляет взаимодействием с уровнем данных, а также отвечает за поддержание UI Синхронизация статусов.
class WishViewModel(private val repository: WishRepository) : ViewModel() {
val wishes: LiveData<List<Wish>> = repository.getWishes().asLiveData()
fun addWish(wish: Wish) {
viewModelScope.launch {
repository.addWish(wish)
}
}
// Новый метод обновления статуса лайков
fun updateWishLikedStatus(wish: Wish, isLiked: Boolean) {
viewModelScope.launch {
repository.updateWishLikedStatus(wish, isLiked)
}
}
// Другая логика обработки намерений...
}
каждый Intent Будут запущены соответствующие обновления статуса.
UI проход слоя Jetpack Compose и Material3 Создайте приложение Пользовательский интерфейс. С помощью Compose Декларативный шаблон проектирования,можно легко создатьмногоразовыйкомпоненты,объединить MVI Убедитесь, что интерфейс автоматически обновляется при изменении статуса.
@Composable
fun HomeScreen(viewModel: WishViewModel) {
val wishes by viewModel.wishes.observeAsState(initial = emptyList())
LazyColumn {
items(wishes) { wish ->
Text(text = wish.title)
}
}
}
View всегда проходить Intent и ViewModel Взаимодействие, Пользовательский интерфейс Рендеринг происходит через неизменяемое состояние.
Jetpack Compose Предоставляет встроенную библиотеку навигации, которая помогает нам управлять переходами на страницы приложения. Логика навигации между помещенными страницами существует MainScreen середина:
@Composable
fun MainScreen() {
val navController = rememberNavController()
NavHost(navController = navController, startDestination = "home") {
composable("home") { HomeScreen(navController) }
composable("detail/{id}") { backStackEntry ->
val id = backStackEntry.arguments?.getString("id")
DetailScreen(navController, id)
}
}
}
Такая конструкция позволяет добиться разделения страниц и уменьшить зависимости.
Состояние да неизменяемо, и все операции каждый будут создавать новое состояние. Следующий обновленный пример пользовательского интерфейса, управляемого состоянием:
@Composable
fun WishItem(viewModel: WishViewModel, wish: Wish) {
var isLiked by remember { mutableStateOf(false) }
Column {
Text(text = wish.title)
IconButton(onClick = {
isLiked = !isLiked
viewModel.updateWishLikedStatus(wish, isLiked) // вызов ViewModel Способ обновления статуса лайка
}) {
Icon(imageVector = Icons.Default.Favorite, tint = if (isLiked) Color.Red else Color.Gray)
}
}
}
Каждый раз, когда пользователь нажимает на значок, статус isLiked Изменения происходят, пользовательский интерфейс Он будет автоматически перерисован в зависимости от нового состояния.
Такая модульная архитектура значительно повышает удобство сопровождения и масштабируемость приложения. Для сложных проектов используйте MVI Такая архитектура одностороннего потока данных может уменьшить путаницу в управлении состоянием и гарантировать, что каждое изменение состояния предсказуемо и контролируемо.
Не стесняйтесь задавать любые вопросы, спасибо всем, кто дочитал)