Android-PullToRefresh的用法 及源码中你应该知道的一些东西
PullToRefresh是一套实现非常好的下拉刷新控件,它支持:
ListView
ExpandableListView
GridView
WebView
ScrollView
HorizontalScrollView
ViewPager
等多种常用的需要刷新的View类型,而且使用起来也十分方便。
(下载地址:https://github.com/chrisbanes/Android-PullToRefresh)
(可以去查看源码,了解具体的实现过程)
、
PullToRefresh基本用法:
1、在布局文件中添加PullToRefresh控件,比如PullToRefreshListView;
2、在Activity中,设置监听器OnRefreshListener以响应用户下拉操作;
3、在监听器的onRefresh()方法中执行数据刷新操作,可以通过AsyncTask来实现;
4、在AsyncTask中获取到数据后,记得调用onRefreshComplete()方法通知PullToRefresh控件数据已获取完毕,可以结束刷新操作。
(注意:实际开发项目中,导入第三方库是不完全的,建议自己给加到自己的实际开发项目中)
1.布局:
<com.motoband.PullToRefresh.PullToRefreshListView
android:id="@+id/medal_pulltorefreshlistview"
android:layout_width="match_parent"
android:layout_height="match_parent" />
2.具体的使用及其设置
medal_pulltorefreshlistview = (PullToRefreshListView) findViewById(R.id.medal_pulltorefreshlistview);
medal_pulltorefreshlistview.setMode(PullToRefreshBase.Mode.PULL_FROM_START);
//设置控件具有那些刷新的方式,只有下拉刷新,只有上拉刷新,上拉下拉都可以刷新(实际开发中建议多去试试)
setMode();
//设置刷新的监听事件
//刷新(单刷新)
medal_pulltorefreshlistview.setOnRefreshListener(new PullToRefreshBase.OnRefreshListener<ListView>() {
@Override
public void onRefresh(PullToRefreshBase<ListView> refreshView) {
new GetDataTask().execute();
}
});
//刷新方法
private class GetDataTask extends AsyncTask<Void, Void, String[]> {
@Override
protected String[] doInBackground(Void... params) {
// Simulates a background job.
try {
Thread.sleep(500);
} catch (InterruptedException e) {
}
return null;
}
@Override
protected void onPostExecute(String[] result) {
//数据准备 网络的 刷新 得到的
freshNetworkMedalData();//这里写你自己的刷新的方法
//结束刷新 ``medal_pulltorefreshlistview.onRefreshComplete();
super.onPostExecute(result);
}
}
//刷新(支持上拉下拉刷新)
//下拉刷新和上拉加载更多
medal_pulltorefreshlistview.setOnRefreshListener(new PullToRefreshBase.OnRefreshListener2<ListView>() {
@Override
public void onPullDownToRefresh(PullToRefreshBase<ListView> refreshView) {
new RefreshGetDataTask().execute();
}
@Override
public void onPullUpToRefresh(PullToRefreshBase<ListView> refreshView) {
new LoadMoreGetDataTask().execute();
}
}
//下拉刷新方法
private class RefreshGetDataTask extends AsyncTask
// 上拉加载更多
private class LoadMoreGetDataTask extends AsyncTask<Void, Void, String[]> {
@Override
protected String[] doInBackground(Void... params) {
// Simulates a background job.
try {
Thread.sleep(500);
} catch (InterruptedException e) {
}
return null;
}
@Override
protected void onPostExecute(String[] result) {
//加载更多的方法 单独去写
networkDynamicLoadMore();
dynamic_pulltorefreshlistview.onRefreshComplete();
super.onPostExecute(result);
}
}
3.接下来介绍一下怎么改变刷新的那个高度
在PullToRefreshBase中
static final float FRICTION = 2.0f;
其中 2.0f 表示弹出框的高度为ListView 是屏幕上的可视区域高度的一半,即 screenHeight / 2,是按照一个比例来的,你可以增大这个值,设置为 5 则是 屏幕的 1/5 多一点,但不要设置太大,导致高度过低这样会影响正常的拉动时显示的提示的高度
4.现在随着RecyclerView的出现,我们接下来就来写一下关于RecyclerView的下拉刷新
/**
* @author madreain
*/
public class PullToRefreshRecyclerView extends PullToRefreshBase<RecyclerView>{
public PullToRefreshRecyclerView(Context context) {
super(context);
}
public PullToRefreshRecyclerView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public PullToRefreshRecyclerView(Context context, Mode mode) {
super(context, mode);
}
public PullToRefreshRecyclerView(Context context, Mode mode, AnimationStyle animStyle) {
super(context, mode, animStyle);
}
@Override
public Orientation getPullToRefreshScrollDirection() {
return null;
}
@Override
protected RecyclerView createRefreshableView(Context context, AttributeSet attrs) {
return null;
}
@Override
protected boolean isReadyForPullEnd() {
return false;
}
@Override
protected boolean isReadyForPullStart() {
return false;
}
/**
* @Description: 判断第一个条目是否完全可见
*
* @return boolean:
* @version 1.0
* @date 2015-9-23
* @Author zhou.wenkai
*/
private boolean isFirstItemVisible() {
final RecyclerView.Adapter<?> adapter = getRefreshableView().getAdapter();
// 如果未设置Adapter或者Adapter没有数据可以下拉刷新
if (null == adapter || adapter.getItemCount() == 0) {
if (DEBUG) {
// Log.d(LOG_TAG, "isFirstItemVisible. Empty View.");
}
return true;
} else {
// 第一个条目完全展示,可以刷新
if (getFirstVisiblePosition() == 0) {
return mRefreshableView.getChildAt(0).getTop() >= mRefreshableView
.getTop();
}
}
return false;
}
/**
* @Description: 获取第一个可见子View的位置下标
*
* @return int: 位置
* @version 1.0
* @date 2015-9-23
* @Author zhou.wenkai
*/
private int getFirstVisiblePosition() {
View firstVisibleChild = mRefreshableView.getChildAt(0);
return firstVisibleChild != null ? mRefreshableView
.getChildAdapterPosition(firstVisibleChild) : -1;
}
/**
* @Description: 判断最后一个条目是否完全可见
*
* @return boolean:
* @version 1.0
* @date 2015-9-23
* @Author zhou.wenkai
*/
private boolean isLastItemVisible() {
final RecyclerView.Adapter<?> adapter = getRefreshableView().getAdapter();
// 如果未设置Adapter或者Adapter没有数据可以上拉刷新
if (null == adapter || adapter.getItemCount() == 0) {
if (DEBUG) {
// Log.d(LOG_TAG, "isLastItemVisible. Empty View.");
}
return true;
} else {
// 最后一个条目View完全展示,可以刷新
int lastVisiblePosition = getLastVisiblePosition();
if(lastVisiblePosition >= mRefreshableView.getAdapter().getItemCount()-1) {
return mRefreshableView.getChildAt(
mRefreshableView.getChildCount() - 1).getBottom() <= mRefreshableView
.getBottom();
}
}
return false;
}
/**
* @Description: 获取最后一个可见子View的位置下标
*
* @return int: 位置
* @version 1.0
* @date 2015-9-23
* @Author zhou.wenkai
*/
private int getLastVisiblePosition() {
View lastVisibleChild = mRefreshableView.getChildAt(mRefreshableView
.getChildCount() - 1);
return lastVisibleChild != null ? mRefreshableView
.getChildAdapterPosition(lastVisibleChild) : -1;
}
}
这个是用的最多的刷新和加载更多的控件,建议多使用,多看源码分析
大家有什么Android开发问题可以一起交流(QQ:965244491 附微信二维码