Android studio обработка свайпа вниз

SwipeRefreshLayout

В марте 2014 года был представлен новый компонент android.support.v4.widget.SwipeRefreshLayout, который входил в состав библиотеки Support Library v4. Сейчас это отдельная библиотека в составе AndroidX.

Компонент позволяет отказаться от сторонних библиотек и собственных велосипедов для реализации шаблона «Pull to Refresh», когда пользователь сдвигает экран, чтобы обновить данные. Подобное поведение можно увидеть в клиентах для Твиттера, чтобы получить новую порцию твитов, не дожидаясь, когда список сообщений обновится самостоятельно.

Пример на Kotlin

В марте 2020 года обзавелась стабильной версией.

В методах setColorSchemeColors() или setColorSchemeResources() следует указать используемые цвета.

Компонент достаточно интересный с занимательной анимацией. Вначале анимация представляла собой цветные полоски под заголовком программы. Позже анимацию заменили в стиле Material Design, теперь это маленький кружочек, внутри которого крутятся цветные линии (или чёрная линия, если не использовать метод setColorSchemeResources() со цветами).

Запустите пример и потяните экран сверх вниз, чтобы увидеть эффект обновления данных.

Устаревший пример для Java

Обернём компоненты родительским элементом SwipeRefreshLayout. На панели инструментов данного компонента нет, поэтому придётся писать код вручную.

В примере реализуется интерфейс OnRefreshListener с методом onRefresh(), в котором следует обновить поступающие данные. В нашем случае просто генерируются случайные числа.

При первом появлении библиотеки использовался метод setColorScheme(), который объявлен устаревшим. Вместо него появились два новых метода setColorSchemeColors() и setColorSchemeResources(). Принцип остался тот же, вам нужно указать четыре цвета по константам Color.XXX или из ресурсов. Вы можете не использовать вызов метода с цветными линиями, тогда будет выводиться только чёрная линия по умолчанию.

Компонент достаточно интересный с занимательной анимацией. Вначале анимация представляла собой цветные полоски под заголовком программы, как представлено на видео.

Позже анимацию заменили в стиле Material Design, теперь это маленький кружочек, внутри которого крутятся цветные линии (или чёрная линия, если не использовать метод setColorSchemeResources() со цветами).

Обновляем список

По такому же принципу обновляем данные в списке.

При каждой попытке обновить список будет добавляться текущая дата и время.

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

Источник

Drag и Swipe в RecyclerView. Часть 1: ItemTouchHelper

Существует множество обучающих материалов, библиотек и примеров реализации drag & drop и swipe-to-dismiss в Android c использованием RecyclerView. В большинстве из них по-прежнему используются устаревший View.OnDragListener и подход SwipeToDismiss, разработанный Романом Нуриком. Хотя уже доступны новые и более эффективные методы. Совсем немногие используют новейшие API, зачастую полагаясь на GestureDetectors и onInterceptTouchEvent или же на другие более сложные имплементации. На самом деле существует очень простой способ добавить эти функции в RecyclerView . Для этого требуется всего лишь один класс, который к тому же является частью Android Support Library.

ItemTouchHelper

ItemTouchHelper — это мощная утилита, которая позаботится обо всём, что необходимо сделать, чтобы добавить функции drag & drop и swipe-to-dismiss в RecyclerView . Эта утилита является подклассом RecyclerView.ItemDecoration, благодаря чему её легко добавить практически к любому существующему LayoutManager и адаптеру. Она также работает с анимацией элементов и предоставляет возможность перетаскивать элементы одного типа на другое место в списке и многое другое. В этой статье я продемонстрирую простую реализацию ItemTouchHelper . Позже, в рамках этой серии статей, мы расширим рамки и рассмотрим остальные возможности.

Примечание. Хотите сразу увидеть результат? Загляните на Github: Android-ItemTouchHelper-Demo. Первый коммит относится к этой статье. Демо .apk -файл можно скачать здесь.

Настройка

Сперва нам нужно настроить RecyclerView . Если вы ещё этого не сделали, добавьте зависимость RecyclerView в свой файл build.gradle .

Читайте также:  Что делать если инстаграм не открывается андроид

ItemTouchHelper будет работать практически с любыми RecyclerView.Adapter и LayoutManager , но эта статья базируется на примерах, использующих эти файлы.

Использование ItemTouchHelper и ItemTouchHelper.Callback

