package cn.juzhong.view.widget;
import cn.juzhong.R;
import android.content.Context;
import android.graphics.Canvas;
import android.util.AttributeSet;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.view.animation.Animation;
import android.view.animation.LinearInterpolator;
import android.view.animation.RotateAnimation;
import android.widget.*;
import android.widget.AbsListView.OnScrollListener;
/**
* 拖拉ListView
* Created by dudc on 14-4-18.
*
* @author dudc
*/
public class PullListView extends ListView implements OnScrollListener,
OnClickListener {
/**
* 加载数据包
*/
public static final int LOADDATA_INDEX = 0;
/**
* 下拉刷新标识
*/
public static final int DRAG_INDEX = 1;
/**
* 加载更多标识
*/
public static final int LOADMORE_INDEX = 2;
/**
* 刷新
*/
public static final int REFRESH_INDEX = 3;
public static final int PAGEDATA_COUNT = 20;
private enum DListViewState {
LV_NORMAL,
LV_PULL_REFRESH,
LV_RELEASE_REFRESH,
LV_LOADING;
}
private enum DListViewLoadingMore {
LV_NORMAL,
LV_LOADING,
LV_OVER;
}
private View mHeadView;
private TextView mRefreshTextview;
private TextView mLastUpdateTextView;
private ImageView mArrowImageView;
private ProgressBar mHeadProgressBar;
private View mHeadHorLineView;
private int mHeadViewWidth;
private int mHeadViewHeight;
private View mFootView;
private View mLoadMoreView;
private TextView mLoadMoreTextView;
private View mLoadingView;
private View mEmptyView;
private TextView mEmptyText;
private Animation animation, reverseAnimation;
private int mFirstItemIndex = -1;
private int mLastItemIndex;
private boolean mIsRecord = false;
private int mStartY, mMoveY;
private DListViewState mlistViewState = DListViewState.LV_NORMAL;
private DListViewLoadingMore loadingMoreState = DListViewLoadingMore.LV_NORMAL;
private final static int RATIO = 2;
private boolean mBack = false;
private OnFooterRefreshListener mOnFooterRefreshListener;
private OnHeaderRefreshListener mOnHeaderRefreshListener;
private boolean isScroller = true;
private boolean isclick = true;
public PullListView(Context context) {
super(context, null);
initDragListView(context);
}
public PullListView(Context context, AttributeSet attrs) {
super(context, attrs);
initDragListView(context);
}
/**
* 初始化ListView
*/
public void initDragListView(Context context) {
/*String time = "";
initHeadView(context, time);
*/
// initLoadMoreView(context);// 初始化footer
initEmptyView(context);
setOnScrollListener(this);
}
/**
* 初始话头部
*
* @param context
* @param time
*/
public void initHeadView(Context context, String time) {
mHeadView = LayoutInflater.from(context).inflate(R.layout.activity_pull_header, null);
mArrowImageView = (ImageView) mHeadView
.findViewById(R.id.head_arrowImageView);
mArrowImageView.setMinimumWidth(60);
mHeadProgressBar = (ProgressBar) mHeadView
.findViewById(R.id.head_progressBar);
mRefreshTextview = (TextView) mHeadView
.findViewById(R.id.head_tipsTextView);
mHeadHorLineView = mHeadView
.findViewById(R.id.head_horLineView);
mLastUpdateTextView = (TextView) mHeadView
.findViewById(R.id.head_lastUpdatedTextView);
mLastUpdateTextView.setText("最近更新:" + time);
measureView(mHeadView);
mHeadViewWidth = mHeadView.getMeasuredWidth();
mHeadViewHeight = mHeadView.getMeasuredHeight();
addHeaderView(mHeadView, null, false);
mHeadView.setPadding(0, -1 * mHeadViewHeight, 0, 0);
initAnimation();// 初始化动画
}
/**
* Resets the list to a normal state after a refresh.
*
* @param lastUpdated Last updated at.
*/
public void onHeaderRefreshComplete(CharSequence lastUpdated) {
setLastUpdated(lastUpdated);
onRefreshComplete();
}
/**
* Set a text to represent when the list was last updated.
*
* @param lastUpdated Last updated at.
*/
public void setLastUpdated(CharSequence lastUpdated) {
if (lastUpdated != null) {
mLastUpdateTextView.setVisibility(View.VISIBLE);
mLastUpdateTextView.setText(lastUpdated);
} else {
mLastUpdateTextView.setVisibility(View.GONE);
}
}
/**
* 初始化底部
*/
private void initLoadMoreView(Context context) {
mFootView = LayoutInflater.from(context).inflate(R.layout.activity_pull_footer, null);
mLoadMoreView = mFootView.findViewById(R.id.load_more_view);
mLoadMoreTextView = (TextView) mFootView
.findViewById(R.id.load_more_tv);
mLoadingView = (LinearLayout) mFootView
.findViewById(R.id.loading_layout);
mLoadMoreView.setOnClickListener(this);
addFooterView(mFootView);
}
/**
* 初始化动画
*/
private void initAnimation() {
animation = new RotateAnimation(0, -180,
RotateAnimation.RELATIVE_TO_SELF, 0.5f,
RotateAnimation.RELATIVE_TO_SELF, 0.5f);
animation.setInterpolator(new LinearInterpolator());
animation.setDuration(250);
animation.setFillAfter(true);
//
reverseAnimation = new RotateAnimation(-180, 0,
RotateAnimation.RELATIVE_TO_SELF, 0.5f,
RotateAnimation.RELATIVE_TO_SELF, 0.5f);
reverseAnimation.setInterpolator(new LinearInterpolator());
reverseAnimation.setDuration(250);
reverseAnimation.setFillAfter(true);
}
/**
* headVie.
*
* @param child
*/
private void measureView(View child) {
ViewGroup.LayoutParams p = child.getLayoutParams();
if (p == null) {
p = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT);
}
int childWidthSpec = ViewGroup.getChildMeasureSpec(0, 0 + 0, p.width);
int lpHeight = p.height;
int childHeightSpec;
if (lpHeight > 0) {
childHeightSpec = MeasureSpec.makeMeasureSpec(lpHeight,
MeasureSpec.EXACTLY);
} else {
childHeightSpec = MeasureSpec.makeMeasureSpec(0,
MeasureSpec.UNSPECIFIED);
}
child.measure(childWidthSpec, childHeightSpec);
}
/**
* touch
*/
@Override
public boolean onTouchEvent(MotionEvent ev) throws NullPointerException {
float xDown = 0.0f;
float xMove;
switch (ev.getAction()) {
// 按下
case MotionEvent.ACTION_DOWN:
xDown = ev.getRawX();
isclick = true;
isCick();
doActionDown(ev);
break;
// 移动
case MotionEvent.ACTION_MOVE:
xMove = ev.getRawX();
if (xMove - xDown > 420) {
isclick = false;
}
isCick();
doActionMove(ev);
break;
// 抬起
case MotionEvent.ACTION_UP:
doActionUp(ev);
break;
default:
break;
}
if (isScroller) {
return super.onTouchEvent(ev);
} else {
return true;
}
}
/**
* 摁下操作
* <p/>
* 作用:获取摁下是的y坐标
*
* @param event
*/
void doActionDown(MotionEvent event) {
if (mIsRecord == false && mFirstItemIndex == 0) {
mStartY = (int) event.getY();
mIsRecord = true;
}
}
/**
* 拖拽移动操作
*
* @param event
*/
void doActionMove(MotionEvent event) {
mMoveY = (int) event.getY();
// 检测是否是一次touch事件.
if (mIsRecord == false && mFirstItemIndex == 0) {
mStartY = (int) event.getY();
mIsRecord = true;
}
/***
* return.
*/
if (mIsRecord == false || mlistViewState == DListViewState.LV_LOADING) {
return;
}
int offset = (mMoveY - mStartY) / RATIO;
if (mHeadView != null) {
switch (mlistViewState) {
// 普通状态
case LV_NORMAL: {
if (offset > 0) {
// 设置headView的padding属性.
mHeadView.setPadding(0, offset - mHeadViewHeight, 0, 0);
switchViewState(DListViewState.LV_PULL_REFRESH);// 下拉状态
}
}
break;
// 下拉状态
case LV_PULL_REFRESH: {
setSelection(0);// 选中第一项,可选.
mHeadView.setPadding(0, offset - mHeadViewHeight, 0, 0);
if (offset < 0) {
/***
* 要明白为什么isScroller = false;
*/
isScroller = false;
switchViewState(DListViewState.LV_NORMAL);
Log.e("jj", "isScroller=" + isScroller);
} else if (offset > mHeadViewHeight) {
switchViewState(DListViewState.LV_RELEASE_REFRESH);
}
}
break;
// 可刷新状态
case LV_RELEASE_REFRESH: {
setSelection(0);
// 设置headView的padding属性.
mHeadView.setPadding(0, offset - mHeadViewHeight, 0, 0);
if (offset >= 0 && offset <= mHeadViewHeight) {
mBack = true;
switchViewState(DListViewState.LV_PULL_REFRESH);
} else if (offset < 0) {
switchViewState(DListViewState.LV_NORMAL);
} else {
}
}
break;
default:
return;
}
;
}
}
/**
* 手势抬起操作
*
* @param event
*/
@SuppressWarnings({"static-access", "incomplete-switch"})
public void doActionUp(MotionEvent event) {
mIsRecord = false;
isScroller = true;
mBack = false;
if (mlistViewState == DListViewState.LV_LOADING) {
return;
}
// 处理相应状态.
switch (mlistViewState) {
case LV_NORMAL:
break;
case LV_PULL_REFRESH:
mHeadView.setPadding(0, -1 * mHeadViewHeight, 0, 0);
switchViewState(mlistViewState.LV_NORMAL);
break;
case LV_RELEASE_REFRESH:
mHeadView.setPadding(0, 0, 0, 0);
switchViewState(mlistViewState.LV_LOADING);
onRefresh();// 下拉刷新
break;
}
}
// 切换headview视图
private void switchViewState(DListViewState state) {
switch (state) {
// 普通状态
case LV_NORMAL: {
mArrowImageView.clearAnimation();// 清除动画
mArrowImageView.setImageResource(R.drawable.pull_arrow);
}
break;
// 下拉状态
case LV_PULL_REFRESH: {
mHeadProgressBar.setVisibility(View.GONE);// 隐藏进度条
mArrowImageView.setVisibility(View.VISIBLE);// 下拉图标
mRefreshTextview.setText("下拉刷新");
mArrowImageView.clearAnimation();// 清除动画
if (mBack) {
mBack = false;
mArrowImageView.clearAnimation();// 清除动画
mArrowImageView.startAnimation(reverseAnimation);// 启动反转动画
}
}
break;
// 松开刷新状态
case LV_RELEASE_REFRESH: {
mHeadProgressBar.setVisibility(View.GONE);// 隐藏进度条
mArrowImageView.setVisibility(View.VISIBLE);// 显示下拉图标
mRefreshTextview.setText("释放立即刷新");
mArrowImageView.clearAnimation();// 清除动画
mArrowImageView.startAnimation(animation);// 启动动画
}
break;
// 加载状态
case LV_LOADING: {
Log.e("!!!!!!!!!!!", "convert to IListViewState.LVS_LOADING");
mHeadProgressBar.setVisibility(View.VISIBLE);
mArrowImageView.clearAnimation();
mArrowImageView.setVisibility(View.GONE);
mRefreshTextview.setText("正在刷新...");
}
break;
default:
return;
}
// 切记不要忘记时时更新状态。
mlistViewState = state;
}
/**
* 下拉刷新
*/
private void onRefresh() {
if (mOnHeaderRefreshListener != null) {
mOnHeaderRefreshListener.onRefresh();
}
}
/**
* 下拉刷新完毕
*/
@SuppressWarnings("static-access")
public void onRefreshComplete() {
mHeadView.setPadding(0, -1 * mHeadViewHeight, 0, 0);// 回归.
switchViewState(mlistViewState.LV_NORMAL);//
}
/**
* 点击加载更多
*
* @param flag 数据是否已全部加载完毕
*/
public void onLoadMoreComplete(boolean flag) {
if (flag) {
updateLoadMoreViewState(DListViewLoadingMore.LV_OVER);
// removeFooterView(mFootView);
} else {
updateLoadMoreViewState(DListViewLoadingMore.LV_NORMAL);
}
}
// 更新Footview视图
private void updateLoadMoreViewState(DListViewLoadingMore state) {
if (mLoadingView != null) {
switch (state) {
// 普通状态
case LV_NORMAL:
mLoadingView.setVisibility(View.GONE);
mLoadMoreTextView.setVisibility(View.VISIBLE);
mLoadMoreTextView.setText("查看更多");
break;
// 加载中状态
case LV_LOADING:
mLoadMoreTextView.setVisibility(View.GONE);
mLoadingView.setVisibility(View.VISIBLE);
break;
// 加载完毕状态
case LV_OVER:
mLoadingView.setVisibility(View.GONE);
mLoadMoreTextView.setVisibility(View.GONE);
// mLoadMoreTextView.setVisibility(View.VISIBLE);
// mLoadMoreTextView.setText(“没有更多了”);
break;
default:
break;
}
loadingMoreState = state;
}
}
/**
* ListView 滑动监听
*/
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
int itemsLastIndex = view.getCount() - 1;
// int lastIndex = itemsLastIndex + 1;
if (scrollState == OnScrollListener.SCROLL_STATE_IDLE && mLastItemIndex == itemsLastIndex) { //自动加载,
if (mOnFooterRefreshListener != null
&& loadingMoreState == DListViewLoadingMore.LV_NORMAL) {
updateLoadMoreViewState(DListViewLoadingMore.LV_LOADING);
mOnFooterRefreshListener.onLoadMore();
}
}
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem,
int visibleItemCount, int totalItemCount) {
mFirstItemIndex = firstVisibleItem;
mLastItemIndex = firstVisibleItem + visibleItemCount - 1;
}
/**
* 点击事件
*/
@Override
public void onClick(View v) {
// 防止重复点击
if (mOnFooterRefreshListener != null
&& loadingMoreState == DListViewLoadingMore.LV_NORMAL) {
updateLoadMoreViewState(DListViewLoadingMore.LV_LOADING);
mOnFooterRefreshListener.onLoadMore();
}
}
/**
* 注入刷新接口
* @param onRefreshLoadingMoreListener
*/
/*public void setOnRefreshListener(
OnRefreshLoadingMoreListener onRefreshLoadingMoreListener) {
this.onRefreshLoadingMoreListener = onRefreshLoadingMoreListener;
}*/
/*public interface OnRefreshLoadingMoreListener {
void onRefresh();
void onLoadMore();
}*/
/**
* set headerRefreshListener
*
* @param headerRefreshListener
*/
public void setOnHeaderRefreshListener(
OnHeaderRefreshListener headerRefreshListener) {
String time = "";
initHeadView(getContext(), time);
mOnHeaderRefreshListener = headerRefreshListener;
}
/**
* set headerRefreshListener
*
* @param footerRefreshListener
*/
public void setOnFooterRefreshListener(
OnFooterRefreshListener footerRefreshListener) {
mOnFooterRefreshListener = footerRefreshListener;
initLoadMoreView(getContext());
}
/**
* Interface
*/
public interface OnFooterRefreshListener {
public void onLoadMore();
}
/**
* Interface
*/
public interface OnHeaderRefreshListener {
public void onRefresh();
}
public void addEmptyView(CharSequence charSequence) {
/*if (mEmptyView.getParent() != null) {
throw new IllegalStateException("The specified child already has a parent. " +
"You must call removeView() on the child's parent first.");
}*/
mEmptyView.setVisibility(View.GONE);
mEmptyText.setText(charSequence);
ViewGroup parent = (ViewGroup) this.getParent();
if (parent != null)
((ViewGroup) this.getParent()).addView(mEmptyView);
this.setEmptyView(mEmptyView);
}
/**
* init empty view
*
* @param context
*/
private void initEmptyView(Context context) {
// LayoutInflater inflate = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
mEmptyView = LayoutInflater.from(context).inflate(R.layout.activity_pull_empty, null);
assert mEmptyView != null;
mEmptyText = (TextView) mEmptyView.findViewById(R.id.emptyText);
}
@Override
protected void dispatchDraw(Canvas canvas) {
try {
super.dispatchDraw(canvas);
} catch (IndexOutOfBoundsException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* show headerline
*
* @param isShow
*/
public void setShowHeaderLine(boolean isShow) {
try {
if (mHeadHorLineView != null) {
if (isShow) {
mHeadHorLineView.setVisibility(VISIBLE);
} else {
mHeadHorLineView.setVisibility(GONE);
}
}
} catch (NullPointerException e) {
e.printStackTrace();
}
}
public boolean isCick() {
return isclick;
}
}
下面是xml文件foot