Как реализовать Android Pull-to-Refresh

В приложениях Android, таких как Twitter (официальное приложение), когда вы сталкиваетесь с ListView, вы можете вытащить его (и он будет возвращаться, когда он будет выпущен), чтобы обновить содержимое.

Интересно, какой лучший способ, на ваш взгляд, реализовать это?

Некоторые возможности, о которых я мог подумать:

  1. Элемент поверх ListView – однако я не думаю, что прокрутка назад к позиции позиции 1 (основанная на 0) с анимацией в ListView – простая задача.
  2. Другое представление вне ListView – но мне нужно позаботиться о том, чтобы перемещать позицию ListView вниз, когда она вытащена, и я не уверен, можем ли мы обнаружить, что перетаскивание в ListView по-прежнему действительно прокручивает элементы в ListView.

Есть рекомендации?

PS Интересно, когда выпущен официальный исходный код приложения для Twitter. Было упомянуто, что он будет выпущен, но прошло 6 месяцев, и с тех пор мы не слышали об этом.

Наконец, Google выпустила официальную версию библиотеки для обновления до обновления.

Он называется SwipeRefreshLayout, внутри библиотеки поддержки, и документация находится здесь:

https://developer.android.com/reference/android/support/v4/widget/SwipeRefreshLayout.html

Я попытался реализовать компонент pull для обновления, это далеко не полный, но демонстрирует возможную реализацию, https://github.com/johannilsson/android-pulltorefresh .

Основная логика реализована в PullToRefreshListView которая расширяет ListView . Внутри он управляет прокруткой заголовка с помощью smoothScrollBy (API уровня 8). Виджет теперь обновляется с поддержкой 1.5 и более поздних версий, однако, пожалуйста, прочитайте поддержку README for 1.5.

В ваших макетах вы просто добавляете его так.

 <com.markupartist.android.widget.PullToRefreshListView android:id="@+id/android:list" android:layout_height="fill_parent" android:layout_width="fill_parent" /> 

Я также внедрил надежную, с открытым исходным кодом, удобную и настраиваемую библиотеку PullToRefresh для Android. Вы можете заменить ListView на PullToRefreshListView, как описано в документации на странице проекта.

https://github.com/erikwt/PullToRefresh-ListView

Самый простой способ, на мой взгляд, предоставляется библиотекой поддержки Android:

android.support.v4.widget.SwipeRefreshLayout;

После импорта, вы можете определить свой макет следующим образом:

  <android.support.v4.widget.SwipeRefreshLayout android:id="@+id/refresh" android:layout_height="match_parent" android:layout_width="match_parent"> <android.support.v7.widget.RecyclerView xmlns:recycler_view="http://schemas.android.com/apk/res-auto" android:id="@android:id/list" android:theme="@style/Theme.AppCompat.Light" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@color/button_material_light" > </android.support.v7.widget.RecyclerView> </android.support.v4.widget.SwipeRefreshLayout> 

Я предполагаю, что вы используете просмотр recycler вместо listview. Тем не менее, listview по-прежнему работает, поэтому вам просто нужно заменить recyclerview на listview и обновить ссылки в java-коде (фрагмент).

В вашем фрагменте действия вы сначала реализуете интерфейс, SwipeRefreshLayout.OnRefreshListener : i, e

 public class MySwipeFragment extends Fragment implements SwipeRefreshLayout.OnRefreshListener{ private SwipeRefreshLayout swipeRefreshLayout; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) { View view = inflater.inflate(R.layout.fragment_item, container, false); swipeRefreshLayout = (SwipeRefreshLayout) view.findViewById(R.id.refresh); swipeRefreshLayout.setOnRefreshListener(this); } @Override public void onRefresh(){ swipeRefreshLayout.setRefreshing(true); refreshList(); } refreshList(){ //do processing to get new data and set your listview's adapter, maybe reinitialise the loaders you may be using or so //when your data has finished loading, cset the refresh state of the view to false swipeRefreshLayout.setRefreshing(false); } } 

Надеюсь, это поможет массам

В этой ссылке вы можете найти вилку известного представления PullToRefresh котором есть новые интересные реализации, такие как PullTorRefreshWebView или PullToRefreshGridView или возможность добавления PullToRefresh в нижнем краю списка.

https://github.com/chrisbanes/Android-PullToRefresh

И самое лучшее, что работа идеально подходит для Android 4.1 (обычный PullToRefresh не работает)

У меня есть очень простой способ сделать это, но теперь я уверен, что это надежный способ. Есть мой код PullDownListView.java

 package com.myproject.widgets; import android.content.Context; import android.util.AttributeSet; import android.view.MotionEvent; import android.widget.AbsListView; import android.widget.AbsListView.OnScrollListener; import android.widget.ListView; /** * @author Pushpan * @date Nov 27, 2012 **/ public class PullDownListView extends ListView implements OnScrollListener { private ListViewTouchEventListener mTouchListener; private boolean pulledDown; public PullDownListView(Context context) { super(context); init(); } public PullDownListView(Context context, AttributeSet attrs) { super(context, attrs); init(); } public PullDownListView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); init(); } private void init() { setOnScrollListener(this); } private float lastY; @Override public boolean dispatchTouchEvent(MotionEvent ev) { if (ev.getAction() == MotionEvent.ACTION_DOWN) { lastY = ev.getRawY(); } else if (ev.getAction() == MotionEvent.ACTION_MOVE) { float newY = ev.getRawY(); setPulledDown((newY - lastY) > 0); postDelayed(new Runnable() { @Override public void run() { if (isPulledDown()) { if (mTouchListener != null) { mTouchListener.onListViewPulledDown(); setPulledDown(false); } } } }, 400); lastY = newY; } else if (ev.getAction() == MotionEvent.ACTION_UP) { lastY = 0; } return super.dispatchTouchEvent(ev); } @Override public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { setPulledDown(false); } @Override public void onScrollStateChanged(AbsListView view, int scrollState) { } public interface ListViewTouchEventListener { public void onListViewPulledDown(); } public void setListViewTouchListener( ListViewTouchEventListener touchListener) { this.mTouchListener = touchListener; } public ListViewTouchEventListener getListViewTouchListener() { return mTouchListener; } public boolean isPulledDown() { return pulledDown; } public void setPulledDown(boolean pulledDown) { this.pulledDown = pulledDown; } } 

