Android studio меню свайпом

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) , чтобы начать перетаскивание вручную. Рассмотрим этот вариант позже.

Читайте также:  Usb шнур для android auto

Чтобы разрешить смахивание после касания где угодно в рамках 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. Первый коммит в основном относится к этой части и немного ко второй.

Источник

Попробуем, пользуясь официальным руководством и примерами кода, построить работающую систему навигации для будущего многоэкранного приложения в соответствии со стандартами Navigation Architecture Component. Статья включает следующие разделы:

Часть 1. Подготовительные работы
— 1.1. Создание проекта
— 1.2. Зависимости (Dependencies)
— 1.3. Страницы: создание фрагментов
— 1.4. Адреса: файл ресурсов типа «Navigation»
— 1.5. Фрейм: виджет NavHostFragment

Часть 2. Элементы навигации
— 2.1. Навигация с помощью кнопок
— 2.2. Боковое меню (Drawer)
— 2.3. Панель инструментов: Toolbar вместо ActionBar
— 2.4. Нижнее меню (Bottom Navigation)
— 2.5. Всплывающее меню (Overflow Menu)

Краткие выводы и ссылка на github

Часть 1. Подготовительные работы

1.1. Создание проекта

Нам понадобятся базовые знания Котлина, IDE Android Studio версии не ниже 3.3, смартфон или эмулятор с версией API 14 или выше.

Создадим в Android Studio новый проект под названием «Navigation2019».

IDE создаст файл главной активности «MainActivity.kt» и его макет (шаблон) «activity_main.xml».

1.2. Зависимости (Dependencies)

Откроем файл «build.gradle» модуля (не проекта, а именно модуля) и в блок «dependencies» добавим необходимые зависимости:

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

1.3. Страницы: создание фрагментов

Фрагменты — это «страницы» нашего будущего приложения. Кликнув правой кнопкой на каталоге с файлами классов, командой «New -> Fragment -> Fragment(Blank)» создадим «Fragment1».

Читайте также:  Nokia lumia 950 прошивка android

IDE создаст kt-файл с классом фрагмента и xml-файл с макетом фрагмента. Таким же образом сгенерируем ещё три фрагмента («Fragment2», «Fragment3», «Fragment4»). Мы будем использовать их для создания четырёх разных типов навигации по приложению.

1.4. Адреса: файл ресурсов типа «Navigation»

Кликнув правой кнопкой мыши по папке «res», создадим файл ресурсов типа «Navigation» с названием «routes.xml» («маршруты»).

Откроем созданный файл и с помощью кнопки «New Destination» добавим в навигационную схему наши фрагменты.

«Хватаясь» мышкой за точку в середине правой стороны фрагмента, соединим фрагменты друг с другом так, как они должны быть связаны в приложении.

В соответствии с их названиями, наши фрагменты получат идентификаторы (id) «fragment1», «fragment2», «fragment3», «fragment4». Это «адреса», которые будут использоваться при указании пунктов назначения («destinations») в инструкциях навигационному контроллеру.

Кроме «id», каждый тег «fragment» содержит ещё три параметра: «name», «label» и «layout». Параметры «name» и «layout» нас сейчас не интересуют. Единственное, что стоит отредактировать в файле «routes.xml» — это названия («label») фрагментов. Заменим их на «Фрагмент №1», «Фрагмент №2», «Фрагмент №3» и «Фрагмент №4».

1.5. Фрейм: виджет NavHostFragment

Откроем файл макета «res/layout/activity_main.xml» и удалим текстовый виджет «Hello World!», он нам не понадобится. В палитре (Palette) выберем раздел «Контейнеры» (Containers) и перетащим оттуда на макет активности виджет NavHostFragment (указав наш файл «routes» в качестве источника информации для него). Он выполнит роль фрейма, в котором будут выводиться различные фрагменты приложения.

Изменим id фрагмента на «navFragment». Код макета главной активности будет выглядеть теперь так:

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

Часть 2. Элементы навигации

2.1. Навигация с помощью кнопок

Откроем макет первого фрагмента («fragment_fragment1.xml»). Удалим ненужный текстовый виджет, изменим тип макета с «FrameLayout» на линейный вертикальный и добавим три кнопки с идентификаторами «button2», «button3», «button4» и соответствующими названиями «Фрагмент 2», «Фрагмент 3», «Фрагмент 4».

В методе «onCreateView» фрагмента получим ссылку на навигационный контроллер (объект «NavController») и запрограммируем поведение при нажатии на кнопки: командой «setOnClickListener» для каждой кнопки создадим слушателя кнопки, который при клике по кнопке будет передавать навигационному контроллеру адрес (id) точки назначения вместе с командой переместиться (navigate) на указанный адрес.

Проверим, как работают наши кнопки.

