private void updateHeaderVisibilities() {
   int top = clippingToPadding ? getPaddingTop() : 0;
   int childCount = getChildCount();
   for (int i = 0; i < childCount; i++) {
     View child = getChildAt(i);
     if (adapter.isHeader(child)) {
       if (child.getTop() < top) {
         if (child.getVisibility() != View.INVISIBLE) {
           child.setVisibility(View.INVISIBLE);
         }
       } else {
         if (child.getVisibility() != View.VISIBLE) {
           child.setVisibility(View.VISIBLE);
         }
       }
     }
   }
 }
  private void scrollChanged(int firstVisibleItem) {
    if (adapter == null || frame == null) {
      return;
    }

    int adapterCount = adapter.getCount();
    if (adapterCount == 0 || !areHeadersSticky) {
      frame.removeHeader();
      return;
    }

    final int listViewHeaderCount = getHeaderViewsCount();
    firstVisibleItem = getFixedFirstVisibleItem(firstVisibleItem) - listViewHeaderCount;

    if (firstVisibleItem < 0 || firstVisibleItem > adapterCount - 1) {
      if (currentHeaderId != null || dataChanged) {
        currentHeaderId = null;
        frame.removeHeader();
        updateHeaderVisibilities();
        invalidate();
        dataChanged = false;
      }
      return;
    }

    boolean headerHasChanged = false;
    long newHeaderId = adapter.getHeaderId(firstVisibleItem);
    if (currentHeaderId == null || currentHeaderId != newHeaderId) {
      headerPosition = firstVisibleItem;
      View header = adapter.getHeaderView(headerPosition, frame.removeHeader(), frame);
      header.setOnClickListener(this);
      frame.setHeader(header);
      headerHasChanged = true;
    }
    currentHeaderId = newHeaderId;

    int childCount = getChildCount();

    if (childCount > 0) {
      View viewToWatch = null;
      int watchingChildDistance = Integer.MAX_VALUE;
      boolean viewToWatchIsFooter = false;

      for (int i = 0; i < childCount; i++) {
        View child = getChildAt(i);
        boolean childIsFooter = footerViews != null && footerViews.contains(child);

        int childDistance;
        if (clippingToPadding) {
          childDistance = child.getTop() - getPaddingTop();
        } else {
          childDistance = child.getTop();
        }

        if (childDistance < 0) {
          continue;
        }

        if (viewToWatch == null
            || (!viewToWatchIsFooter && !adapter.isHeader(viewToWatch))
            || ((childIsFooter || adapter.isHeader(child))
                && childDistance < watchingChildDistance)) {
          viewToWatch = child;
          viewToWatchIsFooter = childIsFooter;
          watchingChildDistance = childDistance;
        }
      }

      int headerHeight = frame.getHeaderHeight();
      int headerBottomPosition = 0;
      if (viewToWatch != null && (viewToWatchIsFooter || adapter.isHeader(viewToWatch))) {

        if (firstVisibleItem == listViewHeaderCount
            && getChildAt(0).getTop() > 0
            && !clippingToPadding) {
          headerBottomPosition = 0;
        } else {
          if (clippingToPadding) {
            headerBottomPosition = Math.min(viewToWatch.getTop(), headerHeight + getPaddingTop());
            headerBottomPosition =
                headerBottomPosition < getPaddingTop()
                    ? headerHeight + getPaddingTop()
                    : headerBottomPosition;
          } else {
            headerBottomPosition = Math.min(viewToWatch.getTop(), headerHeight);
            headerBottomPosition = headerBottomPosition < 0 ? headerHeight : headerBottomPosition;
          }
        }
      } else {
        headerBottomPosition = headerHeight;
        if (clippingToPadding) {
          headerBottomPosition += getPaddingTop();
        }
      }
      if (frame.getHeaderBottomPosition() != headerBottomPosition || headerHasChanged) {
        frame.setHeaderBottomPosition(headerBottomPosition);
      }
      updateHeaderVisibilities();
    }
  }