功能比较齐全的PullToRefreshView,是让下边的View实现下拉刷新功能的:
能够实现刷新功能的控件有:
1.ListView
2.ExpandableListView
3.GridView
4.WebView
5.ScrollView
6.HorizontalScrollView
7.ViewPager
下载项目包(开源项地址:https://github.com/chrisbanes/Android-PullToRefresh),将library包导入即可,下面以PullToRefreshListView为例:
xml布局文件为:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:ptr="http://schemas.android.com/apk/res-auto" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <com.handmark.pulltorefresh.library.PullToRefreshListView android:id="@+id/pull_refresh_list" android:layout_width="fill_parent" android:layout_height="fill_parent" android:cacheColorHint="#ff0000" android:fadingEdge="none" android:divider="#19000000" android:dividerHeight="2dp" android:footerDividersEnabled="true" android:headerDividersEnabled="true" android:smoothScrollbar="true" android:fastScrollEnabled="false" ptr:ptrShowIndicator="false" ptr:ptrMode="pullFromStart" ptr:ptrDrawable="@drawable/default_ptr_rotate" ptr:ptrAnimationStyle="rotate" /> </LinearLayout>这里要说一下,我依赖的是library包,AS不能自动识别 PullToRefreshListView ,我们需要写入全路径com.handmark.pulltorefresh.library.PullToRefreshListView,这样AS才能识别;
Activity中代码:
public class PullToRefreshDemoActivity extends BaseActivity implements AdapterView.OnItemClickListener,PullToRefreshBase.OnRefreshListener2 { private PullToRefreshListView pullToRefreshView; private Handler handler = new Handler(); private ArrayList<String> list; private ArrayAdapter<String> stringArrayAdapter; private int refreshState = 0; private int UP =2; @Override protected void initView() { //刷新样式设置 pullToRefreshView = (PullToRefreshListView) findViewById(R.id.pull_refresh_list); pullToRefreshView.setMode(PullToRefreshBase.Mode.BOTH);//两端刷新 // pullToRefreshView.setMode(PullToRefreshBase.Mode.PULL_FROM_START);//上拉刷新 // pullToRefreshView.setMode(PullToRefreshBase.Mode.PULL_FROM_END);//下拉刷新 //header设置:下拉刷新 pullToRefreshView.getLoadingLayoutProxy(true, false).setPullLabel(getString(R.string.pull_to_load)); pullToRefreshView.getLoadingLayoutProxy(true, false).setRefreshingLabel(getString(R.string.loading)); pullToRefreshView.getLoadingLayoutProxy(true, false).setReleaseLabel(getString(R.string.release_to_load)); pullToRefreshView.getLoadingLayoutProxy(true, false).setLastUpdatedLabel("上次加载:"+getCurrentTime() ); //footer设置:上拉加载更多 pullToRefreshView.getLoadingLayoutProxy(false, true).setPullLabel(getString(R.string.pullup_to_load)); pullToRefreshView.getLoadingLayoutProxy(false, true).setRefreshingLabel(getString(R.string.loading)); pullToRefreshView.getLoadingLayoutProxy(false, true).setReleaseLabel(getString(R.string.release_to_load)); pullToRefreshView.getRefreshableView().setSelector(android.R.color.holo_red_light); pullToRefreshView.setOnRefreshListener(this); pullToRefreshView.setOnItemClickListener(this); } @Override protected void initData() { list = new ArrayList<>(); for (int i = 0; i < 44; i++) { list.add("条目: " + i); } stringArrayAdapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, list); pullToRefreshView.setAdapter(stringArrayAdapter); } @Override protected int getContentId() { return R.layout.puto_to_refresh_demo; } private void taskExecute() { handler.postDelayed(new Runnable() { @Override public void run() { if (refreshState == UP) { list.add(list.size(), "new items: aaa"); }else { list.add(0, "new items: aaa"); } stringArrayAdapter.notifyDataSetChanged(); pullToRefreshView.onRefreshComplete(); refreshState = 0; } }, 1000); } @Override public void onPullDownToRefresh(PullToRefreshBase refreshView) { taskExecute(); } @Override public void onPullUpToRefresh(PullToRefreshBase refreshView) { refreshState = UP; taskExecute(); } public String getCurrentTime(){ SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); String formatD = dateFormat.format(new Date()); return formatD; } @Override public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) { startActivity(new Intent(this,ThreeActivity.class)); overridePendingTransition(R.anim.enter_anim,R.anim.exit_anim); finish(); } }
不仅如此,我们可以分析源码,来设置一些我们需要的刷新样式:
<?xml version="1.0" encoding="utf-8"?> <resources> <declare-styleable name="PullToRefresh"> <!-- A drawable to use as the background of the Refreshable View --> <!-- 设置刷新view的背景 --> <attr name="ptrRefreshableViewBackground" format="reference|color" /> <!-- A drawable to use as the background of the Header and Footer Loading Views --> <!-- 设置头部view的背景 --> <attr name="ptrHeaderBackground" format="reference|color" /> <!-- Text Color of the Header and Footer Loading Views --> <!-- 设置头部/底部文字的颜色 --> <attr name="ptrHeaderTextColor" format="reference|color" /> <!-- Text Color of the Header and Footer Loading Views Sub Header --> <!-- 设置头部/底部副标题的文字颜色 --> <attr name="ptrHeaderSubTextColor" format="reference|color" /> <!-- Mode of Pull-to-Refresh that should be used --> <!-- 设置下拉刷新的模式,有多重方式可选。无刷新功能,从顶部刷新,从底部刷新,二者都有,只允许手动刷新 --> <attr name="ptrMode"> <flag name="disabled" value="0x0" /> <flag name="pullFromStart" value="0x1" /> <flag name="pullFromEnd" value="0x2" /> <flag name="both" value="0x3" /> <flag name="manualOnly" value="0x4" /> <!-- These last two are depreacted --> <!-- 这两个属性不推荐了,用上面的代替即可 --> <flag name="pullDownFromTop" value="0x1" /> <flag name="pullUpFromBottom" value="0x2" /> </attr> <!-- Whether the Indicator overlay(s) should be used --> <!-- 是否显示指示箭头 --> <attr name="ptrShowIndicator" format="reference|boolean" /> <!-- Drawable to use as Loading Indicator. Changes both Header and Footer. --> <!-- 指示箭头的图片 --> <attr name="ptrDrawable" format="reference" /> <!-- Drawable to use as Loading Indicator in the Header View. Overrides value set in ptrDrawable. --> <!-- 顶部指示箭头的图片,设置后会覆盖ptrDrawable中顶部的设置 --> <attr name="ptrDrawableStart" format="reference" /> <!-- Drawable to use as Loading Indicator in the Fooer View. Overrides value set in ptrDrawable. --> <!-- 底部指示箭头的图片,设置后会覆盖ptrDrawable中底部的设置 --> <attr name="ptrDrawableEnd" format="reference" /> <!-- Whether Android's built-in Over Scroll should be utilised for Pull-to-Refresh. --> <attr name="ptrOverScroll" format="reference|boolean" /> <!-- Base text color, typeface, size, and style for Header and Footer Loading Views --> <!-- 设置文字的基本字体 --> <attr name="ptrHeaderTextAppearance" format="reference" /> <!-- Base text color, typeface, size, and style for Header and Footer Loading Views Sub Header --> <!-- 设置副标题的基本字体 --> <attr name="ptrSubHeaderTextAppearance" format="reference" /> <!-- Style of Animation should be used displayed when pulling. --> <!-- 设置下拉时标识图的动画,默认为rotate --> <attr name="ptrAnimationStyle"> <flag name="rotate" value="0x0" /> <flag name="flip" value="0x1" /> </attr> <!-- Whether the user can scroll while the View is Refreshing --> <!-- 设置刷新时是否允许滚动,一般为true --> <attr name="ptrScrollingWhileRefreshingEnabled" format="reference|boolean" /> <!-- Whether PullToRefreshListView has it's extras enabled. This allows the user to be able to scroll while refreshing, and behaves better. It acheives this by adding Header and/or Footer Views to the ListView. --> <!-- 允许在listview中添加头/尾视图 --> <attr name="ptrListViewExtrasEnabled" format="reference|boolean" /> <!-- Whether the Drawable should be continually rotated as you pull. This only takes effect when using the 'Rotate' Animation Style. --> <!-- 当设置rotate时,可以用这个来设置刷新时旋转的图片 --> <attr name="ptrRotateDrawableWhilePulling" format="reference|boolean" /> <!-- BELOW HERE ARE DEPRECEATED. DO NOT USE. --> <attr name="ptrAdapterViewBackground" format="reference|color" /> <attr name="ptrDrawableTop" format="reference" /> <attr name="ptrDrawableBottom" format="reference" /> </declare-styleable> </resources>
此外PullToRefreshListView 的addHeadView不显示问题解决如下:
一.比如add一个imageView到顶部
refreshListView = (PullToRefreshListView) layout.findViewById(R.id.refresh_listview); ListView mListView = refreshListView.getRefreshableView(); mListView.addHeaderView(imageView);
这样理论上可以了,实际还会报一个错
java.lang.ClassCastException: android.widget.LinearLayout$LayoutParams cannot be cast to android.widget.AbsListView$LayoutParams
需要把你的imageView设置一下属性
参考网址: http://www.cnblogs.com/tianzhijiexian/p/4023802.htmlAbsListView.LayoutParams layoutParams = new AbsListView.LayoutParams(AbsListView.LayoutParams.MATCH_PARENT, AbsListView.LayoutParams.WRAP_CONTENT);imageView.setLayoutParams(layoutParams);去翻了一下源码,是因为PullToRefreshListView是继承AbsListView的
二.当要加一个viewPager时
AbsListView.LayoutParams layoutParams = new AbsListView.LayoutParams(AbsListView.LayoutParams.MATCH_PARENT, 300);改为具体像素数值,用WRAP_CONTENT会不显示
这是之前使用PulltoRefresh的时候遇到的一个问题,其实PulltoRefresh有好些bug,曾经试过刷新次数多了偶尔出现报异常崩溃,崩溃代码是PulltoRefreshListView里面的,而且现在这个项目在github已经不维护了,不推荐使用。