android 列表实现下拉刷新,上拉加载更多

版权声明:本文为博主原创文章,如需转载请注明出处 https://blog.csdn.net/u013640004/article/details/52934671

本来想要找一个支持下拉刷新和上拉加载更多的ListView代码,但没找到满意的,大多要导入一些包,很是受不了,而且也有很多问题。

于是干脆自己写,一个类搞定,无需任何包。这里我用的是GridView,GridView和ListView一样用法,只是前者不支持设置头部和尾部,但这里可简单移植成ListView。
基本原理看图。
这里写图片描述
这整一个是一个复合组件,包含头部的下拉刷新部分,中间的GridView,和底部隐藏的上拉加载更多部分。
下拉刷新是将整一个整一个组件下移,上拉加载更多是将组件的内部空间上移,两者移动的不同点是:前者使用了setY()方法,后者使用 scrollTo()方法。
(为什么要这样?因为这样在布局上实现比较简单,或者我应该用相对布局)
———代码比较长,不一一写出,先给大家列出重点难点。
难点一:平滑的滑动与回弹,能应对各种狂刷
关于滑动,我这里使用的算法是,实时用全局变量记录当前GridView的位置,然后用nowY-firshY,得出一个增量,然后加上GridView的初始Y。

float moveHeight = (nowY-firshY)*0.7f;//0.7f为减速运动
PullRefreshGridView.this.setY((int) -(firshViewTop+moveHeight));

nowY在ACTION_MOVE事件里nowY = event.getRawY();
firshViewTop在ACTION_UP里PullRefreshGridView.this.firshViewTop = PullRefreshGridView.this.getY();
使得每次滑动都在当前位置的基础上进行。(具体视源码)

难点二:各种状态的判断,下拉中,放手回弹,加载刷新中,加载更多种等等。
直接使用各种boolean变量了,没办法。通过判断GridView的位置,来判定当前状态,下拉,拉到一定距离,变为松开刷新,松开后回到什么距离,触发下拉刷新的事件,变为正在刷新状态,等待外部调用结束刷新的函数,将状态设置为初始状态。

难点三:也是最难点,怎么精确判断GridView的Item滑到顶部了或者滑到底部了。
这里只说滑到顶部判断,底部基本相同。
结论:当0号Item到顶部的距离等于0的时候,即是滑到顶部。
这里写图片描述
/**
* 获取item到顶部的距离
* @return
*/
@SuppressLint(“NewApi”)
private int getItemTop() {
if(gv_List!=null&&gv_List.getChildCount()>0)
{
int firstVisiblePosition = gv_List.getFirstVisiblePosition() / gv_List.getNumColumns();//这里getNumColumns是gridView每行的列数。
View c = gv_List.getChildAt(0);
if (c == null) {
return 0;
}
int top = c.getTop();
return -top + firstVisiblePosition * c.getHeight() + firstVisiblePosition * gv_List.getVerticalSpacing()
+ errorTop;
//这里getVerticalSpacing是item的间距,errorTop是误差值,这个值可在初始化时计算获取,便永久不变
}
return 0;
}
接着直接判断
if(bHead&&getItemTop()<=0)//如果Item在顶部
{
if(nowViewTop>=-boxHeadHeight)//防止反方向出界
。。。。。

示例项目里面有具体的注释,就先说到这里。组件功能还不够,特别是头部和尾部,功能太少,不过可以直接在布局里添加,想要弄个好点的动画效果应该也挺容易吧。

源码下载地址:
百度云链接:http://pan.baidu.com/s/1jHIRdQm 密码:kmf5

猜你喜欢

转载自blog.csdn.net/u013640004/article/details/52934671