Реализация MVVM в Jetpack Compose и сравнение ViewModel и запоминание
Реализация MVVM в Jetpack Compose и сравнение ViewModel и запоминание

Предисловие

ViewModel и remember да Jetpack Compose Два разных механизма управления данными в формате .

Они имеют следующие различия:

управление жизненным циклом:

  • ViewModel: ViewModel даA добрый для хранения и управления данными, связанными с интерфейсом, которые жизненно важны цикл, связанный с ViewModelStoreOwner связанный (обычно да Activity или Fragment)。 это означает ViewModel вданные будут в ассоциированном ViewModelStoreOwner Поддерживать состояние в присутствии до тех пор, пока не наступит их жизненный цикл окончен.
  • remember: remember да А используется для хранения эфемерных данных Compose Государственный менеджер. 它的жизненный циклс вызовом этогокомпонентысвязанный,Обычно компоненты функционируют. Когда компоненты воссоздаются,remember данные, хранящиеся в нем, будут потеряны.

Обмен данными:

  • ViewModel: ViewModel Обычно используется для хранения данных персистентности, связанных с интерфейсом, которые могут совместно использоваться несколькими компонентами, например, в пределах одного и того же компонента. Activity разница в Fragment распределяется между данными.
  • remember: remember В основном используется для хранения временного локального состояния, например UI статус, временный кэш и т. д. Его область действия обычно ограничивается вызывающей стороной.

Сохранение данных:

  • ViewModel: ViewModel вданные обычно имеют более продолжительный жизненный характер цикл и сохраняется при изменении конфигурации (например, при повороте экрана).
  • remember: remember вданные Обычно временные и не сохраняются при изменении конфигурации.

использование:

  • ViewModel: обычно проходил в Activity или Fragment серединаиспользовать ViewModelProvider получать ViewModel экземпляр и наблюдать при необходимости ViewModel в LiveData илииспользоватьэто обеспечиваетданные。
  • remember: remember Вы можете напрямую Compose компонентывнутреннийиспользовать,Позвонив remember { } или rememberSaveable { } для создания и хранения состояния.

Общий:

  • ViewModel Подходит для управления сохранением данных в различных компонентах распределения. между данными.
  • remember подходит для управления кратковременными UI Штат и местный штат.

remember/rememberSaveable

В создании,rememberиrememberSaveableВседа Метод сохранения состояния компонуемых функций,Но они различаются тем, как сохраняется состояние и при каких обстоятельствах оно пересчитывается.

remember: Эта функция является частью комбинированной функции. цикл всегда остается неизменным. это Это означает, что каждый раз, когда функция композиции вызывается снова, она будет использовать ранее сохраненное значение состояния без его пересчета. Это полезно для статических файлов, которые не изменяются при взаимодействии с пользователем. Если изменение статуса не требуется в компонентахжизненный Стойкость вне цикла,rememberда Более легкий вариант。

Язык кода:javascript
копировать
var password by remember { mutableStateOf("") }

rememberSaveable: Эта функция также сохраняет состояние, но также сохраняет его, чтобы его можно было восстановить после того, как приложение перейдет в фоновый режим и будет уничтожено. Это полезно для приложений, требующих изменения конфигурации (например, поворота экрана). циклстатус очень полезен。Это спасет государство вBundleсередина,обеспечить устойчивость государства.

Язык кода:javascript
копировать
var password by rememberSaveable { mutableStateOf("") }

поэтому,rememberSaveableОбеспечивает постоянную поддержку состояния,иrememberтогда только вкомпонентыжизненный Сохраните состояние в цикле.

Какой из них выбрать, зависит от того, какое состояние вам нужно — нужно ли оно сохраняться при перезапуске приложения.

mutableStateOf/mutableStateListOf

mutableStateOf да Jetpack Compose Функция в , используемая для создания изменяемого состояния.

Его роль – создать состояние, которое можно изменить.,И когда статус когда изменится,Compose будет пересчитан и обновлен UI。

Конкретно,mutableStateOf Функция принимает начальное значение в качестве параметра и возвращает MutableState объект.

MutableState Объект имеет value Атрибуты могут читать и изменять значение этого состояния.

когда MutableState Когда значение объекта изменится, Compose будет пересчитан в зависимости от нового статуса Пользовательский интерфейс для обеспечения UI Отразить последний статус.

Например, предположим, что у нас есть mutableStateOf Объект для представления значения счетчика:

Язык кода:javascript
копировать
val countState = remember { mutableStateOf(0) }

Затем мы можем изменить его, изменив countState.value Значение для обновления состояния счетчика:

Язык кода:javascript
копировать
countState.value += 1

Каждыйкогда countState.value Когда значение изменяется, значение, связанное со статусом UI Оно будет пересчитано и обновлено, чтобы отразить последнее значение счетчика.

Общий:

mutableStateOf Роль да в Jetpack Compose Создайте в нем изменяемое состояние, чтобы его можно было динамически обновлять. UI и убедитесь, что UI Отражает последнее значение статуса.

ViewModel

Класс ViewModelдабизнес-логикаили Контейнер состояний уровня экрана。Он используется для предоставления состояния интерфейсу.,И инкапсулируйте связанную бизнес-логику.

Его главное преимущество заключается в том, что он может кэшировать состояние и сохранять его после изменений конфигурации. это означаетсуществовать activity Интерфейсу не потребуется повторно получать данные при переходе между пользовательскими интерфейсами или после внесения изменений в конфигурацию (например, при повороте экрана).

Добавить курс

Язык кода:javascript
копировать
class MyViewModel : ViewModel() {
    val listItems by mutableStateOf(listOf("Чжан Сан", «Ли Си»,«Ван Ву»))
}

На данный момент мы будем создавать новый объект каждый раз, когда его инициализируем.

Язык кода:javascript
копировать
val mainViewModel:MyViewModel = MyViewModel()
Log.i("ZLog","Код объекта:"+mainViewModel.hashCode())

Таким образом, неудобно повторно использовать настроенные компонентыиспользованные.,можешь ли ты позволить намViewModel的实例существоватьодиндобрыйсерединада Тот же экземпляр?

да Да.

Добавить цитату

Язык кода:javascript
копировать
implementation ("androidx.lifecycle:lifecycle-viewmodel-compose:2.6.1")

На данный момент мы пишем так, когда используем экземпляр

Язык кода:javascript
копировать
val mainViewModel:MyViewModel = viewModel()
Log.i("ZLog","Код объекта:"+mainViewModel.hashCode())

Уведомление :

viewModel()Метод будет основан надобрыйформаи所существовать的ViewModelStoreOwnerСоздается автоматическииэкземпляр кэша。 viewModel Примеры из литературы ViewModelStoreOwner(в целомдаодин Activity или Fragment)связанный的,это означает ViewModel жизненный цикл и его ViewModelStoreOwner дамматчи.

Пример списка

ViewModel

Язык кода:javascript
копировать
class MyViewModel : ViewModel() {
    val listItems = mutableStateListOf<String>()
    fun loadMore(){
        Log.i("ZLog","добавить вданные")        listItems.add((Math.random()*100).toString())
    }
}

Также возможна инициализация данных

