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(); } }