Чтобы использовать ItemTouchHelper , вам необходимо создать ItemTouchHelper.Callback. Это интерфейс, который позволяет отслеживать действия перемещения (англ. move) и смахивания (англ. swipe). Кроме того, здесь вы можете контролировать состояние выделенного view -компонента и переопределять анимацию по умолчанию. Существует вспомогательный класс, который вы можете использовать, если хотите использовать базовую имплементацию, — SimpleCallback. Но для того, чтобы понять, как это работает на практике, сделаем всё самостоятельно.

Основные функции интерфейса, которые мы должны переопределить, чтобы включить базовый функционал drag & drop и swipe-to-dismiss:

Мы также будем использовать несколько вспомогательных методов:

Рассмотрим их поочередно.

ItemTouchHelper позволяет легко определить направление события. Вам нужно переопределить метод getMovementFlags() , чтобы указать, какие направления для перетаскивания будут поддерживаться. Для создания возвращаемых флагов используйте вспомогательный метод ItemTouchHelper.makeMovementFlags(int, int) . В этом примере мы разрешаем перетаскивание и смахивание в обоих направлениях.

ItemTouchHelper можно использовать только для перетаскивания без функционала смахивания (или наоборот), поэтому вы должны точно указать, какие функции должны поддерживаться. Метод isLongPressDragEnabled() должен возвращать значение true , чтобы поддерживалось перетаскивание после длительного нажатия на элемент RecyclerView . В качестве альтернативы можно вызвать метод ItemTouchHelper.startDrag(RecyclerView.ViewHolder) , чтобы начать перетаскивание вручную. Рассмотрим этот вариант позже.

Чтобы разрешить смахивание после касания где угодно в рамках view -компонента, просто верните значение true из метода isItemViewSwipeEnabled() . В качестве альтернативы можно вызвать метод ItemTouchHelper.startSwipe(RecyclerView.ViewHolder) , чтобы начать смахивание вручную.

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

Самый простой способ сделать это — сделать так, чтобы RecyclerListAdapter имплементировал слушателя.

Очень важно вызвать методы notifyItemRemoved() и notifyItemMoved() , чтобы адаптер увидел изменения. Также нужно отметить, что мы меняем позицию элемента каждый раз, когда view -компонент смещается на новый индекс, а не в самом конце перемещения (событие «drop»).

Теперь мы можем вернуться к созданию SimpleItemTouchHelperCallback , поскольку нам всё ещё необходимо переопределить методы onMove() и onSwiped() . Сначала добавьте конструктор и поле для адаптера:

Затем переопределите оставшиеся события и сообщите об этом адаптеру:

В результате класс Callback должен выглядеть примерно так:

Когда Callback готов, мы можем создать ItemTouchHelper и вызвать метод attachToRecyclerView(RecyclerView) (например, в MainFragment.java):

После запуска должно получиться приблизительно следующее:

Заключение

Это максимально упрощённая реализация ItemTouchHelper . Тем не менее, вы можете заметить, что вам не обязательно использовать стороннюю библиотеку для реализации стандартных действий drag & drop и swipe-to-dismiss в RecyclerView . В следующей части мы уделим больше внимания внешнему виду элементов в момент перетаскивания или смахивания.

Исходный код

Я создал проект на GitHub для демонстрации того, о чём рассказывается в этой серии статей: Android-ItemTouchHelper-Demo. Первый коммит в основном относится к этой части и немного ко второй.

Источник

Добавляем кнопки при свайпе в RecyclerView

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

Отличным инструментом для создания продуманного интерфейса в Android являются свайпы (Swipe). С их помощью всего лишь одним-двумя жестами можно выполнять самые разные действия с объектами: перемещать их по экрану, удалять, изменять и много другое. Например, можно с помощью свайпа выводить на экран приложения такие элементы интерфейса, как боковое меню.

В этой статье мы рассмотрим, как добавить свайп для виджета CardView, расположенного внутри RecyclerView, который будет выводить с правой стороны карточки кнопку. Для примера делать мы это будем в одном из наших приложений Менеджер паролей от Wi-Fi сетей.

Задачей здесь является сделать кнопку, которая будет перемещать сети из списка активных в Архив (или удалять, если сеть уже находится в Архиве).

Создание RecyclerView

Поскольку список сетей может быть довольно большим, в приложении используется виджет RecyclerView. Чтобы использовать его в своём проекте, нужно для начала добавить зависимость. Для этого в файле build.gradle модуля приложения в dependencies нужно добавить следующую строку:

