package com.example.xrecyclerview; import android.animation.ValueAnimator; import android.content.Context; import android.graphics.drawable.AnimationDrawable; import android.os.Handler; import android.util.AttributeSet; import android.view.Gravity; import android.view.LayoutInflater; import android.view.ViewGroup; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.TextView; /** * Created by yangcai on 2016/1/27. */ public class YunRefreshHeader extends LinearLayout implements BaseRefreshHeader { private Context mContext; private AnimationDrawable animationDrawable; private TextView msg; private int mState = STATE_NORMAL; private int mMeasuredHeight; private LinearLayout mContainer; public YunRefreshHeader(Context context) { this(context, null); } public YunRefreshHeader(Context context, AttributeSet attrs) { this(context, attrs, 0); } public YunRefreshHeader(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); this.mContext = context; initView(); } private void initView() { LayoutInflater.from(mContext).inflate(R.layout.kaws_refresh_header, this); ImageView img = (ImageView) findViewById(R.id.img); animationDrawable = (AnimationDrawable) img.getDrawable(); if (animationDrawable.isRunning()) { animationDrawable.stop(); } msg = (TextView) findViewById(R.id.msg); measure(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT); mMeasuredHeight = getMeasuredHeight(); setGravity(Gravity.CENTER_HORIZONTAL); mContainer = (LinearLayout) findViewById(R.id.container); mContainer.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, 0)); this.setLayoutParams(new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)); } @Override public void onMove(float delta) { if (getVisiableHeight() > 0 || delta > 0) { setVisiableHeight((int) delta + getVisiableHeight()); if (mState <= STATE_RELEASE_TO_REFRESH) { // 未处于刷新状态,更新箭头 if (getVisiableHeight() > mMeasuredHeight) { setState(STATE_RELEASE_TO_REFRESH); } else { setState(STATE_NORMAL); } } } } private void setState(int state) { if (state == mState) return; switch (state) { case STATE_NORMAL: if (animationDrawable.isRunning()) { animationDrawable.stop(); } msg.setText(R.string.listview_header_hint_normal); break; case STATE_RELEASE_TO_REFRESH: if (mState != STATE_RELEASE_TO_REFRESH) { if (!animationDrawable.isRunning()) { animationDrawable.start(); } msg.setText(R.string.listview_header_hint_release); } break; case STATE_REFRESHING: msg.setText(R.string.refreshing); break; case STATE_DONE: msg.setText(R.string.refresh_done); break; default: } mState = state; } @Override public boolean releaseAction() { boolean isOnRefresh = false; int height = getVisiableHeight(); if (height == 0) // not visible. isOnRefresh = false; if (getVisiableHeight() > mMeasuredHeight && mState < STATE_REFRESHING) { setState(STATE_REFRESHING); isOnRefresh = true; } // refreshing and header isn't shown fully. do nothing. if (mState == STATE_REFRESHING && height <= mMeasuredHeight) { //return; } int destHeight = 0; // default: scroll back to dismiss header. // is refreshing, just scroll back to show all the header. if (mState == STATE_REFRESHING) { destHeight = mMeasuredHeight; } smoothScrollTo(destHeight); return isOnRefresh; } @Override public void refreshComplate() { setState(STATE_DONE); new Handler().postDelayed(new Runnable() { public void run() { reset(); } }, 500); } public void reset() { smoothScrollTo(0); setState(STATE_NORMAL); } private void smoothScrollTo(int destHeight) { ValueAnimator animator = ValueAnimator.ofInt(getVisiableHeight(), destHeight); animator.setDuration(300).start(); animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { setVisiableHeight((int) animation.getAnimatedValue()); } }); animator.start(); } private void setVisiableHeight(int height) { if (height < 0) height = 0; // ` LayoutParams lp = new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 0); lp.height = height; mContainer.setLayoutParams(lp); } @Override public int getVisiableHeight() { return mContainer.getHeight(); } public int getState() { return mState; } }