@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);
 }
  @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();
    }
  }
 @Override
 protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
   int height = mDrawable.getIntrinsicHeight() + getPaddingTop() + getPaddingBottom();
   heightMeasureSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY);
   super.onMeasure(widthMeasureSpec, heightMeasureSpec);
 }
 public void setColorSchemeColors(int[] colors) {
   mDrawable.setColorSchemeColors(colors);
   invalidate();
 }
 private void initView() {
   mDrawable = new MaterialProgressDrawable(getContext(), this);
   mDrawable.setBackgroundColor(Color.WHITE);
   mDrawable.setCallback(this);
 }
 @Override
 public void applyTransformation(float interpolatedTime, Transformation t) {
   mScale = 1f - interpolatedTime;
   mDrawable.setAlpha((int) (255 * mScale));
   invalidate();
 }
 /**
  * perform UI after refresh
  *
  * @param frame
  */
 @Override
 public void onUIRefreshComplete(PtrFrameLayout frame) {
   mDrawable.stop();
 }
 /**
  * perform refreshing UI
  *
  * @param frame
  */
 @Override
 public void onUIRefreshBegin(PtrFrameLayout frame) {
   mDrawable.setAlpha(255);
   mDrawable.start();
 }
 /**
  * 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();
 }
 @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);
 }