Вам просто нужно реализовать ListViewTouchEventListener в своей деятельности, где вы хотите использовать этот ListView и установить прослушиватель

Я реализовал его в PullDownListViewActivity

 package com.myproject.activities; import android.app.Activity; import android.os.Bundle; /** * @author Pushpan * */ public class PullDownListViewActivity extends Activity implements ListViewTouchEventListener { private PullDownListView listView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); listView = new PullDownListView(this); setContentView(listView); listView.setListViewTouchListener(this); //setItems in listview } public void onListViewPulledDown(){ Log.("PullDownListViewActivity", "ListView pulled down"); } } 

Меня устраивает 🙂

Чтобы реализовать андроид Pull-to-Refresh, попробуйте этот фрагмент кода,

 <android.support.v4.widget.SwipeRefreshLayout android:id="@+id/pullToRefresh" android:layout_width="match_parent" android:layout_height="wrap_content"> <ListView android:id="@+id/lv" android:layout_width="match_parent" android:layout_height="match_parent" > </ListView> </android.support.v4.widget.SwipeRefreshLayout> 

Класс деятельности:

 ListView lv = (ListView) findViewById(R.id.lv); SwipeRefreshLayout pullToRefresh = (SwipeRefreshLayout) findViewById(R.id.pullToRefresh); lv.setAdapter(mAdapter); pullToRefresh.setOnRefreshListener(new OnRefreshListener() { @Override public void onRefresh() { // TODO Auto-generated method stub refreshContent(); } }); private void refreshContent(){ new Handler().postDelayed(new Runnable() { @Override public void run() { pullToRefresh.setRefreshing(false); } }, 5000); } 

Никто не упоминает новый тип «Pull to refresh», который отображается поверх панели действий, например, в приложении Google Now или Gmail.

Существует библиотека ActionBar-PullToRefresh, которая работает точно так же.

Обратите внимание, что есть проблемы UX, с которыми можно бороться при внедрении на Android и WP.

«Отличным показателем того, почему разработчики / разработчики не должны реализовывать pull-to-refresh в приложениях iOS для стилей, является то, как Google и их команды никогда не используют pull-to-refresh на Android, пока они действительно используют его в iOS».

https://plus.google.com/109453683460749241197/posts/eqYxXR8L4eb

Если вы не хотите, чтобы ваша программа выглядела как программа для iPhone, которая была встроена в Android, ориентируйтесь на более естественный внешний вид и делайте что-то похожее на Gingerbread:

Alt text

Я написал ссылку для обновления компонента здесь: https://github.com/guillep/PullToRefresh Это событие работает, если в списке нет элементов, и я тестировал его на телефонах = = 1,6 android.

Любое предложение или улучшение оцениваются 🙂

Я думаю, что лучшая библиотека: https://github.com/chrisbanes/Android-PullToRefresh .

Работает с:

 ListView ExpandableListView GridView WebView ScrollView HorizontalScrollView ViewPager 

Чтобы получить последнюю версию Lollipop Pull-Refresh:

  1. Загрузите последнюю библиотеку поддержки Lollipop SDK и Extras / Android
  2. Установите Project Build Build для Android 5.0 (в противном случае пакет поддержки может иметь ошибки с ресурсами)
  3. Обновите свою версию libs / android-v4.jar до 21-й версии
  4. Использовать android.support.v4.widget.SwipeRefreshLayout плюс android.support.v4.widget.SwipeRefreshLayout.OnRefreshListener

Подробное руководство можно найти здесь: http://antonioleiva.com/swiperefreshlayout/

Плюс для ListView Я рекомендую прочитать о canChildScrollUp() в комментариях;)

Очень интересный Pull-to-Refresh от Yalantis . Gif для iOS, но вы можете проверить это 🙂

 <com.yalantis.pulltorefresh.library.PullToRefreshView android:id="@+id/pull_to_refresh" android:layout_width="match_parent" android:layout_height="match_parent"> <ListView android:id="@+id/list_view" android:divider="@null" android:dividerHeight="0dp" android:layout_width="match_parent" android:layout_height="match_parent" />