如何实现Android Pull-to-Refresh

在诸如Twitter(官方应用程序)之类的Android应用程序中,当您遇到ListView时,您可以将其拉下(并在发布时反弹回来)以刷新内容。

我想知道什么是最好的方式来实现呢?

我能想到的一些可能性:

  1. ListView上的一个项目 – 但我不认为滚动回ListView上的animation的项目位置1(0为基础)是一件容易的事情。
  2. 在ListView之外的另一个视图 – 但我需要照顾当拉动ListView位置向下时,我不确定是否可以检测到ListView的拖动触摸仍然真正滚动ListView上的项目。

任何build议?

PS我不知道官方Twitter应用程序源代码何时发布。 有人提到它会被释放,但是6个月过去了,从那时起我们还没有听说过。

最后,谷歌发布了一个正式的拉到刷新库!

在支持库里面叫做SwipeRefreshLayout,文档在这里:

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

我试图实现一个拉刷新组件,这是远远没有完成,但演示了一个可能的实现, https://github.com/johannilsson/android-pulltorefresh

主要逻辑是在扩展ListView PullToRefreshListView中实现的。 在内部,它使用smoothScrollBy (API Level 8)控制标题视图的滚动。 该小部件现在更新支持1.5和更高版本,请阅读自述文件1.5支持。

在你的布局中,你只需要像这样添加它。

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

我还实现了一个强大的,开源的,易于使用和高度可定制的Android的PullToRefresh库。 您可以使用PullToRefreshListViewreplaceListView,如项目页面文档中所述。

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> 

我假设你使用回收视图而不是listview。 但是,listview仍然有效,所以你只需要用listviewreplacerecyclerview,并更新java代码(Fragment)中的引用。

在您的活动片段中,您首先实现接口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); } } 

希望这有助于群众

在这个链接中,你可以find着名的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; } } 

您只需要在您要使用此ListView的活动上实现ListViewTouchEventListener并设置侦听器

我有它在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"); } } 

它适用于我:)

要实现android 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); } 

没有人提到在Google即时或Gmail应用程序中显示在操作栏之上的新型“拉动刷新”。

有一个库ActionBar-PullToRefresh工作完全一样。

请注意,在Android和WP上实施时,有一些用户体验问题需要解决。

“devise师/开发人员不应该在风格iOS应用程序中实现”拉动式“刷新的一个很好的指标是Google和他们的团队在iOS上使用它时从不使用”拉到刷新“。

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

如果你不希望你的程序看起来像一个强制安装到Android上的iPhone程序,那么你的目标就是更加本土的外观和感觉,并且做类似于姜饼的事情:

替代文字

我已经写了一个刷新组件在这里: https : //github.com/guillep/PullToRefresh它的工作事件,如果列表没有项目,我已经testing了> = 1.6 Android手机。

任何build议或改进是赞赏:)

我认为最好的图书馆是: https : //github.com/chrisbanes/Android-PullToRefresh 。

适用于:

 ListView ExpandableListView GridView WebView ScrollView HorizontalScrollView ViewPager 

要获得最新的棒棒糖拉动刷新:

  1. 下载最新的Lollipop SDK和Extras / Android支持库
  2. 将项目的生成目标设置为Android 5.0(否则支持包可能会有资源错误)
  3. 更新你的libs / android-support-v4.jar到第21版
  4. 使用android.support.v4.widget.SwipeRefreshLayout加上android.support.v4.widget.SwipeRefreshLayout.OnRefreshListener

详细的指南可以在这里find: http : //antonioleiva.com/swiperefreshlayout/

再加上ListView我推荐阅读关于canChildScrollUp()的评论;)

非常有趣的Yalantis 拉动刷新 。 为iOS的GIF,但你可以检查它:)

 <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" />