Class StickyHeaderContainer
- All Implemented Interfaces:
Animation, Editable, StyleListener, Iterable<Component>
A scrollable container that pins the most recently scrolled-past section
header to the top of its viewport, in the style of the iOS contacts list
or sectioned material lists. As the next section's header rises into the
pinned slot the previous header is replaced through a configurable
scroll-driven transition: a directional slide where the rising header
pushes the pinned one up and out, or a cover where the rising header
progressively slides on top of the pinned one. The outgoing header can
optionally fade out alongside either transition via
setHeaderFadeOut(boolean). Transitions are driven by scroll position
so the visual stays in sync with the user's gesture and there is no
time-based animation that lags behind a slow drag or skips ahead on a
fling.
Sections are added with addSection(header, content). The header is a
real component that participates in the scroll: when it is the active
section's header it is moved into a pinned overlay slot at the top of
the container, and a same-sized invisible placeholder is left behind in
the scroll content so nothing jumps. Because the pinned header is the
same instance, action listeners and child components remain interactive
while it is pinned.
StickyHeaderContainer sticky = new StickyHeaderContainer();
sticky.setTransitionStyle(StickyHeaderContainer.TRANSITION_SLIDE);
for (char c = 'A'; c <= 'Z'; c++) {
Label header = new Label("" + c, "StickyHeader");
Container items = new Container(BoxLayout.y());
for (int i = 0; i < 5; i++) {
items.add(new Label(c + " entry " + i));
}
sticky.addSection(header, items);
}
form.add(BorderLayout.CENTER, sticky);
-
Field Summary
FieldsModifier and TypeFieldDescriptionstatic final intAs the next section's header rises into the pinned slot from below it progressively slides on top of the pinned header, covering it from the bottom up while the pinned header stays fixed in the slot.static final intConvenience equivalent toTRANSITION_SLIDEcombined withsetHeaderFadeOut(boolean)set totrue: the pinned header both slides up and fades to transparency as the rising header closes the gap.static final intReplace the pinned header without any visible movement of the pinned header.static final intAs the next section's header rises into the pinned slot from below it pushes the pinned header up and out of the slot in sync with the scroll, replacing it once the rising header reaches the top.Fields inherited from class Component
BASELINE, BOTTOM, BRB_CENTER_OFFSET, BRB_CONSTANT_ASCENT, BRB_CONSTANT_DESCENT, BRB_OTHER, CENTER, CROSSHAIR_CURSOR, DEFAULT_CURSOR, DRAG_REGION_IMMEDIATELY_DRAG_X, DRAG_REGION_IMMEDIATELY_DRAG_XY, DRAG_REGION_IMMEDIATELY_DRAG_Y, DRAG_REGION_LIKELY_DRAG_X, DRAG_REGION_LIKELY_DRAG_XY, DRAG_REGION_LIKELY_DRAG_Y, DRAG_REGION_NOT_DRAGGABLE, DRAG_REGION_POSSIBLE_DRAG_X, DRAG_REGION_POSSIBLE_DRAG_XY, DRAG_REGION_POSSIBLE_DRAG_Y, E_RESIZE_CURSOR, HAND_CURSOR, LEFT, MOVE_CURSOR, N_RESIZE_CURSOR, NE_RESIZE_CURSOR, NW_RESIZE_CURSOR, RIGHT, S_RESIZE_CURSOR, SE_RESIZE_CURSOR, SW_RESIZE_CURSOR, TEXT_CURSOR, TOP, W_RESIZE_CURSOR, WAIT_CURSOR -
Constructor Summary
Constructors -
Method Summary
Modifier and TypeMethodDescriptionaddSection(Component header) Adds a header-only section.addSection(Component header, Component content) Adds a section consisting of a sticky header and its content.voidRemoves all sections and content from the container.intReturns the index of the currently pinned section, or-1if no header is currently pinned.Returns the inner scrolling container that hosts the section content.intReturns the current scroll position of the inner scroll container.Returns an unmodifiable view of the registered sticky headers in the order they were added.Returns the overlay container that hosts the currently-pinned header.intfloatReturns the progress of the in-flight transition as a fraction in[0, 1]:0when the next section is just touching the slot from below and1when it has fully displaced the pinned header.intbooleanReturns whether the pinned header is configured to fade out during a swap.booleanReturns true while the next section's header is overlapping the pinned slot, i.e.voidPaints the COVER overlay on top of the pinned slot: when the transition style isTRANSITION_COVERand a push is in flight, the rising section's header is rendered again above the pinned host so it visibly slides over the pinned header instead of being hidden underneath it.voidsetHeaderFadeOut(boolean fade) Whentruethe pinned header fades to transparency in proportion to the push progress as the next section rises into the slot.voidsetScrollPosition(int y) Sets the scroll position of the inner scroll container.voidsetTransitionDurationMillis(int millis) Retained for API compatibility.voidsetTransitionStyle(int style) Selects how the pinned header is replaced when the next section rises into the slot.voidRecomputes which section header should be pinned and how far the next section has displaced it.Methods inherited from class Container
add, add, add, add, add, add, addAll, addComponent, addComponent, addComponent, addComponent, animateHierarchy, animateHierarchyAndWait, animateHierarchyFade, animateHierarchyFadeAndWait, animateLayout, animateLayoutAndWait, animateLayoutFade, animateLayoutFadeAndWait, animateUnlayout, animateUnlayoutAndWait, applyRTL, calcPreferredSize, cancelRepaints, clearClientProperties, constrainHeightWhenScrollable, constrainWidthWhenScrollable, contains, createAnimateHierarchy, createAnimateHierarchyFade, createAnimateLayout, createAnimateLayoutFade, createAnimateLayoutFadeAndWait, createAnimateMotion, createAnimateUnlayout, createReplaceTransition, dragInitiated, drop, encloseIn, encloseIn, findDropTargetAt, findFirstFocusable, fireClicked, flushReplace, forceRevalidate, getBottomGap, getChildrenAsList, getClosestComponentTo, getComponentAt, getComponentAt, getComponentCount, getComponentIndex, getGridPosX, getGridPosY, getLayout, getLayoutHeight, getLayoutWidth, getLeadComponent, getLeadParent, getResponderAt, getSafeAreaRoot, getScrollIncrement, getSideGap, getUIManager, initLaf, invalidate, isEnabled, isSafeArea, isSafeAreaRoot, isScrollableX, isScrollableY, isSelectableInteraction, isSurface, iterator, iterator, keyPressed, keyReleased, layoutContainer, morph, morphAndWait, paintComponentBackground, paintGlass, paramString, pointerPressed, refreshTheme, removeAll, removeComponent, replace, replace, replaceAndWait, replaceAndWait, replaceAndWait, revalidate, revalidateLater, revalidateWithAnimationSafety, scrollComponentToVisible, setCellRenderer, setEnabled, setLayout, setLeadComponent, setSafeArea, setSafeAreaRoot, setScrollable, setScrollableX, setScrollableY, setScrollIncrement, setShouldCalcPreferredSize, setShouldLayout, setUIManager, updateTabIndicesMethods inherited from class Component
addDragFinishedListener, addDragOverListener, addDropListener, addFocusListener, addLongPressListener, addPointerDraggedListener, addPointerPressedListener, addPointerReleasedListener, addPullToRefresh, addScrollListener, addStateChangeListener, animate, announceForAccessibility, bindProperty, blocksSideSwipe, calcScrollSize, contains, containsOrOwns, createStyleAnimation, deinitialize, deinitializeCustomStyle, dragEnter, dragExit, dragFinished, draggingOver, drawDraggedImage, focusGained, focusLost, getAbsoluteX, getAbsoluteY, getAccessibilityText, getAllStyles, getAnimationManager, getBaseline, getBaselineResizeBehavior, getBindablePropertyNames, getBindablePropertyTypes, getBorder, getBoundPropertyValue, getBounds, getBounds, getClientProperty, getCloudBoundProperty, getCloudDestinationProperty, getComponentForm, getComponentState, getCursor, getDefaultDragTransparency, getDirtyRegion, getDisabledStyle, getDraggedx, getDraggedy, getDragImage, getDragRegionStatus, getDragSpeed, getDragTransparency, getEditingDelegate, getHeight, getInlineAllStyles, getInlineDisabledStyles, getInlinePressedStyles, getInlineSelectedStyles, getInlineStylesTheme, getInlineUnselectedStyles, getInnerHeight, getInnerPreferredH, getInnerPreferredW, getInnerWidth, getInnerX, getInnerY, getLabelForComponent, getName, getNativeOverlay, getNextFocusDown, getNextFocusLeft, getNextFocusRight, getNextFocusUp, getOuterHeight, getOuterPreferredH, getOuterPreferredW, getOuterWidth, getOuterX, getOuterY, getOwner, getParent, getPreferredH, getPreferredSize, getPreferredSizeStr, getPreferredTabIndex, getPreferredW, getPressedStyle, getPropertyNames, getPropertyTypeNames, getPropertyTypes, getPropertyValue, getSameHeight, getSameWidth, getScrollable, getScrollAnimationSpeed, getScrollDimension, getScrollOpacity, getScrollOpacityChangeSpeed, getScrollX, getScrollY, getSelectCommandText, getSelectedRect, getSelectedStyle, getStyle, getTabIndex, getTensileLength, getTextSelectionSupport, getTooltip, getUIID, getUnselectedStyle, getVisibleBounds, getVisibleBounds, getWidth, getX, getY, growShrink, handlesInput, hasFixedPreferredSize, hasFocus, hideNativeOverlay, initComponent, initCustomStyle, initDisabledStyle, initPressedStyle, initSelectedStyle, initUnselectedStyle, installDefaultPainter, isAlwaysTensile, isBlockLead, isCellRenderer, isChildOf, isDragActivated, isDragAndDropOperation, isDraggable, isDragRegion, isDropTarget, isEditable, isEditing, isFlatten, isFocusable, isGrabsPointerEvents, isHidden, isHidden, isHideInLandscape, isHideInPortrait, isIgnorePointerEvents, isInClippingRegion, isInitialized, isOpaque, isOwnedBy, isPinchBlocksDragAndDrop, isRippleEffect, isRTL, isScrollable, isScrollVisible, isSetCursorSupported, isSmoothScrolling, isSnapToGrid, isStickyDrag, isTactileTouch, isTactileTouch, isTensileDragEnabled, isTraversable, isVisible, keyRepeated, laidOut, longKeyPress, longPointerPress, onScrollX, onScrollY, onSetFocusable, paintBackground, paintBackgrounds, paintBorder, paintBorderBackground, paintComponent, paintComponent, paintIntersectingComponentsAbove, paintLock, paintLockRelease, paintRippleOverlay, paintScrollbars, paintScrollbarX, paintScrollbarY, paintShadows, parsePreferredSize, pinch, pinch, pinchReleased, pointerDragged, pointerDragged, pointerHover, pointerHoverPressed, pointerHoverReleased, pointerPressed, pointerReleased, pointerReleased, putClientProperty, refreshTheme, refreshTheme, remove, removeDragFinishedListener, removeDragOverListener, removeDropListener, removeFocusListener, removeLongPressListener, removePointerDraggedListener, removePointerPressedListener, removePointerReleasedListener, removeScrollListener, removeStateChangeListener, repaint, repaint, requestFocus, resetFocusable, respondsToPointerEvents, scrollRectToVisible, scrollRectToVisible, setAccessibilityText, setAlwaysTensile, setBlockLead, setBoundPropertyValue, setCloudBoundProperty, setCloudDestinationProperty, setComponentState, setCursor, setDefaultDragTransparency, setDirtyRegion, setDisabledStyle, setDraggable, setDragTransparency, setDropTarget, setEditingDelegate, setFlatten, setFocus, setFocusable, setGrabsPointerEvents, setHandlesInput, setHeight, setHidden, setHidden, setHideInLandscape, setHideInPortrait, setIgnorePointerEvents, setInitialized, setInlineAllStyles, setInlineDisabledStyles, setInlinePressedStyles, setInlineSelectedStyles, setInlineStylesTheme, setInlineUnselectedStyles, setIsScrollVisible, setLabelForComponent, setName, setNextFocusDown, setNextFocusLeft, setNextFocusRight, setNextFocusUp, setOpaque, setOwner, setPinchBlocksDragAndDrop, setPreferredH, setPreferredSize, setPreferredSizeStr, setPreferredTabIndex, setPreferredW, setPressedStyle, setPropertyValue, setRippleEffect, setRTL, setSameHeight, setSameSize, setSameWidth, setScrollAnimationSpeed, setScrollOpacityChangeSpeed, setScrollSize, setScrollVisible, setScrollX, setScrollY, setSelectCommandText, setSelectedStyle, setSize, setSmoothScrolling, setSnapToGrid, setTabIndex, setTactileTouch, setTensileDragEnabled, setTensileLength, setTooltip, setTraversable, setUIID, setUIID, setUIIDFinal, setUnselectedStyle, setVisible, setWidth, setX, setY, shouldBlockSideSwipe, shouldBlockSideSwipeLeft, shouldBlockSideSwipeRight, shouldRenderComponentSelection, showNativeOverlay, startEditingAsync, stopEditing, stripMarginAndPadding, styleChanged, toImage, toString, unbindProperty, updateNativeOverlay, visibleBoundsContains
-
Field Details
-
TRANSITION_NONE
public static final int TRANSITION_NONEReplace the pinned header without any visible movement of the pinned header. The rising section's header stays hidden behind the pinned slot during the overlap and the swap is instant once it reaches the slot top. GenerallyTRANSITION_COVERis a more useful choice, since withTRANSITION_NONEthe rising header disappears under the pinned one with no visual feedback that the swap is approaching. Kept for backward compatibility.- See Also:
-
TRANSITION_SLIDE
public static final int TRANSITION_SLIDEAs the next section's header rises into the pinned slot from below it pushes the pinned header up and out of the slot in sync with the scroll, replacing it once the rising header reaches the top.- See Also:
-
TRANSITION_FADE
public static final int TRANSITION_FADEConvenience equivalent toTRANSITION_SLIDEcombined withsetHeaderFadeOut(boolean)set totrue: the pinned header both slides up and fades to transparency as the rising header closes the gap. Prefer composingsetTransitionStyle(TRANSITION_SLIDE)withsetHeaderFadeOut(true)-- orsetTransitionStyle(TRANSITION_COVER)withsetHeaderFadeOut(true)-- when you want a fade-out on top of another transition. Kept for backward compatibility.- See Also:
-
TRANSITION_COVER
public static final int TRANSITION_COVERAs the next section's header rises into the pinned slot from below it progressively slides on top of the pinned header, covering it from the bottom up while the pinned header stays fixed in the slot. The swap happens once the rising header reaches the slot top, at which point it has fully replaced the pinned one with no jump in position. Combine withsetHeaderFadeOut(boolean)to also fade the covered header out during the overlap.- See Also:
-
-
Constructor Details
-
StickyHeaderContainer
public StickyHeaderContainer()Creates an empty sticky header container. Add sections viaaddSection(header, content).
-
-
Method Details
-
paint
Paints the COVER overlay on top of the pinned slot: when the transition style isTRANSITION_COVERand a push is in flight, the rising section's header is rendered again above the pinned host so it visibly slides over the pinned header instead of being hidden underneath it. The natural paint in the scroller is at the same viewport position, so re-painting the header aftersuper.paint(g)simply moves it to the top of the z-order in the slot region; outside that region the second paint draws over identical scroller content and is invisible. No-op for any other transition style or when no swap is mid-flight. -
addSection
Adds a section consisting of a sticky header and its content. The content may benullfor a header-only section. Returns this for chaining. -
addSection
Adds a header-only section. -
getScrollContainer
Returns the inner scrolling container that hosts the section content. Use this to add non-section components such as a footer, or for programmatic scrolling viasetScrollPosition(int). -
getStickyHost
Returns the overlay container that hosts the currently-pinned header. While a section is active its header lives here; otherwise the host is empty and zero-height. -
getStickyHeaders
-
getActiveSectionIndex
public int getActiveSectionIndex()Returns the index of the currently pinned section, or-1if no header is currently pinned. -
setTransitionStyle
public void setTransitionStyle(int style) Selects how the pinned header is replaced when the next section rises into the slot. One ofTRANSITION_NONE,TRANSITION_SLIDE(default),TRANSITION_FADEorTRANSITION_COVER. The fade-out of the pinned header is a separate, composable concern controlled bysetHeaderFadeOut(boolean). -
getTransitionStyle
public int getTransitionStyle() -
setHeaderFadeOut
public void setHeaderFadeOut(boolean fade) Whentruethe pinned header fades to transparency in proportion to the push progress as the next section rises into the slot. This is independent of the transition style and composes withTRANSITION_SLIDE(slide + fade),TRANSITION_COVER(cover + fade) andTRANSITION_NONE(fade only).TRANSITION_FADEimplies the fade-out behaviour regardless of this flag. Defaults tofalse. -
isHeaderFadeOut
public boolean isHeaderFadeOut()Returns whether the pinned header is configured to fade out during a swap. SeesetHeaderFadeOut(boolean). -
setTransitionDurationMillis
public void setTransitionDurationMillis(int millis) Retained for API compatibility. Transitions are now scroll-driven so the per-frame duration no longer affects visuals; the value is validated and stored but otherwise unused. -
getTransitionDurationMillis
public int getTransitionDurationMillis() -
isTransitionInProgress
public boolean isTransitionInProgress()Returns true while the next section's header is overlapping the pinned slot, i.e. the scroll-driven transition is mid-flight. -
getTransitionProgress
public float getTransitionProgress()Returns the progress of the in-flight transition as a fraction in[0, 1]:0when the next section is just touching the slot from below and1when it has fully displaced the pinned header. Returns0when no transition is in progress. -
setScrollPosition
public void setScrollPosition(int y) Sets the scroll position of the inner scroll container. The value is clamped to the valid range and triggers a sticky-header recompute. -
getScrollPosition
public int getScrollPosition()Returns the current scroll position of the inner scroll container. -
clearSections
public void clearSections()Removes all sections and content from the container. -
updateSticky
public void updateSticky()Recomputes which section header should be pinned and how far the next section has displaced it. Called internally on every scroll event; call it explicitly when section content has been mutated outside of a normal layout cycle.
-