Анимация перетаскивания (Drag & Reorder) в мобильных приложениях

Реализация анимации перетаскивания (Drag & Reorder) в мобильных приложениях Пользователь долго удерживает элемент списка — тот поднимается, масштабируется, а соседние элементы плавно расступаются, показывая место для вставки. Это анимация **Drag & Reorder**. Без неё не обходится ни одно приложени

Разработка и поддержка любых видов мобильных приложений:

Информационные и развлекательные мобильные приложения
Новостные приложения, игры, справочники, онлайн-каталоги, погодные, фитнес и здоровье, туристические, образовательные, социальные сети и мессенджеры, квиз, блоги и подкасты, форумы, агрегаторы
Мобильные приложения электронной коммерции
Интернет-магазины, B2B-приложения, маркетплейсы, онлайн-обменники, кэшбэк-сервисы, биржи, дропшиппинг-платформы, программы лояльности, доставка еды и товаров, платежные системы
Мобильные приложения для управления бизнес-процессами
CRM-системы, ERP-системы, управление проектами, инструменты для команды продаж, учет финансов, управление производством, логистика и доставка, управление персоналом, системы мониторинга данных
Мобильные приложения электронных услуг
Доски объявлений, онлайн-школы, онлайн-кинотеатры, платформы предоставления электронных услуг, платформы кешбека, видеохостинги, тематические порталы, платформы онлайн-бронирования и записи, платформы онлайн-торговли

Это лишь некоторые из типы мобильных приложений, с которыми мы работаем, и каждый из них может иметь свои специфические особенности и функциональность, а также быть адаптированным под конкретные потребности и цели клиента.

Услуги, которые мы предлагаем
Показано 1 из 1Все 1734 услуг
Анимация перетаскивания (Drag & Reorder) в мобильных приложениях
Средний
от 1 дня до 3 дней

Наши компетенции:

Часто задаваемые вопросы

Последние работы

  • image_mobile-applications_feedme_467_0.webp
    Разработка мобильного приложения для компании FEEDME
    895
  • image_mobile-applications_xoomer_471_0.webp
    Разработка мобильного приложения для компании XOOMER
    782
  • image_mobile-applications_rhl_428_0.webp
    Разработка мобильного приложения для компании RHL
    1216
  • image_mobile-applications_zippy_411_0.webp
    Разработка мобильного приложения для компании ZIPPY
    1079
  • image_mobile-applications_affhome_429_0.webp
    Разработка мобильного приложения для компании Affhome
    1002
  • image_mobile-applications_flavors_409_0.webp
    Разработка мобильного приложения для компании FLAVORS
    597

Реализация анимации перетаскивания (Drag & Reorder) в мобильных приложениях

Пользователь долго удерживает элемент списка — тот поднимается, масштабируется, а соседние элементы плавно расступаются, показывая место для вставки. Это анимация Drag & Reorder. Без неё не обходится ни одно приложение с сортируемыми списками: от задачников до интернет-магазинов. Но реализация на разных платформах имеет особенности, которые могут сломать UX. Особенно часты проблемы на проектах с высокой нагрузкой: перетаскивание 1000+ элементов требует троттлинга анимаций. Наши решения проверены в production.

Мы внедрили Drag & Reorder в 15+ проектах за 5 лет опыта. Вот ключевые проблемы: отсутствие стабильных ключей приводит к «прыжкам» при реордеринге; мутация списка без уведомления фреймворка вызывает задержки обновления; игнорирование оптимистичного обновления грозит потерей нового порядка при сбое сети. Это позволяет сэкономить до 30% времени разработки по сравнению с кастомной реализацией. Снижение затрат на поддержку на 20% при использовании готовых API. Разберём, как избежать этих ошибок.

Почему стабильные ключи критичны для анимации?

Каждый элемент списка должен иметь уникальный и стабильный идентификатор. Без этого фреймворк не может корректно отслеживать перемещение и анимировать расступание. Например, в SwiftUI используйте протокол Identifiable, в Compose — key параметр в .items(), во Flutter — ValueKey при построении элементов. Если ключ меняется при реордеринге (например, на основе позиции), анимация ломается.