Читайте также:  Как сделать работу андроида лучше

После этого нужно разместить виджет на разметке активности. Пример этого можно увидеть ниже:

Наше приложение отображает список сетей, сохранённых пользователем. Чтобы RecyclerView смог выводить этот список, для начала нужен класс, который будет хранить данные о сетях. Для этих целей используется класс WifiInfo, содержащий следующий код:

Следующим этапом является создание адаптера. Класс RecyclerView.Adapter крайне важен здесь, поскольку благодаря ему данные, хранящиеся в классе WifiInfo, будут выводиться в итоговый список. В классе нужно переопределить несколько методов, таких как:

  • getItemCount() — возвращает количество элементов, которое мы хотим отобразить;
  • onCreateViewHolder() — создает экземпляр класса RecyclerView.ViewHolder и создает разметку. Он вызывается только тогда, когда RecyclerView требуется добавить в список новый объект.
  • onBindViewHolder() — привязывает данные к разметке ViewHolder. Он вызывается тогда, когда RecyclerView заполняет объект данными.

Ниже вы можете увидеть код адаптера, реализующего заполнение списка данными по сетям.

Здесь же, как можно увидеть, создаётся класс ViewHolder, который описывает разметку элемента и метаданные о его месте в RecyclerView. Реализация адаптера должна использовать ViewHolder в качестве подкласса, поскольку в них кешируются затратные по ресурсам операции findViewById().

Теперь нужно создать разметку, которая будет подгружаться во ViewHolder. Она представляет собой два виджета FrameLayout, помещённых внутри кастомного SwipeRevealLayout, о котором будет сказано позднее. Код разметки вы можете увидеть ниже.

Наконец, нужно создать экземпляр класса RecyclerView в коде активности и инициализировать его. Для правильной работы нужно настроить две вещи: адаптер, который будет предоставлять данные, и менеджер разметки (LayoutManager), который говорит виджету, как нужно отобразить объекты в списке. В результате создание выглядит следующим образом:

Добавление класса для свайпа

Теперь можно приступить к реализации свайпа для элементов списка. Для этого мы использовали в приложении исходный код библиотеки SwipeRevealLayout, которую вы можете скачать на GitHub по следующей ссылке. Стоит заметить, что способ реализации подобных свайпов в сети достаточно много, этот способ был выбран как самый оптимальный для наших задач.

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

Библиотека поддерживает свайпы в любом направлении (слева, справа, сверху, снизу), а также имеет два режима:

  • normal — дополнительный элемент рисуется позади основного;
  • same level — дополнительный элемент рисуется на том же уровне, что и основной.

В библиотеке также используется дополнительный класс ViewBinderHolder, задачей которого является сохранения состояния свайпа и его восстановление. В нашем приложении в этом нет особой необходимости, поэтому этот класс был выкинут вместе с некоторыми методами основного класса. В результате код класса SwipeRevealLayout получился следующим:

В результате мы добавили в список кнопку, которая появляется при свайпе элемента и позволяет либо добавить сеть в архив, либо удалить её.

Источник

Отличный Android UX: Как сделать кнопку свайпа (swipe button)

Суть дизайна не в том, чтобы сделать что-то красивое, а в том, чтобы сделать что-то отличное. Вы можете делать хорошие приложения различными способами, но один из моих любимых — сделать его максимально простым и интуитивно понятным, но при этом оригинальным. Важно, чтобы ваш пользовательский интерфейс (UI) реагировал на пользователя в соответствии с важностью определённого действия. Иногда это действие слишком важно, чтобы запускать его простым кликом, например, разблокирование смартфона. Нажатие на кнопку и получение диалога для подтверждения это нормально. Это работает. Но все так делают! Почему бы не сделать иначе?

Что ж, сегодня мы это сделаем.

В этом уроке я покажу, как сделать кнопку свайпа. Она позволяет пользователю совершать важные действия, не обязательно подтверждая свои намерения, потому что трудно случайно нажать на кнопку (но, пожалуйста, помните: это не невозможно, так что будьте осторожны!). Таким образом, у вас есть гораздо более интуитивный. приятный и простой UX.

Круто? Итак, начнём!

Урок основан на этом репозитории. Если вы хотите использовать готовую кнопку, вы можете добавить его в свой проект через Gradle.

Читайте также:  Камера заднего вида планшет android

Часть 1 — Давайте создадим наш XML

Наша кнопка имеет круглую движущуюся часть и округлый фон. Итак, давайте сделаем эти части:

