@Override public void setAdapter(ListAdapter adapter) { if (this.isInEditMode()) { super.setAdapter(adapter); return; } if (!clipToPaddingHasBeenSet) { clippingToPadding = true; } if (adapter != null && !(adapter instanceof StickyListHeadersAdapter)) { throw new IllegalArgumentException("Adapter must implement StickyListHeadersAdapter"); } if (this.adapter != null) { this.adapter.unregisterInternalDataSetObserver(dataSetChangedObserver); this.adapter = null; } if (adapter != null) { if (adapter instanceof SectionIndexer) { this.adapter = new StickyListHeadersSectionIndexerAdapterWrapper( getContext(), (StickyListHeadersAdapter) adapter); } else { this.adapter = new StickyListHeadersAdapterWrapper(getContext(), (StickyListHeadersAdapter) adapter); } this.adapter.setDivider(divider); this.adapter.setDividerHeight(dividerHeight); this.adapter.registerInternalDataSetObserver(dataSetChangedObserver); setSelectionFromTop(positionToSetWhenAdapterIsReady, offsetToSetWhenAdapterIsReady); } currentHeaderId = null; if (frame != null) { frame.removeHeader(); } updateHeaderVisibilities(); invalidate(); super.setAdapter(this.adapter); }
@Override public void onInvalidated() { currentHeaderId = null; frame.removeHeader(); }
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(); } }