Язык кода:javascript
копировать
val listItems = mutableStateListOf("Чжан Сан","Ли Си»,«Ван Ву»)

компоненты

Язык кода:javascript
копировать
@Composable
fun MyList(mList: List<String>) {
    SideEffect {
        Log.i("ZLog","SideEffect")
    }
    LazyColumn {
        items(mList.size) {
            ListItem(mList[it])
        }
    }
}

@Composable
fun ListItem(text: String) {
    // Создание элементов списка UI
    Text(text = text)
}

данныепри обновленииSideEffectне вызвало。

SideEffect Функция обратного вызова есть только в MyList Компонент вызывается при его первом создании, потому что SideEffect Будет запускать свой блок кода при создании компонентов и каждый раз при повторной сборке компонентов.

Но да в этом случае,MyList компонентысуществовать mList Он не перегруппировывается при изменении, потому что Compose Не удалось обнаружить изменения в данных списка.

сделать SideEffect Вызывается при изменении данных списка, вы можете рассматривать данные списка как key Параметры, переданные в MyList компоненты,Когда данные списка «Когда» меняются вот так,MyList компоненты будут воссозданы, вызывая SideEffect функция обратного вызова.

Например:

Язык кода:javascript
копировать
@Composable
fun MyList(mList: List<String>, key: Any = mList) {
    SideEffect {
        Log.i("ZLog","SideEffect")
    }
    LazyColumn {
        items(mList.size) {
            ListItem(mList[it])
        }
    }
}

После этой модификации MyList В, мы используем key Параметры будут перечисленыданныеперешел ккомпоненты。так,Когда данные списка меняются,key Значение также изменится, что приведет к срабатыванию MyList рекомбинация, так что SideEffect может быть выполнено снова.

использовать

Язык кода:javascript
копировать
Box() {
    val mainViewModel: MyViewModel = viewModel()
    MyList(mainViewModel.listItems)
    Button(modifier=Modifier.align(Alignment.BottomEnd).padding(10.dp),onClick = {
        mainViewModel.loadMore()
    }) {
        Text("нагрузкаданные")    }
}

Уведомление

Данные в ViewModel должны быть обновлены в потоке пользовательского интерфейса до начала обновления страницы.

Распространенные ошибки

Запрос интерфейса

Reading a state that was created after the snapshot was taken or in a snapshot that has not yet been applied

возобновлятьданныесуществоватьLaunchedEffect

Язык кода:javascript
копировать
val appViewModel: AppViewModel = viewModel()
LaunchedEffect(Unit){
    appViewModel.loadInit()
}
boy illustration
Углубленный анализ переполнения памяти CUDA: OutOfMemoryError: CUDA не хватает памяти. Попыталась выделить 3,21 Ги Б (GPU 0; всего 8,00 Ги Б).
boy illustration
[Решено] ошибка установки conda. Среда решения: не удалось выполнить первоначальное зависание. Повторная попытка с помощью файла (графическое руководство).
boy illustration
Прочитайте нейросетевую модель Трансформера в одной статье
boy illustration
.ART Теплые зимние предложения уже открыты
boy illustration
Сравнительная таблица описания кодов ошибок Amap
boy illustration
Уведомление о последних правилах Points Mall в декабре 2022 года.
boy illustration
Даже новички могут быстро приступить к работе с легким сервером приложений.
boy illustration
Взгляд на RSAC 2024|Защита конфиденциальности в эпоху больших моделей
boy illustration
Вы используете ИИ каждый день и до сих пор не знаете, как ИИ дает обратную связь? Одна статья для понимания реализации в коде Python общих функций потерь генеративных моделей + анализ принципов расчета.
boy illustration
Используйте (внутренний) почтовый ящик для образовательных учреждений, чтобы использовать Microsoft Family Bucket (1T дискового пространства на одном диске и версию Office 365 для образовательных учреждений)
boy illustration
Руководство по началу работы с оперативным проектом (7) Практическое сочетание оперативного письма — оперативного письма на основе интеллектуальной системы вопросов и ответов службы поддержки клиентов
boy illustration
[docker] Версия сервера «Чтение 3» — создайте свою собственную программу чтения веб-текста
boy illustration
Обзор Cloud-init и этапы создания в рамках PVE
boy illustration
Корпоративные пользователи используют пакет регистрационных ресурсов для регистрации ICP для веб-сайта и активации оплаты WeChat H5 (с кодом платежного узла версии API V3)
boy illustration
Подробное объяснение таких показателей производительности с высоким уровнем параллелизма, как QPS, TPS, RT и пропускная способность.
boy illustration
Удачи в конкурсе Python Essay Challenge, станьте первым, кто испытает новую функцию сообщества [Запускать блоки кода онлайн] и выиграйте множество изысканных подарков!
boy illustration
[Техническая посадка травы] Кровавая рвота и отделка позволяют вам необычным образом ощипывать гусиные перья! Не распространяйте информацию! ! !
boy illustration
[Официальное ограниченное по времени мероприятие] Сейчас ноябрь, напишите и получите приз
boy illustration
Прочтите это в одной статье: Учебник для няни по созданию сервера Huanshou Parlu на базе CVM-сервера.
boy illustration
Cloud Native | Что такое CRD (настраиваемые определения ресурсов) в K8s?
boy illustration
Как использовать Cloudflare CDN для настройки узла (CF самостоятельно выбирает IP) Гонконг, Китай/Азия узел/сводка и рекомендации внутреннего высокоскоростного IP-сегмента
boy illustration
Дополнительные правила вознаграждения амбассадоров акции в марте 2023 г.
boy illustration
Можно ли открыть частный сервер Phantom Beast Palu одним щелчком мыши? Супер простой урок для начинающих! (Прилагается метод обновления сервера)
boy illustration
[Играйте с Phantom Beast Palu] Обновите игровой сервер Phantom Beast Pallu одним щелчком мыши
boy illustration
Maotouhu делится: последний доступный внутри страны адрес склада исходного образа Docker 2024 года (обновлено 1 декабря)
boy illustration
Кодирование Base64 в MultipartFile
boy illustration
5 точек расширения SpringBoot, супер практично!
boy illustration
Глубокое понимание сопоставления индексов Elasticsearch.
boy illustration
15 рекомендуемых платформ разработки с нулевым кодом корпоративного уровня. Всегда найдется та, которая вам понравится.
boy illustration
Аннотация EasyExcel позволяет экспортировать с сохранением двух десятичных знаков.