Activity定义使用的相关的属性:
/** 活动精选距离屏幕的坐标 */
private int[] locationActive = new int[2];
/** title标题距离屏幕的坐标 */
private int locationTitleY;
/** 是否手指向上滑动(startY>MoveY) */
private boolean isMoveUp;
/** 是否执行title显示或隐藏动画 */
private boolean isRunAnim;
/** 是否显示 */
private boolean isTitleShow;
/** title的高度 */
int titleHeight;
int[] locationTitle = new int[2];
rlActTitleParent.getLocationOnScreen(locationTitle);
titleHeight = getResources().getDimensionPixelSize(R.dimen.home_title_height);
locationTitleY = locationTitle[1] + titleHeight;
lvWelfare.setOnMoveListener(new OnMoveListener() {
@Override
public void onMoveList(Boolean isShow) {// 滑动显示隐藏title
isMoveUp = isShow;
showTitle();
}
});
lvWelfare.setOnScrollListenerExtra(new OnScrollListener() {
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {// 这个方法只有松开手才会执行
if (scrollState == SCROLL_STATE_IDLE) {// setOnMoveListener OnScrollListener结合滑动显示隐藏title
showTitle();
}
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
}
});
/***
*
* @description 显示title
* @author zhongwr
* @params
* @update 2016年1月28日 下午5:56:35
*/
private void showTitle() {
if (isRunAnim) {
return;
}
rlActiveTitleParent.getLocationOnScreen(locationActive);
if (isMoveUp) {// 手指向下滑动(starty locationTitleY) {
if (!isTitleShow) {
isTitleShow = true;
rlActTitleParent.setVisibility(View.VISIBLE);
setShowTitleAnimator(true);
}
}
} else {// 手指向上滑动:starty>MoveY
if (locationActive[1] <= locationTitleY) {
if (isTitleShow) {
isTitleShow = false;
// rlActTitleParent.setVisibility(View.GONE);
setShowTitleAnimator(false);
}
}
}
}
/**
*
* @description 设置动画
* @author zhongwr
* @params
* @update 2016年1月28日 下午6:00:45
*/
private void setShowTitleAnimator(final boolean isShow) {
ValueAnimator animator;
if (isShow) {// 显示
animator = ValueAnimator.ofFloat(-titleHeight, 0).setDuration(200);
} else {// 隐藏
animator = ValueAnimator.ofFloat(0, -titleHeight).setDuration(200);
}
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
float translationY = (Float) animation.getAnimatedValue();
// 设置控件rlActTitleParent沿Y移动动画,移动位置是translationY
ViewHelper.setTranslationY(rlActTitleParent, translationY);
}
});
animator.addListener(new AnimatorListener() {
@Override
public void onAnimationStart(Animator arg0) {
isRunAnim = true;
}
@Override
public void onAnimationRepeat(Animator arg0) {
}
@Override
public void onAnimationEnd(Animator arg0) {
isRunAnim = false;
if (!isShow) {
rlActTitleParent.setVisibility(View.GONE);
}
}
@Override
public void onAnimationCancel(Animator arg0) {
isRunAnim = false;
}
});
animator.start();
}
public class PullToRefreshListView extends ListView implements OnScrollListener {
private static final String TAG = "ElasticScrollView";
private final static int RELEASE_To_REFRESH = 0;
private final static int PULL_To_REFRESH = 1;
private final static int REFRESHING = 2;
private final static int DONE = 3;
private final static int LOADING = 4;
// 实际的padding的距离与界面上偏移距离的比例
private final static int RATIO = 3;
private int headContentWidth;
private int headContentHeight;
private LinearLayout innerLayout;
private LinearLayout headView;
private ProgressBar arrowImageView;
private ProgressBar progressBar;
private TextView tipsTextview;
private TextView lastUpdatedTextView;
private OnRefreshListener refreshListener;
private OnMoveListener mOnMoveListener;
private OnScrollStateChangedListener mScrollStateChangedListener;
private boolean isRefreshable;
private int state;
private boolean isBack;
// private RotateAnimation animation;
// private RotateAnimation reverseAnimation;
private boolean canReturn;
private boolean isRecored;
private int startY;
private String down_str = "下拉刷新";
private String release_str = "松开刷新";
private OnPullUpListener pullUpListener;
private Context mContext;
public PullToRefreshListView(Context context) {
super(context);
init(context);
}
public PullToRefreshListView(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
}
private void init(Context context) {
mContext = context;
LayoutInflater inflater = LayoutInflater.from(context);
View view = getFirstHeadView();
if(view != null)
{
addHeaderView(view);
}
headView = (LinearLayout) inflater.inflate(R.layout.mylistview_head, null);
arrowImageView = (ProgressBar) headView.findViewById(R.id.head_arrowImageView);
progressBar = (ProgressBar) headView.findViewById(R.id.head_progressBar);
tipsTextview = (TextView) headView.findViewById(R.id.head_tipsTextView);
lastUpdatedTextView = (TextView) headView.findViewById(R.id.head_lastUpdatedTextView);
measureView(headView);
headContentHeight = headView.getMeasuredHeight();
headContentWidth = headView.getMeasuredWidth();
headView.setPadding(0, -1 * headContentHeight, 0, 0);
headView.invalidate();
Log.i("size", "width:" + headContentWidth + " height:" + headContentHeight);
addHeaderView(headView);
// animation = new RotateAnimation(0, -180,
// Animation.RELATIVE_TO_SELF, 0.5f,
// Animation.RELATIVE_TO_SELF, 0.5f);
// animation.setInterpolator(new LinearInterpolator());
// animation.setDuration(250);
// animation.setFillAfter(true);
//
// reverseAnimation = new RotateAnimation(-180, 0,
// Animation.RELATIVE_TO_SELF, 0.5f,
// Animation.RELATIVE_TO_SELF, 0.5f);
// reverseAnimation.setInterpolator(new LinearInterpolator());
// reverseAnimation.setDuration(200);
// reverseAnimation.setFillAfter(true);
state = DONE;
isRefreshable = false;
canReturn = false;
}
public View getFirstHeadView()
{
return null;
}
@Override
public boolean onTouchEvent(MotionEvent event) {
try {
if (isRefreshable) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
if (getScrollY() == 0 && !isRecored) {
isRecored = true;
startY = (int) event.getY();
Log.i(TAG, "在down时候记录当前位置‘");
}
break;
case MotionEvent.ACTION_UP:
if (state != REFRESHING && state != LOADING) {
if (state == DONE) {
// 什么都不做
}
if (state == PULL_To_REFRESH) {
state = DONE;
changeHeaderViewByState();
onPullUp();
Log.i(TAG, "由下拉刷新状态,到done状态");
}
if (state == RELEASE_To_REFRESH) {
state = REFRESHING;
changeHeaderViewByState();
onRefresh();
onPullUp();
Log.i(TAG, "由松开刷新状态,到done状态");
}
}
isRecored = false;
isBack = false;
break;
case MotionEvent.ACTION_MOVE:
int tempY = (int) event.getY();
if (!isRecored && getScrollY() == 0) {
Log.i(TAG, "在move时候记录下位置");
isRecored = true;
startY = tempY;
} else {
if (startY < tempY) {
if (mOnMoveListener != null) {
mOnMoveListener.onMoveList(true);
}
} else {
if (mOnMoveListener != null) {
mOnMoveListener.onMoveList(false);
}
}
}
if (state != REFRESHING && isRecored && state != LOADING
&& PullToRefreshListView.this.getFirstVisiblePosition() == 0) {
// 可以松手去刷新了
if (state == RELEASE_To_REFRESH) {
canReturn = true;
if (((tempY - startY) / RATIO < headContentHeight) && (tempY - startY) > 0) {
state = PULL_To_REFRESH;
changeHeaderViewByState();
Log.i(TAG, "由松开刷新状态转变到下拉刷新状态");
}
// 一下子推到顶了
else if (tempY - startY <= 0) {
state = DONE;
changeHeaderViewByState();
Log.i(TAG, "由松开刷新状态转变到done状态");
} else {
// 不用进行特别的操作,只用更新paddingTop的值就行了
}
}
// 还没有到达显示松开刷新的时候,DONE或者是PULL_To_REFRESH状态
if (state == PULL_To_REFRESH) {
canReturn = true;
// 下拉到可以进入RELEASE_TO_REFRESH的状态
if ((tempY - startY) / RATIO >= headContentHeight) {
state = RELEASE_To_REFRESH;
isBack = true;
changeHeaderViewByState();
Log.i(TAG, "由done或者下拉刷新状态转变到松开刷新");
}
// 上推到顶了
else if (tempY - startY <= 0) {
state = DONE;
changeHeaderViewByState();
Log.i(TAG, "由DOne或者下拉刷新状态转变到done状态");
}
}
// done状态下
if (state == DONE) {
if (tempY - startY > 0) {
state = PULL_To_REFRESH;
changeHeaderViewByState();
}
}
// 更新headView的size
if (state == PULL_To_REFRESH) {
headView.setPadding(0, -1 * headContentHeight + (tempY - startY) / RATIO, 0, 0);
}
// 更新headView的paddingTop
if (state == RELEASE_To_REFRESH) {
headView.setPadding(0, (tempY - startY) / RATIO - headContentHeight, 0, 0);
}
if (canReturn) {
canReturn = false;
return true;
}
}
break;
}
}
return super.onTouchEvent(event);
} catch (Exception ex) {
ex.printStackTrace();
return false;
}
}
/**
* 显示“正在刷新”view
*/
public void showRefreshingView() {
state = REFRESHING;
changeHeaderViewByState();
}
// 当状态改变时候,调用该方法,以更新界面
private void changeHeaderViewByState() {
switch (state) {
case RELEASE_To_REFRESH:
arrowImageView.setVisibility(View.VISIBLE);
progressBar.setVisibility(View.GONE);
tipsTextview.setVisibility(View.VISIBLE);
lastUpdatedTextView.setVisibility(View.VISIBLE);
// arrowImageView.clearAnimation();
// arrowImageView.startAnimation(animation);
tipsTextview.setText(release_str);
Log.i(TAG, "当前状态,松开刷新");
break;
case PULL_To_REFRESH:
progressBar.setVisibility(View.GONE);
tipsTextview.setVisibility(View.VISIBLE);
lastUpdatedTextView.setVisibility(View.VISIBLE);
arrowImageView.clearAnimation();
arrowImageView.setVisibility(View.VISIBLE);
// 是由RELEASE_To_REFRESH状态转变来的
if (isBack) {
isBack = false;
// arrowImageView.clearAnimation();
// arrowImageView.startAnimation(reverseAnimation);
tipsTextview.setText(down_str);
} else {
tipsTextview.setText(down_str);
}
Log.i(TAG, "当前状态,下拉刷新");
break;
case REFRESHING:
headView.setPadding(0, 0, 0, 0);
progressBar.setVisibility(View.VISIBLE);
arrowImageView.clearAnimation();
arrowImageView.setVisibility(View.GONE);
tipsTextview.setText("正在刷新...");
lastUpdatedTextView.setVisibility(View.VISIBLE);
Log.i(TAG, "当前状态,正在刷新...");
break;
case DONE:
headView.setPadding(0, -1 * headContentHeight, 0, 0);
progressBar.setVisibility(View.GONE);
arrowImageView.clearAnimation();
arrowImageView.destroyDrawingCache();
progressBar.destroyDrawingCache();
// arrowImageView.setImageResource(R.drawable.head_arrow);
tipsTextview.setText(down_str);
lastUpdatedTextView.setVisibility(View.VISIBLE);
Log.i(TAG, "当前状态,done");
break;
}
}
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);
}
public void setOnMoveListener(OnMoveListener moveListener) {
this.mOnMoveListener = moveListener;
}
public interface OnMoveListener {
public void onMoveList(Boolean isShow);
}
public void setonRefreshListener(OnRefreshListener refreshListener) {
this.refreshListener = refreshListener;
isRefreshable = true;
}
public interface OnRefreshListener {
public void onRefresh();
}
@SuppressWarnings("deprecation")
public void onRefreshComplete() {
state = DONE;
lastUpdatedTextView.setText("最近更新:" + new Date().toLocaleString());
changeHeaderViewByState();
invalidate();
scrollTo(0, 0);
}
public void setDownStr(String s) {
down_str = s;
}
public void setReleaseStr(String s) {
release_str = s;
}
private void onRefresh() {
if (refreshListener != null) {
if (null != mLoadingMoreListener) {
setFootVisiable(View.GONE, View.GONE, llFootLoadingParent.getVisibility());
}
refreshListener.onRefresh();
}
}
public void addChild(View child) {
innerLayout.addView(child);
}
public void addChild(View child, int position) {
innerLayout.addView(child, position);
}
public int getState() {
return state;
}
public void setState(int state) {
this.state = state;
}
private void onPullUp() {
if (pullUpListener != null) {
pullUpListener.onPullUp();
}
}
public void setOnPullUpListener(OnPullUpListener pullUpListener) {
this.pullUpListener = pullUpListener;
}
public interface OnPullUpListener {
public void onPullUp();
}
/**
* xml加载完之后会调用这个方法
* */
@Override
protected void onFinishInflate() {
super.onFinishInflate();
}
/** 加载更多的底部 */
private View mFootView;
private RelativeLayout rlFootNoMoreParent;
private LinearLayout llFootLoadingParent;
/** 加载更多的监听器 */
private OnLoadingMoreListener mLoadingMoreListener;
/** 加载出错时,点击加载更多 */
private Button btnReload;
/**没有更多*/
private TextView tvNoMoreText;
/** 设置上拉加载更多可用 */
public void setLoadingMoreEnable(OnLoadingMoreListener loadingMoreListener) {
this.mLoadingMoreListener = loadingMoreListener;
// 添加底部
mFootView = LayoutInflater.from(mContext).inflate(R.layout.get_more, null);
rlFootNoMoreParent = (RelativeLayout) this.mFootView.findViewById(R.id.rl_no_more_parent);
llFootLoadingParent = (LinearLayout) this.mFootView.findViewById(R.id.ll_loading_parent);
tvNoMoreText = (TextView) this.mFootView.findViewById(R.id.foot_layout_no_more_text);
btnReload = (Button) this.mFootView.findViewById(R.id.bt_load);
btnReload.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if ("加载失败,点击重试".equals(btnReload.getText().toString()) && null != mLoadingMoreListener) {
mLoadingMoreListener.onLoadingMore(PullToRefreshListView.this, OnScrollListener.SCROLL_STATE_IDLE);
}
}
});
// 首次加载应该是隐藏的
// setFootVisiable(View.VISIBLE, View.GONE, View.GONE);
addFooterView(this.mFootView);
// 添加底部之后就可以上拉加载更多 :这个监听器,可以消除上滑的时候不加载图片
setOnScrollListener(new PauseOnScrollListener(ImageLoader.getInstance(), true, true, this));
}
/**
*
* @description 设置没有更多文本颜色值
* @author zhongwr
* @update 2015-12-14 下午8:26:07
*/
public void setNoMoreTextColor(int colorResId) {
if (null != tvNoMoreText) {
tvNoMoreText.setTextColor(colorResId);
}
}
public View getFootView() {
return mFootView;
}
public boolean removeFootView() {
return removeFooterView(this.mFootView);
}
/**
*
* @description 加载完成
* @param isNoMore
* 是否没有更多了
* @author zhongwr
* @update 2015-11-6 上午1:08:15
*/
public void setOnLoadingMoreCompelete(boolean isNoMore) {
setOnLoadingMoreCompelete(isNoMore, false);
}
public void setOnLoadingMoreCompelete() {
setFootVisiable(View.GONE, View.GONE, View.GONE);
this.isLoadingMore = false;
}
/**
*
* @description 加载完成
* @param isNoMore
* 是否没有更多了
* @param isLoadingMoreFailed
* 加载更多时出错
* @author zhongwr
* @update 2015-11-6 上午1:08:15
*/
public void setOnLoadingMoreCompelete(boolean isNoMore, boolean isLoadingMoreFailed) {
if (!isLoadingMoreFailed) {
if (!"加载更多...".equals(btnReload.getText().toString())) {
btnReload.setText("加载更多...");
}
if (isNoMore) {
setFootVisiable(View.VISIBLE, View.VISIBLE, View.GONE);
} else {
setFootVisiable(View.VISIBLE, View.GONE, View.VISIBLE);
}
} else {// 加载失败,提示点击重试
btnReload.setText("加载失败,点击重试");
setFootVisiable(View.VISIBLE, View.GONE, View.VISIBLE);
}
this.isLoadingMore = false;
}
/***
*
* @description 用于下拉刷新时,隐藏底部
* @author zhongwr
* @update 2015-11-25 下午5:24:51
*/
public void hiddenFootView() {
if (null != mFootView) {
isLoadingMore = false;
mFootView.setVisibility(View.GONE);
}
}
/**
*
* @description 显示底部
* @author zhongwr
* @params
* @update 2016年1月4日 下午4:16:06
*/
public void showFootView() {
if (null != mFootView) {
mFootView.setVisibility(View.VISIBLE);
}
}
/***
*
* @description 设置底部可见:加载更多或没有更多
* @author zhongwr
* @param footView
* 这个底部是否可见
* @param footNoMoreParent
* 没有更多是否可见
* @param footLoadingParent
* 加载更多是否可见
* @update 2015年9月24日 上午11:26:32
*/
private void setFootVisiable(int footView, int footNoMoreParent, int footLoadingParent) {
if (null != mFootView) {
if (footView != mFootView.getVisibility()) {
mFootView.setVisibility(footView);
}
// 整个底部可见,设置子布局是否可见
if (footNoMoreParent != rlFootNoMoreParent.getVisibility()) {
this.rlFootNoMoreParent.setVisibility(footNoMoreParent);
}
if (footLoadingParent != llFootLoadingParent.getVisibility()) {
llFootLoadingParent.setVisibility(footLoadingParent);
}
}
}
/** 是否加载更多 */
private boolean isLoadingMore;
@Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
if(mOnScrollListenerExtra != null)
{
mOnScrollListenerExtra.onScroll(view, firstVisibleItem, visibleItemCount, totalItemCount);
}
}
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
// 不是首页&历史数据没有加载完&最后一天item&上一次已经加载完成
Logcat.dLog("isLoadingMore = " + (view.getLastVisiblePosition() == view.getCount() - 1) + " idle = "
+ (scrollState == SCROLL_STATE_IDLE) + " done = " + (state == DONE) + " isLoadingMore = "
+ isLoadingMore);
Logcat.dLog("rlFootNoMoreParent = "+(rlFootNoMoreParent.getVisibility() == View.GONE));
if (rlFootNoMoreParent.getVisibility() == View.GONE && view.getLastVisiblePosition() == view.getCount() - 1 && scrollState == SCROLL_STATE_IDLE && state == DONE
&& !isLoadingMore) {
isLoadingMore = true;
setFootVisiable(View.VISIBLE, View.GONE, View.VISIBLE);
if (null != mLoadingMoreListener) {
mLoadingMoreListener.onLoadingMore(view, scrollState);
}
}
// 实现滑动状态改变事件
if (mScrollStateChangedListener != null) {
mScrollStateChangedListener.onScrollStateChanged(view, scrollState);
}
if(mOnScrollListenerExtra != null)
{
mOnScrollListenerExtra.onScrollStateChanged(view, scrollState);
}
}
/**
* @Description 增加ListView滑动状态改变监听 接口
* @author chenxinghong
* @date 2015-12-17
*/
public interface OnScrollStateChangedListener {
public void onScrollStateChanged(AbsListView view, int scrollState);
}
public void setOnScrollStateChangedListener(OnScrollStateChangedListener listener) {
this.mScrollStateChangedListener = listener;
}
private OnScrollListener mOnScrollListenerExtra;
public void setOnScrollListenerExtra(OnScrollListener listener) {
this.mOnScrollListenerExtra = listener;
}
/***
* 加载更多的接口
*
* @author zhongwr
* @update 2015年9月28日 下午6:03:35
*/
public interface OnLoadingMoreListener {
public void onLoadingMore(AbsListView view, int scrollState);
}
}