@Override protected void dispatchDraw(Canvas canvas) { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.FROYO) { post( new Runnable() { @Override public void run() { scrollChanged(StickyListHeadersListView.super.getFirstVisiblePosition()); } }); } if (!drawingListUnderStickyHeader) { canvas.clipRect( 0, Math.max(frame.getHeaderBottomPosition(), 0), canvas.getWidth(), canvas.getHeight()); } super.dispatchDraw(canvas); }
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(); } }