Как выбрать между встроенными API и кастомной реализацией?

Встроенные API (iOS UIKit, SwiftUI .onMove, Flutter ReorderableListView) покрывают 80% сценариев. Кастомная реализация нужна, если:

  • требуется нестандартная анимация поднятого элемента (например, подъём с тенью, изменение цвета);
  • список содержит сложные ячейки с вложенными жестами;
  • необходима интеграция с drag-and-drop между разными списками или вкладками.

Мы рекомендуем начинать со встроенных API и добавлять кастомизацию только при необходимости. Это ускоряет разработку и упрощает тестирование.

Как внедрить Drag & Reorder за 4 шага?

  1. Выбор API. iOS (UIKit) — встроенные UICollectionViewDragDelegate/UICollectionViewDropDelegate. Android Compose — библиотека reorderable. Flutter — ReorderableListView.
  2. Настройка анимации. Поднятый элемент масштабируем и приподнимаем с помощью shadow. На iOS это происходит автоматически; на Android используем animateFloatAsState, на Flutter — proxyDecorator.
  3. Сохранение порядка. После завершения перетаскивания отправляем новый массив на backend. Применяем оптимистичное обновление: UI меняется сразу, при ошибке сети — откат.
  4. Тестирование. Проверяем на устройствах с разными версиями ОС, особенно на старых iOS (12 и выше) и Android (API 26+).

Как реализовать Drag & Reorder на iOS (UIKit)?

Согласно Apple Human Interface Guidelines, анимация перетаскивания должна быть плавной и предсказуемой. Используем UICollectionView с делегатами:

collectionView.dragDelegate = self collectionView.dropDelegate = self collectionView.dragInteractionEnabled = true // UICollectionViewDragDelegate func collectionView(_ collectionView: UICollectionView, itemsForBeginning session: UIDragSession, at indexPath: IndexPath) -> [UIDragItem] { let item = items[indexPath.item] let itemProvider = NSItemProvider(object: item.id as NSString) let dragItem = UIDragItem(itemProvider: itemProvider) dragItem.localObject = item return [dragItem] } // UICollectionViewDropDelegate func collectionView(_ collectionView: UICollectionView, performDropWith coordinator: UICollectionViewDropCoordinator) { guard let destinationIndexPath = coordinator.destinationIndexPath, let item = coordinator.items.first, let sourceIndexPath = item.sourceIndexPath else { return } collectionView.performBatchUpdates { items.move(fromOffsets: IndexSet(integer: sourceIndexPath.item), toOffset: destinationIndexPath.item) collectionView.moveItem(at: sourceIndexPath, to: destinationIndexPath) } coordinator.drop(item.dragItem, toItemAt: destinationIndexPath) } 

UICollectionView автоматически анимирует перемещение ячеек. Для UITableView подход аналогичен с UITableViewDragDelegate/UITableViewDropDelegate. В SwiftUI используйте .onMove — он добавляет drag handles, но без кастомизации внешнего вида.

Как анимировать перетаскивание в Android Compose?

В Compose встроенного reorder нет, используем библиотеку sh.calvin.reorderable:reorderable:2.4.0:

val listState = rememberLazyListState() var list by remember { mutableStateOf(items) } val reorderState = rememberReorderableLazyListState(listState) { from, to -> list = list.toMutableList().apply { add(to.index, removeAt(from.index)) } } LazyColumn( state = listState, modifier = Modifier.reorderable(reorderState) ) { items(list, key = { it.id }) { item -> ReorderableItem(reorderState, key = item.id) { isDragging -> val elevation by animateDpAsState(if (isDragging) 8.dp else 0.dp) val scale by animateFloatAsState(if (isDragging) 1.05f else 1f) Card( modifier = Modifier .fillMaxWidth() .scale(scale) .shadow(elevation) ) { Row { Text(item.title, modifier = Modifier.weight(1f).padding(16.dp)) Icon( Icons.Default.DragHandle, contentDescription = null, modifier = Modifier .detectReorderAfterLongPress(reorderState) .padding(16.dp) ) } } } } } 

