RefreshListView下拉刷新
1.RefreshListView继承ListView
2.在构造方法初始化头控件和相应的动画
3.在onTouchEvent中判断逻辑:
1.判断滑动方向
2.处理滑动各个状态相应的控件属性和动画
4.回调接口:
1.在正在刷新的状态时候判断接口是否为空
2.回调接口方法,通知刷新状态
5.刷新结束,更新刷新时间:
1.方法设置传入context参数
2.开启子线程睡眠模拟刷新耗时(可省略)
3.开启通过context.runOnUiThread初始化头布局
4.更新刷新时间
HeaderView效果图:
代码如下:
package com.cf.zhbj.view;
import android.app.Activity;
import android.content.Context;
import android.os.SystemClock;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.RotateAnimation;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.TextView;
import com.cf.zhbj.R;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* Created by chenfan on 2016/7/19.
*/
public class RefreshListView extends ListView {
View mHeraderView;
int mHeraderViewHeight;
private static final int STATE_PULL_TO_REFRESH=0;//下拉刷新状态
private static final int STATE_RELEASE_TO_REFRESH =1;//松开刷新
private static final int STATE_REFRESH=2;//正在刷新
private int mCurrentState=STATE_PULL_TO_REFRESH;//默认是下拉刷新状态
private TextView tvState;
private TextView tvTime;
private ImageView ivArrow;
private ProgressBar pbLoading;
private RotateAnimation animUp;
private RotateAnimation animDown;
public RefreshListView(Context context) {
this(context,null);
}
public RefreshListView(Context context, AttributeSet attrs) {
this(context, attrs,-1);
}
public RefreshListView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initHeaderView();
}
//初始化头布局
private void initHeaderView(){
mHeraderView = View.inflate(getContext(), R.layout.pull_to_refresh_header,null);
addHeaderView(mHeraderView);//给ListView添加头布局
tvState= (TextView) mHeraderView.findViewById(R.id.tv_state);
tvTime= (TextView) mHeraderView.findViewById(R.id.tv_time);
ivArrow= (ImageView) mHeraderView.findViewById(R.id.iv_arrow);
pbLoading= (ProgressBar) mHeraderView.findViewById(R.id.pb_loading);
//隐藏头布局
//获取当前头布局高度,然后设置负paddingTop,布局就会向上走
mHeraderView.measure(0,0);//手动测量,宽高传0
mHeraderViewHeight =mHeraderView.getMeasuredHeight();
//System.out.println("height"+ mHeraderViewHeight);
mHeraderView.setPadding(0,-mHeraderViewHeight,0,0);
//初始化动画
initArrowAnim();
}
private int startY=-1;
@Override
public boolean onTouchEvent(MotionEvent ev) {
switch (ev.getAction()){
case MotionEvent.ACTION_DOWN:
startY = (int)ev.getY();
break;
case MotionEvent.ACTION_MOVE:
if(startY==-1){//没有获取到按下的事件(按住头条新闻滑动时,按下ViewPager消费了)
startY= (int) ev.getY();//重新获取起点位置
}
int endY= (int) ev.getY();
int dy=endY-startY;
if(mCurrentState==STATE_REFRESH){
//如果正在刷新,什么都不做
break;
}
int firstVisiblePosition = this.getFirstVisiblePosition();//当前显示第一个Item的位置
if(dy>0&&firstVisiblePosition==0){
//下拉动作&当前在ListView的顶部
int padding=-mHeraderViewHeight+dy;
if(padding>0&&mCurrentState!=STATE_RELEASE_TO_REFRESH){
//切换到松开刷新状态
mCurrentState= STATE_RELEASE_TO_REFRESH;
refreshState();
}else if(padding<=0&&mCurrentState!=STATE_PULL_TO_REFRESH){
//切换到下拉刷新状态
mCurrentState=STATE_PULL_TO_REFRESH;
refreshState();
}
//通过修改padding来设置当前控件刷新的位置
mHeraderView.setPadding(0,padding,0,0);
return true;//消耗掉事件
}
break;
case MotionEvent.ACTION_UP://离开触摸时
startY=-1;//起始位置归0
if(mCurrentState==STATE_RELEASE_TO_REFRESH){
//切换成正在刷新
mCurrentState=STATE_REFRESH;
//回到起始位置
mHeraderView.setPadding(0,0,0,0);
refreshState();
}else if(mCurrentState==STATE_PULL_TO_REFRESH){
//隐藏刷新控件
mHeraderView.setPadding(0,-mHeraderViewHeight,0,0);
}
break;
}
return super.onTouchEvent(ev); //ListView原生滑动处理
}
private void initArrowAnim(){
//箭头向上
animUp=new RotateAnimation(0,-180, Animation.RELATIVE_TO_SELF,0.5f,
Animation.RELATIVE_TO_SELF,0.5f);
animUp.setDuration(300);
animUp.setFillAfter(true);//保持动画结束的状态
//箭头向下
animDown=new RotateAnimation(-180,0, Animation.RELATIVE_TO_SELF,0.5f,
Animation.RELATIVE_TO_SELF,0.5f);
animDown.setDuration(300);
animDown.setFillAfter(true);//保持动画结束的状态
}
private void refreshState() {
switch (mCurrentState){
case STATE_PULL_TO_REFRESH:
tvState.setText("下拉刷新");
pbLoading.setVisibility(View.INVISIBLE);
ivArrow.setVisibility(View.VISIBLE);
ivArrow.startAnimation(animDown);
break;
case STATE_RELEASE_TO_REFRESH:
tvState.setText("松开刷新");
pbLoading.setVisibility(View.INVISIBLE);
ivArrow.setVisibility(View.VISIBLE);
ivArrow.startAnimation(animUp);
break;
case STATE_REFRESH:
tvState.setText("正在刷新...");
pbLoading.setVisibility(View.VISIBLE);
ivArrow.clearAnimation();//清理掉动画才能隐藏
ivArrow.setVisibility(View.INVISIBLE);
//回调下拉刷新
if(mListener!=null){
mListener.onRefresh();
}
break;
}
}
//刷新结束,隐藏控件
public void onRefreshComplete(final Activity activity){
new Thread(){
@Override
public void run() {
SystemClock.sleep(1000);//模拟耗时
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
mHeraderView.setPadding(0,-mHeraderViewHeight,0,0);
//初始化状态
tvState.setText("下拉刷新");
pbLoading.setVisibility(View.INVISIBLE);
ivArrow.setVisibility(View.VISIBLE);
mCurrentState=STATE_PULL_TO_REFRESH;
//更新刷新时间
setRefreshTime();
}
});
}
}.start();
}
private OnRefreshListener mListener;
public void setOnRefreshListener(OnRefreshListener listener){
mListener=listener;
}
//回调接口,通知刷新状态
public interface OnRefreshListener{
//下拉刷新的回调
public void onRefresh();
}
private void setRefreshTime(){
SimpleDateFormat format=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String time = format.format(new Date());
tvTime.setText(time);
}
}