Если внимательно посмотреть на поведение людей в поисковых полях, становится понятно:
пальцы работают быстрее, чем приложение успевает реагировать.
Пользователь печатает «a», тут же «an», следом «and» — а приложение в панике пытается перестроить результаты после каждого шага. Поток начинает «стрелять» событиями, система перегружается, а интерфейс выглядит так, будто его кто-то перематывает на ускоренной перемотке.
Главная проблема здесь не скорость человека — а то, что приложение воспринимает каждую мелочь как повод что-то пересчитать.
Чтобы интерфейс работал предсказуемо, нужно научить поток реагировать не на каждое изменение, а на осмысленное завершение ввода.
⏳ Зачем нужен debounce()
Оператор debounce() работает как фильтр слишком быстрых изменений:
- быстрые изменения подряд — игнорируются
- устойчивое значение после паузы — двигаются по потоку дальше
Поток перестаёт реагировать на каждую букву и начинает слушать устойчивые состояния строки.
val results = queryFlow
.debounce(300) // значение задержки можно менять
.distinctUntilChanged()
.map { term -> searchData(term) }
.stateIn(viewModelScope, SharingStarted.WhileSubscribed(5000), emptyList())
------------
Помимо полезных символов, пользователь может случайно добавить пробел в конце или другой невидный символ. Фактически это тот же запрос — но без обработки поиск запустится повторно.
В таких случаях можно определиться как оператор distinctUntilChanged() будет сранивать значения:
queryFlow
.debounce(300)
.distinctUntilChanged { old, new ->
old.trim() == new.trim()
}
Теперь оба состояния считаются одинаковыми, и поиск не перезапускается зря.
#kotlin #coroutines #flow #android
Please open Telegram to view this post
VIEW IN TELEGRAM
8❤80👍54🤔3
Скачать сборку можно тут
#android #opensource #пример
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
2❤24👍14🔥9🤔3
С релизом Compose Material 3 — версии 1.4.0 Google сделала радикальный шаг: библиотека androidx.compose.material.icons исключена из Material3 и больше не рекомендуется к использованию.
Что произошло
👉 Material Icons удалены из актуального релиза Material3 1.4.0
👉 Поддержка библиотеки прекращена
👉 Можно подключить вручную, но это временная мера для тех, кто не успел мигрировать
Google предлагает переходить на Vector Drawable XML в Android или Compose Multiplatform ресурсах. Скачивайте иконки с вкладки Android на странице Material Symbols и храните в ресурсах проекта
Преимущества использования Material Symbole:
Источник - официальная документация Android Jepack
Благодарю подписчика Evgeny F. за то, что обратил внимание на изменение.
#Android #AndroidJetpack #Material3 #Compose #CMP
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥81🤯40👍23🙏4🤝2❤1
Google выпустил Android 16 QPR2 — первое минорное обновление платформы, которое приносит новые функции без ломающих изменений.
🔧 Новый подход к версиям SDK
Теперь можно проверять минорные обновления через новые поля в Build:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.BAKLAVA &&
Build.VERSION.SDK_INT_FULL >= Build.VERSION_CODES_FULL.BAKLAVA_1) {
// API из QPR2
}
Ключевые изменения:
👉 Расширенная темная тема — система автоматически инвертирует интерфейс для доступности
👉 Пользовательские формы иконок — пользователи могут менять форму всех иконок
👉 Интерактивный шеринг — обновление контента в реальном времени в превью шаринга
👉 Новый сборщик мусора — снижает нагрузку на CPU
Каждую фичу разберем подробнее в следующих постах! Подписывайте на @android_broadcast, чтобы не пропустить
#Android16 #AndroidDev #Android
Please open Telegram to view this post
VIEW IN TELEGRAM
❤22👍17🔥1
Приложение включает примеры:
👉 Генерацию картинок в чате
👉 Генерации ответов или изменения текста в чате
👉 Мультимодальные возможности
👉 Суммаризация
👉 Генерация описания картинок
👉 и много всего еще
Что-то делается из этого на устройстве, а что-то через облако
#Android #AI #Gemini
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥21👍6❤1
Media is too big
VIEW IN TELEGRAM
Гугл выпустил Navigation 3 — это новая глава в построении навигации для Android-приложений. Всё, что вы знали, теперь стало мощнее, гибче и композабльнее!
00:00 — Базовые принципы Navigation 3
02:09 — NavEntry и entryProvider
03:29 — Разбор API на практике
07:17 — Навигация в многомодульном приложении
11:27 — Модуляризация: пишем код
15:57 — Анимации экранов
16:15 — Погружаемся в анимации
19:44 — Адаптивные макеты (Scenes)
23:01 — Scenes в действии
24:39 — Краткий итог и выводы
🔗 Официальное руководство
🔗 Рецепты для работы с Nav3 (Code recipes)
Навигация больше не будет болью! Смотрите, внедряйте и делитесь впечатлениями в комментариях.
#Android #AndroidDev #Jetpack #Compose #KMP
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥31👍9🎉3
Forwarded from Compose Broadcast
👉 Стабильное API Shared Transition
👉 Оптимизированный скролл
👉 Новые подходы к сохранению данных при пересоздании Activity через ViewModel
🚀 Повышена производительность UI на Compose
🛠 Исправлено багов и шероховатостей
Изменений действительно много — в один пост всё не поместить.
Буду разбирать ключевые обновления по отдельности в следующих публикациях на @compose_broadcast ✨
#compose #android
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥27❤9👍3
WebGPU — это новый графический и вычислительный API, который приходит на смену устаревающему WebGL. Его цель — дать разработчикам современный доступ к GPU для тяжёлых визуальных и вычислительных задач как в вебе, так и теперь — в Android, благодаря androidx.webgpu. Если упрощённо — WebGPU открывает дверь к автоматически оптимизированной работе с видеокартой без необходимости использовать низкоуровневые графические движки.
Что даёт WebGPU разработчикам:
🧩 Современная графика уровня Vulkan/Metal/DX12
⚙️ Compute-шейдеры для вычислений прямо на GPU
🚀 Высокую производительность рендеринга и ML-вычислений
🔁 Кроссплатформенность: единый подход Web + Android (и не только)
📦 Потенциально меньше нативного кода на C++/NDK
🧪 Удобный доступ к GPU-фичам для прототипов и экспериментов
Версия для Android пока в alpha, API нестабилен, документации немного. Но это важный шаг: Google фактически легализует WebGPU как будущий GPU-базис на Android.
#AndroidDev #Android #Jetpack #AndroidJetpack #WEB #GPU
Please open Telegram to view this post
VIEW IN TELEGRAM
👍30🔥9❤1
В этой части Никита @Nek12 разбирает, как FlowMVI применяет архитектурные подходы, позволяющие поддерживать предсказуемое поведение приложения и исключать хаотичные ошибки. Покажет, как инструмент помогает выстраивать MVI архитектуру, ориентированную на устойчивую работу в условиях многопоточности и постоянных изменений данных.
#Android #KMP #MVI #Архитектура
Please open Telegram to view this post
VIEW IN TELEGRAM
🤔20👍8🔥3🆒1
Раньше системный шузер для шаринга был «односторонним»: вы собрали Intent, отдали его в
Intent.createChooser(...) — и дальше всё полностью контролирует система.После открытия sharesheet вы уже не можете:
👉 обновить текст или вложения;
👉 убрать/добавить таргеты;
👉 синхронизировать состояние с продолжающимся действием в приложении.
Если пользователь что-то поменял (например, отредактировал текст или выбор вложений), приходилось закрывать шузер и открывать его заново.
Не так давно была возможность изменить контент для шаринга из шузера (сделали похожим как в iOS), а также добавить действия.
В Android 16 QPR2 / API 36.1 появился новый механизм — Interactive Chooser Sessions. Теперь приложение может держать живую сессию шаринга, обновлять её и получать события, пока открыт системный sharesheet. Для этого используются
ChooserManager и ChooserSession. // Базовый пример: запуск интерактивной сессии (Kotlin)
val chooserManager: ChooserManager = context.getSystemService()
val shareIntent = Intent(Intent.ACTION_SEND).apply {
type = "text/plain"
putExtra(Intent.EXTRA_TEXT, "This is a message that will be shared.")
}
val chooserIntent = Intent.createChooser(shareIntent, null)
val session: ChooserSession = chooserManager.startSession(context, chooserIntent)
val token: ChooserSessionToken = session.token
token можно сохранить в ViewModel или savedStateHandle, чтобы потом восстановить сессию после поворота экрана или пересоздания Activity.
val existingToken: ChooserSessionToken = /* restore from state */
val existingSession: ChooserSession = chooserManager.getSession(existingToken) ?: return
Управление сессией через ChooserSession API
val executor: Executor = ContextCompat.getMainExecutor(context)
session.addStateListener(executor, object : ChooserSession.StateListener {
override fun onStateChanged(state: Int) { }
override fun onBoundsChanged(bounds: Rect) { }
})
Временное отключение таргетов на время долгой операции:
session.setTargetsEnabled(false)
val updatedShareIntent = Intent(Intent.ACTION_SEND).apply {
type = "text/plain"
putExtra(Intent.EXTRA_TEXT, "Updated message generated in runtime")
}
val updatedChooserIntent = Intent.createChooser(updatedShareIntent, null)
session.updateIntent(updatedChooserIntent)
session.setTargetsEnabled(true)
// Завершение сессии, когда шаринг больше не нужен:
session.endSession()
#Android #Android16
Please open Telegram to view this post
VIEW IN TELEGRAM
👍30❤6