No video

Шаблон MVVM по-простому. LiveData.

  Рет қаралды 25,034

Petrov Yuri

Petrov Yuri

Күн бұрын

Приветствую 🖐 друзья, в данных видео уроках мы с вами изучим компонент 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 #создатьприложение

Пікірлер: 129
@mr.developer
@mr.developer 3 жыл бұрын
Можно поддержать автора и канал 🤝 купив полный курс по 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.
@annasakharova922
@annasakharova922 4 жыл бұрын
Один из лучших каналов по мобильной разработке на ютубе. Просто супер, все доступно.
@mr.developer
@mr.developer 4 жыл бұрын
Благодарю за отзыв)
@quietplayer7733
@quietplayer7733 4 жыл бұрын
1 из немногих ютуберов кто внятно объясняет новичкам простыми словами и примерами кода-MVVM, спасибо за контент , надеюсь что это не последнее видео на эту тему и хотелось бы увидеть простенкое приложение на этом патерне, чтобы понять как создавать приложения без лишнего кода))
@mr.developer
@mr.developer 4 жыл бұрын
Благодарю за отзыв, приложение-пример будет
@user-de6dd1dd8e
@user-de6dd1dd8e 4 жыл бұрын
Уроки супер ! Друг, сделай пожалуйста про корутины, коль ты их здесь упомянул
@NevilPlay
@NevilPlay 4 жыл бұрын
Прекрасное объяснение работы LiveData, перечислены множество способов работать с БД. Пока новичок в AS Kotlin, немного сложно изучать данный паттерн, думаю, что со временем все пойму. Спасибо!
@user-ky2zi4fp9r
@user-ky2zi4fp9r 2 жыл бұрын
Спасибо! Отличный ролик, после просмотра стало понятно, как работает LiveData.
@mr.developer
@mr.developer 2 жыл бұрын
Благодарю вас за отзыв 🤝
@youandpsycho625
@youandpsycho625 Жыл бұрын
Спасибо!
@mr.developer
@mr.developer 10 ай бұрын
Благодарю вас за отзыв, очень приятно ☺️🤝
@itcat8369
@itcat8369 4 жыл бұрын
Отличное объяснение, спасибо за ваш труд, надеюсь не остановитесь, так как очень интересно вас слушать. И не думали ли вы также затронуть такие темы, как: dagger/koin, rxJava/corutines
@mr.developer
@mr.developer 4 жыл бұрын
Спасибо за отзыв, я подумаю)
@annasakharova922
@annasakharova922 4 жыл бұрын
@@mr.developer как постоянным Вашим подписчикам, именно от Вас такие видео было бы просто чудесно изучить)
@8Sapphire8
@8Sapphire8 3 жыл бұрын
Ты крут, подача бомба, я такого пока не встречал. Очень полезно.
@user-vn9fk3mh3c
@user-vn9fk3mh3c 2 жыл бұрын
Спасибо тебе за твой труд. Самое понятное объяснение. Если б ты сделал видеокурс по андроид разработке в целом, купил бы даже за деньги.
@user-hu8uw3fr6m
@user-hu8uw3fr6m Жыл бұрын
Всё отлично, ошибок нет: Hello world. ))))
@Arman_127
@Arman_127 2 жыл бұрын
Большое спасибо всё оказывается просто
@mr.developer
@mr.developer 2 жыл бұрын
Благодарю за отзыв 🤝
@elpirato5428
@elpirato5428 4 жыл бұрын
А покажете на простом примере как тесты проводить, как отдельно тестировать модель, вью, вьюмодель?
@cryptoman7743
@cryptoman7743 3 жыл бұрын
В видео, когда прописали корутину значение hello world! не изменилось. И никто этого не заметил((
@alexeymurnikov1413
@alexeymurnikov1413 3 жыл бұрын
Тоже это смутило, как только это увидел. Но если посмотреть на код автора, то измениться ничего и не должно было, т.к. он изменял значения лайвдаты в фоновом потоке, а значение текствью не трогал и оно осталось по умолчанию. Если цель была в том, чтобы показать, что в фоновом потоке нужно использовать постВэлью, чтобы избежать ошибок, то все было сделано верно)
@shepelavka
@shepelavka 3 жыл бұрын
Тоже заметил. Потом обмотал по видео и увидел - он удалил строчку, где строковое значение из лайвдаты присваивал текстовой вьюхе на активити...))
@user-zi2sl7jh3t
@user-zi2sl7jh3t 3 жыл бұрын
я заметил вот хочу тоже написать про это
@NeSpor6
@NeSpor6 2 жыл бұрын
спасибо
@mr.developer
@mr.developer 2 жыл бұрын
Благодарю за отзыв 🤝
@user-cm6ke4ys7h
@user-cm6ke4ys7h 2 жыл бұрын
Спасибо большое! Отличное видео!
@mr.developer
@mr.developer 2 жыл бұрын
Благодарю за отзыв 🤝
@kuzd4niil
@kuzd4niil 3 жыл бұрын
Отличный видеоурок. Большое спасибо
@openfrom03
@openfrom03 3 жыл бұрын
Урок понравился, лайк поставил, подписался. Было бы здорово, если бы соблюдали стилистику кода - ставили отступы. Рефакторинг кода можно сделать сочетанием клавиш CTRL + ALT + L (Win) /OPTION + CMD + L (Mac)
@Nazaro4ka
@Nazaro4ka Жыл бұрын
Полюбил этот канал за клавиатурные титры
@mr.developer
@mr.developer 10 ай бұрын
Благодарю вас за отзыв, очень приятно ☺️🤝
@sno-oze
@sno-oze 4 жыл бұрын
Годно, ну, ребята, годно же, а? Даже деда спросил: дед тоже сказал, мол "чётко". Ждём следующего видео, глядишь скоро и до Hilt дойдём.
@user-cp7yq4zd5e
@user-cp7yq4zd5e 3 жыл бұрын
7:26 "все отлично, ошибок нет". Но текст "Hello world", а должен быть "Hello live data", разве нет? В чем проблема?
@Nidvoraich
@Nidvoraich 3 жыл бұрын
Не должен. Посмотрите код
@halulkin
@halulkin 3 жыл бұрын
Он передал значение в liveDateString, но не присвоил его для test_text1. Поэтому текст в TextView остался старым.
@user-ke3jt3uh3m
@user-ke3jt3uh3m 3 жыл бұрын
Как на 4:56 обратиться к test_text1.text из MainActivity? У меня тупо не видит такого id-шника :(
@user-ke3jt3uh3m
@user-ke3jt3uh3m 3 жыл бұрын
Если кому актуально, то в 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.*
@user-ke3jt3uh3m
@user-ke3jt3uh3m 3 жыл бұрын
p.s. в самых новых версиях нужно просто добавить строчку "id 'kotlin-android-extensions'" в build.gradel module -> plugins
@user-sq5cr5uq8i
@user-sq5cr5uq8i 3 жыл бұрын
Шикарные уроки! Ты лучшииииий
@inex550
@inex550 3 жыл бұрын
Не понятно зачем мне MediatorLiveData, если я могу просто создать две MutableLiveData, установить им по Observer-у и затем дёргать нужную
@behtold
@behtold 3 жыл бұрын
Абсолютно согласен. Автор не объяснил... Полагаю, что данный метод вызывается при каждом обновлении любой из добавленных MutableLiveData и может взаимодействовать между ними.
@kairatkudaibergenov7255
@kairatkudaibergenov7255 3 жыл бұрын
пересмотри там всё понятно
@ipvoodoo
@ipvoodoo 4 жыл бұрын
Спасибо, отлично объяснил!
@mr.developer
@mr.developer 4 жыл бұрын
Благодарю за отзыв
@sergeykrivenkov6436
@sergeykrivenkov6436 3 жыл бұрын
Откуда столько восторженных отзывов, при том что в коде косяк на косяке?
@abuiman5251
@abuiman5251 3 жыл бұрын
На 7:27 когда вы передали через postValue данные в LiveData, то как эту строку установить в test_text?? На экране Hello World
@-Alexey-
@-Alexey- 3 жыл бұрын
Обсервер повесить
@cinderellarouge
@cinderellarouge 2 жыл бұрын
Я тоже заметила
@Nidvoraich
@Nidvoraich 3 жыл бұрын
Про медиатор. Прежде, чем объяснять, как оно работает - нужно сначала объяснить, зачем оно нужно. Ну отслеживает медиатор сразу две даты. А толку от этого? Насколько я понимаю - слово медиатор как бы подсказывает, что таким образом можно реализовать взаимообмен данными между лайв датами. Но это только предположение. Резюме: чтоб было проще объяснить - сначала ставьте перед учеником проблему. А потом рассказывайте, как её можно решить. А то знание об инструменте получено, а на какую полку этот инструмент положить - непонятно.
@mikhaillazarev5378
@mikhaillazarev5378 8 ай бұрын
Про mediatorLiveData как-то с примером не дошло, правильно ли я понял, что по сути эти две LiveData можно спокойно было сделать и без этого mediatora. Лично я не понял его смысл.. Поправить если я не прав.. А так спасибо за видео 😊
@mr.developer
@mr.developer 8 ай бұрын
К сожалению уже не помню ), давно это было. Может поменялось апи
@trunker2010
@trunker2010 3 жыл бұрын
Не очень понял как работает observer, на 24:30 устанавливается observer после изменения, в моем представлении он должен реагировать на изменения только после того, как был установлен
@sanek_180st
@sanek_180st 3 жыл бұрын
Спасибо, объясняете доступно. LiveData всё понятно. но зачем нужен медиатор (MediatorLiveData) ? мы можем и лайвдате прописать observer ... что без медиатора два раза обсервер, что с медиатором два раза ... суть только в том что появится еще один общий обьединяющий observer ?
@mlazebny
@mlazebny 3 жыл бұрын
Более структуризированно и понятно.В программировании ценится код который структуризирован, понятен, сжат.
@sanek_180st
@sanek_180st 3 жыл бұрын
@@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, в этом суть ? или я чтото упустил еще ?
@mlazebny
@mlazebny 3 жыл бұрын
@@sanek_180st когда испоользуется 2 разных источника данных лучше использовать mediator, легче взаимодействоваьть с элементами
@sanek_180st
@sanek_180st 3 жыл бұрын
@@mlazebny ну вот я в примере привел две лайв даты в чем разница, мы что так что так задаём два обсерва ... Единственное что в медиаторе можно сделать общий обсервер, вы это имеете ввиду ?
@mlazebny
@mlazebny 3 жыл бұрын
@@sanek_180st да
@adventuretrip1440
@adventuretrip1440 Жыл бұрын
На 7:25 минуте не отображается "Hello live data" там "Hello World"
@mr.developer
@mr.developer 10 ай бұрын
👍
@tilt8215
@tilt8215 5 ай бұрын
Как ты регистрируешь свой макет в мейн Активити ? Через что ? Нет бандинга и регистрации вьюшек, как ты это делаешь ?
@abuiman5251
@abuiman5251 3 жыл бұрын
👍🏻👍🏻👍🏻
@kovanodevelop
@kovanodevelop 3 жыл бұрын
Доброго дня! Весьма интересное видео. А как "провалиться"?
@user-pl1zw7cg8y
@user-pl1zw7cg8y 2 жыл бұрын
Ctrl + ЛКМ
@mr.developer
@mr.developer 10 ай бұрын
Благодарю за отзыв, очень приятно ☺️🤝
@iqmaxima
@iqmaxima 2 жыл бұрын
Каким образом без findById находить id test_text1 ?
@mr.developer
@mr.developer 2 жыл бұрын
Kotlin extension, но сейчас устарели. Используйте VBinding
@user-xq5jk9dq6g
@user-xq5jk9dq6g 2 жыл бұрын
Немного не понял, а почему мы не можем создавать для каждой LiveData свой observe. Он же также отработает. В чем преимущество и тем более использование медиатора если у нас несколько LiveDat??
@mr.developer
@mr.developer 10 ай бұрын
Да наверно можно
@Valerii07
@Valerii07 3 жыл бұрын
Вопрос: правильно понимаю, что Лайвдата всегда автоматом срабатывает и выдает список в вью, если в Комнату вставить или обновить, удалить? А как быть если надо в фоновом режиме подкачивать пополнять те вставлять еще данные из Сервера например из Файербейс, то список в вью будет обновляться что не нужно, или вообще какие то фоновые работы выполняются?
@Valerii07
@Valerii07 3 жыл бұрын
Не пользоваться Лайвдата, а сделать мьютоблЛист + обсервер с очисткой его в онДестройВьюМодел и в онСтарт проверять пуст не пуст, если пуст запрос в Комнату далее срабатывает обсервер и список в Вью обновляется. Может так сделать, А ЛайвДате по идее должен быть выкл автооновлений?
@cinderellarouge
@cinderellarouge 2 жыл бұрын
Здравствуйте, на минуте 32:58, когда вы поменяли значение postavalue " "hello world " вышло , но должно было "hello there world".
@mr.developer
@mr.developer 2 жыл бұрын
🤷‍♂️ я уж не помню)
@user-be2cy2fb9u
@user-be2cy2fb9u 3 жыл бұрын
18:40 не понял в чем прикол, весь каеф подписки лайф даты в том, что ну нежно задумываться о жизненном цикле, все это под капотом делается...
@KekLolChill
@KekLolChill 4 жыл бұрын
При каждом клике на кнопку вешать обсервер так себе идея)
@mr.developer
@mr.developer 4 жыл бұрын
Вы правы, но это лишь демонстрация возможностей а не руководство к действию.
@user-hc8wi1vd1b
@user-hc8wi1vd1b 3 жыл бұрын
Самые годные уроки в русскоязычном сегменте. Хотя, когда автор пишет большие программы, то на мой взгляд, слишком много функционально стиля, и если посмотреть на диаграмму классов, то встречаются ошибки при построении архитектуры
@qonahx9743
@qonahx9743 4 жыл бұрын
Зачем в onStart() и onStop() подписываться и отписываться от данных, если класс в принципе был создан для того что бы делать это самостоятельно?
@mr.developer
@mr.developer 4 жыл бұрын
Здравствуйте, это не отписка а удаление наблюдателя. И это я просто показал, что бы явно было видно , что с объектом можно делать.
@sergeykrivenkov6436
@sergeykrivenkov6436 3 жыл бұрын
Автор просто не разобрался в теме которой пытается учить других. Это не может быть "бест практишь", потому что противоречит принципу LiveData - а именно автоматизация. Как раз для того что бы не заниматься подпиской/отпиской на каждый start/stop, в LiveData реализован механизм active/inactive. Тем самым вы не создаете лишних обьектов (observer, observer wrapper), не нагружаете GC, не делаете лишних вычислений. И удалится observer тоже автоматически при переходе Lifecycle в состояние DESTROYED.
@GriNAME
@GriNAME 3 жыл бұрын
Получается медиатор лайвдаты делает так, чтобы обзёрвер был один на все лайвдаты? Если простым языком
@mr.developer
@mr.developer 3 жыл бұрын
Да
@serioussem-l2
@serioussem-l2 2 жыл бұрын
А какие плагины вы используете в студии? нравиться подсветка кода
@mr.developer
@mr.developer 2 жыл бұрын
Это своя тема
@fiodar_vasilets
@fiodar_vasilets 2 жыл бұрын
так зачем нам медиатор не опнятно ведь и так можно observe подписать на сами LiveData, сделали пустой observe у медиатара, и оставить его пустым ? для чего?
@mr.developer
@mr.developer 10 ай бұрын
👍
@fiodar_vasilets
@fiodar_vasilets 10 ай бұрын
@@mr.developer И что это значит?)
@mr.developer
@mr.developer 10 ай бұрын
Можно по разному)
@fiodar_vasilets
@fiodar_vasilets 10 ай бұрын
Да это понятно) что может быть несколько решений у задачи, но они как бы должны предоставлять свою логику с + и - от других вариантов, а тут я просто хотел бы узнать для чего нам это тут вообще и не лишнее ли это)@@mr.developer
@mr.developer
@mr.developer 10 ай бұрын
@fiodar_vasilets ох, я к сожелению сейчас не вспомню нюансов. Давно это было 🤷‍♂️
@user-vr5qt8ys2y
@user-vr5qt8ys2y 3 жыл бұрын
Не понятно, зачем нужен Transformations.map. Можно ведь сделать просто: ldStrind.value = ldInt.value.toString().
@mr.developer
@mr.developer 2 жыл бұрын
Конечно можно, можно вообще ничего не использовать, а писать функциональный код)
@asp424
@asp424 3 жыл бұрын
А если какие-то переменные не изменяются, например, состояние авторизации, то лучше использовать константы или LiveData?
@mr.developer
@mr.developer 3 жыл бұрын
Здравствуйте, переменные не бывают неизменяемые, на то они и переменные. Если есть свойства класса которые не изменяется то это константы.
@asp424
@asp424 3 жыл бұрын
@@mr.developer понятно, спасибо. Туплю ещё. Всё же, когда лучше константы, а когда LiveData?
@user-zo7mz4lp9r
@user-zo7mz4lp9r 2 жыл бұрын
А что нормально то с корутинами, там же не тот текст был. Там был просто Hello Word пересмотри сам видео
@mr.developer
@mr.developer 10 ай бұрын
👍
@Nidvoraich
@Nidvoraich 3 жыл бұрын
Да
@AlekseyKleon
@AlekseyKleon 4 жыл бұрын
Сорян за ламерский вопрос: пытаюсь сделать то же самое в джаве, там нету корутин((( Через Thread не получается - при операции postValue исключения не возникает, но и визуальных изменений нет. Пожалуйста, не советуйте юзать котлин, мне нужно сделать на джаве.
@aiwarkzn6728
@aiwarkzn6728 3 жыл бұрын
Здравствуйте, а как сделать так чтобы к view можно было обращаться без ссылки через R.id. как это сделано у вас? Это расширение какое то?
@mr.developer
@mr.developer 3 жыл бұрын
Да это котлин-расширения. Но сейчас они устарели, используйте ViewBindind
@aiwarkzn6728
@aiwarkzn6728 3 жыл бұрын
@@mr.developer Понял, спасибо за ответ 🤝
@user-oi2hk9yt1o
@user-oi2hk9yt1o 3 жыл бұрын
А что это за прикол в 19 строке на 5:13 , когда обращение из кода к текст вью идет просто по айди, без findViewById, без viewBinding?
@mr.developer
@mr.developer 3 жыл бұрын
Kotlin extension
@user-ru2qq3de4x
@user-ru2qq3de4x 3 жыл бұрын
@@mr.developer А как подключить это?
@user-ru2qq3de4x
@user-ru2qq3de4x 3 жыл бұрын
@@mr.developer Сорян за беспокойство. Нашёл выше.
@mr.developer
@mr.developer 3 жыл бұрын
👍
@shantarampampam
@shantarampampam 3 жыл бұрын
18:30
@user-jr8sz8cf3q
@user-jr8sz8cf3q 3 жыл бұрын
Добрый день! Я б купил курс по MVVM, но не через вк,есть варианты?
@mr.developer
@mr.developer 3 жыл бұрын
Здравствуйте, в Телеграм t.me/mobile_developing/71
@andrewdobosh2153
@andrewdobosh2153 3 жыл бұрын
А как вы в котлин коде обращаетесь к элементу UI без его инициализации методом findViewById? 14:50 здесь например вы ставите клик листенер на кнопку используя ее id? Для этого плагин какой-то нужен?
@mr.developer
@mr.developer 3 жыл бұрын
Это extension Kotlin. Но сейчас он deprecated. Используйте binding
@user-pq1ku2ut1m
@user-pq1ku2ut1m 7 ай бұрын
@@mr.developer А как в этом случае избежать огромного количества слова "binging" в коде?)
@Nidvoraich
@Nidvoraich 3 жыл бұрын
Если кому станет намного скучно слушать - просто отвечайте "да" каждый раз, как автор спрашивает это ;)
@agp1444
@agp1444 3 жыл бұрын
помоему это не лайвдата подписывается на активити, а активити - на лайвдату
@mr.developer
@mr.developer 10 ай бұрын
👍
@spornov91
@spornov91 Жыл бұрын
можно утонуть от такого колличества лишних слов.
@mr.developer
@mr.developer 10 ай бұрын
🙈
@cubuanic
@cubuanic 4 жыл бұрын
В описании линк на Котлин обрезан. Вот нормальный линк: kzbin.info/aero/PLY8G5DMG6TiNVIy6sZ0RHb14nKDFG7uQc
@mr.developer
@mr.developer 4 жыл бұрын
Спаисибо
@azimjon0910
@azimjon0910 Жыл бұрын
А в чем разница между подходами liveData.observe(this, Observer) и mediatorLD.addSource(liveData, Observer)?
@mr.developer
@mr.developer 10 ай бұрын
🤷‍♂️
@elpirato5428
@elpirato5428 4 жыл бұрын
спасибо
Шаблон MVVM по-простому. ViewModel. AndroidViewModel. AndroidViewModelFactory
14:37
Мобильный разработчик | Юрий Петров
Рет қаралды 24 М.
Шаблон MVVM по-простому. Navigation.
19:53
Мобильный разработчик | Юрий Петров
Рет қаралды 10 М.
Чёрная ДЫРА 🕳️ | WICSUR #shorts
00:49
Бискас
Рет қаралды 7 МЛН
Bend The Impossible Bar Win $1,000
00:57
Stokes Twins
Рет қаралды 39 МЛН
SPONGEBOB POWER-UPS IN BRAWL STARS!!!
08:35
Brawl Stars
Рет қаралды 24 МЛН
Миграция с LiveData на Coroutines Flow
25:02
Android Broadcast. Все об Андроид разработке
Рет қаралды 29 М.
MVVM в Android на практике
41:32
Тимофей Коваленко
Рет қаралды 48 М.
Кто и почему убивает Фронтенд?
20:40
Миша Ларченко
Рет қаралды 22 М.
Уроки по Android Clean Architecture, слой DATA на практике
36:26
Тимофей Коваленко
Рет қаралды 28 М.
Шаблон MVVM по-простому + Android Architecture Components.
12:58
Мобильный разработчик | Юрий Петров
Рет қаралды 37 М.
Чёрная ДЫРА 🕳️ | WICSUR #shorts
00:49
Бискас
Рет қаралды 7 МЛН