И фон: shape_rounded.xml:

Радиус может быть любым, поэтому границы полукруглые. Вы можете использовать другие цвета, если захотите.

Итак, теперь у нас есть xml. Давайте создадим нас пользовательский View.

Часть 2 — Делаем наш собственный View

Мы собираемся наследовать RelativeLayout, как показано ниже:

Вы, должно быть, думаете… «Это кнопка, почему мы наследуем RelativeLayout?»

Поскольку это составная кнопка, нам нужно добавить несколько представлений (views), чтобы иметь возможность сконструировать поведением, которое нам нужно, поэтому нам нужен ViewGroup. RelativeLayout — хороший вариант, потому что многие представления будут заходить один на другой в этом компоненте.

У нас есть много внутренних представлений. Итак, давайте разберём эту реализацию поэтапно.

Для вас также важно понятно переменные, объявленные в классе:

  • slidingButton — это движущаяся компонента. Она содержит иконку.
  • initialX — это позиция движущейся части, когда пользователь начнёт её перемещать.
  • active — это переменная, которая говорит, активна кнопка или нет.
  • initialButtonWidth — это начальная ширина движущейся части. Нам нужно сохранить её, чтобы мы могли вернуться в исходное положение.
  • centerText — это текст в центре кнопки.
  • disabledDrawable / enadledDrawable — иконки, которые движущаяся часть будет использовать, когда кнопка активна или неактивна. Используйте те иконки. которые нравятся вам.

Сначала добавим фон:

Этот View отвечает за округленный фон кнопки.

Текст

Теперь мы добавим в конец метода init() информативный текст для кнопки.

Это текст в центре компоненты. Я просто захардкодил текст для простоты, но вы можете использовать строковые ресурсы для интернационализации. Вы можете добавить отступы как вам нравится. Именно так вы контролируете размер фона вашего изображения.

Добавление движущейся иконки

Это движущаяся часть компоненты. Мы должны установить иконки для неактивного и активного состояний. Настройка отступов позволяет установить размер движущейся части.

Добавление слушателя касания

Добавьте эту строку в конец метода init(). Мы поговорим о ней в следующем разделе. В результате init() должен выглядеть следующим образом:

Уже сейчас вы можете добавить кнопку в своё приложение и увидеть результат. Например, кнопка со следующей разметкой:

Будет выглядеть так:

Пока всё выглядит хорошо. Но мы не реализовали поведение. В следующем разделе вы найдёте логику для своей кнопки!

Часть 3 — Реализация логики кнопки

Давайте реализуем метод getButtonTouchLisneter().

Теперь у нас есть слушатель. Давайте добавим логику в ACTION_MOVE.

Логика перемещения

Давайте разберём условия.

Первое заключается в том. чтобы убедиться, что мы знаем начальную позицию кнопки, если она не равна нулю.

Второе условие отвечает за касание кнопки пальцем. event.getX() возвращает позицию текущего касания. В этой части кода мы устанавливаем центр кнопки в положение касания и уменьшаем альфа-канала текста по мере свайпа.

Третье и четвёртое условия несут ответственность за то, чтобы установить положение подвижной части на границы компонента, когда пользователь переместится за пределы.

Логика раскрытия

В раскрытии нам нужны три метода:

Если кнопка отпущена и она активна, нам нужно её свернуть. Если кнопка сдвинута очень близко к границе компонента, тогда нужно её развернуть. Если кнопка отпускается далеко от правого края, она должна проделать путь обратно.

Примечание: Если вы хотите подробнее узнать, как создавать анимацию, то вы можете пройти по ссылке.

Вот эти анимации:

Анимация расширения

Анимация кажется сложной, правда? Не волнуйся, у тебя всё получится! Позволь мне объяснить:

Во-первых, slidingButton будет анимировать левый край вашего компонента. Это positionAnimator.

Во-вторых, кнопка должна расширяться и занимать всё пространство компонента. Это widthAnimator.

В-третьих, мы создаём AnimatorSet, чтобы можно было вместе воспроизводить анимацию. В конце анимации мы устанавливаем состояние кнопки как активное и меняем изображение.

Анимация сворачивания

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

Возвращение кнопки назад

Эта анимация перемещает кнопку назад к левому краю и восстанавливает альфа-канал текста.

Часть 4 — Результат

Если вы всё сделали правильно, то получите следующий результат (используйте тёмный фон на вашей активности):

Источник

Оцените статью