package in.srain.cube.views.ptr.header;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.Transformation;
import in.srain.cube.views.ptr.PtrFrameLayout;
import in.srain.cube.views.ptr.PtrUIHandler;
import in.srain.cube.views.ptr.PtrUIHandlerHook;
import in.srain.cube.views.ptr.indicator.PtrIndicator;
public class MaterialHeader extends View implements PtrUIHandler {
private MaterialProgressDrawable mDrawable;
private float mScale = 1f;
private PtrFrameLayout mPtrFrameLayout;
private Animation mScaleAnimation = new Animation() {
@Override
public void applyTransformation(float interpolatedTime, Transformation t) {
mScale = 1f - interpolatedTime;
mDrawable.setAlpha((int) (255 * mScale));
invalidate();
}
};
public MaterialHeader(Context context) {
super(context);
initView();
}
public MaterialHeader(Context context, AttributeSet attrs) {
super(context, attrs);
initView();
}
public MaterialHeader(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initView();
}
public void setPtrFrameLayout(PtrFrameLayout layout) {
final PtrUIHandlerHook mPtrUIHandlerHook = new PtrUIHandlerHook() {
@Override
public void run() {
startAnimation(mScaleAnimation);
}
};
mScaleAnimation.setDuration(200);
mScaleAnimation.setAnimationListener(new Animation.AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {
}
@Override
public void onAnimationEnd(Animation animation) {
mPtrUIHandlerHook.resume();
}
@Override
public void onAnimationRepeat(Animation animation) {
}
});
mPtrFrameLayout = layout;
mPtrFrameLayout.setRefreshCompleteHook(mPtrUIHandlerHook);
}
private void initView() {
mDrawable = new MaterialProgressDrawable(getContext(), this);
mDrawable.setBackgroundColor(Color.WHITE);
mDrawable.setCallback(this);
}
@Override
public void invalidateDrawable(Drawable dr) {
if (dr == mDrawable) {
invalidate();
} else {
super.invalidateDrawable(dr);
}
}
public void setColorSchemeColors(int[] colors) {
mDrawable.setColorSchemeColors(colors);
invalidate();
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int height = mDrawable.getIntrinsicHeight() + getPaddingTop() + getPaddingBottom();
heightMeasureSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY);
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
final int size = mDrawable.getIntrinsicHeight();
mDrawable.setBounds(0, 0, size, size);
}
@Override
protected void onDraw(Canvas canvas) {
final int saveCount = canvas.save();
Rect rect = mDrawable.getBounds();
int l = getPaddingLeft() + (getMeasuredWidth() - mDrawable.getIntrinsicWidth()) / 2;
canvas.translate(l, getPaddingTop());
canvas.scale(mScale, mScale, rect.exactCenterX(), rect.exactCenterY());
mDrawable.draw(canvas);
canvas.restoreToCount(saveCount);
}
/**
* When the content view has reached top and refresh has been completed, view will be reset.
*
* @param frame
*/
@Override
public void onUIReset(PtrFrameLayout frame) {
mScale = 1f;
mDrawable.stop();
}
/**
* prepare for loading
*
* @param frame
*/
@Override
public void onUIRefreshPrepare(PtrFrameLayout frame) {
}
/**
* perform refreshing UI
*
* @param frame
*/
@Override
public void onUIRefreshBegin(PtrFrameLayout frame) {
mDrawable.setAlpha(255);
mDrawable.start();
}
/**
* perform UI after refresh
*
* @param frame
*/
@Override
public void onUIRefreshComplete(PtrFrameLayout frame) {
mDrawable.stop();
}
@Override
public void onUIPositionChange(PtrFrameLayout frame, boolean isUnderTouch, byte status, PtrIndicator ptrIndicator) {
float percent = Math.min(1f, ptrIndicator.getCurrentPercent());
if (status == PtrFrameLayout.PTR_STATUS_PREPARE) {
mDrawable.setAlpha((int) (255 * percent));
mDrawable.showArrow(true);
float strokeStart = ((percent) * .8f);
mDrawable.setStartEndTrim(0f, Math.min(0.8f, strokeStart));
mDrawable.setArrowScale(Math.min(1f, percent));
// magic
float rotation = (-0.25f + .4f * percent + percent * 2) * .5f;
mDrawable.setProgressRotation(rotation);
invalidate();
}
}
}