@Override
  public boolean onTouchEvent(MotionEvent ev) {
    if (mLastY == -1) {
      mLastY = ev.getRawY();
    }

    switch (ev.getAction()) {
      case MotionEvent.ACTION_DOWN:
        mLastY = ev.getRawY();
        break;

      case MotionEvent.ACTION_MOVE:
        final float deltaY = ev.getRawY() - mLastY;
        mLastY = ev.getRawY();

        if (getFirstVisiblePosition() == 0 && (mHeader.getVisibleHeight() > 0 || deltaY > 0)) {
          // the first item is showing, header has shown or pull down.
          updateHeaderHeight(deltaY / OFFSET_RADIO);
          invokeOnScrolling();

        } else if (getLastVisiblePosition() == mTotalItemCount - 1
            && (mFooterView.getBottomMargin() > 0 || deltaY < 0)) {
          // last item, already pulled up or want to pull up.
          updateFooterHeight(-deltaY / OFFSET_RADIO);
        }
        break;

      default:
        // reset
        mLastY = -1;
        if (getFirstVisiblePosition() == 0) {
          // invoke refresh
          if (mEnablePullRefresh && mHeader.getVisibleHeight() > mHeaderHeight) {
            mPullRefreshing = true;
            mHeader.setState(XHeaderView.STATE_REFRESHING);
            refresh();
          }

          resetHeaderHeight();

        } else if (getLastVisiblePosition() == mTotalItemCount - 1) {
          // invoke load more.
          if (mEnablePullLoad && mFooterView.getBottomMargin() > PULL_LOAD_MORE_DELTA) {
            startLoadMore();
          }
          resetFooterHeight();
        }
        break;
    }
    return super.onTouchEvent(ev);
  }
Beispiel #2
0
  private void initWithContext(Context context) {
    mLayout = (LinearLayout) View.inflate(context, R.layout.vw_xscrollview_layout, null);
    mContentLayout = (LinearLayout) mLayout.findViewById(R.id.content_layout);

    mScroller = new Scroller(context, new DecelerateInterpolator());
    // XScrollView need the scroll event, and it will dispatch the event to user's listener (as a
    // proxy).
    this.setOnScrollListener(this);

    // init header view
    mHeader = new XHeaderView(context);
    mHeaderContent = (RelativeLayout) mHeader.findViewById(R.id.header_content);
    mHeaderTime = (TextView) mHeader.findViewById(R.id.header_hint_time);
    LinearLayout headerLayout = (LinearLayout) mLayout.findViewById(R.id.header_layout);
    headerLayout.addView(mHeader);

    // init footer view
    mFooterView = new XFooterView(context);
    LinearLayout.LayoutParams params =
        new LinearLayout.LayoutParams(
            LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT);
    params.gravity = Gravity.CENTER;
    LinearLayout footLayout = (LinearLayout) mLayout.findViewById(R.id.footer_layout);
    footLayout.addView(mFooterView, params);

    // init header height
    ViewTreeObserver observer = mHeader.getViewTreeObserver();
    if (null != observer) {
      observer.addOnGlobalLayoutListener(
          new OnGlobalLayoutListener() {
            @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
            @SuppressWarnings("deprecation")
            @Override
            public void onGlobalLayout() {
              mHeaderHeight = mHeaderContent.getHeight();
              ViewTreeObserver observer = getViewTreeObserver();
              if (null != observer) {
                if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
                  observer.removeGlobalOnLayoutListener(this);
                } else {
                  observer.removeOnGlobalLayoutListener(this);
                }
              }
            }
          });
    }

    this.addView(mLayout);
  }
  private void updateHeaderHeight(float delta) {
    mHeader.setVisibleHeight((int) delta + mHeader.getVisibleHeight());

    if (mEnablePullRefresh && !mPullRefreshing) {
      // update the arrow image unrefreshing
      if (mHeader.getVisibleHeight() > mHeaderHeight) {
        mHeader.setState(XHeaderView.STATE_READY);
      } else {
        mHeader.setState(XHeaderView.STATE_NORMAL);
      }
    }

    // scroll to top each time
    setSelection(0);
  }
  /** Auto call back refresh. */
  public void autoRefresh() {
    mHeader.setVisibleHeight(mHeaderHeight);

    if (mEnablePullRefresh && !mPullRefreshing) {
      // update the arrow image not refreshing
      if (mHeader.getVisibleHeight() > mHeaderHeight) {
        mHeader.setState(XHeaderView.STATE_READY);
      } else {
        mHeader.setState(XHeaderView.STATE_NORMAL);
      }
    }

    mPullRefreshing = true;
    mHeader.setState(XHeaderView.STATE_REFRESHING);
    refresh();
  }
