public class RefreshListView extends ListView {
private ImageView iv_red_arrow;
private ProgressBar pb_status;
private TextView tv_status;
private TextView tv_time;
/**
* 整个header(下拉刷新控件和顶部轮播图)
*/
private LinearLayout headerView;
/**
* 下拉刷新控件
*/
private View ll_pull_dwon;
private int headViewHeight;
private View topNewsView; //顶部轮播图
private int listViewOnScreemY=-1; //listview在Y轴的坐标
/**
* 下拉刷新状态
**/
private static final int PULL_DOWN_REFRESH = 1;
/**
* 手松刷新状态
**/
private static final int RELEASE_REFRESH = 2;
/**
* 正在刷新状态
**/
private static final int REFRESHING = 3;
/**
* 当前状态
*/
private int currentState = PULL_DOWN_REFRESH;
private Animation upAnimation,downAnimation;
private View footView;
private int footViewHight;
private boolean isLoadMore=false;
public RefreshListView(Context context) {
this(context,null);
}
public RefreshListView(Context context, AttributeSet attrs) {
this(context, attrs,0);
}
public RefreshListView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initHeaderView(context);
initAnimation();
initFooterView(context);
setOnScrollListener(new MyOnScrollListener());
}
class MyOnScrollListener implements OnScrollListener{
@Override
public void onScrollStateChanged(AbsListView absListView, int i) {
//静止或者滚动
if (i == OnScrollListener.SCROLL_STATE_IDLE || i == OnScrollListener.SCROLL_STATE_TOUCH_SCROLL) {
if (getLastVisiblePosition() == getAdapter().getCount() - 1) {
footView.setPadding(10,10,10,10);
isLoadMore=true;
if (mOnRefreshLisener != null) {
mOnRefreshLisener.onLoadMore();
}
}
}
}
@Override
public void onScroll(AbsListView absListView, int i, int i1, int i2) {
}
}
private void initFooterView(Context context) {
footView = View.inflate(context, R.layout.refresh_footer, null);
footView.measure(0,0);
footViewHight=footView.getMeasuredHeight();
footView.setPadding(0,-footViewHight,0,0);
RefreshListView.this.addFooterView(footView);
}
private void initAnimation() {
upAnimation=new RotateAnimation(0,-180,Animation.RELATIVE_TO_SELF,0.5f,Animation.RELATIVE_TO_SELF,0.5f);
upAnimation.setDuration(500);
upAnimation.setFillAfter(true);
downAnimation=new RotateAnimation(-180,-360,Animation.RELATIVE_TO_SELF,0.5f,Animation.RELATIVE_TO_SELF,0.5f);
downAnimation.setDuration(500);
downAnimation.setFillAfter(true);
}
private void initHeaderView(Context context) {
headerView= (LinearLayout) View.inflate(context, R.layout.header_view,null);
ll_pull_dwon = headerView.findViewById(R.id.ll_pull_donw);
iv_red_arrow = (ImageView) headerView.findViewById(R.id.iv_red_arrow);
pb_status = (ProgressBar) headerView.findViewById(R.id.pb_status);
tv_status = (TextView) headerView.findViewById(R.id.tv_status);
tv_time = (TextView) headerView.findViewById(R.id.tv_time);
ll_pull_dwon.measure(0,0);
headViewHeight=ll_pull_dwon.getMeasuredHeight();
ll_pull_dwon.setPadding(0,-headViewHeight,0,0);
RefreshListView.this.addHeaderView(headerView);
}
float startY=0;
@Override
public boolean onTouchEvent(MotionEvent ev) {
switch (ev.getAction()){
case MotionEvent.ACTION_DOWN:
startY = ev.getY();
break;
case MotionEvent.ACTION_MOVE:
if (startY==0){
startY = ev.getY();
}
//判断是下拉还是上拉
Boolean isDisplayTopNews=isTopNewsDisplay();
if (!isDisplayTopNews){ //不是完全显示,则不需处理下拉刷新逻辑
break;
}
float endY=ev.getY();
float distanceY=endY-startY;
if (distanceY>0){
int paddingTop= (int) (-headViewHeight+distanceY);
if (paddingTop < 0 && currentState != PULL_DOWN_REFRESH) {
//下拉刷新
currentState = PULL_DOWN_REFRESH;
refreshStatus();
//更新状态
} else if (paddingTop > 0 && currentState != RELEASE_REFRESH) {
//手势刷新
currentState = RELEASE_REFRESH;
//更新状态
refreshStatus();
}
ll_pull_dwon.setPadding(0,paddingTop,0,0);
}
break;
case MotionEvent.ACTION_UP:
startY=0;
if (currentState == PULL_DOWN_REFRESH) {
//View.setPadding(0,-控件高,0,0);//完成隐藏
ll_pull_dwon.setPadding(0, -headViewHeight, 0, 0);
} else if (currentState == RELEASE_REFRESH) {
currentState = REFRESHING;
//View.setPadding(0,0,0,0);//完成显示
ll_pull_dwon.setPadding(0, 0, 0, 0);
//状态要更新
refreshStatus();
if (mOnRefreshLisener!=null){
mOnRefreshLisener.pullDownRefresh();
}
}
break;
default:
break;
}
return super.onTouchEvent(ev);
}
private void refreshStatus() {
switch (currentState){
case PULL_DOWN_REFRESH:
tv_status.setText("下拉刷新...");
iv_red_arrow.startAnimation(downAnimation);
break;
case RELEASE_REFRESH:
tv_status.setText("手松刷新...");
iv_red_arrow.startAnimation(upAnimation);
break;
case REFRESHING:
tv_status.setText("正在刷新...");
pb_status.setVisibility(VISIBLE);
iv_red_arrow.setVisibility(GONE);
iv_red_arrow.clearAnimation();
break;
}
}
/**
* 判断顶部轮播图是否完全显示
* @return
*/
private Boolean isTopNewsDisplay() {
if (topNewsView != null) {
int[] location=new int[2];
if (listViewOnScreemY==-1){
this.getLocationOnScreen(location);
listViewOnScreemY=location[1];
}
topNewsView.getLocationOnScreen(location);
int topNewsViewOnScreemY=location[1];
if (topNewsViewOnScreemY>=listViewOnScreemY){
return true;
}else{
return false;
}
}else{
return true;
}
}
public void addTopNewView(View topNewsView) {
if (topNewsView!=null&&headerView!=null){
this.topNewsView=topNewsView;
headerView.addView(topNewsView); //代码添加顶部轮播图
}
}
public void onRefreshFinish(boolean success) {
if(isLoadMore){
//加载更多
isLoadMore = false;
footView.setPadding(0,-footViewHight,0,0);
}else{
//下拉刷新
iv_red_arrow.clearAnimation();
iv_red_arrow.setVisibility(VISIBLE);
pb_status.setVisibility(GONE);
tv_status.setText("下拉刷新...");
ll_pull_dwon.setPadding(0, -headViewHeight, 0, 0);
currentState = PULL_DOWN_REFRESH;
if (success) {
//更新时间
tv_time.setText("更新时间:" + getSystemTime());
}
}
}
private String getSystemTime() {
SimpleDateFormat format=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
return format.format(new Date());
}
/**
* 视图刷新监听接口
*/
public interface onRefreshLisener{
public void pullDownRefresh(); //调用接口时执行此方法
public void onLoadMore();
}
private onRefreshLisener mOnRefreshLisener;
/**
* 添加视图刷新的监听
* by ppa
* @param lisener
*/
public void setmOnRefreshLisener(onRefreshLisener lisener){
this.mOnRefreshLisener=lisener;
}
}
自定义下拉刷新
1.自定义一个类RefreshListView继承ListView,重写构造方法 在构造方法里面初始化下拉刷新的布局
2.写下拉刷新的布局refresh_header.xml 自定义ProgressBar,把控件初始化
3.实现手指移动下拉刷新控件 下拉刷新控件隐藏和显示的原理 View.setPadding(0,-控件高,0,0);//完成隐藏 View.setPadding(0,0,0,0);//完成显示 View.setPadding(0,控件高,0,0);//两倍完全显示
4.重写控件的onTouchEvent() a,在down的时候记录起始坐标 startY
b,在move float endY ;
float distanceY = endY - startY; if(distanceY >0){
int paddingTop = - 控件的高 + distanceY;
View.setPadding(0,paddingTop,0,0)//动态显示下拉刷新控件
}
c,在up的时候,要重新赋值startY = 0;
5.解决下拉刷新的bug,判断顶部轮播图是否完全显示 如何判断顶部轮播图是否完全显示呢 当ListView在Y轴的坐标小于或者等于顶部轮播图部分在Y轴的坐标的时候
6.下拉刷新状态和动画
/* 下拉刷新状态 */ private static final int pull_down_refresh = 1;
/* 手松刷新状态 */ private static final int release_refresh = 2;
/**
正在刷新状态 **/ private static final int refreshing = 3;
private int currentState = pull_down_refresh;
在move float endY ;
float distanceY = endY - startY; if(distanceY >0){
int paddingTop = - 控件的高 + distanceY;
if(paddingTop < 0 && currentState != pull_down_refresh){
//下拉刷新
currentState = pull_down_refresh;
//更新状态
}else if(paddingTop >0 && currentState != release_refresh){
//手势刷新
currentState = release_refresh;
//更新状态
}
View.setPadding(0,paddingTop,0,0)//动态显示下拉刷新控件
}
在up
if(currentState == pull_down_refresh){ //View.setPadding(0,-控件高,0,0);//完成隐藏 }else if(currentState ==release_refresh){
currentState = refreshing;
//状态要更新
//View.setPadding(0,0,0,0);//完成显示
//回调接口
}
7.定义下拉刷新接口
/**
监听视图刷新监听者 / public interface OnRefreshListener{ / 当下拉刷新的时候回调这个方法 */ public void onPullDownlRefresh(); }
private OnRefreshListener mOnRefreshListener;
/* 设置视图刷新的监听 / public void setOnRefreshListener(OnRefreshListener l){ this.mOnRefreshListener = l; }
在up
if(currentState == pull_down_refresh){ //View.setPadding(0,-控件高,0,0);//完成隐藏 }else if(currentState ==release_refresh){
currentState = refreshing;
//状态要更新
//View.setPadding(0,0,0,0);//完成显示
//回调接口
if(mOnRefreshListener != null){
mOnRefreshListener.onPullDownlRefresh();
}
}
上拉刷新(加载更多)
1.在构造方法中初始化
2.监听ListVivew滑到最后一条
3.写加载更多的接口方法
/**
监听视图刷新监听者 / public interface OnRefreshListener{ / 当下拉刷新的时候回调这个方法 */ public void onPullDownlRefresh();
/**
当加载更多的时候回调这方法
*/
public void onLoadMore();
}
4.调用接口 //回调接口 if(mOnRefreshListener != null){ mOnRefreshListener.onLoadMore(); }
5.在TabDetailPager,对接口实现,加载更多