自定义下拉刷新和上拉加载ListView,修改原代码,可以随意指定自己想要的动画
自定义的ListView
package com.pandacredit.administrator.customview;
import android.content.Context;
import android.os.Handler;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.LinearInterpolator;
import android.view.animation.RotateAnimation;
import android.widget.AbsListView;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.TextView;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* Created by Administrator on 2016/11/6.
*/
public class PullToRefreshView extends ListView {
/**
* 头部文件的高度
*/
private int topHeight;
/**
* 底部文件的高度
*/
private int rootHeight;
/**
* 下拉等待刷新状态
*/
private static final int STATE_DRAW_DOWN = 0;
/**
* 正在刷新状态
*/
private static final int STATE_REFRESHING = 1;
/**
* 空闲状态
*/
private static final int STATE_FREE = 3;
/**
* 释放刷新
*/
private static final int STATE_TO_REFRESH = 4;
/**
* 记录当前状态,默认未空闲状态
*/
private int state = STATE_FREE;
/**
* 刷新条最大高的
*/
private int maxHeight ;
private Context context;
/**
* 手按下去的y轴坐标
*/
private int startPosition = 0;
/**
* 最新的手的y轴坐标
*/
private int lastPositon =0;
/**
* 最小移动距离为10
*/
private int minDistance = 10;
/**
* LinearLayout:头部文件
*/
private LinearLayout llHander;
/**
* 下拉刷新状态
*/
private LinearLayout llDrawDown;
/**
* 准备刷新状态
*/
private LinearLayout llToRefresh;
/**
* 正在刷新状态
*/
private LinearLayout llRefreshing;
/**
* 刷新完成状态
*/
private LinearLayout llRefreshed;
/**
* 显示正在刷新的进度条
*/
private ImageView ivProgress;
/**
* 记录上次刷新的时间
*/
private TextView tvTime;
/**
* LinearLayout:头部跟节点
*/
private LinearLayout rlRoot;
/**
* int :刷新条的高度
*/
private int marginTop;
/**
* 记录上次刷新的时间
*/
private long lastTime = 0;
/**
* 旋转动画
*/
private RotateAnimation rotate;
private Handler handler;
/**
* LinearLayout:底部的view(跟节点)
*/
private LinearLayout llRoot;
/**
* LinearLayout:底部的view
*/
private LinearLayout llRootView;
private ImageView ivProgressRoot;
public PullToRefreshView(Context context) {
super(context);
inits(context);
}
public PullToRefreshView(Context context, AttributeSet attrs) {
super(context, attrs);
inits(context);
}
public PullToRefreshView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
inits(context);
}
/**
* 初始化
* @param context
*/
private void inits(Context context) {
this.context = context;
handler = new Handler();
maxHeight = DisplayUtil.dip2px(context,60);
rlRoot = (LinearLayout) View.inflate(context,R.layout.header_listview,null);
// getHeight()要求控件显示出来,height=0
// height=headerView.getHeight();
// 控件没显示出来,得高度必须用getMeasuredHeight
// 用getMeasuredHeight必须先调用measure()
// 0是一种测量方式,不指定大小,相当于match_parent
rlRoot.measure(0, 0);
// Measure 测量
topHeight = rlRoot.getMeasuredHeight();
addHeaderView(rlRoot);
llRoot = (LinearLayout) View.inflate(context,R.layout.footer_listview,null);
llRoot.measure(0,0);
rootHeight = llRoot.getMeasuredHeight();
addFooterView(llRoot);
llRootView = (LinearLayout) llRoot.findViewById(R.id.ll_root_view);
ivProgressRoot = (ImageView) llRoot.findViewById(R.id.iv_progress_loading);
llHander = (LinearLayout) rlRoot.findViewById(R.id.ll_hander);
llDrawDown = (LinearLayout) rlRoot.findViewById(R.id.ll_state_draw_down);
llRefreshed = (LinearLayout) rlRoot.findViewById(R.id.ll_state_refreshed);
llRefreshing = (LinearLayout) rlRoot.findViewById(R.id.ll_state_refreshing);
llToRefresh = (LinearLayout) rlRoot.findViewById(R.id.ll_state_to_refresh);
ivProgress = (ImageView) rlRoot.findViewById(R.id.iv_progress_refreshing);
tvTime = (TextView) rlRoot.findViewById(R.id.tv_last_time_refresh);
//初始化头部文件
resetState();
setRotateAnimation();
llRootView.setVisibility(GONE);
}
/**
* 初始化动画
*/
private void setRotateAnimation() {
rotate = new RotateAnimation(0f,360f, Animation.RELATIVE_TO_SELF,
0.5f,Animation.RELATIVE_TO_SELF,0.5f);
//无限循环
rotate.setRepeatCount(-1);
rotate.setDuration(5000);
//匀速旋转
rotate.setInterpolator(new LinearInterpolator());
}
/**
* 重置头部文件
*/
private void resetHander() {
marginTop = 0-topHeight;
setHanderHeight();
}
/**
* 设置头部文件的高度
*/
private void setHanderHeight(){
llHander.setPadding(DisplayUtil.dip2px(context,16),marginTop,DisplayUtil.dip2px(context,16),0);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()){
case MotionEvent.ACTION_DOWN:
if(state==STATE_FREE){
state = STATE_DRAW_DOWN;
this.startPosition = (int)event. getY();
}
break;
case MotionEvent.ACTION_UP:
if(state == STATE_TO_REFRESH){
refresh();
}else if (state==STATE_DRAW_DOWN){
resetState();
}
break;
case MotionEvent.ACTION_MOVE:
//下拉刷新状态
if(state==STATE_DRAW_DOWN){
lastPositon = (int) event.getY();
drawDown();
}
break;
}
return super.onTouchEvent(event);
}
/**
* 刷新数据
*/
private void refresh() {
state =STATE_REFRESHING;
marginTop = 0;
llRefreshing.setVisibility(VISIBLE);
llToRefresh.setVisibility(GONE);
//开启动画
if(rotate==null){
setRotateAnimation();
}
ivProgress.startAnimation(rotate);
onRefreshListener.onRefresh();
}
/**
* 在下拉的过程
*/
private void drawDown() {
int move = lastPositon-startPosition;
if(move>=minDistance && marginTop<=maxHeight+DisplayUtil.dip2px(context,2)){
marginTop = move-topHeight;
setHanderHeight();
}
if(marginTop>=maxHeight){
//准备刷新状态
state = STATE_TO_REFRESH;
llToRefresh.setVisibility(VISIBLE);
llDrawDown.setVisibility(GONE);
}
}
/**
* 刷新完成,重置
*/
private void resetState() {
state = STATE_FREE;
llRefreshing.setVisibility(GONE);
llDrawDown.setVisibility(VISIBLE);
llHander.setVisibility(VISIBLE);
llRefreshing.setVisibility(GONE);
llRefreshed.setVisibility(GONE);
if(lastTime==0){
tvTime.setVisibility(GONE);
}else {
tvTime.setVisibility(VISIBLE);
tvTime.setText("最后一次刷新:"+dateFromat());
}
marginTop = -topHeight;
startPosition = 0;
lastPositon = 0;
resetHander();
}
/**
* 日期格式化
* @return
*/
private String dateFromat(){
Date date = new Date(lastTime);
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm");
return format.format(date);
}
/**
* 实现刷新过程的回调接口
*/
private OnRefreshListener onRefreshListener;
public void setOnRefreshListener(OnRefreshListener onRefreshListener){
this.onRefreshListener = onRefreshListener;
}
public interface OnRefreshListener{
public void onRefresh();
}
/**
* 刷新完成调用
*/
public void onRefreshComplete(){
lastTime = System.currentTimeMillis();
tvTime.setText("最后一次刷新:"+dateFromat());
llRefreshed.setVisibility(VISIBLE);
llRefreshing.setVisibility(GONE);
//取消动画
if(rotate!=null){
rotate.cancel();
}
handler.postDelayed(new Runnable() {
@Override
public void run() {
//刷新完成,重置
resetState();
}
},1000);
}
/**
* 上拉加载数据,显示加载进度条
*/
public void onLoadingData(){
llRootView.setVisibility(VISIBLE);
setRotateAnimation();
ivProgressRoot.startAnimation(rotate);
}
/**
* 上拉加载数据完成,隐藏加载进度条
*/
public void onLoadedData(){
llRootView.setVisibility(GONE);
rotate.cancel();
}
}
头部文件的布局
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:background="#fefefe"
android:orientation="vertical"
android:layout_height="wrap_content">
<LinearLayout
android:id="@+id/ll_hander"
android:layout_width="match_parent"
android:gravity="center_horizontal"
android:orientation="vertical"
android:layout_height="wrap_content">
<LinearLayout
android:id="@+id/ll_state_draw_down"
android:layout_width="wrap_content"
android:orientation="horizontal"
android:gravity="center_vertical"
android:layout_height="wrap_content">
<ImageView
android:src="@mipmap/ic_loading_jt_1"
android:layout_width="30dp"
android:scaleType="fitXY"
android:layout_height="30dp" />
<TextView
android:layout_marginLeft="8dp"
android:layout_width="wrap_content"
android:textColor="#a1a1a1"
android:textSize="12dp"
android:text="下拉刷新"
android:layout_height="wrap_content" />
</LinearLayout>
<LinearLayout
android:visibility="gone"
android:id="@+id/ll_state_to_refresh"
android:layout_width="wrap_content"
android:orientation="horizontal"
android:gravity="center_vertical"
android:layout_height="wrap_content">
<ImageView
android:src="@mipmap/ic_loading_jt"
android:layout_width="30dp"
android:scaleType="fitXY"
android:layout_height="30dp" />
<TextView
android:layout_marginLeft="8dp"
android:layout_width="wrap_content"
android:textColor="#a1a1a1"
android:textSize="12dp"
android:text="释放立即刷新"
android:layout_height="wrap_content" />
</LinearLayout>
<LinearLayout
android:visibility="gone"
android:id="@+id/ll_state_refreshing"
android:layout_width="wrap_content"
android:orientation="horizontal"
android:gravity="center_vertical"
android:layout_height="wrap_content">
<ImageView
android:id="@+id/iv_progress_refreshing"
android:src="@mipmap/ic_loading_01"
android:layout_width="24dp"
android:scaleType="centerInside"
android:layout_height="24dp" />
<TextView
android:layout_marginLeft="8dp"
android:layout_width="wrap_content"
android:textColor="#a1a1a1"
android:textSize="12dp"
android:text="正在刷新中"
android:layout_height="wrap_content" />
</LinearLayout>
<LinearLayout
android:visibility="gone"
android:id="@+id/ll_state_refreshed"
android:layout_width="wrap_content"
android:orientation="horizontal"
android:gravity="center_vertical"
android:layout_height="wrap_content">
<ImageView
android:src="@mipmap/ic_loading_ok"
android:layout_width="20dp"
android:scaleType="centerInside"
android:layout_height="20dp" />
<TextView
android:layout_marginLeft="8dp"
android:layout_width="wrap_content"
android:textColor="#a1a1a1"
android:textSize="12dp"
android:text="刷新成功"
android:layout_height="wrap_content" />
</LinearLayout>
<TextView
android:id="@+id/tv_last_time_refresh"
android:layout_marginTop="6dp"
android:layout_width="wrap_content"
android:textSize="10sp"
android:textColor="#a1a1a1"
android:text="上次刷新:2016.06.08 06:58"
android:paddingBottom="16dp"
android:layout_height="wrap_content" />
</LinearLayout>
</LinearLayout>
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:gravity="center"
android:orientation="vertical"
android:background="#efefef"
android:layout_height="wrap_content">
<LinearLayout
android:id="@+id/ll_root_view"
android:layout_width="match_parent"
android:gravity="center"
android:orientation="horizontal"
android:layout_height="50dp">
<ImageView
android:id="@+id/iv_progress_loading"
android:layout_width="26dp"
android:scaleType="centerInside"
android:src="@mipmap/ic_loading_02"
android:layout_height="26dp" />
<TextView
android:layout_width="wrap_content"
android:textSize="14sp"
android:layout_marginLeft="10dp"
android:text="加载....."
android:textColor="#a1a1a1"
android:layout_height="wrap_content" />
</LinearLayout>
</LinearLayout>