Одна кнопка — одна строчка кода — и клик по кнопке перемещает нас к указанному фрагменту. Просто, не так ли?

Но без меню не очень удобно, приходится использовать кнопку «Назад» для возвращения на стартовый экран.

2.2. Боковое меню (drawer)

2.2.1. Ресурсный файл меню

В каталоге «res/menu» создадим ресурсный файл меню «drawer_menu.xml». Добавим в него пункты меню, каждый из которых представляет собой тег «item» с параметрами «id» (должен соответствовать таковому в навигационном графе «routes.xml», «title» (заголовок, он может быть другим), «icon» (мы используем одну и ту же картинку для всех пунктов, но, конечно же, они могут быть разными) и др. Наше меню будет выглядеть так:

2.2.2. Шаблон DrawerLayout и виджет NavigationView в макете активности

Откроем файл макета активности «activity_main.xml».

После первого тега (xml version…) добавим начало тега «DrawerLayout».

В конец файла добавим виджет «NavigationView» и окончание тега «DrawerLayout».

Читайте также:  Как заблокировать сообщения мчс андроид

2.2.3. Подключение бокового меню в классе активности

Откроем файл «MainActivity.kt» и в методе «onCreate» получим ссылку на «navController» (в активности это выглядит чуть сложнее, чем было во фрагментах).

Затем включим боковое меню:

Код класса теперь выглядит так:

Теперь меню появляется в ответ на свайп от левого края экрана:

Хорошо было бы добавить и кнопку слева-вверху для вызова бокового меню, верно?

2.3. Кнопка и название фрагмента на панели инструментов

Существующий по умолчанию ActionBar, как рекомендует официальное руководство, заменим на Toolbar.

Чтобы отключить существующий ActionBar, в файле «res/values/styles.xml» найдём строку

и заменим «DarkActionBar» на «NoActionBar».

Отлично, ActionBar мы отключили.

Теперь добавим Toolbar. Откроем файл «activity_main.xml», в палитре (Palette) выберем раздел «Контейнеры» (Containers) и перетащим оттуда на макет активности виджет «Toolbar». Панель инструментов добавлена, но она пока пуста.

Переходим в файл активности «MainActivity.kt». Чтобы на Toolbar вывести кнопку и название текущего фрагмента, в метод «onCreate()» добавим следующие строки:

Toolbar теперь выводит название фрагмента и кнопку «Вверх» (Up) для вложенных фрагментов.

Кнопка «вверх» в android’е почему-то обозначается стрелкой «влево»:

Чтобы на стартовом экране приложения выводилась кнопка-гамбургер, нам необходимо в конфигурацию панели инструментов добавить параметр «drawerLayout», который содержит id виджета DrawerLayout из файла «activity_main.xml».

Клик по этой кнопке выводит боковое меню.

2.4. Нижнее меню (Bottom Navigation)

Иногда бывает необходимо акцентировать внимание пользователя на определённых действиях, и эффективно сделать это помогает нижнее меню. Добавим его в третий фрагмент.

Сначала создадим ресурсный файл меню «bottom_nav_menu.xml» с парой ссылок. Затем откроем макет фрагмента №3 (файл «fragment_fragment3.xml») и перетащим на него виджет «BottomNavigationView», попутно согласившись с предложением IDE добавить в dependencies библиотеку «com.android.support:design».

Если бы мы создавали нижнее меню не для одного фрагмента, а сразу для всех, то в метод «onCreate» класса активности (файл «MainActivity.kt») нужно было бы включить следующий код:

Конечно, и виджет «BottomNavigationView» в таком случае надо было бы поместить в макет активности, а не фрагмента.

Но поскольку данное меню нам требуется только во фрагменте №3, то и редактировать мы будем класс фрагмента (файл «Fragment3.kt»), а код будет выглядеть чуть сложнее:

В итоге мы получим нижнее меню, которое будет выводиться только в 3-м фрагменте.

То же самое, но с другими ссылками, сделаем и в 4-м фрагменте.

2.5. Всплывающее меню (Overflow Menu)

Ещё один вид меню — всплывающее меню, которое выводится при клике по кнопке (трём вертикально расположенным точкам) в правом верхнем углу экрана.

Создадим ресурсный файл меню «top_right_menu.xml» с необходимыми ссылками.

В файле «MainActivity» в метод «onCreate» перед «toolBar.setupWithNavController. » добавим строку «setSupportActionBar(toolBar)».

И далее в этом же классе переопределим два метода:

Нажатие на верхнюю правую кнопку теперь отображает всплывающее меню:

Краткие выводы и ссылка на github

Очевидно, что Navigation Architecture Component существенно облегчает труд разработчика. Сложные в прошлом задачи теперь решаются несколькими строчками кода.

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

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

Источник

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