private void updateOrClearHeader(int firstVisiblePosition) {
    final int adapterCount = mAdapter == null ? 0 : mAdapter.getCount();
    if (adapterCount == 0 || !mAreHeadersSticky) {
      return;
    }

    final int headerViewCount = mList.getHeaderViewsCount();
    final int realFirstVisibleItem = firstVisiblePosition - headerViewCount;

    // It is not a mistake to call getFirstVisiblePosition() here.
    // Most of the time getFixedFirstVisibleItem() should be called
    // but that does not work great together with getChildAt()
    final boolean doesListHaveChildren = mList.getChildCount() != 0;
    final boolean isFirstViewBelowTop =
        doesListHaveChildren
            && mList.getFirstVisiblePosition() == 0
            && mList.getChildAt(0).getTop() > 0;
    final boolean isFirstVisibleItemOutsideAdapterRange =
        realFirstVisibleItem > adapterCount - 1 || realFirstVisibleItem < 0;
    if (!doesListHaveChildren || isFirstVisibleItemOutsideAdapterRange || isFirstViewBelowTop) {
      clearHeader();
      return;
    }

    updateHeader(realFirstVisibleItem);
  }
  private void prepareAnimation() {
    yMap.clear();
    positionMap.clear();
    beforeVisible.clear();
    afterVisible.clear();

    adapter.setMayNotify(false);

    final int childCount = getChildCount();

    final int firstVisiblePosition = getFirstVisiblePosition();

    for (int i = 0; i < childCount; i++) {
      final View child = getChildAt(i);
      final long id = adapter.getItemId(firstVisiblePosition + i);

      yMap.put(id, ViewHelper.getY(child));
      positionMap.put(id, firstVisiblePosition + i);
    }

    for (int i = 0; i < firstVisiblePosition; i++) {
      final long id = adapter.getItemId(i);
      beforeVisible.add(id);
    }

    final int count = adapter.getCount();

    for (int i = firstVisiblePosition + childCount; i < count; i++) {
      final long id = adapter.getItemId(i);
      afterVisible.add(id);
    }
  }
  protected int getPositionForId(final long id) {
    for (int i = 0; i < adapter.getCount(); i++) {
      if (adapter.getItemId(i) == id) {
        return i;
      }
    }

    return -1;
  }