package cn.coderss.otherPullrefresh;
import cn.coderss.edu.R;
import android.content.Context;
import android.os.Handler;
import android.os.Message;
import android.util.AttributeSet;
import android.util.Log;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.animation.LinearInterpolator;
import android.view.animation.RotateAnimation;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.ScrollView;
import android.widget.Scroller;
import android.widget.TextView;
/**
* @author wangning
*
*/
public class TryRefreshableView extends LinearLayout {
public static final int READYTOREFRESH = 0; // 初始状态
public static final int TAP_TO_REFRESH = 1; // 初始状态
public static final int PULL_TO_REFRESH = 2; // 拉动刷新
public static final int RELEASE_TO_REFRESH = 3; // 释放刷新
public static final int REFRESHING = 4; // 正在刷新
public int mRefreshState;// 记录头当前状态
public int mfooterRefreshState;// 记录尾当前状态
public Scroller scroller;
public TryPullToRefreshScrollView sv;
private View refreshView;// 头部视图
public TextView mfooterViewText;
private ImageView refreshIndicatorView;
private int refreshTargetTop = -60;
public int refreshFooter;
private ProgressBar bar;
private TextView downTextView;
private TextView timeTextView;
private RefreshListener refreshListener;
private int lastY;
// 动画效果
// 变为向下的箭头
private RotateAnimation mFlipAnimation;
// 变为逆向的箭头
private RotateAnimation mReverseFlipAnimation;
public int nowpull = -1;// 0为头部下拉,1为尾部上拉
private boolean isRecord;
private Context mContext;
Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
// process incoming messages here
super.handleMessage(msg);
switch (msg.what) {
case 1:
Log.d("TryPullToRefreshScrollView", "view.getMeasureHeight:"
+ getMeasuredHeight());
if (getMeasuredHeight() - 20 <= getScrollY() + getHeight()) {
if (onBottomListener != null) {
onBottomListener.onBottom();
}
}
break;
default:
break;
}
}
};
/**
* 定义接口
*
*/
public interface OnBottomListener {
void onBottom();
}
private OnBottomListener onBottomListener;
public void setOnBottomListener(OnBottomListener onScrollListener) {
this.onBottomListener = onScrollListener;
}
public TryRefreshableView(Context context) {
super(context);
mContext = context;
}
public TryRefreshableView(Context context, AttributeSet attrs) {
super(context, attrs);
mContext = context;
init();
}
private void init() {
// 初始化动画
//
mFlipAnimation = new RotateAnimation(0, -180,
RotateAnimation.RELATIVE_TO_SELF, 0.5f,
RotateAnimation.RELATIVE_TO_SELF, 0.5f);
mFlipAnimation.setInterpolator(new LinearInterpolator());
mFlipAnimation.setDuration(250);
mFlipAnimation.setFillAfter(true);
mReverseFlipAnimation = new RotateAnimation(-180, 0,
RotateAnimation.RELATIVE_TO_SELF, 0.5f,
RotateAnimation.RELATIVE_TO_SELF, 0.5f);
mReverseFlipAnimation.setInterpolator(new LinearInterpolator());
mReverseFlipAnimation.setDuration(250);
mReverseFlipAnimation.setFillAfter(true);
// 滑动对象,
scroller = new Scroller(mContext);
// 刷新视图顶端的的view
refreshView = LayoutInflater.from(mContext).inflate(
R.layout.otherpull_to_refresh_header, null);
// 箭头图标
refreshIndicatorView = (ImageView) refreshView
.findViewById(R.id.pull_to_refresh_image);
// 刷新bar
bar = (ProgressBar) refreshView
.findViewById(R.id.pull_to_refresh_progress);
// 下拉显示text
downTextView = (TextView) refreshView
.findViewById(R.id.pull_to_refresh_text);
// 下来显示时间
timeTextView = (TextView) refreshView
.findViewById(R.id.pull_to_refresh_updated_at);
// 添加头部view
refreshView.setMinimumHeight(50);
LayoutParams lp = new LinearLayout.LayoutParams(
LayoutParams.FILL_PARENT, -refreshTargetTop);
lp.topMargin = refreshTargetTop;
lp.gravity = Gravity.CENTER;
addView(refreshView, lp);
isRecord = false;
mRefreshState = TAP_TO_REFRESH;
mfooterRefreshState = TAP_TO_REFRESH;
}
public boolean onTouchEvent(MotionEvent event) {
int y = (int) event.getRawY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
// 记录下y坐标
if (isRecord == false) {
Log.i("moveY", "lastY:" + y);
lastY = y;
isRecord = true;
}
break;
case MotionEvent.ACTION_MOVE:
Log.i("TAG", "ACTION_MOVE");
// y移动坐标
Log.i("moveY", "lastY:" + lastY);
Log.i("moveY", "y:" + y);
int m = y - lastY;
doMovement(m);
// 记录下此刻y坐标
lastY = y;
break;
case MotionEvent.ACTION_UP:
Log.i("TAG", "ACTION_UP");
handler.sendEmptyMessage(1);
fling();
isRecord = false;
break;
}
return true;
}
/**
* up事件处理
*/
private void fling() {
if (nowpull == 0 && mRefreshState != REFRESHING) {
LinearLayout.LayoutParams lp = (LayoutParams) refreshView
.getLayoutParams();
Log.i("TAG", "fling()" + lp.topMargin);
if (lp.topMargin > 0) {// 拉到了触发可刷新事件
refresh();
} else {
returnInitState();
}
}
}
// 刷新
public void onDownRefresh() {
Log.d("TAG", "执行刷新");
if (refreshListener != null) {
refreshListener.onDownRefresh();
}
}
private void returnInitState() {
mRefreshState = TAP_TO_REFRESH;
LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) this.refreshView
.getLayoutParams();
int i = lp.topMargin;
scroller.startScroll(0, i, 0, refreshTargetTop);
invalidate();
}
private void refresh() {
mRefreshState = READYTOREFRESH;
LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) this.refreshView
.getLayoutParams();
int i = lp.topMargin;
refreshIndicatorView.setVisibility(View.GONE);
refreshIndicatorView.setImageDrawable(null);
bar.setVisibility(View.VISIBLE);
timeTextView.setVisibility(View.GONE);
downTextView.setText(R.string.pull_to_refresh_refreshing_label);
scroller.startScroll(0, i, 0, 0 - i);
invalidate();
onDownRefresh();
mRefreshState = REFRESHING;
}
private void resetFooterPadding() {
LayoutParams svlp = (LayoutParams) sv.getLayoutParams();
svlp.bottomMargin = 0;
sv.setLayoutParams(svlp);
// TryPullToRefreshScrollView.ScrollToPoint(sv, sv.getChildAt(0), 0);
}
public void FooterPrepareForRefresh() {
resetFooterPadding();
mfooterViewText
.setText("下拉刷新");
mfooterRefreshState = REFRESHING;
}
/**
*
*/
@Override
public void computeScroll() {
if (scroller.computeScrollOffset()) {
int i = this.scroller.getCurrY();
LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) this.refreshView
.getLayoutParams();
int k = Math.max(i, refreshTargetTop);
lp.topMargin = k;
this.refreshView.setLayoutParams(lp);
this.refreshView.invalidate();
invalidate();
}
}
/**
* 下拉move事件处理
*
* @param moveY
*/
public void doMovement(int moveY) {
LinearLayout.LayoutParams lp = (LayoutParams) refreshView
.getLayoutParams();
if (sv.getScrollY() == 0 && moveY > 0 && refreshFooter <= 0) {
nowpull = 0;
}
if (sv.getChildAt(0).getMeasuredHeight() <= sv.getScrollY()
+ getHeight()
&& moveY < 0 && lp.topMargin <= refreshTargetTop) {
nowpull = 1;
}
if (nowpull == 0 && mRefreshState != REFRESHING) {
// 获取view的上边距
float f1 = lp.topMargin;
float f2 = f1 + moveY * 0.3F;
int i = (int) f2;
// 修改上边距
lp.topMargin = i;
// 修改后刷新
refreshView.setLayoutParams(lp);
refreshView.invalidate();
invalidate();
downTextView.setVisibility(View.VISIBLE);
refreshIndicatorView.setVisibility(View.VISIBLE);
bar.setVisibility(View.GONE);
if (lp.topMargin > 0 && mRefreshState != RELEASE_TO_REFRESH) {
downTextView.setText("下拉");
// refreshIndicatorView.setImageResource(R.drawable.goicon);
refreshIndicatorView.clearAnimation();
refreshIndicatorView.startAnimation(mFlipAnimation);
mRefreshState = RELEASE_TO_REFRESH;
Log.i("TAG", "现在处于下拉状态");
} else if (lp.topMargin <= 0 && mRefreshState != PULL_TO_REFRESH) {
downTextView.setText("下拉");
// refreshIndicatorView.setImageResource(R.drawable.goicon);
if (mRefreshState != TAP_TO_REFRESH) {
refreshIndicatorView.clearAnimation();
refreshIndicatorView.startAnimation(mReverseFlipAnimation);
Log.i("TAG", "现在处于回弹状态");
}
mRefreshState = PULL_TO_REFRESH;
}
}
}
public void setRefreshListener(RefreshListener listener) {
this.refreshListener = listener;
}
/**
* 结束刷新事件
*/
public void finishRefresh() {
Log.i("TAG", "执行了=====finishRefresh");
if (mRefreshState != TAP_TO_REFRESH) {
mRefreshState = TAP_TO_REFRESH; // 初始刷新状态
LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) this.refreshView
.getLayoutParams();
int i = lp.topMargin;
refreshIndicatorView.setImageResource(R.drawable.xlistview_arrow);
refreshIndicatorView.clearAnimation();
bar.setVisibility(View.GONE);
refreshIndicatorView.setVisibility(View.GONE);
downTextView.setText("上拉");
scroller.startScroll(0, i, 0, refreshTargetTop);
invalidate();
}
}
/*
* 该方法一般和ontouchEvent 一起用
*
* @see
* android.view.ViewGroup#onInterceptTouchEvent(android.view.MotionEvent)
*/
@Override
public boolean onInterceptTouchEvent(MotionEvent e) {
int action = e.getAction();
int y = (int) e.getRawY();
switch (action) {
case MotionEvent.ACTION_DOWN:
// lastY = y;
if (isRecord == false) {
Log.i("moveY", "lastY:" + y);
lastY = y;
isRecord = true;
}
break;
case MotionEvent.ACTION_MOVE:
// y移动坐标
int m = y - lastY;
if (canScroll(m)) {
return true;
}
break;
case MotionEvent.ACTION_UP:
isRecord = false;
break;
case MotionEvent.ACTION_CANCEL:
break;
}
return false;
}
private boolean canScroll(int diff) {
View childView;
Log.i("other", "mRefreshState:" + mRefreshState);
// if (mRefreshState == REFRESHING || mfooterRefreshState == REFRESHING)
// {
// return true;
// }
if (getChildCount() > 1) {
childView = this.getChildAt(1);
if (childView instanceof ListView) {
int top = ((ListView) childView).getChildAt(0).getTop();
int pad = ((ListView) childView).getListPaddingTop();
if ((Math.abs(top - pad)) < 3
&& ((ListView) childView).getFirstVisiblePosition() == 0) {
return true;
} else {
return false;
}
} else if (childView instanceof ScrollView) {
// 头部下拉
if (((ScrollView) childView).getScrollY() == 0 && diff > 0) {
nowpull = 0;
Log.i("other", "外框处理");
return true;
} else if ((((ScrollView) childView).getChildAt(0)
.getMeasuredHeight() <= ((ScrollView) childView)
.getScrollY() + getHeight() && diff < 0)) {// 底部上拉
Log.i("other", "外框处理2");
nowpull = 1;
return true;
} else {
Log.i("other", "ScrollView处理");
return false;
}
}
}
return false;
}
/**
* 刷新监听接口
*
* @author Nono
*
*/
public interface RefreshListener {
public void onDownRefresh();
}
}