package com.github.jdsjlzx.view;
import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Color;
import android.os.Handler;
import android.support.v4.content.ContextCompat;
import android.util.AttributeSet;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.Animation;
import android.view.animation.RotateAnimation;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.TextView;
import com.github.jdsjlzx.R;
import com.github.jdsjlzx.interfaces.IRefreshHeader;
import com.github.jdsjlzx.progressindicator.AVLoadingIndicatorView;
import com.github.jdsjlzx.recyclerview.ProgressStyle;
import java.util.Date;
public class ArrowRefreshHeader extends LinearLayout implements IRefreshHeader {
private LinearLayout mContainer;
private ImageView mArrowImageView;
private SimpleViewSwitcher mProgressBar;
private TextView mStatusTextView;
private int mState = STATE_NORMAL;
private TextView mHeaderTimeView;
private Animation mRotateUpAnim;
private Animation mRotateDownAnim;
private static final int ROTATE_ANIM_DURATION = 180;
public int mMeasuredHeight;
private int hintColor;
public ArrowRefreshHeader(Context context) {
super(context);
initView();
}
/**
* @param context
* @param attrs
*/
public ArrowRefreshHeader(Context context, AttributeSet attrs) {
super(context, attrs);
initView();
}
private void initView() {
// 初始情况,设置下拉刷新view高度为0
LayoutParams lp = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
lp.setMargins(0, 0, 0, 0);
this.setLayoutParams(lp);
this.setPadding(0, 0, 0, 0);
mContainer = (LinearLayout) LayoutInflater.from(getContext()).inflate(R.layout.listview_header, null);
addView(mContainer, new LayoutParams(LayoutParams.MATCH_PARENT, 0));
setGravity(Gravity.BOTTOM);
mArrowImageView = (ImageView)findViewById(R.id.listview_header_arrow);
mStatusTextView = (TextView)findViewById(R.id.refresh_status_textview);
//init the progress view
mProgressBar = (SimpleViewSwitcher)findViewById(R.id.listview_header_progressbar);
mProgressBar.setView(initIndicatorView(ProgressStyle.BallSpinFadeLoader));
mRotateUpAnim = new RotateAnimation(0.0f, -180.0f,
Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
mRotateUpAnim.setDuration(ROTATE_ANIM_DURATION);
mRotateUpAnim.setFillAfter(true);
mRotateDownAnim = new RotateAnimation(-180.0f, 0.0f,
Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
mRotateDownAnim.setDuration(ROTATE_ANIM_DURATION);
mRotateDownAnim.setFillAfter(true);
mHeaderTimeView = (TextView)findViewById(R.id.last_refresh_time);
measure(ViewGroup.LayoutParams.WRAP_CONTENT,ViewGroup.LayoutParams.WRAP_CONTENT);
mMeasuredHeight = getMeasuredHeight();
hintColor = android.R.color.darker_gray;
}
public void setProgressStyle(int style) {
if (style == ProgressStyle.SysProgress) {
ProgressBar progressBar = new ProgressBar(getContext(), null, android.R.attr.progressBarStyle);
mProgressBar.setView(progressBar);
} else {
mProgressBar.setView(initIndicatorView(style));
}
}
private View initIndicatorView(int style) {
AVLoadingIndicatorView progressView = (AVLoadingIndicatorView) LayoutInflater.from(getContext()).inflate(R.layout.layout_indicator_view, null);
progressView.setIndicatorId(style);
progressView.setIndicatorColor(Color.GRAY);
return progressView;
}
public void setIndicatorColor(int color) {
if(mProgressBar.getChildAt(0) instanceof AVLoadingIndicatorView){
AVLoadingIndicatorView progressView = (AVLoadingIndicatorView) mProgressBar.getChildAt(0);
progressView.setIndicatorColor(color);
}
}
public void setHintTextColor(int color) {
this.hintColor = color;
}
public void setViewBackgroundColor(int color) {
this.setBackgroundColor(ContextCompat.getColor(getContext(), color));
}
public void setArrowImageView(int resid){
mArrowImageView.setImageResource(resid);
}
public void setState(int state) {
if (state == mState) return ;
if (state == STATE_REFRESHING) { // 显示进度
mArrowImageView.clearAnimation();
mArrowImageView.setVisibility(View.INVISIBLE);
mProgressBar.setVisibility(View.VISIBLE);
smoothScrollTo(mMeasuredHeight);
} else if(state == STATE_DONE) {
mArrowImageView.setVisibility(View.INVISIBLE);
mProgressBar.setVisibility(View.INVISIBLE);
} else { // 显示箭头图片
mArrowImageView.setVisibility(View.VISIBLE);
mProgressBar.setVisibility(View.INVISIBLE);
}
mStatusTextView.setTextColor(ContextCompat.getColor(getContext(), hintColor));
switch(state){
case STATE_NORMAL:
if (mState == STATE_RELEASE_TO_REFRESH) {
mArrowImageView.startAnimation(mRotateDownAnim);
}
if (mState == STATE_REFRESHING) {
mArrowImageView.clearAnimation();
}
mStatusTextView.setText(R.string.listview_header_hint_normal);
break;
case STATE_RELEASE_TO_REFRESH:
if (mState != STATE_RELEASE_TO_REFRESH) {
mArrowImageView.clearAnimation();
mArrowImageView.startAnimation(mRotateUpAnim);
mStatusTextView.setText(R.string.listview_header_hint_release);
}
break;
case STATE_REFRESHING:
mStatusTextView.setText(R.string.refreshing);
break;
case STATE_DONE:
mStatusTextView.setText(R.string.refresh_done);
break;
default:
}
mState = state;
}
public int getState() {
return mState;
}
@Override
public void refreshComplete(){
mHeaderTimeView.setText(friendlyTime(new Date()));
setState(STATE_DONE);
new Handler().postDelayed(new Runnable(){
public void run() {
reset();
}
}, 200);
}
@Override
public View getHeaderView() {
return this;
}
public void setVisibleHeight(int height) {
if (height < 0) height = 0;
LayoutParams lp = (LayoutParams) mContainer .getLayoutParams();
lp.height = height;
mContainer.setLayoutParams(lp);
}
public int getVisibleHeight() {
LayoutParams lp = (LayoutParams) mContainer.getLayoutParams();
return lp.height;
}
@Override
public void onReset() {
setState(STATE_NORMAL);
}
@Override
public void onPrepare() {
setState(STATE_RELEASE_TO_REFRESH);
}
@Override
public void onRefreshing() {
setState(STATE_REFRESHING);
}
@Override
public void onMove(float offSet, float sumOffSet) {
if (getVisibleHeight() > 0 || offSet > 0) {
setVisibleHeight((int) offSet + getVisibleHeight());
if (mState <= STATE_RELEASE_TO_REFRESH) { // 未处于刷新状态,更新箭头
if (getVisibleHeight() > mMeasuredHeight) {
onPrepare();
} else {
onReset();
}
}
}
}
@Override
public boolean onRelease() {
boolean isOnRefresh = false;
int height = getVisibleHeight();
if (height == 0) {// not visible.
isOnRefresh = false;
}
if(getVisibleHeight() > mMeasuredHeight && mState < STATE_REFRESHING){
setState(STATE_REFRESHING);
isOnRefresh = true;
}
// refreshing and header isn't shown fully. do nothing.
if (mState == STATE_REFRESHING && height > mMeasuredHeight) {
smoothScrollTo(mMeasuredHeight);
}
if (mState != STATE_REFRESHING) {
smoothScrollTo(0);
}
if (mState == STATE_REFRESHING) {
int destHeight = mMeasuredHeight;
smoothScrollTo(destHeight);
}
return isOnRefresh;
}
public void reset() {
smoothScrollTo(0);
new Handler().postDelayed(new Runnable() {
public void run() {
setState(STATE_NORMAL);
}
}, 500);
}
private void smoothScrollTo(int destHeight) {
ValueAnimator animator = ValueAnimator.ofInt(getVisibleHeight(), destHeight);
animator.setDuration(300).start();
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation)
{
setVisibleHeight((int) animation.getAnimatedValue());
}
});
animator.start();
}
public String friendlyTime(Date time) {
int ct = (int) ((System.currentTimeMillis() - time.getTime()) / 1000);
if (ct == 0) {
return getContext().getResources().getString(R.string.text_just);
}
if (ct > 0 && ct < 60) {
return ct + getContext().getResources().getString(R.string.text_seconds_ago);
}
if (ct >= 60 && ct < 3600) {
return Math.max(ct / 60, 1) + getContext().getResources().getString(R.string.text_minute_ago);
}
if (ct >= 3600 && ct < 86400)
return ct / 3600 + getContext().getResources().getString(R.string.text_hour_ago);
if (ct >= 86400 && ct < 2592000) { //86400 * 30
int day = ct / 86400;
return day + getContext().getResources().getString(R.string.text_day_ago);
}
if (ct >= 2592000 && ct < 31104000) { //86400 * 30
return ct / 2592000 + getContext().getResources().getString(R.string.text_month_ago);
}
return ct / 31104000 + getContext().getResources().getString(R.string.text_year_ago);
}
}