ListView下拉刷新,加载更多
近期做一个小项目,需要实现下拉刷新,滑动加载更多的功能,所以自己研究了很多牛人的demo,自己写了一个,直接使用自定义的ListView就可以实现。具体如下
(大多自己定义的都有注释)。
package com.android.widget.pulltorefresh;
import android.content.Context;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.RotateAnimation;
import android.widget.AbsListView;
import android.widget.AbsListView.OnScrollListener;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.TextView;
import com.android.iuhelp.activity.R;
/**
* @author Johnson
* @Description 添加了下拉刷新的listview
*/
public class HkxListView extends ListView implements OnScrollListener {
private Context context;
private View headView;// 下拉头header
private View footView;// 底部footer
private int headHeight;// 顶部布局文件的高度
private int firstVisibleItem;// 第一个可见item的位置
private boolean is_top;// 记录是否在最顶端
private float begin_y;// 开始y轴坐标的记录值
private int scrollstate;// 记录滚动状态
// private BaseAdapter adapter;//*****************
private int status;// 当前的状态
final int NORMAL = 0;// 正常状态
final int PULL = 1;// 下拉状态、下拉可刷新
final int RELEASE = 2;// 放开提示状态、松开刷新
final int LOADING = 3;// 加载状态、加载中
public boolean isLoading = false;// 判断是否正在加载,避免多次加载
private int space;// 滑动的距离
private RefreshListener refresh;// 回调的更新接口
private int visibleLastIndex = 0; // 10个数据后加载footer
public HkxListView(Context context) {
super(context);
this.context = context;
initView(context);
}
public HkxListView(Context context, AttributeSet attrs) {
super(context, attrs);
this.context = context;
initView(context);
}
/**
* 初始化界面,添加顶部布局文件
*
* @param context
*/
public void initView(Context context) {
LayoutInflater inflater = LayoutInflater.from(context);
headView = inflater.inflate(R.layout.hkxlistview_header, null);
footView = inflater.inflate(R.layout.hkxlistview_footer, null);
measureView(headView);
headHeight = headView.getMeasuredHeight();
topPadding(-headHeight);
this.addHeaderView(headView);
// this.addFooterView(footView);
this.setOnScrollListener(this);
}
/**
* 通过设置上边距来隐藏header
*
* @param topPadding
*/
public void topPadding(int topPadding) {
headView.setPadding(headView.getPaddingLeft(), topPadding,
headView.getPaddingRight(), headView.getPaddingBottom());
headView.invalidate();
}
/**
* 通知父布局子布局的大小
*
* @param view
*/
public void measureView(View view) {
ViewGroup.LayoutParams p = view.getLayoutParams();
if (p == null) {
p = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT);
}
int width = ViewGroup.getChildMeasureSpec(0, 0, p.width);
int height;
int tempheight = p.height;
if (tempheight > 0) {
height = MeasureSpec.makeMeasureSpec(tempheight,
MeasureSpec.EXACTLY);
} else {
height = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
}
view.measure(width, height);
}
@Override
public void onScroll(AbsListView arg0, int firstVisibleItem,
int visibleItemCount, int totalItemCount) {
this.firstVisibleItem = firstVisibleItem;
visibleLastIndex = visibleItemCount;
}
@Override
public void onScrollStateChanged(AbsListView view, int scrollstate) {
this.scrollstate = scrollstate;
// 当可见item大于2个时,显示底文件footer
if (space < -25 && visibleLastIndex > 2 && !isLoading) {
isLoading = true;
haveFooter(true);
// 上滑动加载更多
refresh.onLoadMore();
} else if (space < -25 && !isLoading) {
isLoading= true;
// 上滑动加载更多
refresh.onLoadMore();
}
}
/**
* 添加或删除footView
*/
public void haveFooter(boolean f) {
if (f == true) {
addFooterView(footView);
} else {
removeFooterView(footView);
}
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
if (firstVisibleItem == 0) {
is_top = true;
begin_y = (int) ev.getY();
}
break;
case MotionEvent.ACTION_MOVE:
onMove(ev);
break;
case MotionEvent.ACTION_UP:
if (status == RELEASE) {
status = LOADING;
reflashViewByStatus();
// 下拉刷新数据;
refresh.onRefresh();
} else if (status == PULL) {
status = NORMAL;
is_top = false;
reflashViewByStatus();
}
break;
}
return super.onTouchEvent(ev);
}
/**
*
* 内部封装一个方式,移动中的过程操作
*
* @param ev
*/
private void onMove(MotionEvent ev) {
if (!is_top) {
return;
}
int tempY = (int) ev.getY();
// 手势滑动和真实滑动1:3的距离
space = (int) (tempY - begin_y) * 2/5;
int topPadding = (space - headHeight);
switch (status) {
case NORMAL:
if (space > 0) {
status = PULL;
reflashViewByStatus();
}
break;
case PULL:
topPadding(topPadding);
if (space > headHeight + 35) {
status = RELEASE;
reflashViewByStatus();
}
break;
case RELEASE:
topPadding(topPadding);
if (space < headHeight + 35) {
status = PULL;
reflashViewByStatus();
} else if (space <= 0) {
status = NORMAL;
is_top = false;
reflashViewByStatus();
}
break;
}
}
/**
* 根据当前状态改变界面显示
*
*/
private void reflashViewByStatus() {
TextView tip = (TextView) headView
.findViewById(R.id.mainfragment_listview_head_text);
ImageView arrow = (ImageView) headView
.findViewById(R.id.mainfragment_listview_head_arrowimage);
ProgressBar progress = (ProgressBar) headView
.findViewById(R.id.mainfragment_listview_head_progressbar);
RotateAnimation anim = new RotateAnimation(0, 180,
RotateAnimation.RELATIVE_TO_SELF, 0.5f,
RotateAnimation.RELATIVE_TO_SELF, 0.5f);
anim.setDuration(300);
anim.setFillAfter(true);
switch (status) {
case NORMAL:
arrow.clearAnimation();
topPadding(-headHeight);
break;
case PULL:
arrow.setVisibility(View.VISIBLE);
progress.setVisibility(View.GONE);
arrow.clearAnimation();
tip.setText("下拉刷新");
break;
case RELEASE:
arrow.setVisibility(View.VISIBLE);
progress.setVisibility(View.GONE);
tip.setText("松开刷新");
arrow.clearAnimation();
arrow.setAnimation(anim);
break;
case LOADING:
topPadding(50);
arrow.setVisibility(View.GONE);
progress.setVisibility(View.VISIBLE);
tip.setText("加载中...");
arrow.clearAnimation();
break;
}
}
/**
* 刷新完成
*/
public void refreshFinish() {
is_top = false;
status = NORMAL;
reflashViewByStatus();
}
public void setInterface(RefreshListener refresh) {
this.refresh = refresh;
}
/**
* @author Johnson
* @Description 定义一个回调接口,用来加载更多和更新
*/
public interface RefreshListener {
public void onRefresh();// 刷新的方法
public void onLoadMore();// 加载更多的方法
}
}
在项目中直接调用HkxListView 就能实现这个功能,还有不足多多指教。