Beispiel #5
0
  private void resetHeaderOrBottom() {
    if (isTop()) {
      // invoke refresh
      if (mEnablePullRefresh && mHeader.getVisibleHeight() > mHeaderHeight) {
        mPullRefreshing = true;
        mHeader.setState(XHeaderView.STATE_REFRESHING);
        refresh();
      }
      resetHeaderHeight();

    } else if (isBottom()) {
      // invoke load more.
      if (mEnablePullLoad && mFooterView.getBottomMargin() > PULL_LOAD_MORE_DELTA) {
        startLoadMore();
      }
      resetFooterHeight();
    }
  }
  private void initWithContext(Context context) {
    mScroller = new Scroller(context, new DecelerateInterpolator());
    super.setOnScrollListener(this);

    // init header view
    mHeader = new XHeaderView(context);
    mHeaderContent = (RelativeLayout) mHeader.findViewById(R.id.header_content);
    mHeaderTime = (TextView) mHeader.findViewById(R.id.header_hint_time);
    addHeaderView(mHeader);

    // init footer view
    mFooterView = new XFooterView(context);
    mFooterLayout = new LinearLayout(context);
    LinearLayout.LayoutParams params =
        new LinearLayout.LayoutParams(
            LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT);
    params.gravity = Gravity.CENTER;
    mFooterLayout.addView(mFooterView, params);

    // init header height
    ViewTreeObserver observer = mHeader.getViewTreeObserver();
    if (null != observer) {
      observer.addOnGlobalLayoutListener(
          new OnGlobalLayoutListener() {
            @SuppressWarnings("deprecation")
            @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
            @Override
            public void onGlobalLayout() {
              mHeaderHeight = mHeaderContent.getHeight();
              ViewTreeObserver observer = getViewTreeObserver();

              if (null != observer) {
                if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
                  observer.removeGlobalOnLayoutListener(this);
                } else {
                  observer.removeOnGlobalLayoutListener(this);
                }
              }
            }
          });
    }
  }
Beispiel #7
0
  private void updateHeaderHeight(float delta) {
    mHeader.setVisibleHeight((int) delta + mHeader.getVisibleHeight());

    if (mEnablePullRefresh && !mPullRefreshing) {
      // update the arrow image unrefreshing
      if (mHeader.getVisibleHeight() > mHeaderHeight) {
        mHeader.setState(XHeaderView.STATE_READY);
      } else {
        mHeader.setState(XHeaderView.STATE_NORMAL);
      }
    }

    // scroll to top each time
    post(
        new Runnable() {
          @Override
          public void run() {
            XScrollView.this.fullScroll(ScrollView.FOCUS_UP);
          }
        });
  }
Beispiel #8
0
  @Override
  public void computeScroll() {
    if (mScroller.computeScrollOffset()) {
      if (mScrollBack == SCROLL_BACK_HEADER) {
        mHeader.setVisibleHeight(mScroller.getCurrY());
      } else {
        mFooterView.setBottomMargin(mScroller.getCurrY());
      }

      postInvalidate();
      invokeOnScrolling();
    }
    super.computeScroll();
  }
  private void resetHeaderHeight() {
    int height = mHeader.getVisibleHeight();
    if (height == 0) return;

    // refreshing and header isn't shown fully. do nothing.
    if (mPullRefreshing && height <= mHeaderHeight) return;

    // default: scroll back to dismiss header.
    int finalHeight = 0;
    // is refreshing, just scroll back to show all the header.
    if (mPullRefreshing && height > mHeaderHeight) {
      finalHeight = mHeaderHeight;
    }

    mScrollBack = SCROLL_BACK_HEADER;
    mScroller.startScroll(0, height, 0, finalHeight - height, SCROLL_DURATION);

    // trigger computeScroll
    invalidate();
  }
Beispiel #10
0
  @Override
  public boolean onTouchEvent(MotionEvent ev) {
    if (mLastY == -1) {
      mLastY = ev.getRawY();
    }

    switch (ev.getAction()) {
      case MotionEvent.ACTION_DOWN:
        mLastY = ev.getRawY();
        break;

      case MotionEvent.ACTION_MOVE:
        final float deltaY = ev.getRawY() - mLastY;
        mLastY = ev.getRawY();

        if (isTop() && (mHeader.getVisibleHeight() > 0 || deltaY > 0)) {
          // the first item is showing, header has shown or pull down.
          updateHeaderHeight(deltaY / OFFSET_RADIO);
          invokeOnScrolling();

        } else if (isBottom() && (mFooterView.getBottomMargin() > 0 || deltaY < 0)) {
          // last item, already pulled up or want to pull up.
          updateFooterHeight(-deltaY / OFFSET_RADIO);
        }
        break;

      default:
        // reset
        mLastY = -1;

        resetHeaderOrBottom();
        break;
    }

    return super.onTouchEvent(ev);
  }
Beispiel #11
0
 private boolean isTop() {
   return getScrollY() <= 0
       || mHeader.getVisibleHeight() > mHeaderHeight
       || mContentLayout.getTop() > 0;
 }