刷新的行为接口RefreshOperation的代码:
代码如下:
public interface RefreshOperation {
public void OnRefreshStart();
public void OnRefreshing();
public void OnRefreshEnd();
}
列表拉下来时,箭头翻转的动画arrow_rotate.xml:
代码如下:
?xml version="1.0" encoding="utf-8"?
rotate
xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@android:anim/linear_interpolator"
android:fromDegrees="0"
android:toDegrees="180"
android:duration="300"
android:pivotX="50%"
android:pivotY="50%"
android:fillAfter="true"
android:repeatCount="0"
/rotate
这些文件和一些资源文件备齐了之后,接下来就是下拉刷新列表PushRefreshList的具体实现:
代码如下:
package com.chenzong;
import java.util.Calendar;
import com.doall.pushrefreshlist.R;
import android.content.Context;
import android.os.Handler;
import android.os.Message;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.ListView;
import android.widget.TextView;
public class PushRefreshList extends ListView implements RefreshOperation{
private int header_layout=R.layout.chenzong_push_refresh_header;
//表头文件
private int arrow_down=R.drawable.arrow_down;
//箭头往下的资源
private int arrow_up=R.drawable.arrow_up;
//箭头往上的资源
private int img=R.id.push_refresh_header_img;
//显示箭头的控件id
private int pb=R.id.push_refresh_header_pb;
//刷新时的进度条
private int startPoint=0;
//触摸的起始点
private RefreshOperation refresh;
//刷新行为的对象
private Animation animation=null;
private Context context;
private View headerView;
private int minPushHeight;
private final String TAG="pushRefresh";
public PushRefreshList(Context cotext, AttributeSet attrs) {
super(context, attrs);
View empty=new View(context);
//判断是否到列表的顶端,通常要用到this.getFirstVisiblePosition(),这里创建一个高度的为零View,加到headerView和数据之间
this.addHeaderView(empty);
LayoutInflater inflater=LayoutInflater.from(context);
headerView=inflater.inflate(header_layout, null);
this.addHeaderView(headerView);
this.setRefreshOperation(this);
this.context=context;
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
this.minPushHeight=headerView.getMeasuredHeight();
//获取下拉刷新的触发高度
super.onLayout(changed, l, t, r, b);
}
private boolean canHandleEvent(int dy)
{
return (dy0&&this.getFirstVisiblePosition()==0&&!isPbVisible());
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
int action=ev.getAction();
switch(action)
{
case MotionEvent.ACTION_DOWN:
startPoint=(int)ev.getY();
break;
case MotionEvent.ACTION_MOVE:
int dy=startPoint-(int)ev.getY();
if(canHandleEvent(dy))
{
if(animation==null)
{
if(Math.abs(this.getScrollY())=this.minPushHeight)
{
animation=AnimationUtils.loadAnimation(context, R.anim.arrow_rotate);
View mView=headerView.findViewById(img);
mView.startAnimation(animation);
this.setScrollbarFadingEnabled(true);
}
}
this.scrollTo(0,dy/2);
return true;
}
break;
case MotionEvent.ACTION_UP:
this.setScrollbarFadingEnabled(false);
if(animation!=null)
{
setImgBackgroundUp();
switchCompent(View.INVISIBLE,View.VISIBLE);
this.scrollTo(0,-minPushHeight);
PushRefreshList.this.refresh.OnRefreshStart();
new Thread(mRunnable).start();
animation=null;
}
else
this.scrollTo(0,0);
break;
}
return super.onTouchEvent(ev);
}
private Runnable mRunnable=new Runnable()
{
@Override
public void run() {
PushRefreshList.this.refresh.OnRefreshing();
mHandler.obtainMessage().sendToTarget();
}
};
private Handler mHandler=new Handler()
{
@Override
public void handleMessage(Message msg) {
PushRefreshList.this.refresh.OnRefreshEnd();
PushRefreshList.this.scrollTo(0, 0);
PushRefreshList.this.setImgBackgroundDown();
PushRefreshList.this.switchCompent(View.VISIBLE, View.GONE);
TextView tv=(TextView)headerView.findViewById(R.id.push_refresh_header_date);
tv.setText(this.getDateStr());
}
private String getDateStr()
{
Calendar ca=Calendar.getInstance();
int year=ca.get(Calendar.YEAR);
int month=ca.get(Calendar.MONTH);
int date=ca.get(Calendar.DATE);
int hour=ca.get(Calendar.HOUR);
int mintes=ca.get(Calendar.MINUTE);
int second=ca.get(Calendar.SECOND);
return year+"-"+(month+1)+"-"+date+" "+hour+":"+mintes+":"+second;
}
};
private void switchCompent(int imgStatus,int pbStatus)
{
View img=headerView.findViewById(R.id.push_refresh_header_img);
img.clearAnimation();
//执行了动画的控件如果不调用clearAnimation,setVisibility(View.GONE)会失效
img.setVisibility(imgStatus);
headerView.findViewById(R.id.push_refresh_header_pb).setVisibility(pbStatus);
}
private boolean isPbVisible()
{
return View.VISIBLE==headerView.findViewById(R.id.push_refresh_header_pb).getVisibility();
}
private void setImgBackgroundUp()
{
View mView=headerView.findViewById(this.img);
mView.setBackgroundResource(arrow_up);
}
private void setImgBackgroundDown()
{
View mView=headerView.findViewById(this.img);
mView.setBackgroundResource(arrow_down);
}
public void setRefreshOperation(RefreshOperation refresh)
{
this.refresh=refresh;
}
@Override
public void OnRefreshStart() {
}
@Override
public void OnRefreshing() {
}
@Override
public void OnRefreshEnd() {
}