以前实现listView的下拉刷新和上拉加载,都是用的开源项目,现在各大应用都有一套属于自己的下拉刷新样式,于是,自己就研究了下listView如何实现下拉刷新,结果很是让我兴奋。一直以为实现它会很困难。然而,却不是那样的。主要你敢尝试,其实并不困难。有时,我们只是被自己 吓到了而已。闲话不多说。
要实现下拉刷新,我们 需要写一个header布局,来实现下拉头。listView中有两个方法,是addHeaderView()和addFooteViewr();这两个方法的出现,相信你也会有些感触。
1、实现下拉刷新
写属于自己风格的header_layout.xml,,通过addheaderView将其加入listView之中,默认header布局是不显示的,我们设置其padding让它一开始偏移到屏幕外
/**
* 设置header布局上边距
*
* @param topPadding
*/
private void topPadding(int topPadding) {
headerView.setPadding(headerView.getPaddingLeft(), topPadding,
headerView.getPaddingRight(), headerView.getPaddingBottom());
headerView.invalidate();
}
父布局它的一些参数
private void measuerView(View headerView) {
ViewGroup.LayoutParams lp = headerView.getLayoutParams();
if (lp == null) {
lp = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT);
}
int with = ViewGroup.getChildMeasureSpec(0, 0, lp.width);
int height;
int tempHeight = lp.height;
if (tempHeight > 0) {
height = MeasureSpec.makeMeasureSpec(tempHeight, MeasureSpec.EXACTLY);
} else {
height = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
}
headerView.measure(with, height);
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
if (firstVisibleItem == 0) {
isHeaderPress = true;
startY = (int) ev.getY();
}
break;
case MotionEvent.ACTION_MOVE:
onMove(ev);
break;
case MotionEvent.ACTION_UP:
if (state == RELEASE) {
state = REFRESHING;
//加载新数据
if (refreshListener != null) {
refreshListener.onRefresh();
}
} else if (state == PULL) {
state = NONE;
isHeaderPress = false;
}
refreshHeaderView();
break;
}
return super.onTouchEvent(ev);
}
private void onMove(MotionEvent ev) {
if (!isHeaderPress)
return;
int tempY = (int) ev.getY();
int offset = tempY - startY;
int topPadding = offset - headerdHeight;
switch (state) {
case NONE:
if (offset > 0)
state = PULL;
break;
case PULL:
if (offset > headerdHeight + 30 && scrollState == SCROLL_STATE_TOUCH_SCROLL)
state = RELEASE;
break;
case RELEASE:
if (offset < headerdHeight + 30) {
state = PULL;
} else if (offset <= 0) {
state = NONE;
}
break;
}
topPadding(topPadding);
//根据状态,改变界面显示
refreshHeaderView();
}
2、实现加载更多
同样自定义Footer布局,通过addFooterView,将其加入其中,判断当前item是否滚动到最后,
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
this.scrollState = scrollState;
if(!isLoading && scrollState==SCROLL_STATE_IDLE){
isLoading=true;
if(refreshListener!=null){
footLayout.setVisibility(View.VISIBLE);
//加载更多数据
refreshListener.onLoading();
}
}
}
/**
* Callback method to be invoked when the list or grid has been scrolled. This will be
* called after the scroll has completed
*
* @param view The view whose scroll state is being reported
* @param firstVisibleItem the index of the first visible cell (ignore if
* visibleItemCount == 0)
* @param visibleItemCount the number of visible cells
* @param totalItemCount the number of items in the list adaptor
*/
@Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
this.firstVisibleItem = firstVisibleItem;
this.totalItemCount=totalItemCount;
this.lastVisibleItem=firstVisibleItem+visibleItemCount;
}
;
3.实现监听回调函数
/**
* 刷新数据回调接口
*/
public interface OnRefreshListener {
/**
* 下拉加载更多数据
*/
void onRefresh();
/**
* 上拉加载更多数据
*/
void onLoading();
}
public void setOnRefreshListener(OnRefreshListener refreshListener) {
this.refreshListener = refreshListener;
}
4.通知listView,数据已经加载完成,做相应布局的隐藏
/**
* 下拉获取完数据
*/
public void refreshComplete() {
state = NONE;
isHeaderPress = false;
refreshHeaderView();
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
lastTime.setText(format.format(new Date()));
}
/**
* 加载更多数据完成
*/
public void loadComplete(){
isLoading=false;
footLayout.setVisibility(View.GONE);
}
图片就不发放了,想看效果的下面有
5、源码下载地址 :http://download.csdn.net/user/qq_21840193 点击打开链接