isDragging управляет анимацией поднятого элемента. Для кастомной анимации расступания соседних элементов на Compose 1.7+ используйте Modifier.animateItem().

Flutter: ReorderableListView с proxyDecorator

ReorderableListView.builder( itemCount: items.length, itemBuilder: (context, index) { return ListTile( key: ValueKey(items[index].id), title: Text(items[index].title), trailing: ReorderableDragStartListener( index: index, child: const Icon(Icons.drag_handle), ), ); }, onReorder: (oldIndex, newIndex) { setState(() { if (newIndex > oldIndex) newIndex--; final item = items.removeAt(oldIndex); items.insert(newIndex, item); }); }, proxyDecorator: (child, index, animation) { return AnimatedBuilder( animation: animation, builder: (context, child) { final scale = Tween<double>(begin: 1.0, end: 1.05) .evaluate(CurvedAnimation(parent: animation, curve: Curves.easeOut)); return Transform.scale(scale: scale, child: child); }, child: child, ); }, ) 

proxyDecorator позволяет поднять перетаскиваемый элемент без изменения оригинального виджета.

Сравнение платформ: что выбрать?

Платформа Встроенная поддержка Время реализации (простой) Время реализации (кастомный)
iOS (UIKit) Да (с iOS 11) 2-3 часа 1 день
SwiftUI Да (.onMove) 1 час 0,5 дня
Android Compose Нет (нужна библиотека) 3-4 часа 1 день
Flutter Да (ReorderableListView) 2 часа 0,5 дня

iOS решается в два раза быстрее Android Compose, если использовать встроенные API. Flutter — золотая середина по скорости и гибкости.

Сравнение анимационных возможностей

Платформа Поднятие элемента Расступание соседей Кастомизация
iOS UIKit Автоматически (scale + shadow) Автоматически Ограниченная
SwiftUI Через .onMove с dragPreview Через withAnimation Средняя
Android Compose Ручная (animateFloatAsState) Через animateItem() Высокая
Flutter Через proxyDecorator Автоматически Высокая

Что входит в работу

При заказе реализации Drag & Reorder под ключ мы предоставляем:

  • Анализ текущего списка и выбор оптимального API для вашей платформы
  • Реализацию анимации поднятия и расступания элементов
  • Интеграцию с backend для сохранения нового порядка (включая оптимистичное обновление)
  • Тестирование на реальных устройствах с разными версиями ОС
  • Документацию по внедрению и поддержке

Наши инженеры с 5-летним опытом гарантируют качественную реализацию. Закажите внедрение анимации перетаскивания и получите консультацию по вашему проекту.

Типичные ошибки

  • Отсутствие стабильных ключей — элементы без key приводят к тому, что фреймворк не может корректно анимировать перемещение. Всегда используйте key: ValueKey(item.id) (Flutter), id в .items(key=...) (Compose) или реализуйте Hashable (SwiftUI).
  • Мутация списка без уведомления — в Compose обязательно используйте mutableStateOf и создавайте новый список при мутации. Во Flutter — setState. В iOS — performBatchUpdates с move.
  • Игнорирование сохранения порядка — после onReorder сразу отправляйте новый порядок на backend. Используйте оптимистичное обновление: UI обновляется мгновенно, при ошибке сети — откат.

Подробнее о драг-энд-дроп на iOS читайте в официальной документации Apple. Для Android Compose — Android Developers.

Сроки и стоимость

Drag & Reorder для простого списка (используем встроенные API) — полдня. Кастомный drag с анимированным проксивидом, расступанием соседних элементов и интеграцией с хранилищем — 1-2 дня. Стоимость рассчитывается индивидуально. Наши сертифицированные инженеры гарантируют качество — более 5 лет опыта. Получите консультацию или закажите реализацию уже сегодня.