content: package com.cjj;
  
  import android.content.Context;
  import android.content.res.TypedArray;
  import android.graphics.Color;
  import android.os.Build;
  import android.support.v4.view.ViewCompat;
  import android.support.v4.view.ViewPropertyAnimatorCompat;
  import android.support.v4.view.ViewPropertyAnimatorUpdateListener;
  import android.util.AttributeSet;
  import android.util.Log;
  import android.view.Gravity;
  import android.view.MotionEvent;
  import android.view.View;
  import android.view.ViewGroup;
  import android.view.animation.DecelerateInterpolator;
  import android.widget.AbsListView;
  import android.widget.FrameLayout;
  
  public class MaterialRefreshLayout extends FrameLayout {
  
      public static final String Tag = MaterialRefreshLayout.class.getSimpleName();
      private final static int DEFAULT_WAVE_HEIGHT = 140;
      private final static int HIGHER_WAVE_HEIGHT = 180;
      private final static int DEFAULT_HEAD_HEIGHT = 70;
      private final static int hIGHER_HEAD_HEIGHT = 100;
      private final static int DEFAULT_PROGRESS_SIZE = 50;
      private final static int BIG_PROGRESS_SIZE = 60;
      private final static int PROGRESS_STOKE_WIDTH = 3;
  
      private MaterialHeaderView mMaterialHeaderView;
      private MaterialFooterView mMaterialFooterView;
      private SunLayout mSunLayout;
      private boolean isOverlay;
      private int waveType;
      private int waveColor;
      protected float mWaveHeight;
      protected float mHeadHeight;
      private View mChildView;
      protected boolean isRefreshing;
      private float mTouchY;
      private float mCurrentY;
      private DecelerateInterpolator decelerateInterpolator;
      private float headHeight;
      private float waveHeight;
      private int[] colorSchemeColors;
      private int colorsId;
      private int progressTextColor;
      private int progressValue, progressMax;
      private boolean showArrow = true;
      private int textType;
      private MaterialRefreshListener refreshListener;
      private boolean showProgressBg;
      private int progressBg;
      private boolean isShowWave;
      private int progressSizeType;
      private int progressSize = 0;
      private boolean isLoadMoreing;
      private boolean isLoadMore;
      private boolean isSunStyle = false;
  
      public MaterialRefreshLayout(Context context) {
          this(context, null, 0);
      }
  
      public MaterialRefreshLayout(Context context, AttributeSet attrs) {
          this(context, attrs, 0);
      }
  
      public MaterialRefreshLayout(Context context, AttributeSet attrs, int defStyleAttr) {
          super(context, attrs, defStyleAttr);
          init(context, attrs, defStyleAttr);
      }
  
      private void init(Context context, AttributeSet attrs, int defstyleAttr) {
          if (isInEditMode()) {
              return;
          }
  
          if (getChildCount() > 1) {
              throw new RuntimeException("can only have one child widget");
          }
  
          decelerateInterpolator = new DecelerateInterpolator(10);
  
  
          TypedArray t = context.obtainStyledAttributes(attrs, R.styleable.MaterialRefreshLayout, defstyleAttr, 0);
          isOverlay = t.getBoolean(R.styleable.MaterialRefreshLayout_overlay, false);
          /**attrs for materialWaveView*/
          waveType = t.getInt(R.styleable.MaterialRefreshLayout_wave_height_type, 0);
          if (waveType == 0) {
              headHeight = DEFAULT_HEAD_HEIGHT;
              waveHeight = DEFAULT_WAVE_HEIGHT;
              MaterialWaveView.DefaulHeadHeight = DEFAULT_HEAD_HEIGHT;
              MaterialWaveView.DefaulWaveHeight = DEFAULT_WAVE_HEIGHT;
          } else {
              headHeight = hIGHER_HEAD_HEIGHT;
              waveHeight = HIGHER_WAVE_HEIGHT;
              MaterialWaveView.DefaulHeadHeight = hIGHER_HEAD_HEIGHT;
              MaterialWaveView.DefaulWaveHeight = HIGHER_WAVE_HEIGHT;
          }
          waveColor = t.getColor(R.styleable.MaterialRefreshLayout_wave_color, Color.WHITE);
          isShowWave = t.getBoolean(R.styleable.MaterialRefreshLayout_wave_show, true);
  
          /**attrs for circleprogressbar*/
          colorsId = t.getResourceId(R.styleable.MaterialRefreshLayout_progress_colors, R.array.material_colors);
          colorSchemeColors = context.getResources().getIntArray(colorsId);
          showArrow = t.getBoolean(R.styleable.MaterialRefreshLayout_progress_show_arrow, true);
          textType = t.getInt(R.styleable.MaterialRefreshLayout_progress_text_visibility, 1);
          progressTextColor = t.getColor(R.styleable.MaterialRefreshLayout_progress_text_color, Color.BLACK);
          progressValue = t.getInteger(R.styleable.MaterialRefreshLayout_progress_value, 0);
          progressMax = t.getInteger(R.styleable.MaterialRefreshLayout_progress_max_value, 100);
          showProgressBg = t.getBoolean(R.styleable.MaterialRefreshLayout_progress_show_circle_backgroud, true);
          progressBg = t.getColor(R.styleable.MaterialRefreshLayout_progress_backgroud_color, CircleProgressBar.DEFAULT_CIRCLE_BG_LIGHT);
          progressSizeType = t.getInt(R.styleable.MaterialRefreshLayout_progress_size_type, 0);
          if (progressSizeType == 0) {
              progressSize = DEFAULT_PROGRESS_SIZE;
          } else {
              progressSize = BIG_PROGRESS_SIZE;
          }
          isLoadMore = t.getBoolean(R.styleable.MaterialRefreshLayout_isLoadMore, false);
          t.recycle();
      }
  
  
      @Override
      protected void onAttachedToWindow() {
          super.onAttachedToWindow();
          Log.i(Tag, "onAttachedToWindow");
  
          Context context = getContext();
  
          mChildView = getChildAt(0);
  
          if (mChildView == null) {
              return;
          }
  
          setWaveHeight(Util.dip2px(context, waveHeight));
          setHeaderHeight(Util.dip2px(context, headHeight));
  
          if (isSunStyle) {
              mSunLayout = new SunLayout(context);
              LayoutParams layoutParams = new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, Util.dip2px(context, hIGHER_HEAD_HEIGHT));
              layoutParams.gravity = Gravity.TOP;
              mSunLayout.setVisibility(View.GONE);
              setHeaderView(mSunLayout);
          } else {
              mMaterialHeaderView = new MaterialHeaderView(context);
              LayoutParams layoutParams = new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, Util.dip2px(context, hIGHER_HEAD_HEIGHT));
              layoutParams.gravity = Gravity.TOP;
              mMaterialHeaderView.setLayoutParams(layoutParams);
              mMaterialHeaderView.setWaveColor(isShowWave ? waveColor : Color.TRANSPARENT);
              mMaterialHeaderView.showProgressArrow(showArrow);
              mMaterialHeaderView.setProgressSize(progressSize);
              mMaterialHeaderView.setProgressColors(colorSchemeColors);
              mMaterialHeaderView.setProgressStokeWidth(PROGRESS_STOKE_WIDTH);
              mMaterialHeaderView.setTextType(textType);
              mMaterialHeaderView.setProgressTextColor(progressTextColor);
              mMaterialHeaderView.setProgressValue(progressValue);
              mMaterialHeaderView.setProgressValueMax(progressMax);
              mMaterialHeaderView.setIsProgressBg(showProgressBg);
              mMaterialHeaderView.setProgressBg(progressBg);
              mMaterialHeaderView.setVisibility(View.GONE);
              setHeaderView(mMaterialHeaderView);
          }
  
  
          mMaterialFooterView = new MaterialFooterView(context);
          LayoutParams layoutParams2 = new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, Util.dip2px(context, hIGHER_HEAD_HEIGHT));
          layoutParams2.gravity = Gravity.BOTTOM;
          mMaterialFooterView.setLayoutParams(layoutParams2);
          mMaterialFooterView.showProgressArrow(showArrow);
          mMaterialFooterView.setProgressSize(progressSize);
          mMaterialFooterView.setProgressColors(colorSchemeColors);
          mMaterialFooterView.setProgressStokeWidth(PROGRESS_STOKE_WIDTH);
          mMaterialFooterView.setTextType(textType);
          mMaterialFooterView.setProgressValue(progressValue);
          mMaterialFooterView.setProgressValueMax(progressMax);
          mMaterialFooterView.setIsProgressBg(showProgressBg);
          mMaterialFooterView.setProgressBg(progressBg);
          mMaterialFooterView.setVisibility(View.GONE);
          setFooderView(mMaterialFooterView);
      }
  
  
      @Override
      public boolean onInterceptTouchEvent(MotionEvent ev) {
          if (isRefreshing) return true;
          switch (ev.getAction()) {
              case MotionEvent.ACTION_DOWN:
                  mTouchY = ev.getY();
                  mCurrentY = mTouchY;
                  break;
              case MotionEvent.ACTION_MOVE:
                  float currentY = ev.getY();
                  float dy = currentY - mTouchY;
                  if (dy > 0 && !canChildScrollUp()) {
                      if (mMaterialHeaderView != null) {
                          mMaterialHeaderView.setVisibility(View.VISIBLE);
                          mMaterialHeaderView.onBegin(this);
                      } else if (mSunLayout != null) {
                          mSunLayout.setVisibility(View.VISIBLE);
                          mSunLayout.onBegin(this);
                      }
                      return true;
                  } else if (dy < 0 && !canChildScrollDown() && isLoadMore) {
                      if (mMaterialFooterView != null && !isLoadMoreing) {
                          soveLoadMoreLogic();
                      }
                      return super.onInterceptTouchEvent(ev);
                  }
                  break;
          }
          return super.onInterceptTouchEvent(ev);
      }
  
      private void soveLoadMoreLogic() {
          isLoadMoreing = true;
          mMaterialFooterView.setVisibility(View.VISIBLE);
          mMaterialFooterView.onBegin(this);
          mMaterialFooterView.onRefreshing(this);
          if (refreshListener != null) {
              refreshListener.onRefreshLoadMore(MaterialRefreshLayout.this);
          }
      }
  
      @Override
      public boolean onTouchEvent(MotionEvent e) {
          if (isRefreshing) {
              return super.onTouchEvent(e);
          }
  
          switch (e.getAction()) {
              case MotionEvent.ACTION_MOVE:
                  mCurrentY = e.getY();
                  float dy = mCurrentY - mTouchY;
                  dy = Math.min(mWaveHeight * 2, dy);
                  dy = Math.max(0, dy);
                  if (mChildView != null) {
                      float offsetY = decelerateInterpolator.getInterpolation(dy / mWaveHeight / 2) * dy / 2;
                      float fraction = offsetY / mHeadHeight;
                      if (mMaterialHeaderView != null) {
                          mMaterialHeaderView.getLayoutParams().height = (int) offsetY;
                          mMaterialHeaderView.requestLayout();
                          mMaterialHeaderView.onPull(this, fraction);
                      } else if (mSunLayout != null) {
                          mSunLayout.getLayoutParams().height = (int) offsetY;
                          mSunLayout.requestLayout();
                          mSunLayout.onPull(this, fraction);
                      }
                      if (!isOverlay)
                          ViewCompat.setTranslationY(mChildView, offsetY);
  
                  }
                  return true;
              case MotionEvent.ACTION_CANCEL:
              case MotionEvent.ACTION_UP:
                  if (mChildView != null) {
                      if (mMaterialHeaderView != null) {
                          if (isOverlay) {
                              if (mMaterialHeaderView.getLayoutParams().height > mHeadHeight) {
  
                                  updateListener();
  
                                  mMaterialHeaderView.getLayoutParams().height = (int) mHeadHeight;
                                  mMaterialHeaderView.requestLayout();
  
                              } else {
                                  mMaterialHeaderView.getLayoutParams().height = 0;
                                  mMaterialHeaderView.requestLayout();
                              }
  
                          } else {
                              if (ViewCompat.getTranslationY(mChildView) >= mHeadHeight) {
                                  createAnimatorTranslationY(mChildView, mHeadHeight, mMaterialHeaderView);
                                  updateListener();
                              } else {
                                  createAnimatorTranslationY(mChildView, 0, mMaterialHeaderView);
                              }
                          }
                      } else if (mSunLayout != null) {
                          if (isOverlay) {
                              if (mSunLayout.getLayoutParams().height > mHeadHeight) {
  
                                  updateListener();
  
                                  mSunLayout.getLayoutParams().height = (int) mHeadHeight;
                                  mSunLayout.requestLayout();
  
                              } else {
                                  mSunLayout.getLayoutParams().height = 0;
                                  mSunLayout.requestLayout();
                              }
  
                          } else {
                              if (ViewCompat.getTranslationY(mChildView) >= mHeadHeight) {
                                  createAnimatorTranslationY(mChildView, mHeadHeight, mSunLayout);
                                  updateListener();
                              } else {
                                  createAnimatorTranslationY(mChildView, 0, mSunLayout);
                              }
                          }
                      }
  
  
                  }
                  return true;
          }
  
          return super.
  
                  onTouchEvent(e);
  
      }
  
      public void setSunStyle(boolean isSunStyle) {
          this.isSunStyle = isSunStyle;
      }
  
      public void autoRefresh() {
          this.postDelayed(new Runnable() {
              @Override
              public void run() {
                  if (!isRefreshing) {
                      if (mMaterialHeaderView != null) {
                          mMaterialHeaderView.setVisibility(View.VISIBLE);
  
                          if (isOverlay) {
                              mMaterialHeaderView.getLayoutParams().height = (int) mHeadHeight;
                              mMaterialHeaderView.requestLayout();
                          } else {
                              createAnimatorTranslationY(mChildView, mHeadHeight, mMaterialHeaderView);
                          }
                      } else if (mSunLayout != null) {
                          mSunLayout.setVisibility(View.VISIBLE);
                          if (isOverlay) {
                              mSunLayout.getLayoutParams().height = (int) mHeadHeight;
                              mSunLayout.requestLayout();
                          } else {
                              createAnimatorTranslationY(mChildView, mHeadHeight, mSunLayout);
                          }
                      }
  
                      updateListener();
  
  
                  }
              }
          }, 50);
  
  
      }
  
      public void autoRefreshLoadMore() {
          this.post(new Runnable() {
              @Override
              public void run() {
                  if (isLoadMore) {
                      soveLoadMoreLogic();
                  } else {
                      throw new RuntimeException("you must setLoadMore ture");
                  }
              }
          });
      }
  
      public void updateListener() {
          isRefreshing = true;
  
          if (mMaterialHeaderView != null) {
              mMaterialHeaderView.onRefreshing(MaterialRefreshLayout.this);
          } else if (mSunLayout != null) {
              mSunLayout.onRefreshing(MaterialRefreshLayout.this);
          }
  
          if (refreshListener != null) {
              refreshListener.onRefresh(MaterialRefreshLayout.this);
          }
  
      }
  
      public void setLoadMore(boolean isLoadMore) {
          this.isLoadMore = isLoadMore;
      }
  
      public void setProgressColors(int[] colors) {
          this.colorSchemeColors = colors;
      }
  
      public void setShowArrow(boolean showArrow) {
          this.showArrow = showArrow;
      }
  
      public void setShowProgressBg(boolean showProgressBg) {
          this.showProgressBg = showProgressBg;
      }
  
      public void setWaveColor(int waveColor) {
          this.waveColor = waveColor;
      }
  
      public void setWaveShow(boolean isShowWave) {
          this.isShowWave = isShowWave;
      }
  
      public void setIsOverLay(boolean isOverLay) {
          this.isOverlay = isOverLay;
      }
  
  //    public void setProgressValue(int progressValue) {
  //        this.progressValue = progressValue;
  //        mMaterialHeaderView.setProgressValue(progressValue);
  //    }
  
      public void createAnimatorTranslationY(final View v, final float h, final FrameLayout fl) {
          ViewPropertyAnimatorCompat viewPropertyAnimatorCompat = ViewCompat.animate(v);
          viewPropertyAnimatorCompat.setDuration(250);
          viewPropertyAnimatorCompat.setInterpolator(new DecelerateInterpolator());
          viewPropertyAnimatorCompat.translationY(h);
          viewPropertyAnimatorCompat.start();
          viewPropertyAnimatorCompat.setUpdateListener(new ViewPropertyAnimatorUpdateListener() {
              @Override
              public void onAnimationUpdate(View view) {
                  float height = ViewCompat.getTranslationY(v);
                  fl.getLayoutParams().height = (int) height;
                  fl.requestLayout();
              }
          });
      }
  
      /**
       * @return Whether it is possible for the child view of this layout to
       * scroll up. Override this if the child view is a custom view.
       */
      public boolean canChildScrollUp() {
          if (mChildView == null) {
              return false;
          }
          if (Build.VERSION.SDK_INT < 14) {
              if (mChildView instanceof AbsListView) {
                  final AbsListView absListView = (AbsListView) mChildView;
                  return absListView.getChildCount() > 0
                          && (absListView.getFirstVisiblePosition() > 0 || absListView.getChildAt(0)
                          .getTop() < absListView.getPaddingTop());
              } else {
                  return ViewCompat.canScrollVertically(mChildView, -1) || mChildView.getScrollY() > 0;
              }
          } else {
              return ViewCompat.canScrollVertically(mChildView, -1);
          }
      }
  
      public boolean canChildScrollDown() {
          if (mChildView == null) {
              return false;
          }
          if (android.os.Build.VERSION.SDK_INT < 14) {
              if (mChildView instanceof AbsListView) {
                  final AbsListView absListView = (AbsListView) mChildView;
                  if (absListView.getChildCount() > 0) {
                      int lastChildBottom = absListView.getChildAt(absListView.getChildCount() - 1).getBottom();
                      return absListView.getLastVisiblePosition() == absListView.getAdapter().getCount() - 1 && lastChildBottom <= absListView.getMeasuredHeight();
                  } else {
                      return false;
                  }
  
              } else {
                  return ViewCompat.canScrollVertically(mChildView, 1) || mChildView.getScrollY() > 0;
              }
          } else {
              return ViewCompat.canScrollVertically(mChildView, 1);
          }
      }
  
      public void setWaveHigher() {
          headHeight = hIGHER_HEAD_HEIGHT;
          waveHeight = HIGHER_WAVE_HEIGHT;
          MaterialWaveView.DefaulHeadHeight = hIGHER_HEAD_HEIGHT;
          MaterialWaveView.DefaulWaveHeight = HIGHER_WAVE_HEIGHT;
      }
  
      public void finishRefreshing() {
          if (mChildView != null) {
              ViewPropertyAnimatorCompat viewPropertyAnimatorCompat = ViewCompat.animate(mChildView);
              viewPropertyAnimatorCompat.setDuration(200);
              viewPropertyAnimatorCompat.y(ViewCompat.getTranslationY(mChildView));
              viewPropertyAnimatorCompat.translationY(0);
              viewPropertyAnimatorCompat.setInterpolator(new DecelerateInterpolator());
              viewPropertyAnimatorCompat.start();
  
              if (mMaterialHeaderView != null) {
                  mMaterialHeaderView.onComlete(MaterialRefreshLayout.this);
              } else if (mSunLayout != null) {
                  mSunLayout.onComlete(MaterialRefreshLayout.this);
              }
  
              if (refreshListener != null) {
                  refreshListener.onfinish();
              }
          }
          isRefreshing = false;
          progressValue = 0;
      }
  
      public void finishRefresh() {
          this.post(new Runnable() {
              @Override
              public void run() {
                  finishRefreshing();
              }
          });
      }
  
      public void finishRefreshLoadMore() {
          this.post(new Runnable() {
              @Override
              public void run() {
                  if (mMaterialFooterView != null && isLoadMoreing) {
                      isLoadMoreing = false;
                      mMaterialFooterView.onComlete(MaterialRefreshLayout.this);
                  }
              }
          });
  
      }
  
      private void setHeaderView(final View headerView) {
          addView(headerView);
      }
  
      public void setHeader(final View headerView) {
          setHeaderView(headerView);
      }
  
      public void setFooderView(final View fooderView) {
          this.addView(fooderView);
      }
  
  
      public void setWaveHeight(float waveHeight) {
          this.mWaveHeight = waveHeight;
      }
  
      public void setHeaderHeight(float headHeight) {
          this.mHeadHeight = headHeight;
      }
  
      public void setMaterialRefreshListener(MaterialRefreshListener refreshListener) {
          this.refreshListener = refreshListener;
      }
  
  }
  