Шаблон MVVM по-простому. LiveData.
ฝัง
- เผยแพร่เมื่อ 1 ต.ค. 2024
- Приветствую 🖐 друзья, в данных видео уроках мы с вами изучим компонент LiveData
Ссылка на полный курс по MVVM
market-...
🤝 Поддержка канала:
✅ ВКонтакте: donate_...
✅ Donationalerts www.donational....
❗️ Важные ссылки ❗️
1️⃣ Презентацию можно скачать в группе ВКонтакте: mobile_...
2️⃣ LiveData: developer.andr...
3️⃣ Корутины: github.com/kot...
📚 Рекомендуемое бесплатное изучение языка Kotlin
1️⃣ Приложение для запоминания ключевых слов Kotlin: play.google.co....
2️⃣ Мини курс по Kotlin в картинках: • #1. Kotlin в картинках...
√ Тэги для поиска:
#kotlin #mvvm #livedata #androidstudio #firebase #telegram #создатьприложение
Можно поддержать автора и канал 🤝 купив полный курс по MVVM здесь:
boosty.to/mr.developer/posts/fe32632b-1f7e-4c82-9a8e-d2a4e2cb2146?share=post_link
Список уроков:
1. Создание проекта.
2. Заполнение activity_main.xml.
3. Заполнение fragment_main.xml. Добавление note_item.xml
4. Заполнение макетов. Добавление кнопок на тулбар
5. Инициализация объектов в MainActivity
6. Инициализация StartFragment.kt, создание модели AppNote.kt
7. Создание DatabaseRepository.kt, реализация репозитория Room
8. Создание базы данных AppRoomDatabase.kt
9. Переход с MainFragment.kt на AddNewNoteFragment.kt
10. Создание новой заметки
11. Заполнение RecyclerView. Отображение списка заметок
12. Переход в NoteFragment.kt, удаление заметки из БД
13. Настройка поведения навигационного графа
14. Создание с нуля проекта в Firebase
15. Подключение к Firebase
16. Макет для выбора базы данных
17. Быстрая авторизация в Firebase
18. Создание LiveData для работы с Firebase
19. Создание новой заметки в Firebase
20. Удаление заметки из Firebase
21. Реализация функции выхода из аккаунта Firebase
22. Добавление анимации в навигацию
23. Сохранение настроек в SharedPreference.
Где применим стек технологий:
-Android SDK;
-Kotlin;
-MVVM;
-LiveData;
-ViewModel;
-Room (SQLite);
-Navigation;
-Kotlin Coroutines;
-Firebase SDK;
-RecyclerView.
Про медиатор. Прежде, чем объяснять, как оно работает - нужно сначала объяснить, зачем оно нужно.
Ну отслеживает медиатор сразу две даты. А толку от этого?
Насколько я понимаю - слово медиатор как бы подсказывает, что таким образом можно реализовать взаимообмен данными между лайв датами. Но это только предположение.
Резюме: чтоб было проще объяснить - сначала ставьте перед учеником проблему. А потом рассказывайте, как её можно решить.
А то знание об инструменте получено, а на какую полку этот инструмент положить - непонятно.
В видео, когда прописали корутину значение hello world! не изменилось. И никто этого не заметил((
Тоже это смутило, как только это увидел. Но если посмотреть на код автора, то измениться ничего и не должно было, т.к. он изменял значения лайвдаты в фоновом потоке, а значение текствью не трогал и оно осталось по умолчанию. Если цель была в том, чтобы показать, что в фоновом потоке нужно использовать постВэлью, чтобы избежать ошибок, то все было сделано верно)
Тоже заметил. Потом обмотал по видео и увидел - он удалил строчку, где строковое значение из лайвдаты присваивал текстовой вьюхе на активити...))
я заметил вот хочу тоже написать про это
Как на 4:56 обратиться к test_text1.text из MainActivity? У меня тупо не видит такого id-шника :(
Если кому актуально, то в build.gradel module нужно было добавить несколько зависимостей (отдельно от основного всего. В самом начале программы)
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
И после этого станет доступен импорт в MainActivity.kt:
import kotlinx.android.synthetic.main.activity_main.*
p.s. в самых новых версиях нужно просто добавить строчку "id 'kotlin-android-extensions'" в build.gradel module -> plugins
Уроки супер ! Друг, сделай пожалуйста про корутины, коль ты их здесь упомянул
Не понятно зачем мне MediatorLiveData, если я могу просто создать две MutableLiveData, установить им по Observer-у и затем дёргать нужную
Абсолютно согласен. Автор не объяснил... Полагаю, что данный метод вызывается при каждом обновлении любой из добавленных MutableLiveData и может взаимодействовать между ними.
пересмотри там всё понятно
7:26 "все отлично, ошибок нет". Но текст "Hello world", а должен быть "Hello live data", разве нет? В чем проблема?
Не должен. Посмотрите код
Он передал значение в liveDateString, но не присвоил его для test_text1. Поэтому текст в TextView остался старым.
А покажете на простом примере как тесты проводить, как отдельно тестировать модель, вью, вьюмодель?
Отличное объяснение, спасибо за ваш труд, надеюсь не остановитесь, так как очень интересно вас слушать. И не думали ли вы также затронуть такие темы, как: dagger/koin, rxJava/corutines
Спасибо за отзыв, я подумаю)
@@mr.developer как постоянным Вашим подписчикам, именно от Вас такие видео было бы просто чудесно изучить)
Один из лучших каналов по мобильной разработке на ютубе. Просто супер, все доступно.
Благодарю за отзыв)
На 7:27 когда вы передали через postValue данные в LiveData, то как эту строку установить в test_text?? На экране Hello World
Обсервер повесить
Я тоже заметила
Про mediatorLiveData как-то с примером не дошло, правильно ли я понял, что по сути эти две LiveData можно спокойно было сделать и без этого mediatora. Лично я не понял его смысл.. Поправить если я не прав..
А так спасибо за видео 😊
К сожалению уже не помню ), давно это было. Может поменялось апи
На 7:25 минуте не отображается "Hello live data" там "Hello World"
👍
Всё отлично, ошибок нет: Hello world. ))))
Откуда столько восторженных отзывов, при том что в коде косяк на косяке?
18:40 не понял в чем прикол, весь каеф подписки лайф даты в том, что ну нежно задумываться о жизненном цикле, все это под капотом делается...
Прекрасное объяснение работы LiveData, перечислены множество способов работать с БД. Пока новичок в AS Kotlin, немного сложно изучать данный паттерн, думаю, что со временем все пойму. Спасибо!
Каким образом без findById находить id test_text1 ?
Kotlin extension, но сейчас устарели. Используйте VBinding
При каждом клике на кнопку вешать обсервер так себе идея)
Вы правы, но это лишь демонстрация возможностей а не руководство к действию.
Спасибо, объясняете доступно. LiveData всё понятно. но зачем нужен медиатор (MediatorLiveData) ? мы можем и лайвдате прописать observer ... что без медиатора два раза обсервер, что с медиатором два раза ... суть только в том что появится еще один общий обьединяющий observer ?
Более структуризированно и понятно.В программировании ценится код который структуризирован, понятен, сжат.
@@mlazebny
первый код без медиатора:
val mLiveData1 = MyLiveDate()
val mLiveData2 = MyLiveDate()
...
mLiveData1.observe(this, {...})
mLiveData2.observe(this, {...})
-------------------
второй код с медиатором:
val mLiveData1 = MyLiveDate()
val mLiveData2 = MyLiveDate()
val mediatorLiveData = MediatorLiveData()
...
mediatorLiveData.addSource(mLiveData1, {...})
mediatorLiveData.addSource(mLiveData2, {...})
---------------
чем он стал структурирован или сжат ?) я вижу разницу только в том что появится общий observer, в этом суть ? или я чтото упустил еще ?
@@sanek_180st когда испоользуется 2 разных источника данных лучше использовать mediator, легче взаимодействоваьть с элементами
@@mlazebny ну вот я в примере привел две лайв даты в чем разница, мы что так что так задаём два обсерва ... Единственное что в медиаторе можно сделать общий обсервер, вы это имеете ввиду ?
@@sanek_180st да
Не очень понял как работает observer, на 24:30 устанавливается observer после изменения, в моем представлении он должен реагировать на изменения только после того, как был установлен
Как ты регистрируешь свой макет в мейн Активити ? Через что ? Нет бандинга и регистрации вьюшек, как ты это делаешь ?
А в чем разница между подходами
liveData.observe(this, Observer) и mediatorLD.addSource(liveData, Observer)?
🤷♂️
Годно, ну, ребята, годно же, а? Даже деда спросил: дед тоже сказал, мол "чётко". Ждём следующего видео, глядишь скоро и до Hilt дойдём.
1 из немногих ютуберов кто внятно объясняет новичкам простыми словами и примерами кода-MVVM, спасибо за контент , надеюсь что это не последнее видео на эту тему и хотелось бы увидеть простенкое приложение на этом патерне, чтобы понять как создавать приложения без лишнего кода))
Благодарю за отзыв, приложение-пример будет
можно утонуть от такого колличества лишних слов.
🙈
спасибо
Немного не понял, а почему мы не можем создавать для каждой LiveData свой observe. Он же также отработает. В чем преимущество и тем более использование медиатора если у нас несколько LiveDat??
Да наверно можно
Ты крут, подача бомба, я такого пока не встречал. Очень полезно.
Вопрос: правильно понимаю, что Лайвдата всегда автоматом срабатывает и выдает список в вью, если в Комнату вставить или обновить, удалить? А как быть если надо в фоновом режиме подкачивать пополнять те вставлять еще данные из Сервера например из Файербейс, то список в вью будет обновляться что не нужно, или вообще какие то фоновые работы выполняются?
Не пользоваться Лайвдата, а сделать мьютоблЛист + обсервер с очисткой его в онДестройВьюМодел и в онСтарт проверять пуст не пуст, если пуст запрос в Комнату далее срабатывает обсервер и список в Вью обновляется. Может так сделать, А ЛайвДате по идее должен быть выкл автооновлений?
Доброго дня! Весьма интересное видео. А как "провалиться"?
Ctrl + ЛКМ
Благодарю за отзыв, очень приятно ☺️🤝
Спасибо!
Благодарю вас за отзыв, очень приятно ☺️🤝
спасибо
Благодарю за отзыв 🤝
А что нормально то с корутинами, там же не тот текст был. Там был просто Hello Word пересмотри сам видео
👍
Спасибо тебе за твой труд. Самое понятное объяснение. Если б ты сделал видеокурс по андроид разработке в целом, купил бы даже за деньги.
Зачем в onStart() и onStop() подписываться и отписываться от данных, если класс в принципе был создан для того что бы делать это самостоятельно?
Здравствуйте, это не отписка а удаление наблюдателя. И это я просто показал, что бы явно было видно , что с объектом можно делать.
Автор просто не разобрался в теме которой пытается учить других. Это не может быть "бест практишь", потому что противоречит принципу LiveData - а именно автоматизация. Как раз для того что бы не заниматься подпиской/отпиской на каждый start/stop, в LiveData реализован механизм active/inactive. Тем самым вы не создаете лишних обьектов (observer, observer wrapper), не нагружаете GC, не делаете лишних вычислений. И удалится observer тоже автоматически при переходе Lifecycle в состояние DESTROYED.
помоему это не лайвдата подписывается на активити, а активити - на лайвдату
👍
Если кому станет намного скучно слушать - просто отвечайте "да" каждый раз, как автор спрашивает это ;)
Самые годные уроки в русскоязычном сегменте. Хотя, когда автор пишет большие программы, то на мой взгляд, слишком много функционально стиля, и если посмотреть на диаграмму классов, то встречаются ошибки при построении архитектуры
Урок понравился, лайк поставил, подписался.
Было бы здорово, если бы соблюдали стилистику кода - ставили отступы.
Рефакторинг кода можно сделать сочетанием клавиш CTRL + ALT + L (Win) /OPTION + CMD + L (Mac)
Большое спасибо всё оказывается просто
Благодарю за отзыв 🤝
👍🏻👍🏻👍🏻
Здравствуйте, на минуте 32:58, когда вы поменяли значение postavalue " "hello world " вышло , но должно было "hello there world".
🤷♂️ я уж не помню)
Не понятно, зачем нужен Transformations.map. Можно ведь сделать просто: ldStrind.value = ldInt.value.toString().
Конечно можно, можно вообще ничего не использовать, а писать функциональный код)
Спасибо большое! Отличное видео!
Благодарю за отзыв 🤝
Отличный видеоурок. Большое спасибо
18:30
Получается медиатор лайвдаты делает так, чтобы обзёрвер был один на все лайвдаты? Если простым языком
Да
так зачем нам медиатор не опнятно ведь и так можно observe подписать на сами LiveData, сделали пустой observe у медиатара, и оставить его пустым ? для чего?
👍
@@mr.developer И что это значит?)
Можно по разному)
Да это понятно) что может быть несколько решений у задачи, но они как бы должны предоставлять свою логику с + и - от других вариантов, а тут я просто хотел бы узнать для чего нам это тут вообще и не лишнее ли это)@@mr.developer
@fiodar_vasilets ох, я к сожелению сейчас не вспомню нюансов. Давно это было 🤷♂️
Спасибо! Отличный ролик, после просмотра стало понятно, как работает LiveData.
Благодарю вас за отзыв 🤝
Добрый день! Я б купил курс по MVVM, но не через вк,есть варианты?
Здравствуйте, в Телеграм
t.me/mobile_developing/71
А какие плагины вы используете в студии? нравиться подсветка кода
Это своя тема
Да
Здравствуйте, а как сделать так чтобы к view можно было обращаться без ссылки через R.id. как это сделано у вас? Это расширение какое то?
Да это котлин-расширения. Но сейчас они устарели, используйте ViewBindind
@@mr.developer Понял, спасибо за ответ 🤝
А если какие-то переменные не изменяются, например, состояние авторизации, то лучше использовать константы или LiveData?
Здравствуйте, переменные не бывают неизменяемые, на то они и переменные. Если есть свойства класса которые не изменяется то это константы.
@@mr.developer понятно, спасибо. Туплю ещё. Всё же, когда лучше константы, а когда LiveData?
Шикарные уроки! Ты лучшииииий
В описании линк на Котлин обрезан.
Вот нормальный линк: th-cam.com/play/PLY8G5DMG6TiNVIy6sZ0RHb14nKDFG7uQc.html
Спаисибо
А что это за прикол в 19 строке на 5:13 , когда обращение из кода к текст вью идет просто по айди, без findViewById, без viewBinding?
Kotlin extension
@@mr.developer А как подключить это?
@@mr.developer Сорян за беспокойство. Нашёл выше.
👍
Спасибо, отлично объяснил!
Благодарю за отзыв
Сорян за ламерский вопрос: пытаюсь сделать то же самое в джаве, там нету корутин((( Через Thread не получается - при операции postValue исключения не возникает, но и визуальных изменений нет. Пожалуйста, не советуйте юзать котлин, мне нужно сделать на джаве.
А как вы в котлин коде обращаетесь к элементу UI без его инициализации методом findViewById? 14:50 здесь например вы ставите клик листенер на кнопку используя ее id? Для этого плагин какой-то нужен?
Это extension Kotlin. Но сейчас он deprecated. Используйте binding
@@mr.developer А как в этом случае избежать огромного количества слова "binging" в коде?)