Swipe android studio java

SwipeRefreshLayout

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

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

Пример на Kotlin

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

 implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.1.0" 

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

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

 package ru.alexanderklimov.swipe import android.os.Bundle import android.os.Handler import androidx.appcompat.app.AppCompatActivity import kotlinx.android.synthetic.main.activity_main.* import java.util.* class MainActivity : AppCompatActivity() < private lateinit var random: Random private lateinit var handler: Handler private lateinit var runnable: Runnable override fun onCreate(savedInstanceState: Bundle?) < super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) random = Random() handler = Handler() swipeRefreshLayout.setOnRefreshListener < // Initialize a new Runnable runnable = Runnable < // Update the text view text with a random number textView.text = "Котика пора кормить. Его не кормили уже $минут" // Hide swipe to refresh icon animation swipeRefreshLayout.isRefreshing = false > // Execute the task after specified time handler.postDelayed( runnable, 3000.toLong() ) > swipeRefreshLayout.setColorSchemeResources( android.R.color.holo_blue_bright, android.R.color.holo_green_light, android.R.color.holo_orange_light, android.R.color.holo_red_light ) > > 

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

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

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

 package ru.alexanderklimov.swipe; import android.os.Bundle; import android.os.Handler; import android.support.v4.widget.SwipeRefreshLayout; import android.support.v7.app.AppCompatActivity; import android.widget.TextView; import java.util.Random; public class MainActivity extends AppCompatActivity implements SwipeRefreshLayout.OnRefreshListener < private SwipeRefreshLayout mSwipeRefreshLayout; private TextView mCatTextView; @Override protected void onCreate(Bundle savedInstanceState) < super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mCatTextView = findViewById(R.id.textViewCat); mSwipeRefreshLayout = findViewById(R.id.swipe_container); mSwipeRefreshLayout.setOnRefreshListener(this); mSwipeRefreshLayout.setColorSchemeResources(android.R.color.holo_blue_bright, android.R.color.holo_green_light, android.R.color.holo_orange_light, android.R.color.holo_red_light); // Альтернативный способ // mSwipeRefreshLayout.setColorSchemeColors( // Color.RED, Color.GREEN, Color.BLUE, Color.CYAN); >@Override public void onRefresh() < new Handler().postDelayed(new Runnable() < @Override public void run() < // Отменяем анимацию обновления mSwipeRefreshLayout.setRefreshing(false); Random random = new Random(); mCatTextView.setText("Котика пора кормить. Его не кормили уже " + (1 + random.nextInt(10)) + " мин."); >>, 4000); > > 

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

Читайте также:  New captcha in php

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

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

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

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

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

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

 import android.os.Bundle; import android.support.v4.widget.SwipeRefreshLayout; import android.support.v7.app.AppCompatActivity; import android.widget.ArrayAdapter; import android.widget.ListAdapter; import android.widget.ListView; import java.text.DateFormat; import java.util.ArrayList; import java.util.Date; import java.util.List; public class MainActivity extends AppCompatActivity < private SwipeRefreshLayout mSwipeRefreshLayout; private ListView mListView; private ListmList; @Override protected void onCreate(Bundle savedInstanceState) < super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mSwipeRefreshLayout = findViewById(R.id.swipeRefreshLayout); mSwipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() < @Override public void onRefresh() < String currentDateTime = DateFormat.getDateTimeInstance().format(new Date()); mList.add(currentDateTime); mListView.invalidateViews(); mSwipeRefreshLayout.setRefreshing(false); >>); mListView = findViewById(R.id.listView); mList = new ArrayList<>(); ListAdapter mAdapter = new ArrayAdapter<>( this, android.R.layout.simple_list_item_1, mList); mListView.setAdapter(mAdapter); > > 

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

Источник

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

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 . Позже, в рамках этой серии статей, мы расширим рамки и рассмотрим остальные возможности.

Читайте также:  Css move div center

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

Настройка

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

compile 'com.android.support:recyclerview-v7:22.2.0'

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

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

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

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

getMovementFlags(RecyclerView, ViewHolder) onMove(RecyclerView, ViewHolder, ViewHolder) onSwiped(ViewHolder, int)

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

isLongPressDragEnabled() isItemViewSwipeEnabled()
@Override public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder)

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

@Override public boolean isLongPressDragEnabled()

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

@Override public boolean isItemViewSwipeEnabled()

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

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

public interface ItemTouchHelperAdapter

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

public class RecyclerListAdapter extends RecyclerView.Adapter implements ItemTouchHelperAdapter < // . код из [примера](https://gist.github.com/iPaulPro/2216ea5e14818056cfcc#file-recyclerlistadapter-java) @Override public void onItemDismiss(int position) < mItems.remove(position); notifyItemRemoved(position); >@Override public boolean onItemMove(int fromPosition, int toPosition) < if (fromPosition < toPosition) < for (int i = fromPosition; i < toPosition; i++) < Collections.swap(mItems, i, i + 1); >> else < for (int i = fromPosition; i >toPosition; i--) < Collections.swap(mItems, i, i - 1); >> notifyItemMoved(fromPosition, toPosition); return true; >

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

Читайте также:  Размер границы border css

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

private final ItemTouchHelperAdapter mAdapter; public SimpleItemTouchHelperCallback( ItemTouchHelperAdapter adapter)

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

@Override public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) < mAdapter.onItemMove(viewHolder.getAdapterPosition(), target.getAdapterPosition()); return true; >@Override public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction)

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

public class SimpleItemTouchHelperCallback extends ItemTouchHelper.Callback < private final ItemTouchHelperAdapter mAdapter; public SimpleItemTouchHelperCallback(ItemTouchHelperAdapter adapter) < mAdapter = adapter; >@Override public boolean isLongPressDragEnabled() < return true; >@Override public boolean isItemViewSwipeEnabled() < return true; >@Override public int getMovementFlags(RecyclerView recyclerView, ViewHolder viewHolder) < int dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN; int swipeFlags = ItemTouchHelper.START | ItemTouchHelper.END; return makeMovementFlags(dragFlags, swipeFlags); >@Override public boolean onMove(RecyclerView recyclerView, ViewHolder viewHolder, ViewHolder target) < mAdapter.onItemMove(viewHolder.getAdapterPosition(), target.getAdapterPosition()); return true; >@Override public void onSwiped(ViewHolder viewHolder, int direction) < mAdapter.onItemDismiss(viewHolder.getAdapterPosition()); >>

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

ItemTouchHelper.Callback callback = new SimpleItemTouchHelperCallback(adapter); ItemTouchHelper touchHelper = new ItemTouchHelper(callback); touchHelper.attachToRecyclerView(recyclerView);

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

Заключение

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

Исходный код

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

  • android development
  • android
  • андроид
  • recyclerview
  • списки
  • lists
  • работа со списками
  • перевод с английского
  • программирование
  • разработка
  • devcolibri
  • никто не читает теги

Источник

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