Subclasses:
HorizontalGridView, VerticalGridView
Gradle dependencies
compile group: 'androidx.leanback', name: 'leanback-grid', version: '1.0.0-alpha03'
- groupId: androidx.leanback
- artifactId: leanback-grid
- version: 1.0.0-alpha03
Artifact androidx.leanback:leanback-grid:1.0.0-alpha03 it located at Google repository (https://maven.google.com/)
Androidx class mapping:
androidx.leanback.widget.BaseGridView android.support.v17.leanback.widget.BaseGridView
Overview
An abstract base class for vertically and horizontally scrolling lists. The items come
from the associated with this view.
Do not directly use this class, use VerticalGridView and HorizontalGridView.
The class is not intended to be subclassed other than VerticalGridView and
HorizontalGridView.
Summary
Fields |
---|
public static final int | FOCUS_SCROLL_ALIGNED Always keep focused item at a aligned position. |
public static final int | FOCUS_SCROLL_ITEM Scroll to make the focused item inside client area. |
public static final int | FOCUS_SCROLL_PAGE Scroll a page of items when focusing to item outside the client area. |
public static final float | ITEM_ALIGN_OFFSET_PERCENT_DISABLED Value indicates that percent is not used. |
public static final int | SAVE_ALL_CHILD Save on screen views plus save off screen child views without any limitation. |
public static final int | SAVE_LIMITED_CHILD Save on screen views plus save off screen child views states up to
BaseGridView.getSaveChildrenLimitNumber(). |
public static final int | SAVE_NO_CHILD Dont save states of any child views. |
public static final int | SAVE_ON_SCREEN_CHILD Only save on screen child views, the states are lost when they become off screen. |
public static final int | WINDOW_ALIGN_BOTH_EDGE The first item and last item are aligned with the two edges of the
viewport. |
public static final int | WINDOW_ALIGN_HIGH_EDGE The last item is aligned with the high edge of the viewport when
navigating to the end of list. |
public static final int | WINDOW_ALIGN_LOW_EDGE The first item is aligned with the low edge of the viewport. |
public static final int | WINDOW_ALIGN_NO_EDGE The focused item always stays in a key line location. |
public static final float | WINDOW_ALIGN_OFFSET_PERCENT_DISABLED Value indicates that percent is not used. |
from RecyclerView | HORIZONTAL, INVALID_TYPE, NO_ID, NO_POSITION, SCROLL_STATE_DRAGGING, SCROLL_STATE_IDLE, SCROLL_STATE_SETTLING, TOUCH_SLOP_DEFAULT, TOUCH_SLOP_PAGING, UNDEFINED_DURATION, VERTICAL |
Methods |
---|
public void | addOnChildViewHolderSelectedListener(OnChildViewHolderSelectedListener listener)
Registers a callback to be invoked when an item in BaseGridView has
been selected. |
public final void | addOnLayoutCompletedListener(BaseGridView.OnLayoutCompletedListener listener)
Registers a callback to be invoked when the BaseGridView completes a full layout calculation. |
public void | animateIn()
Undo animateOut() and slide in child views. |
public void | animateOut()
Temporarily slide out child views to bottom (for VerticalGridView) or end
(for HorizontalGridView). |
protected boolean | dispatchGenericFocusedEvent(MotionEvent event)
|
public boolean | dispatchKeyEvent(KeyEvent event)
|
public boolean | dispatchTouchEvent(MotionEvent event)
|
public View | focusSearch(int direction)
|
public int | getChildDrawingOrder(int childCount, int i)
|
public int | getExtraLayoutSpace()
Returns pixels of extra space for layout child in invisible area. |
public int | getFocusScrollStrategy()
Returns the strategy used to scroll in response to item focus changing. |
public int | getHorizontalMargin()
Returns the spacing in pixels between two child items horizontally. |
public int | getHorizontalSpacing()
Returns the horizontal spacing in pixels between two child items. |
public int | getInitialPrefetchItemCount()
Gets the number of items to prefetch in
,
which defines how many inner items should be prefetched when this GridView is nested inside
another RecyclerView. |
public int | getItemAlignmentOffset()
Returns number of pixels to the end of low edge. |
public float | getItemAlignmentOffsetPercent()
Returns the offset percent for item alignment in addition to BaseGridView.getItemAlignmentOffset(). |
public int | getItemAlignmentViewId()
Returns the id of the view to align with, or android.view.View for the root
. |
public BaseGridView.OnUnhandledKeyListener | getOnUnhandledKeyListener()
Returns the unhandled key listener. |
public final int | getSaveChildrenLimitNumber()
Returns the limit used when when BaseGridView.getSaveChildrenPolicy() is
BaseGridView.SAVE_LIMITED_CHILD |
public final int | getSaveChildrenPolicy()
Returns the policy for saving children. |
public int | getSelectedPosition()
Returns the adapter position of selected item. |
public int | getSelectedSubPosition()
Returns the sub selected item position started from zero. |
public BaseGridView.SmoothScrollByBehavior | getSmoothScrollByBehavior()
Returns custom behavior for smoothScrollBy(). |
public final int | getSmoothScrollMaxPendingMoves()
When holding DPAD, DPAD events are generated faster than the grid view can scroll. |
public final float | getSmoothScrollSpeedFactor()
|
public int | getVerticalMargin()
Returns the spacing in pixels between two child items vertically. |
public int | getVerticalSpacing()
Returns the vertical spacing in pixels between two child items. |
public void | getViewSelectedOffsets(View view, int[] offsets[])
Returns the x/y offsets to final position from current position if the view
is selected. |
public int | getWindowAlignment()
Returns the method for focused item alignment in the view. |
public int | getWindowAlignmentOffset()
Returns the offset in pixels for window alignment key line. |
public float | getWindowAlignmentOffsetPercent()
Returns the offset percent for window alignment key line in addition to
BaseGridView.getWindowAlignmentOffset(). |
public boolean | hasOverlappingRendering()
|
public boolean | hasPreviousViewInSameRow(int position)
Returns true if the view at the given position has a same row sibling
in front of it. |
public boolean | isChildLayoutAnimated()
Returns true if an animation will run when a child changes size or when
adding or removing a child. |
public boolean | isFocusDrawingOrderEnabled()
Returns true if draws selected child at last, false otherwise. |
public final boolean | isFocusSearchDisabled()
Returns true if focus search is disabled. |
public boolean | isItemAlignmentOffsetWithPadding()
Returns true if applies padding to item alignment when
BaseGridView.getItemAlignmentOffsetPercent() is 0 or 100; returns false otherwise. |
public boolean | isScrollEnabled()
Returns true if scrolling is enabled, false otherwise. |
public boolean | isWindowAlignmentPreferKeyLineOverHighEdge()
Returns whether prefer key line over high edge when BaseGridView.WINDOW_ALIGN_HIGH_EDGE is used. |
public boolean | isWindowAlignmentPreferKeyLineOverLowEdge()
Returns whether prefer key line over low edge when BaseGridView.WINDOW_ALIGN_LOW_EDGE is used. |
protected void | onFocusChanged(boolean gainFocus, int direction, Rect previouslyFocusedRect)
|
public boolean | onRequestFocusInDescendants(int direction, Rect previouslyFocusedRect)
|
public void | onRtlPropertiesChanged(int layoutDirection)
Notify layout manager that layout directionality has been updated |
public void | removeOnChildViewHolderSelectedListener(OnChildViewHolderSelectedListener listener)
Remove the callback invoked when an item in BaseGridView has been selected. |
public final void | removeOnLayoutCompletedListener(BaseGridView.OnLayoutCompletedListener listener)
Removes a callback to be invoked when the BaseGridView completes a full layout calculation. |
public void | removeView(View view)
|
public void | removeViewAt(int index)
|
public void | scrollToPosition(int position)
Convenience method to scroll to a certain position. |
public void | setAnimateChildLayout(boolean animateChildLayout)
Sets whether ItemAnimator should run when a child changes size or when adding
or removing a child. |
public void | setChildrenVisibility(int visibility)
Changes and overrides children's visibility. |
public void | setExtraLayoutSpace(int extraLayoutSpace)
Sets pixels of extra space for layout child in invisible area. |
public void | setFocusDrawingOrderEnabled(boolean enabled)
Enables or disables the default "focus draw at last" order rule. |
public void | setFocusScrollStrategy(int scrollStrategy)
Sets the strategy used to scroll in response to item focus changing:
|
public final void | setFocusSearchDisabled(boolean disabled)
Disables or enables focus search. |
public void | setGravity(int gravity)
Sets the gravity used for child view positioning. |
public void | setHasOverlappingRendering(boolean hasOverlapping)
|
public void | setHorizontalMargin(int margin)
Sets the spacing in pixels between two child items horizontally. |
public void | setHorizontalSpacing(int spacing)
Sets the horizontal spacing in pixels between two child items. |
public void | setInitialPrefetchItemCount(int itemCount)
Sets the number of items to prefetch in
,
which defines how many inner items should be prefetched when this GridView is nested inside
another RecyclerView. |
public void | setItemAlignmentOffset(int offset)
Sets number of pixels to the end of low edge. |
public void | setItemAlignmentOffsetPercent(float offsetPercent)
Sets the offset percent for item alignment in addition to BaseGridView.getItemAlignmentOffset(). |
public void | setItemAlignmentOffsetWithPadding(boolean withPadding)
Sets whether applies padding to item alignment when BaseGridView.getItemAlignmentOffsetPercent()
is 0 or 100. |
public void | setItemAlignmentViewId(int viewId)
Sets the id of the view to align with. |
public void | setItemMargin(int margin)
Sets the spacing in pixels between two child items. |
public void | setItemSpacing(int spacing)
Sets the vertical and horizontal spacing in pixels between two child items. |
public void | setLayoutEnabled(boolean layoutEnabled)
Enables or disables layout. |
public void | setLayoutManager(RecyclerView.LayoutManager layout)
Set the RecyclerView.LayoutManager that this RecyclerView will use. |
public void | setOnChildLaidOutListener(OnChildLaidOutListener listener)
Registers a callback to be invoked when an item in BaseGridView has
been laid out. |
public void | setOnChildSelectedListener(OnChildSelectedListener listener)
Registers a callback to be invoked when an item in BaseGridView has
been selected. |
public void | setOnChildViewHolderSelectedListener(OnChildViewHolderSelectedListener listener)
Registers a callback to be invoked when an item in BaseGridView has
been selected. |
public void | setOnKeyInterceptListener(BaseGridView.OnKeyInterceptListener listener)
Sets the key intercept listener. |
public void | setOnMotionInterceptListener(BaseGridView.OnMotionInterceptListener listener)
Sets the generic motion intercept listener. |
public void | setOnTouchInterceptListener(BaseGridView.OnTouchInterceptListener listener)
Sets the touch intercept listener. |
public void | setOnUnhandledKeyListener(BaseGridView.OnUnhandledKeyListener listener)
Sets the unhandled key listener. |
public void | setPruneChild(boolean pruneChild)
Enables or disables pruning of children. |
public final void | setSaveChildrenLimitNumber(int limitNumber)
Sets the limit number when BaseGridView.getSaveChildrenPolicy() is BaseGridView.SAVE_LIMITED_CHILD. |
public final void | setSaveChildrenPolicy(int savePolicy)
Sets the policy for saving children. |
public void | setScrollEnabled(boolean scrollEnabled)
Enables or disables scrolling. |
public void | setSelectedPosition(int position)
Changes the selected item immediately without animation. |
public void | setSelectedPosition(int position, int scrollExtra)
Changes the selected item immediately without animation, scrollExtra is
applied in primary scroll direction. |
public void | setSelectedPosition(int position, ViewHolderTask task)
Perform a task on ViewHolder at given position after scroll to it. |
public void | setSelectedPositionSmooth(int position)
Changes the selected item and run an animation to scroll to the target
position. |
public void | setSelectedPositionSmooth(int position, ViewHolderTask task)
Perform a task on ViewHolder at given position after smooth scrolling to it. |
public void | setSelectedPositionSmoothWithSub(int position, int subposition)
Changes the selected item and/or subposition, runs an animation to scroll to the target
position. |
public void | setSelectedPositionWithSub(int position, int subposition)
Changes the selected item and/or subposition immediately without animation. |
public void | setSelectedPositionWithSub(int position, int subposition, int scrollExtra)
Changes the selected item and/or subposition immediately without animation, scrollExtra is
applied in primary scroll direction. |
public final void | setSmoothScrollByBehavior(BaseGridView.SmoothScrollByBehavior behavior)
Set custom behavior for smoothScrollBy(). |
public final void | setSmoothScrollMaxPendingMoves(int maxPendingMoves)
When holding DPAD, DPAD events are generated faster than the grid view can scroll. |
public final void | setSmoothScrollSpeedFactor(float smoothScrollSpeedFactor)
Set factor of how slow the smoothScroller should run. |
public void | setVerticalMargin(int margin)
Sets the spacing in pixels between two child items vertically. |
public void | setVerticalSpacing(int spacing)
Sets the vertical spacing in pixels between two child items. |
public void | setWindowAlignment(int windowAlignment)
Sets the method for focused item alignment in the view. |
public void | setWindowAlignmentOffset(int offset)
Sets the offset in pixels for window alignment key line. |
public void | setWindowAlignmentOffsetPercent(float offsetPercent)
Sets the offset percent for window alignment key line in addition to BaseGridView.getWindowAlignmentOffset(). |
public void | setWindowAlignmentPreferKeyLineOverHighEdge(boolean preferKeyLineOverHighEdge)
Returns whether prefer key line over high edge when BaseGridView.WINDOW_ALIGN_HIGH_EDGE is used. |
public void | setWindowAlignmentPreferKeyLineOverLowEdge(boolean preferKeyLineOverLowEdge)
Sets whether prefer key line over low edge when BaseGridView.WINDOW_ALIGN_LOW_EDGE is used. |
public void | smoothScrollBy(int dx, int dy)
Animate a scroll by the given amount of pixels along either axis. |
public void | smoothScrollBy(int dx, int dy, Interpolator interpolator)
Animate a scroll by the given amount of pixels along either axis. |
public void | smoothScrollToPosition(int position)
Starts a smooth scroll to an adapter position. |
from RecyclerView | addFocusables, addItemDecoration, addItemDecoration, addOnChildAttachStateChangeListener, addOnItemTouchListener, addOnScrollListener, addRecyclerListener, checkLayoutParams, clearOnChildAttachStateChangeListeners, clearOnScrollListeners, computeHorizontalScrollExtent, computeHorizontalScrollOffset, computeHorizontalScrollRange, computeVerticalScrollExtent, computeVerticalScrollOffset, computeVerticalScrollRange, dispatchNestedFling, dispatchNestedPreFling, dispatchNestedPreScroll, dispatchNestedPreScroll, dispatchNestedScroll, dispatchNestedScroll, dispatchNestedScroll, dispatchPopulateAccessibilityEvent, dispatchRestoreInstanceState, dispatchSaveInstanceState, draw, drawChild, findChildViewUnder, findContainingItemView, findContainingViewHolder, findViewHolderForAdapterPosition, findViewHolderForItemId, findViewHolderForLayoutPosition, findViewHolderForPosition, fling, focusSearch, generateDefaultLayoutParams, generateLayoutParams, generateLayoutParams, getAccessibilityClassName, getAdapter, getBaseline, getChildAdapterPosition, getChildItemId, getChildLayoutPosition, getChildPosition, getChildViewHolder, getClipToPadding, getCompatAccessibilityDelegate, getDecoratedBoundsWithMargins, getEdgeEffectFactory, getItemAnimator, getItemDecorationAt, getItemDecorationCount, getLayoutManager, getMaxFlingVelocity, getMinFlingVelocity, getOnFlingListener, getPreserveFocusAfterLayout, getRecycledViewPool, getScrollState, hasFixedSize, hasNestedScrollingParent, hasNestedScrollingParent, hasPendingAdapterUpdates, invalidateItemDecorations, isAnimating, isAttachedToWindow, isComputingLayout, isLayoutFrozen, isLayoutSuppressed, isNestedScrollingEnabled, nestedScrollBy, offsetChildrenHorizontal, offsetChildrenVertical, onAttachedToWindow, onChildAttachedToWindow, onChildDetachedFromWindow, onDetachedFromWindow, onDraw, onGenericMotionEvent, onInterceptTouchEvent, onLayout, onMeasure, onRestoreInstanceState, onSaveInstanceState, onScrolled, onScrollStateChanged, onSizeChanged, onTouchEvent, removeDetachedView, removeItemDecoration, removeItemDecorationAt, removeOnChildAttachStateChangeListener, removeOnItemTouchListener, removeOnScrollListener, removeRecyclerListener, requestChildFocus, requestChildRectangleOnScreen, requestDisallowInterceptTouchEvent, requestLayout, scrollBy, scrollTo, sendAccessibilityEventUnchecked, setAccessibilityDelegateCompat, setAdapter, setChildDrawingOrderCallback, setClipToPadding, setDebugAssertionsEnabled, setEdgeEffectFactory, setHasFixedSize, setItemAnimator, setItemViewCacheSize, setLayoutFrozen, setLayoutTransition, setNestedScrollingEnabled, setOnFlingListener, setOnScrollListener, setPreserveFocusAfterLayout, setRecycledViewPool, setRecyclerListener, setScrollingTouchSlop, setVerboseLoggingEnabled, setViewCacheExtension, smoothScrollBy, startNestedScroll, startNestedScroll, stopNestedScroll, stopNestedScroll, stopScroll, suppressLayout, swapAdapter |
from java.lang.Object | clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait |
Fields
public static final int
FOCUS_SCROLL_ALIGNEDAlways keep focused item at a aligned position. Developer can use
WINDOW_ALIGN_XXX and ITEM_ALIGN_XXX to define how focused item is aligned.
In this mode, the last focused position will be remembered and restored when focus
is back to the view.
public static final int
FOCUS_SCROLL_ITEMScroll to make the focused item inside client area.
public static final int
FOCUS_SCROLL_PAGEScroll a page of items when focusing to item outside the client area.
The page size matches the client area size of RecyclerView.
public static final int
WINDOW_ALIGN_LOW_EDGEThe first item is aligned with the low edge of the viewport. When
navigating away from the first item, the focus item is aligned to a key line location.
For HorizontalGridView, low edge refers to getPaddingLeft() when RTL is false or
getWidth() - getPaddingRight() when RTL is true.
For VerticalGridView, low edge refers to getPaddingTop().
The key line location is calculated by "windowAlignOffset" and
"windowAlignOffsetPercent"; if neither of these two is defined, the
default value is 1/2 of the size.
Note if there are very few items between low edge and key line, use
BaseGridView.setWindowAlignmentPreferKeyLineOverLowEdge(boolean) to control whether you prefer
to align the items to key line or low edge. Default is preferring low edge.
public static final int
WINDOW_ALIGN_HIGH_EDGEThe last item is aligned with the high edge of the viewport when
navigating to the end of list. When navigating away from the end, the
focus item is aligned to a key line location.
For HorizontalGridView, high edge refers to getWidth() - getPaddingRight() when RTL is false
or getPaddingLeft() when RTL is true.
For VerticalGridView, high edge refers to getHeight() - getPaddingBottom().
The key line location is calculated by "windowAlignOffset" and
"windowAlignOffsetPercent"; if neither of these two is defined, the
default value is 1/2 of the size.
Note if there are very few items between high edge and key line, use
BaseGridView.setWindowAlignmentPreferKeyLineOverHighEdge(boolean) to control whether you prefer
to align the items to key line or high edge. Default is preferring key line.
public static final int
WINDOW_ALIGN_BOTH_EDGEThe first item and last item are aligned with the two edges of the
viewport. When navigating in the middle of list, the focus maintains a
key line location.
The key line location is calculated by "windowAlignOffset" and
"windowAlignOffsetPercent"; if neither of these two is defined, the
default value is 1/2 of the size.
public static final int
WINDOW_ALIGN_NO_EDGEThe focused item always stays in a key line location.
The key line location is calculated by "windowAlignOffset" and
"windowAlignOffsetPercent"; if neither of these two is defined, the
default value is 1/2 of the size.
public static final float
WINDOW_ALIGN_OFFSET_PERCENT_DISABLEDValue indicates that percent is not used.
public static final float
ITEM_ALIGN_OFFSET_PERCENT_DISABLEDValue indicates that percent is not used.
public static final int
SAVE_NO_CHILDDont save states of any child views.
public static final int
SAVE_ON_SCREEN_CHILDOnly save on screen child views, the states are lost when they become off screen.
public static final int
SAVE_LIMITED_CHILDSave on screen views plus save off screen child views states up to
BaseGridView.getSaveChildrenLimitNumber().
public static final int
SAVE_ALL_CHILDSave on screen views plus save off screen child views without any limitation.
This might cause out of memory, only use it when you are dealing with limited data.
Methods
public void
setFocusScrollStrategy(int scrollStrategy)
Sets the strategy used to scroll in response to item focus changing:
public int
getFocusScrollStrategy()
Returns the strategy used to scroll in response to item focus changing.
public void
setWindowAlignment(int windowAlignment)
Sets the method for focused item alignment in the view.
Parameters:
windowAlignment: BaseGridView.WINDOW_ALIGN_BOTH_EDGE,
BaseGridView.WINDOW_ALIGN_LOW_EDGE, BaseGridView.WINDOW_ALIGN_HIGH_EDGE or
BaseGridView.WINDOW_ALIGN_NO_EDGE.
public int
getWindowAlignment()
Returns the method for focused item alignment in the view.
Returns:
BaseGridView.WINDOW_ALIGN_BOTH_EDGE, BaseGridView.WINDOW_ALIGN_LOW_EDGE,
BaseGridView.WINDOW_ALIGN_HIGH_EDGE or BaseGridView.WINDOW_ALIGN_NO_EDGE.
public void
setWindowAlignmentPreferKeyLineOverLowEdge(boolean preferKeyLineOverLowEdge)
Sets whether prefer key line over low edge when BaseGridView.WINDOW_ALIGN_LOW_EDGE is used.
When true, if there are very few items between low edge and key line, align items to key
line instead of align items to low edge.
Default value is false (aka prefer align to low edge).
Parameters:
preferKeyLineOverLowEdge: True to prefer key line over low edge, false otherwise.
public void
setWindowAlignmentPreferKeyLineOverHighEdge(boolean preferKeyLineOverHighEdge)
Returns whether prefer key line over high edge when BaseGridView.WINDOW_ALIGN_HIGH_EDGE is used.
When true, if there are very few items between high edge and key line, align items to key
line instead of align items to high edge.
Default value is true (aka prefer align to key line).
Parameters:
preferKeyLineOverHighEdge: True to prefer key line over high edge, false otherwise.
public boolean
isWindowAlignmentPreferKeyLineOverLowEdge()
Returns whether prefer key line over low edge when BaseGridView.WINDOW_ALIGN_LOW_EDGE is used.
When true, if there are very few items between low edge and key line, align items to key
line instead of align items to low edge.
Default value is false (aka prefer align to low edge).
Returns:
True to prefer key line over low edge, false otherwise.
public boolean
isWindowAlignmentPreferKeyLineOverHighEdge()
Returns whether prefer key line over high edge when BaseGridView.WINDOW_ALIGN_HIGH_EDGE is used.
When true, if there are very few items between high edge and key line, align items to key
line instead of align items to high edge.
Default value is true (aka prefer align to key line).
Returns:
True to prefer key line over high edge, false otherwise.
public void
setWindowAlignmentOffset(int offset)
Sets the offset in pixels for window alignment key line.
Parameters:
offset: The number of pixels to offset. If the offset is positive,
it is distance from low edge (see BaseGridView.WINDOW_ALIGN_LOW_EDGE);
if the offset is negative, the absolute value is distance from high
edge (see BaseGridView.WINDOW_ALIGN_HIGH_EDGE).
Default value is 0.
public int
getWindowAlignmentOffset()
Returns the offset in pixels for window alignment key line.
Returns:
The number of pixels to offset. If the offset is positive,
it is distance from low edge (see BaseGridView.WINDOW_ALIGN_LOW_EDGE);
if the offset is negative, the absolute value is distance from high
edge (see BaseGridView.WINDOW_ALIGN_HIGH_EDGE).
Default value is 0.
public void
setWindowAlignmentOffsetPercent(float offsetPercent)
Sets the offset percent for window alignment key line in addition to BaseGridView.getWindowAlignmentOffset().
Parameters:
offsetPercent: Percentage to offset. E.g., 40 means 40% of the
width from low edge. Use
BaseGridView.WINDOW_ALIGN_OFFSET_PERCENT_DISABLED to disable.
Default value is 50.
public float
getWindowAlignmentOffsetPercent()
Returns the offset percent for window alignment key line in addition to
BaseGridView.getWindowAlignmentOffset().
Returns:
Percentage to offset. E.g., 40 means 40% of the width from the
low edge, or BaseGridView.WINDOW_ALIGN_OFFSET_PERCENT_DISABLED if
disabled. Default value is 50.
public void
setItemAlignmentOffset(int offset)
Sets number of pixels to the end of low edge. Supports right to left layout direction.
Item alignment settings are ignored for the child if ItemAlignmentFacet
is provided by or FacetProviderAdapter.
Parameters:
offset: In left to right or vertical case, it's the offset added to left/top edge.
In right to left case, it's the offset subtracted from right edge.
public int
getItemAlignmentOffset()
Returns number of pixels to the end of low edge. Supports right to left layout direction. In
left to right or vertical case, it's the offset added to left/top edge. In right to left
case, it's the offset subtracted from right edge.
Item alignment settings are ignored for the child if ItemAlignmentFacet
is provided by or FacetProviderAdapter.
Returns:
The number of pixels to the end of low edge.
public void
setItemAlignmentOffsetWithPadding(boolean withPadding)
Sets whether applies padding to item alignment when BaseGridView.getItemAlignmentOffsetPercent()
is 0 or 100.
When true:
Applies start/top padding if BaseGridView.getItemAlignmentOffsetPercent() is 0.
Applies end/bottom padding if BaseGridView.getItemAlignmentOffsetPercent() is 100.
Does not apply padding if BaseGridView.getItemAlignmentOffsetPercent() is neither 0 nor 100.
When false: does not apply padding
public boolean
isItemAlignmentOffsetWithPadding()
Returns true if applies padding to item alignment when
BaseGridView.getItemAlignmentOffsetPercent() is 0 or 100; returns false otherwise.
When true:
Applies start/top padding when BaseGridView.getItemAlignmentOffsetPercent() is 0.
Applies end/bottom padding when BaseGridView.getItemAlignmentOffsetPercent() is 100.
Does not apply padding if BaseGridView.getItemAlignmentOffsetPercent() is neither 0 nor 100.
When false: does not apply padding
public void
setItemAlignmentOffsetPercent(float offsetPercent)
Sets the offset percent for item alignment in addition to BaseGridView.getItemAlignmentOffset().
Item alignment settings are ignored for the child if ItemAlignmentFacet
is provided by or FacetProviderAdapter.
Parameters:
offsetPercent: Percentage to offset. E.g., 40 means 40% of the
width from the low edge. Use
BaseGridView.ITEM_ALIGN_OFFSET_PERCENT_DISABLED to disable.
public float
getItemAlignmentOffsetPercent()
Returns the offset percent for item alignment in addition to BaseGridView.getItemAlignmentOffset().
Returns:
Percentage to offset. E.g., 40 means 40% of the width from the
low edge, or BaseGridView.ITEM_ALIGN_OFFSET_PERCENT_DISABLED if
disabled. Default value is 50.
public void
setItemAlignmentViewId(int viewId)
Sets the id of the view to align with. Use android.view.View
(default)
for the root .
Item alignment settings on BaseGridView are if ItemAlignmentFacet
is provided by or FacetProviderAdapter.
public int
getItemAlignmentViewId()
Returns the id of the view to align with, or android.view.View
for the root
.
Returns:
The id of the view to align with, or android.view.View
for the root
.
public void
setItemMargin(int margin)
Deprecated: use BaseGridView.setItemSpacing(int)
Sets the spacing in pixels between two child items.
public void
setItemSpacing(int spacing)
Sets the vertical and horizontal spacing in pixels between two child items.
Parameters:
spacing: Vertical and horizontal spacing in pixels between two child items.
public void
setVerticalMargin(int margin)
Deprecated: Use BaseGridView.setVerticalSpacing(int)
Sets the spacing in pixels between two child items vertically.
public int
getVerticalMargin()
Deprecated: Use BaseGridView.getVerticalSpacing()
Returns the spacing in pixels between two child items vertically.
public void
setHorizontalMargin(int margin)
Deprecated: Use BaseGridView.setHorizontalSpacing(int)
Sets the spacing in pixels between two child items horizontally.
public int
getHorizontalMargin()
Deprecated: Use BaseGridView.getHorizontalSpacing()
Returns the spacing in pixels between two child items horizontally.
public void
setVerticalSpacing(int spacing)
Sets the vertical spacing in pixels between two child items.
Parameters:
spacing: Vertical spacing between two child items.
public int
getVerticalSpacing()
Returns the vertical spacing in pixels between two child items.
Returns:
The vertical spacing in pixels between two child items.
public void
setHorizontalSpacing(int spacing)
Sets the horizontal spacing in pixels between two child items.
Parameters:
spacing: Horizontal spacing in pixels between two child items.
public int
getHorizontalSpacing()
Returns the horizontal spacing in pixels between two child items.
Returns:
The Horizontal spacing in pixels between two child items.
Registers a callback to be invoked when an item in BaseGridView has
been laid out.
Parameters:
listener: The listener to be invoked.
Registers a callback to be invoked when an item in BaseGridView has
been selected. Note that the listener may be invoked when there is a
layout pending on the view, affording the listener an opportunity to
adjust the upcoming layout based on the selection state.
Parameters:
listener: The listener to be invoked.
Registers a callback to be invoked when the BaseGridView completes a full layout calculation.
Parameters:
listener: The listener to be invoked.
Removes a callback to be invoked when the BaseGridView completes a full layout calculation.
Parameters:
listener: The listener to be invoked.
Registers a callback to be invoked when an item in BaseGridView has
been selected. Note that the listener may be invoked when there is a
layout pending on the view, affording the listener an opportunity to
adjust the upcoming layout based on the selection state.
This method will clear all existing listeners added by
BaseGridView.addOnChildViewHolderSelectedListener(OnChildViewHolderSelectedListener).
Parameters:
listener: The listener to be invoked.
Registers a callback to be invoked when an item in BaseGridView has
been selected. Note that the listener may be invoked when there is a
layout pending on the view, affording the listener an opportunity to
adjust the upcoming layout based on the selection state.
Parameters:
listener: The listener to be invoked.
Remove the callback invoked when an item in BaseGridView has been selected.
Parameters:
listener: The listener to be removed.
public void
setSelectedPosition(int position)
Changes the selected item immediately without animation.
public void
setSelectedPositionWithSub(int position, int subposition)
Changes the selected item and/or subposition immediately without animation.
public void
setSelectedPosition(int position, int scrollExtra)
Changes the selected item immediately without animation, scrollExtra is
applied in primary scroll direction. The scrollExtra will be kept until
another BaseGridView.setSelectedPosition(int) or BaseGridView.setSelectedPositionSmooth(int) call.
public void
setSelectedPositionWithSub(int position, int subposition, int scrollExtra)
Changes the selected item and/or subposition immediately without animation, scrollExtra is
applied in primary scroll direction. The scrollExtra will be kept until
another BaseGridView.setSelectedPosition(int) or BaseGridView.setSelectedPositionSmooth(int) call.
public void
setSelectedPositionSmooth(int position)
Changes the selected item and run an animation to scroll to the target
position.
Parameters:
position: Adapter position of the item to select.
public void
setSelectedPositionSmoothWithSub(int position, int subposition)
Changes the selected item and/or subposition, runs an animation to scroll to the target
position.
public void
setSelectedPositionSmooth(int position,
ViewHolderTask task)
Perform a task on ViewHolder at given position after smooth scrolling to it.
Parameters:
position: Position of item in adapter.
task: Task to executed on the ViewHolder at a given position.
Perform a task on ViewHolder at given position after scroll to it.
Parameters:
position: Position of item in adapter.
task: Task to executed on the ViewHolder at a given position.
public int
getSelectedPosition()
Returns the adapter position of selected item.
Returns:
The adapter position of selected item.
public int
getSelectedSubPosition()
Returns the sub selected item position started from zero. An item can have
multiple ItemAlignmentFacets provided by
or FacetProviderAdapter. Zero is returned when no ItemAlignmentFacet
is defined.
public void
setAnimateChildLayout(boolean animateChildLayout)
Sets whether ItemAnimator should run when a child changes size or when adding
or removing a child.
Parameters:
animateChildLayout: True to enable ItemAnimator, false to disable.
public boolean
isChildLayoutAnimated()
Returns true if an animation will run when a child changes size or when
adding or removing a child.
Returns:
True if ItemAnimator is enabled, false otherwise.
public void
setGravity(int gravity)
Sets the gravity used for child view positioning. Defaults to
GRAVITY_TOP|GRAVITY_START.
Parameters:
gravity: See
Set the RecyclerView.LayoutManager that this RecyclerView will use.
In contrast to other adapter-backed views such as
or , RecyclerView allows client code to provide custom
layout arrangements for child views. These arrangements are controlled by the
RecyclerView.LayoutManager. A LayoutManager must be provided for RecyclerView to function.
Several default strategies are provided for common uses such as lists and grids.
Parameters:
layout: LayoutManager to use
public boolean
onRequestFocusInDescendants(int direction, Rect previouslyFocusedRect)
public void
getViewSelectedOffsets(View view, int[] offsets[])
Returns the x/y offsets to final position from current position if the view
is selected.
Parameters:
view: The view to get offsets.
offsets: offsets[0] holds offset of X, offsets[1] holds offset of Y.
public int
getChildDrawingOrder(int childCount, int i)
public View
focusSearch(int direction)
protected void
onFocusChanged(boolean gainFocus, int direction, Rect previouslyFocusedRect)
public final void
setFocusSearchDisabled(boolean disabled)
Disables or enables focus search.
Parameters:
disabled: True to disable focus search, false to enable.
public final boolean
isFocusSearchDisabled()
Returns true if focus search is disabled.
Returns:
True if focus search is disabled.
public void
setLayoutEnabled(boolean layoutEnabled)
Enables or disables layout. All children will be removed when layout is
disabled.
Parameters:
layoutEnabled: True to enable layout, false otherwise.
public void
setChildrenVisibility(int visibility)
Changes and overrides children's visibility.
Parameters:
visibility: See View
.
public void
setPruneChild(boolean pruneChild)
Enables or disables pruning of children. Disable is useful during transition.
Parameters:
pruneChild: True to prune children out side visible area, false to enable.
public void
setScrollEnabled(boolean scrollEnabled)
Enables or disables scrolling. Disable is useful during transition.
Parameters:
scrollEnabled: True to enable scroll, false to disable.
public boolean
isScrollEnabled()
Returns true if scrolling is enabled, false otherwise.
Returns:
True if scrolling is enabled, false otherwise.
public boolean
hasPreviousViewInSameRow(int position)
Returns true if the view at the given position has a same row sibling
in front of it. This will return true if first item view is not created.
Parameters:
position: Position in adapter.
Returns:
True if the view at the given position has a same row sibling in front of it.
public void
setFocusDrawingOrderEnabled(boolean enabled)
Enables or disables the default "focus draw at last" order rule. Default is enabled.
Parameters:
enabled: True to draw the selected child at last, false otherwise.
public boolean
isFocusDrawingOrderEnabled()
Returns true if draws selected child at last, false otherwise. Default is enabled.
Returns:
True if draws selected child at last, false otherwise.
Sets the touch intercept listener.
Parameters:
listener: The touch intercept listener.
Sets the generic motion intercept listener.
Parameters:
listener: The motion intercept listener.
Sets the key intercept listener.
Parameters:
listener: The key intercept listener.
Sets the unhandled key listener.
Parameters:
listener: The unhandled key intercept listener.
Returns the unhandled key listener.
Returns:
The unhandled key listener.
public boolean
dispatchKeyEvent(KeyEvent event)
public boolean
dispatchTouchEvent(MotionEvent event)
protected boolean
dispatchGenericFocusedEvent(MotionEvent event)
public final int
getSaveChildrenPolicy()
Returns the policy for saving children.
Returns:
policy, one of BaseGridView.SAVE_NO_CHILD
BaseGridView.SAVE_ON_SCREEN_CHILD BaseGridView.SAVE_LIMITED_CHILD BaseGridView.SAVE_ALL_CHILD.
public final int
getSaveChildrenLimitNumber()
Returns the limit used when when BaseGridView.getSaveChildrenPolicy() is
BaseGridView.SAVE_LIMITED_CHILD
public final void
setSaveChildrenPolicy(int savePolicy)
Sets the policy for saving children.
Parameters:
savePolicy: One of BaseGridView.SAVE_NO_CHILD BaseGridView.SAVE_ON_SCREEN_CHILD
BaseGridView.SAVE_LIMITED_CHILD BaseGridView.SAVE_ALL_CHILD.
public final void
setSaveChildrenLimitNumber(int limitNumber)
Sets the limit number when BaseGridView.getSaveChildrenPolicy() is BaseGridView.SAVE_LIMITED_CHILD.
public boolean
hasOverlappingRendering()
public void
setHasOverlappingRendering(boolean hasOverlapping)
public void
onRtlPropertiesChanged(int layoutDirection)
Notify layout manager that layout directionality has been updated
public void
setExtraLayoutSpace(int extraLayoutSpace)
Sets pixels of extra space for layout child in invisible area.
Parameters:
extraLayoutSpace: Pixels of extra space for layout invisible child.
Must be bigger or equals to 0.
public int
getExtraLayoutSpace()
Returns pixels of extra space for layout child in invisible area.
Temporarily slide out child views to bottom (for VerticalGridView) or end
(for HorizontalGridView). Layout and scrolling will be suppressed until
BaseGridView.animateIn() is called.
Undo animateOut() and slide in child views.
public void
scrollToPosition(int position)
Convenience method to scroll to a certain position.
RecyclerView does not implement scrolling logic, rather forwards the call to
RecyclerView.LayoutManager.scrollToPosition(int)
Parameters:
position: Scroll to this adapter position
See also: RecyclerView.LayoutManager.scrollToPosition(int)
public void
smoothScrollToPosition(int position)
Starts a smooth scroll to an adapter position.
To support smooth scrolling, you must override
RecyclerView.LayoutManager and create a
RecyclerView.SmoothScroller.
RecyclerView.LayoutManager is responsible for creating the actual scroll action. If you want to
provide a custom smooth scroll logic, override
RecyclerView.LayoutManager in your
LayoutManager.
Parameters:
position: The adapter position to scroll to
See also: RecyclerView.LayoutManager
Set custom behavior for smoothScrollBy().
Parameters:
behavior: Custom behavior of SmoothScrollBy(). Null for default behavior.
Returns custom behavior for smoothScrollBy().
Returns:
Custom behavior for SmoothScrollBy(). Null for default behavior.
public void
smoothScrollBy(int dx, int dy)
Animate a scroll by the given amount of pixels along either axis.
Parameters:
dx: Pixels to scroll horizontally
dy: Pixels to scroll vertically
public void
smoothScrollBy(int dx, int dy, Interpolator interpolator)
Animate a scroll by the given amount of pixels along either axis.
Parameters:
dx: Pixels to scroll horizontally
dy: Pixels to scroll vertically
interpolator: to be used for scrolling. If it is
null, RecyclerView will use an internal default interpolator.
public final void
setSmoothScrollSpeedFactor(float smoothScrollSpeedFactor)
Set factor of how slow the smoothScroller should run. For example when set to 2f, the smooth
scroller is twice slower. The value is 1f by default.
Parameters:
smoothScrollSpeedFactor: Factor of how slow the smooth scroll is.
public final float
getSmoothScrollSpeedFactor()
Returns:
Factor of how slow the smoothScroller runs. Default value is 1f.
public final void
setSmoothScrollMaxPendingMoves(int maxPendingMoves)
When holding DPAD, DPAD events are generated faster than the grid view can scroll. The
grid view counts unhandled DPAD events and completes the movement after user release DPAD.
If the value is set too high, the scrolling will last very long after DPAD is released. If
the value is set too low, it may miss many DPAD events. The default value is 10. If app
increases BaseGridView.setSmoothScrollSpeedFactor(float), it may need decrease the max pending
DPAD events to avoid scrolling too long after DPAD release.
Parameters:
maxPendingMoves: Maximum number of pending DPAD events to be remembered.
public final int
getSmoothScrollMaxPendingMoves()
When holding DPAD, DPAD events are generated faster than the grid view can scroll. The
grid view counts unhandled DPAD events and complete the movement after user release DPAD.
If the value is set too high, the scrolling will last very long after DPAD is released. If
the value is set too low, it may miss many DPAD events. The default value is 10. If app
increases BaseGridView.setSmoothScrollSpeedFactor(float), it may need decrease the max pending
DPAD events to avoid scrolling too long after DPAD release.
Returns:
Maximum number of pending DPAD events to be remembered when smooth scroll cannot
catch up speed of DPAD events being sent.
public void
setInitialPrefetchItemCount(int itemCount)
Sets the number of items to prefetch in
,
which defines how many inner items should be prefetched when this GridView is nested inside
another RecyclerView.
Set this value to the number of items this inner GridView will display when it is
first scrolled into the viewport. RecyclerView will attempt to prefetch that number of items
so they are ready, avoiding jank as the inner GridView is scrolled into the viewport.
For example, take a VerticalGridView of scrolling HorizontalGridViews. The rows always
have 6 items visible in them (or 7 if not aligned). Passing 6
to this method
for each inner GridView will enable RecyclerView's prefetching feature to do create/bind work
for 6 views within a row early, before it is scrolled on screen, instead of just the default
4.
Calling this method does nothing unless the LayoutManager is in a RecyclerView
nested in another RecyclerView.
Note: Setting this value to be larger than the number of
views that will be visible in this view can incur unnecessary bind work, and an increase to
the number of Views created and in active use.
Parameters:
itemCount: Number of items to prefetch
See also: BaseGridView.getInitialPrefetchItemCount()
public int
getInitialPrefetchItemCount()
Gets the number of items to prefetch in
,
which defines how many inner items should be prefetched when this GridView is nested inside
another RecyclerView.
Returns:
number of items to prefetch.
See also: , BaseGridView.setInitialPrefetchItemCount(int)
public void
removeView(View view)
public void
removeViewAt(int index)
Source
/*
* Copyright 2021 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package androidx.leanback.widget;
import static androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
import android.view.animation.Interpolator;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.RestrictTo;
import androidx.recyclerview.widget.RecyclerView;
import androidx.recyclerview.widget.SimpleItemAnimator;
/**
* An abstract base class for vertically and horizontally scrolling lists. The items come
* from the {@link RecyclerView.Adapter} associated with this view.
* Do not directly use this class, use {@link VerticalGridView} and {@link HorizontalGridView}.
* The class is not intended to be subclassed other than {@link VerticalGridView} and
* {@link HorizontalGridView}.
*/
public abstract class BaseGridView extends RecyclerView {
/**
* Always keep focused item at a aligned position. Developer can use
* WINDOW_ALIGN_XXX and ITEM_ALIGN_XXX to define how focused item is aligned.
* In this mode, the last focused position will be remembered and restored when focus
* is back to the view.
*
*/
@RestrictTo(LIBRARY_GROUP_PREFIX)
public static final int FOCUS_SCROLL_ALIGNED = 0;
/**
* Scroll to make the focused item inside client area.
*
*/
@RestrictTo(LIBRARY_GROUP_PREFIX)
public static final int FOCUS_SCROLL_ITEM = 1;
/**
* Scroll a page of items when focusing to item outside the client area.
* The page size matches the client area size of RecyclerView.
*
*/
@RestrictTo(LIBRARY_GROUP_PREFIX)
public static final int FOCUS_SCROLL_PAGE = 2;
/**
* The first item is aligned with the low edge of the viewport. When
* navigating away from the first item, the focus item is aligned to a key line location.
* <p>
* For HorizontalGridView, low edge refers to getPaddingLeft() when RTL is false or
* getWidth() - getPaddingRight() when RTL is true.
* For VerticalGridView, low edge refers to getPaddingTop().
* <p>
* The key line location is calculated by "windowAlignOffset" and
* "windowAlignOffsetPercent"; if neither of these two is defined, the
* default value is 1/2 of the size.
* <p>
* Note if there are very few items between low edge and key line, use
* {@link #setWindowAlignmentPreferKeyLineOverLowEdge(boolean)} to control whether you prefer
* to align the items to key line or low edge. Default is preferring low edge.
*/
public static final int WINDOW_ALIGN_LOW_EDGE = 1;
/**
* The last item is aligned with the high edge of the viewport when
* navigating to the end of list. When navigating away from the end, the
* focus item is aligned to a key line location.
* <p>
* For HorizontalGridView, high edge refers to getWidth() - getPaddingRight() when RTL is false
* or getPaddingLeft() when RTL is true.
* For VerticalGridView, high edge refers to getHeight() - getPaddingBottom().
* <p>
* The key line location is calculated by "windowAlignOffset" and
* "windowAlignOffsetPercent"; if neither of these two is defined, the
* default value is 1/2 of the size.
* <p>
* Note if there are very few items between high edge and key line, use
* {@link #setWindowAlignmentPreferKeyLineOverHighEdge(boolean)} to control whether you prefer
* to align the items to key line or high edge. Default is preferring key line.
*/
public static final int WINDOW_ALIGN_HIGH_EDGE = 1 << 1;
/**
* The first item and last item are aligned with the two edges of the
* viewport. When navigating in the middle of list, the focus maintains a
* key line location.
* <p>
* The key line location is calculated by "windowAlignOffset" and
* "windowAlignOffsetPercent"; if neither of these two is defined, the
* default value is 1/2 of the size.
*/
public static final int WINDOW_ALIGN_BOTH_EDGE =
WINDOW_ALIGN_LOW_EDGE | WINDOW_ALIGN_HIGH_EDGE;
/**
* The focused item always stays in a key line location.
* <p>
* The key line location is calculated by "windowAlignOffset" and
* "windowAlignOffsetPercent"; if neither of these two is defined, the
* default value is 1/2 of the size.
*/
public static final int WINDOW_ALIGN_NO_EDGE = 0;
/**
* Value indicates that percent is not used.
*/
public static final float WINDOW_ALIGN_OFFSET_PERCENT_DISABLED = -1;
/**
* Value indicates that percent is not used.
*/
public static final float ITEM_ALIGN_OFFSET_PERCENT_DISABLED =
ItemAlignmentFacet.ITEM_ALIGN_OFFSET_PERCENT_DISABLED;
/**
* Dont save states of any child views.
*/
public static final int SAVE_NO_CHILD = 0;
/**
* Only save on screen child views, the states are lost when they become off screen.
*/
public static final int SAVE_ON_SCREEN_CHILD = 1;
/**
* Save on screen views plus save off screen child views states up to
* {@link #getSaveChildrenLimitNumber()}.
*/
public static final int SAVE_LIMITED_CHILD = 2;
/**
* Save on screen views plus save off screen child views without any limitation.
* This might cause out of memory, only use it when you are dealing with limited data.
*/
public static final int SAVE_ALL_CHILD = 3;
private static final int PFLAG_RETAIN_FOCUS_FOR_CHILD = 1;
/**
* Defines behavior of duration and interpolator for smoothScrollBy().
*/
public interface SmoothScrollByBehavior {
/**
* Defines duration in milliseconds of smoothScrollBy().
*
* @param dx x distance in pixels.
* @param dy y distance in pixels.
* @return Duration in milliseconds or UNDEFINED_DURATION for default value.
*/
int configSmoothScrollByDuration(int dx, int dy);
/**
* Defines interpolator of smoothScrollBy().
*
* @param dx x distance in pixels.
* @param dy y distance in pixels.
* @return Interpolator to be used or null for default interpolator.
*/
@Nullable
Interpolator configSmoothScrollByInterpolator(int dx, int dy);
}
/**
* Listener for intercepting touch dispatch events.
*/
public interface OnTouchInterceptListener {
/**
* Returns true if the touch dispatch event should be consumed.
*/
boolean onInterceptTouchEvent(@NonNull MotionEvent event);
}
/**
* Listener for intercepting generic motion dispatch events.
*/
public interface OnMotionInterceptListener {
/**
* Returns true if the touch dispatch event should be consumed.
*/
boolean onInterceptMotionEvent(@NonNull MotionEvent event);
}
/**
* Listener for intercepting key dispatch events.
*/
public interface OnKeyInterceptListener {
/**
* Returns true if the key dispatch event should be consumed.
*/
boolean onInterceptKeyEvent(@NonNull KeyEvent event);
}
/**
* Listener for intercepting unhandled key events.
*/
public interface OnUnhandledKeyListener {
/**
* Returns true if the key event should be consumed.
*/
boolean onUnhandledKey(@NonNull KeyEvent event);
}
/**
* Interface for receiving notification when BaseGridView has completed a full layout
* calculation.
*/
public interface OnLayoutCompletedListener {
/**
* Called after a full layout calculation is finished.
*
* @param state Transient state of RecyclerView
*/
void onLayoutCompleted(@NonNull RecyclerView.State state);
}
GridLayoutManager mLayoutManager;
private SmoothScrollByBehavior mSmoothScrollByBehavior;
/**
* Animate layout changes from a child resizing or adding/removing a child.
*/
private boolean mAnimateChildLayout = true;
private boolean mHasOverlappingRendering = true;
private RecyclerView.ItemAnimator mSavedItemAnimator;
private OnTouchInterceptListener mOnTouchInterceptListener;
private OnMotionInterceptListener mOnMotionInterceptListener;
private OnKeyInterceptListener mOnKeyInterceptListener;
private OnUnhandledKeyListener mOnUnhandledKeyListener;
/**
* Number of items to prefetch when first coming on screen with new data.
*/
int mInitialPrefetchItemCount = 4;
private int mPrivateFlag;
BaseGridView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
mLayoutManager = new GridLayoutManager(this);
setLayoutManager(mLayoutManager);
// leanback LayoutManager already restores focus inside onLayoutChildren().
setPreserveFocusAfterLayout(false);
setDescendantFocusability(FOCUS_AFTER_DESCENDANTS);
setHasFixedSize(true);
setChildrenDrawingOrderEnabled(true);
setWillNotDraw(true);
setOverScrollMode(View.OVER_SCROLL_NEVER);
// Disable change animation by default on leanback.
// Change animation will create a new view and cause undesired
// focus animation between the old view and new view.
((SimpleItemAnimator) getItemAnimator()).setSupportsChangeAnimations(false);
super.addRecyclerListener(new RecyclerView.RecyclerListener() {
@Override
public void onViewRecycled(@NonNull RecyclerView.ViewHolder holder) {
mLayoutManager.onChildRecycled(holder);
}
});
}
@SuppressLint("CustomViewStyleable")
void initBaseGridViewAttributes(Context context, AttributeSet attrs) {
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.lbBaseGridView);
boolean throughFront = a.getBoolean(R.styleable.lbBaseGridView_focusOutFront, false);
boolean throughEnd = a.getBoolean(R.styleable.lbBaseGridView_focusOutEnd, false);
mLayoutManager.setFocusOutAllowed(throughFront, throughEnd);
boolean throughSideStart = a.getBoolean(R.styleable.lbBaseGridView_focusOutSideStart, true);
boolean throughSideEnd = a.getBoolean(R.styleable.lbBaseGridView_focusOutSideEnd, true);
mLayoutManager.setFocusOutSideAllowed(throughSideStart, throughSideEnd);
mLayoutManager.setVerticalSpacing(
a.getDimensionPixelSize(R.styleable.lbBaseGridView_android_verticalSpacing,
a.getDimensionPixelSize(R.styleable.lbBaseGridView_verticalMargin, 0)));
mLayoutManager.setHorizontalSpacing(
a.getDimensionPixelSize(R.styleable.lbBaseGridView_android_horizontalSpacing,
a.getDimensionPixelSize(R.styleable.lbBaseGridView_horizontalMargin, 0)));
if (a.hasValue(R.styleable.lbBaseGridView_android_gravity)) {
setGravity(a.getInt(R.styleable.lbBaseGridView_android_gravity, Gravity.NO_GRAVITY));
}
a.recycle();
}
/**
* Sets the strategy used to scroll in response to item focus changing:
* <ul>
* <li>{@link #FOCUS_SCROLL_ALIGNED} (default) </li>
* <li>{@link #FOCUS_SCROLL_ITEM}</li>
* <li>{@link #FOCUS_SCROLL_PAGE}</li>
* </ul>
*
*/
@RestrictTo(LIBRARY_GROUP_PREFIX)
public void setFocusScrollStrategy(int scrollStrategy) {
if (scrollStrategy != FOCUS_SCROLL_ALIGNED && scrollStrategy != FOCUS_SCROLL_ITEM
&& scrollStrategy != FOCUS_SCROLL_PAGE) {
throw new IllegalArgumentException("Invalid scrollStrategy");
}
mLayoutManager.setFocusScrollStrategy(scrollStrategy);
requestLayout();
}
/**
* Returns the strategy used to scroll in response to item focus changing.
* <ul>
* <li>{@link #FOCUS_SCROLL_ALIGNED} (default) </li>
* <li>{@link #FOCUS_SCROLL_ITEM}</li>
* <li>{@link #FOCUS_SCROLL_PAGE}</li>
* </ul>
*
*/
@RestrictTo(LIBRARY_GROUP_PREFIX)
public int getFocusScrollStrategy() {
return mLayoutManager.getFocusScrollStrategy();
}
/**
* Sets the method for focused item alignment in the view.
*
* @param windowAlignment {@link #WINDOW_ALIGN_BOTH_EDGE},
* {@link #WINDOW_ALIGN_LOW_EDGE}, {@link #WINDOW_ALIGN_HIGH_EDGE} or
* {@link #WINDOW_ALIGN_NO_EDGE}.
*/
public void setWindowAlignment(int windowAlignment) {
mLayoutManager.setWindowAlignment(windowAlignment);
requestLayout();
}
/**
* Returns the method for focused item alignment in the view.
*
* @return {@link #WINDOW_ALIGN_BOTH_EDGE}, {@link #WINDOW_ALIGN_LOW_EDGE},
* {@link #WINDOW_ALIGN_HIGH_EDGE} or {@link #WINDOW_ALIGN_NO_EDGE}.
*/
public int getWindowAlignment() {
return mLayoutManager.getWindowAlignment();
}
/**
* Sets whether prefer key line over low edge when {@link #WINDOW_ALIGN_LOW_EDGE} is used.
* When true, if there are very few items between low edge and key line, align items to key
* line instead of align items to low edge.
* Default value is false (aka prefer align to low edge).
*
* @param preferKeyLineOverLowEdge True to prefer key line over low edge, false otherwise.
*/
public void setWindowAlignmentPreferKeyLineOverLowEdge(boolean preferKeyLineOverLowEdge) {
mLayoutManager.mWindowAlignment.mainAxis()
.setPreferKeylineOverLowEdge(preferKeyLineOverLowEdge);
requestLayout();
}
/**
* Returns whether prefer key line over high edge when {@link #WINDOW_ALIGN_HIGH_EDGE} is used.
* When true, if there are very few items between high edge and key line, align items to key
* line instead of align items to high edge.
* Default value is true (aka prefer align to key line).
*
* @param preferKeyLineOverHighEdge True to prefer key line over high edge, false otherwise.
*/
public void setWindowAlignmentPreferKeyLineOverHighEdge(boolean preferKeyLineOverHighEdge) {
mLayoutManager.mWindowAlignment.mainAxis()
.setPreferKeylineOverHighEdge(preferKeyLineOverHighEdge);
requestLayout();
}
/**
* Returns whether prefer key line over low edge when {@link #WINDOW_ALIGN_LOW_EDGE} is used.
* When true, if there are very few items between low edge and key line, align items to key
* line instead of align items to low edge.
* Default value is false (aka prefer align to low edge).
*
* @return True to prefer key line over low edge, false otherwise.
*/
public boolean isWindowAlignmentPreferKeyLineOverLowEdge() {
return mLayoutManager.mWindowAlignment.mainAxis().isPreferKeylineOverLowEdge();
}
/**
* Returns whether prefer key line over high edge when {@link #WINDOW_ALIGN_HIGH_EDGE} is used.
* When true, if there are very few items between high edge and key line, align items to key
* line instead of align items to high edge.
* Default value is true (aka prefer align to key line).
*
* @return True to prefer key line over high edge, false otherwise.
*/
public boolean isWindowAlignmentPreferKeyLineOverHighEdge() {
return mLayoutManager.mWindowAlignment.mainAxis().isPreferKeylineOverHighEdge();
}
/**
* Sets the offset in pixels for window alignment key line.
*
* @param offset The number of pixels to offset. If the offset is positive,
* it is distance from low edge (see {@link #WINDOW_ALIGN_LOW_EDGE});
* if the offset is negative, the absolute value is distance from high
* edge (see {@link #WINDOW_ALIGN_HIGH_EDGE}).
* Default value is 0.
*/
public void setWindowAlignmentOffset(int offset) {
mLayoutManager.setWindowAlignmentOffset(offset);
requestLayout();
}
/**
* Returns the offset in pixels for window alignment key line.
*
* @return The number of pixels to offset. If the offset is positive,
* it is distance from low edge (see {@link #WINDOW_ALIGN_LOW_EDGE});
* if the offset is negative, the absolute value is distance from high
* edge (see {@link #WINDOW_ALIGN_HIGH_EDGE}).
* Default value is 0.
*/
public int getWindowAlignmentOffset() {
return mLayoutManager.getWindowAlignmentOffset();
}
/**
* Sets the offset percent for window alignment key line in addition to {@link
* #getWindowAlignmentOffset()}.
*
* @param offsetPercent Percentage to offset. E.g., 40 means 40% of the
* width from low edge. Use
* {@link #WINDOW_ALIGN_OFFSET_PERCENT_DISABLED} to disable.
* Default value is 50.
*/
public void setWindowAlignmentOffsetPercent(float offsetPercent) {
mLayoutManager.setWindowAlignmentOffsetPercent(offsetPercent);
requestLayout();
}
/**
* Returns the offset percent for window alignment key line in addition to
* {@link #getWindowAlignmentOffset()}.
*
* @return Percentage to offset. E.g., 40 means 40% of the width from the
* low edge, or {@link #WINDOW_ALIGN_OFFSET_PERCENT_DISABLED} if
* disabled. Default value is 50.
*/
public float getWindowAlignmentOffsetPercent() {
return mLayoutManager.getWindowAlignmentOffsetPercent();
}
/**
* Sets number of pixels to the end of low edge. Supports right to left layout direction.
* Item alignment settings are ignored for the child if {@link ItemAlignmentFacet}
* is provided by {@link RecyclerView.ViewHolder} or {@link FacetProviderAdapter}.
*
* @param offset In left to right or vertical case, it's the offset added to left/top edge.
* In right to left case, it's the offset subtracted from right edge.
*/
public void setItemAlignmentOffset(int offset) {
mLayoutManager.setItemAlignmentOffset(offset);
requestLayout();
}
/**
* Returns number of pixels to the end of low edge. Supports right to left layout direction. In
* left to right or vertical case, it's the offset added to left/top edge. In right to left
* case, it's the offset subtracted from right edge.
* Item alignment settings are ignored for the child if {@link ItemAlignmentFacet}
* is provided by {@link RecyclerView.ViewHolder} or {@link FacetProviderAdapter}.
*
* @return The number of pixels to the end of low edge.
*/
public int getItemAlignmentOffset() {
return mLayoutManager.getItemAlignmentOffset();
}
/**
* Sets whether applies padding to item alignment when {@link #getItemAlignmentOffsetPercent()}
* is 0 or 100.
* <p>When true:
* Applies start/top padding if {@link #getItemAlignmentOffsetPercent()} is 0.
* Applies end/bottom padding if {@link #getItemAlignmentOffsetPercent()} is 100.
* Does not apply padding if {@link #getItemAlignmentOffsetPercent()} is neither 0 nor 100.
* </p>
* <p>When false: does not apply padding</p>
*/
public void setItemAlignmentOffsetWithPadding(boolean withPadding) {
mLayoutManager.setItemAlignmentOffsetWithPadding(withPadding);
requestLayout();
}
/**
* Returns true if applies padding to item alignment when
* {@link #getItemAlignmentOffsetPercent()} is 0 or 100; returns false otherwise.
* <p>When true:
* Applies start/top padding when {@link #getItemAlignmentOffsetPercent()} is 0.
* Applies end/bottom padding when {@link #getItemAlignmentOffsetPercent()} is 100.
* Does not apply padding if {@link #getItemAlignmentOffsetPercent()} is neither 0 nor 100.
* </p>
* <p>When false: does not apply padding</p>
*/
public boolean isItemAlignmentOffsetWithPadding() {
return mLayoutManager.isItemAlignmentOffsetWithPadding();
}
/**
* Sets the offset percent for item alignment in addition to {@link
* #getItemAlignmentOffset()}.
* Item alignment settings are ignored for the child if {@link ItemAlignmentFacet}
* is provided by {@link RecyclerView.ViewHolder} or {@link FacetProviderAdapter}.
*
* @param offsetPercent Percentage to offset. E.g., 40 means 40% of the
* width from the low edge. Use
* {@link #ITEM_ALIGN_OFFSET_PERCENT_DISABLED} to disable.
*/
public void setItemAlignmentOffsetPercent(float offsetPercent) {
mLayoutManager.setItemAlignmentOffsetPercent(offsetPercent);
requestLayout();
}
/**
* Returns the offset percent for item alignment in addition to {@link
* #getItemAlignmentOffset()}.
*
* @return Percentage to offset. E.g., 40 means 40% of the width from the
* low edge, or {@link #ITEM_ALIGN_OFFSET_PERCENT_DISABLED} if
* disabled. Default value is 50.
*/
public float getItemAlignmentOffsetPercent() {
return mLayoutManager.getItemAlignmentOffsetPercent();
}
/**
* Sets the id of the view to align with. Use {@link android.view.View#NO_ID} (default)
* for the root {@link RecyclerView.ViewHolder#itemView}.
* Item alignment settings on BaseGridView are if {@link ItemAlignmentFacet}
* is provided by {@link RecyclerView.ViewHolder} or {@link FacetProviderAdapter}.
*/
public void setItemAlignmentViewId(int viewId) {
mLayoutManager.setItemAlignmentViewId(viewId);
}
/**
* Returns the id of the view to align with, or {@link android.view.View#NO_ID} for the root
* {@link RecyclerView.ViewHolder#itemView}.
*
* @return The id of the view to align with, or {@link android.view.View#NO_ID} for the root
* {@link RecyclerView.ViewHolder#itemView}.
*/
public int getItemAlignmentViewId() {
return mLayoutManager.getItemAlignmentViewId();
}
/**
* Sets the spacing in pixels between two child items.
*
* @deprecated use {@link #setItemSpacing(int)}
*/
@Deprecated
public void setItemMargin(int margin) {
setItemSpacing(margin);
}
/**
* Sets the vertical and horizontal spacing in pixels between two child items.
*
* @param spacing Vertical and horizontal spacing in pixels between two child items.
*/
public void setItemSpacing(int spacing) {
mLayoutManager.setItemSpacing(spacing);
requestLayout();
}
/**
* Sets the spacing in pixels between two child items vertically.
*
* @deprecated Use {@link #setVerticalSpacing(int)}
*/
@Deprecated
public void setVerticalMargin(int margin) {
setVerticalSpacing(margin);
}
/**
* Returns the spacing in pixels between two child items vertically.
*
* @deprecated Use {@link #getVerticalSpacing()}
*/
@Deprecated
public int getVerticalMargin() {
return mLayoutManager.getVerticalSpacing();
}
/**
* Sets the spacing in pixels between two child items horizontally.
*
* @deprecated Use {@link #setHorizontalSpacing(int)}
*/
@Deprecated
public void setHorizontalMargin(int margin) {
setHorizontalSpacing(margin);
}
/**
* Returns the spacing in pixels between two child items horizontally.
*
* @deprecated Use {@link #getHorizontalSpacing()}
*/
@Deprecated
public int getHorizontalMargin() {
return mLayoutManager.getHorizontalSpacing();
}
/**
* Sets the vertical spacing in pixels between two child items.
*
* @param spacing Vertical spacing between two child items.
*/
public void setVerticalSpacing(int spacing) {
mLayoutManager.setVerticalSpacing(spacing);
requestLayout();
}
/**
* Returns the vertical spacing in pixels between two child items.
*
* @return The vertical spacing in pixels between two child items.
*/
public int getVerticalSpacing() {
return mLayoutManager.getVerticalSpacing();
}
/**
* Sets the horizontal spacing in pixels between two child items.
*
* @param spacing Horizontal spacing in pixels between two child items.
*/
public void setHorizontalSpacing(int spacing) {
mLayoutManager.setHorizontalSpacing(spacing);
requestLayout();
}
/**
* Returns the horizontal spacing in pixels between two child items.
*
* @return The Horizontal spacing in pixels between two child items.
*/
public int getHorizontalSpacing() {
return mLayoutManager.getHorizontalSpacing();
}
/**
* Registers a callback to be invoked when an item in BaseGridView has
* been laid out.
*
* @param listener The listener to be invoked.
*/
public void setOnChildLaidOutListener(@Nullable OnChildLaidOutListener listener) {
mLayoutManager.setOnChildLaidOutListener(listener);
}
/**
* Registers a callback to be invoked when an item in BaseGridView has
* been selected. Note that the listener may be invoked when there is a
* layout pending on the view, affording the listener an opportunity to
* adjust the upcoming layout based on the selection state.
*
* @param listener The listener to be invoked.
*/
@SuppressLint("ReferencesDeprecated")
@SuppressWarnings("deprecation")
public void setOnChildSelectedListener(@Nullable OnChildSelectedListener listener) {
mLayoutManager.setOnChildSelectedListener(listener);
}
/**
* Registers a callback to be invoked when the BaseGridView completes a full layout calculation.
*
* @param listener The listener to be invoked.
*/
public final void addOnLayoutCompletedListener(@NonNull OnLayoutCompletedListener listener) {
mLayoutManager.addOnLayoutCompletedListener(listener);
}
/**
* Removes a callback to be invoked when the BaseGridView completes a full layout calculation.
*
* @param listener The listener to be invoked.
*/
public final void removeOnLayoutCompletedListener(@NonNull OnLayoutCompletedListener listener) {
mLayoutManager.removeOnLayoutCompletedListener(listener);
}
/**
* Registers a callback to be invoked when an item in BaseGridView has
* been selected. Note that the listener may be invoked when there is a
* layout pending on the view, affording the listener an opportunity to
* adjust the upcoming layout based on the selection state.
* This method will clear all existing listeners added by
* {@link #addOnChildViewHolderSelectedListener}.
*
* @param listener The listener to be invoked.
*/
public void setOnChildViewHolderSelectedListener(
@Nullable OnChildViewHolderSelectedListener listener) {
mLayoutManager.setOnChildViewHolderSelectedListener(listener);
}
/**
* Registers a callback to be invoked when an item in BaseGridView has
* been selected. Note that the listener may be invoked when there is a
* layout pending on the view, affording the listener an opportunity to
* adjust the upcoming layout based on the selection state.
*
* @param listener The listener to be invoked.
*/
public void addOnChildViewHolderSelectedListener(
@NonNull OnChildViewHolderSelectedListener listener) {
mLayoutManager.addOnChildViewHolderSelectedListener(listener);
}
/**
* Remove the callback invoked when an item in BaseGridView has been selected.
*
* @param listener The listener to be removed.
*/
public void removeOnChildViewHolderSelectedListener(
@NonNull OnChildViewHolderSelectedListener listener) {
mLayoutManager.removeOnChildViewHolderSelectedListener(listener);
}
/**
* Changes the selected item immediately without animation.
*/
public void setSelectedPosition(int position) {
mLayoutManager.setSelection(position, 0);
}
/**
* Changes the selected item and/or subposition immediately without animation.
*
*/
@RestrictTo(LIBRARY_GROUP_PREFIX)
public void setSelectedPositionWithSub(int position, int subposition) {
mLayoutManager.setSelectionWithSub(position, subposition, 0);
}
/**
* Changes the selected item immediately without animation, scrollExtra is
* applied in primary scroll direction. The scrollExtra will be kept until
* another {@link #setSelectedPosition} or {@link #setSelectedPositionSmooth} call.
*/
public void setSelectedPosition(int position, int scrollExtra) {
mLayoutManager.setSelection(position, scrollExtra);
}
/**
* Changes the selected item and/or subposition immediately without animation, scrollExtra is
* applied in primary scroll direction. The scrollExtra will be kept until
* another {@link #setSelectedPosition} or {@link #setSelectedPositionSmooth} call.
*
*/
@RestrictTo(LIBRARY_GROUP_PREFIX)
public void setSelectedPositionWithSub(int position, int subposition, int scrollExtra) {
mLayoutManager.setSelectionWithSub(position, subposition, scrollExtra);
}
/**
* Changes the selected item and run an animation to scroll to the target
* position.
*
* @param position Adapter position of the item to select.
*/
public void setSelectedPositionSmooth(int position) {
mLayoutManager.setSelectionSmooth(position);
}
/**
* Changes the selected item and/or subposition, runs an animation to scroll to the target
* position.
*
*/
@RestrictTo(LIBRARY_GROUP_PREFIX)
public void setSelectedPositionSmoothWithSub(int position, int subposition) {
mLayoutManager.setSelectionSmoothWithSub(position, subposition);
}
/**
* Perform a task on ViewHolder at given position after smooth scrolling to it.
*
* @param position Position of item in adapter.
* @param task Task to executed on the ViewHolder at a given position.
*/
@SuppressWarnings("deprecation")
public void setSelectedPositionSmooth(final int position, @Nullable final ViewHolderTask task) {
if (task != null) {
RecyclerView.ViewHolder vh = findViewHolderForPosition(position);
if (vh == null || hasPendingAdapterUpdates()) {
addOnChildViewHolderSelectedListener(new OnChildViewHolderSelectedListener() {
@Override
public void onChildViewHolderSelected(@NonNull RecyclerView parent,
RecyclerView.ViewHolder child, int selectedPosition, int subposition) {
if (selectedPosition == position) {
removeOnChildViewHolderSelectedListener(this);
task.run(child);
}
}
});
} else {
task.run(vh);
}
}
setSelectedPositionSmooth(position);
}
/**
* Perform a task on ViewHolder at given position after scroll to it.
*
* @param position Position of item in adapter.
* @param task Task to executed on the ViewHolder at a given position.
*/
@SuppressWarnings("deprecation")
public void setSelectedPosition(final int position, @Nullable final ViewHolderTask task) {
if (task != null) {
RecyclerView.ViewHolder vh = findViewHolderForPosition(position);
if (vh == null || hasPendingAdapterUpdates()) {
addOnChildViewHolderSelectedListener(new OnChildViewHolderSelectedListener() {
@Override
public void onChildViewHolderSelectedAndPositioned(@NonNull RecyclerView parent,
RecyclerView.ViewHolder child, int selectedPosition, int subposition) {
if (selectedPosition == position) {
removeOnChildViewHolderSelectedListener(this);
task.run(child);
}
}
});
} else {
task.run(vh);
}
}
setSelectedPosition(position);
}
/**
* Returns the adapter position of selected item.
*
* @return The adapter position of selected item.
*/
public int getSelectedPosition() {
return mLayoutManager.getSelection();
}
/**
* Returns the sub selected item position started from zero. An item can have
* multiple {@link ItemAlignmentFacet}s provided by {@link RecyclerView.ViewHolder}
* or {@link FacetProviderAdapter}. Zero is returned when no {@link ItemAlignmentFacet}
* is defined.
*
*/
@RestrictTo(LIBRARY_GROUP_PREFIX)
public int getSelectedSubPosition() {
return mLayoutManager.getSubSelection();
}
/**
* Sets whether ItemAnimator should run when a child changes size or when adding
* or removing a child.
*
* @param animateChildLayout True to enable ItemAnimator, false to disable.
*/
public void setAnimateChildLayout(boolean animateChildLayout) {
if (mAnimateChildLayout != animateChildLayout) {
mAnimateChildLayout = animateChildLayout;
if (!mAnimateChildLayout) {
mSavedItemAnimator = getItemAnimator();
super.setItemAnimator(null);
} else {
super.setItemAnimator(mSavedItemAnimator);
}
}
}
/**
* Returns true if an animation will run when a child changes size or when
* adding or removing a child.
*
* @return True if ItemAnimator is enabled, false otherwise.
*/
public boolean isChildLayoutAnimated() {
return mAnimateChildLayout;
}
/**
* Sets the gravity used for child view positioning. Defaults to
* GRAVITY_TOP|GRAVITY_START.
*
* @param gravity See {@link android.view.Gravity}
*/
public void setGravity(int gravity) {
mLayoutManager.setGravity(gravity);
requestLayout();
}
@Override
public void setLayoutManager(@Nullable RecyclerView.LayoutManager layout) {
if (layout == null) {
super.setLayoutManager(null);
if (mLayoutManager != null) {
mLayoutManager.setGridView(null);
}
mLayoutManager = null;
return;
}
mLayoutManager = (GridLayoutManager) layout;
mLayoutManager.setGridView(this);
super.setLayoutManager(layout);
}
@Override
public boolean onRequestFocusInDescendants(int direction,
@Nullable Rect previouslyFocusedRect) {
if ((mPrivateFlag & PFLAG_RETAIN_FOCUS_FOR_CHILD) == PFLAG_RETAIN_FOCUS_FOR_CHILD) {
// dont focus to child if GridView itself retains focus for child
return false;
}
return mLayoutManager.gridOnRequestFocusInDescendants(this, direction,
previouslyFocusedRect);
}
/**
* Returns the x/y offsets to final position from current position if the view
* is selected.
*
* @param view The view to get offsets.
* @param offsets offsets[0] holds offset of X, offsets[1] holds offset of Y.
*/
public void getViewSelectedOffsets(@NonNull View view, @NonNull int[] offsets) {
mLayoutManager.getViewSelectedOffsets(view, offsets);
}
@Override
public int getChildDrawingOrder(int childCount, int i) {
return mLayoutManager.getChildDrawingOrder(this, childCount, i);
}
final boolean isChildrenDrawingOrderEnabledInternal() {
return isChildrenDrawingOrderEnabled();
}
@Override
@Nullable
public View focusSearch(int direction) {
if (isFocused()) {
// focusSearch(int) is called when GridView itself is focused.
// Calling focusSearch(view, int) to get next sibling of current selected child.
View view = mLayoutManager.findViewByPosition(mLayoutManager.getSelection());
if (view != null) {
return focusSearch(view, direction);
}
}
// otherwise, go to mParent to perform focusSearch
return super.focusSearch(direction);
}
@Override
protected void onFocusChanged(boolean gainFocus, int direction,
@Nullable Rect previouslyFocusedRect) {
super.onFocusChanged(gainFocus, direction, previouslyFocusedRect);
mLayoutManager.onFocusChanged(gainFocus, direction, previouslyFocusedRect);
}
/**
* Disables or enables focus search.
*
* @param disabled True to disable focus search, false to enable.
*/
public final void setFocusSearchDisabled(boolean disabled) {
// LayoutManager may detachView and attachView in fastRelayout, it causes RowsFragment
// re-gain focus after a BACK key pressed, so block children focus during transition.
setDescendantFocusability(disabled ? FOCUS_BLOCK_DESCENDANTS : FOCUS_AFTER_DESCENDANTS);
mLayoutManager.setFocusSearchDisabled(disabled);
}
/**
* Returns true if focus search is disabled.
*
* @return True if focus search is disabled.
*/
public final boolean isFocusSearchDisabled() {
return mLayoutManager.isFocusSearchDisabled();
}
/**
* Enables or disables layout. All children will be removed when layout is
* disabled.
*
* @param layoutEnabled True to enable layout, false otherwise.
*/
public void setLayoutEnabled(boolean layoutEnabled) {
mLayoutManager.setLayoutEnabled(layoutEnabled);
}
/**
* Changes and overrides children's visibility.
*
* @param visibility See {@link View#getVisibility()}.
*/
public void setChildrenVisibility(int visibility) {
mLayoutManager.setChildrenVisibility(visibility);
}
/**
* Enables or disables pruning of children. Disable is useful during transition.
*
* @param pruneChild True to prune children out side visible area, false to enable.
*/
public void setPruneChild(boolean pruneChild) {
mLayoutManager.setPruneChild(pruneChild);
}
/**
* Enables or disables scrolling. Disable is useful during transition.
*
* @param scrollEnabled True to enable scroll, false to disable.
*/
public void setScrollEnabled(boolean scrollEnabled) {
mLayoutManager.setScrollEnabled(scrollEnabled);
}
/**
* Returns true if scrolling is enabled, false otherwise.
*
* @return True if scrolling is enabled, false otherwise.
*/
public boolean isScrollEnabled() {
return mLayoutManager.isScrollEnabled();
}
/**
* Returns true if the view at the given position has a same row sibling
* in front of it. This will return true if first item view is not created.
*
* @param position Position in adapter.
* @return True if the view at the given position has a same row sibling in front of it.
*/
public boolean hasPreviousViewInSameRow(int position) {
return mLayoutManager.hasPreviousViewInSameRow(position);
}
/**
* Enables or disables the default "focus draw at last" order rule. Default is enabled.
*
* @param enabled True to draw the selected child at last, false otherwise.
*/
public void setFocusDrawingOrderEnabled(boolean enabled) {
super.setChildrenDrawingOrderEnabled(enabled);
}
/**
* Returns true if draws selected child at last, false otherwise. Default is enabled.
*
* @return True if draws selected child at last, false otherwise.
*/
public boolean isFocusDrawingOrderEnabled() {
return super.isChildrenDrawingOrderEnabled();
}
/**
* Sets the touch intercept listener.
*
* @param listener The touch intercept listener.
*/
public void setOnTouchInterceptListener(@Nullable OnTouchInterceptListener listener) {
mOnTouchInterceptListener = listener;
}
/**
* Sets the generic motion intercept listener.
*
* @param listener The motion intercept listener.
*/
public void setOnMotionInterceptListener(@Nullable OnMotionInterceptListener listener) {
mOnMotionInterceptListener = listener;
}
/**
* Sets the key intercept listener.
*
* @param listener The key intercept listener.
*/
public void setOnKeyInterceptListener(@Nullable OnKeyInterceptListener listener) {
mOnKeyInterceptListener = listener;
}
/**
* Sets the unhandled key listener.
*
* @param listener The unhandled key intercept listener.
*/
public void setOnUnhandledKeyListener(@Nullable OnUnhandledKeyListener listener) {
mOnUnhandledKeyListener = listener;
}
/**
* Returns the unhandled key listener.
*
* @return The unhandled key listener.
*/
@Nullable
public OnUnhandledKeyListener getOnUnhandledKeyListener() {
return mOnUnhandledKeyListener;
}
@Override
public boolean dispatchKeyEvent(@NonNull KeyEvent event) {
if (mOnKeyInterceptListener != null && mOnKeyInterceptListener.onInterceptKeyEvent(event)) {
return true;
}
if (super.dispatchKeyEvent(event)) {
return true;
}
return mOnUnhandledKeyListener != null && mOnUnhandledKeyListener.onUnhandledKey(event);
}
@Override
public boolean dispatchTouchEvent(@NonNull MotionEvent event) {
if (mOnTouchInterceptListener != null) {
if (mOnTouchInterceptListener.onInterceptTouchEvent(event)) {
return true;
}
}
return super.dispatchTouchEvent(event);
}
@Override
protected boolean dispatchGenericFocusedEvent(@NonNull MotionEvent event) {
if (mOnMotionInterceptListener != null) {
if (mOnMotionInterceptListener.onInterceptMotionEvent(event)) {
return true;
}
}
return super.dispatchGenericFocusedEvent(event);
}
/**
* Returns the policy for saving children.
*
* @return policy, one of {@link #SAVE_NO_CHILD}
* {@link #SAVE_ON_SCREEN_CHILD} {@link #SAVE_LIMITED_CHILD} {@link #SAVE_ALL_CHILD}.
*/
public final int getSaveChildrenPolicy() {
return mLayoutManager.mChildrenStates.getSavePolicy();
}
/**
* Returns the limit used when when {@link #getSaveChildrenPolicy()} is
* {@link #SAVE_LIMITED_CHILD}
*/
public final int getSaveChildrenLimitNumber() {
return mLayoutManager.mChildrenStates.getLimitNumber();
}
/**
* Sets the policy for saving children.
*
* @param savePolicy One of {@link #SAVE_NO_CHILD} {@link #SAVE_ON_SCREEN_CHILD}
* {@link #SAVE_LIMITED_CHILD} {@link #SAVE_ALL_CHILD}.
*/
public final void setSaveChildrenPolicy(int savePolicy) {
mLayoutManager.mChildrenStates.setSavePolicy(savePolicy);
}
/**
* Sets the limit number when {@link #getSaveChildrenPolicy()} is {@link #SAVE_LIMITED_CHILD}.
*/
public final void setSaveChildrenLimitNumber(int limitNumber) {
mLayoutManager.mChildrenStates.setLimitNumber(limitNumber);
}
@Override
public boolean hasOverlappingRendering() {
return mHasOverlappingRendering;
}
public void setHasOverlappingRendering(boolean hasOverlapping) {
mHasOverlappingRendering = hasOverlapping;
}
/**
* Notify layout manager that layout directionality has been updated
*/
@Override
public void onRtlPropertiesChanged(int layoutDirection) {
if (mLayoutManager != null) {
mLayoutManager.onRtlPropertiesChanged(layoutDirection);
}
}
/**
* Sets pixels of extra space for layout child in invisible area.
*
* @param extraLayoutSpace Pixels of extra space for layout invisible child.
* Must be bigger or equals to 0.
*/
@RestrictTo(LIBRARY_GROUP_PREFIX)
public void setExtraLayoutSpace(int extraLayoutSpace) {
mLayoutManager.setExtraLayoutSpace(extraLayoutSpace);
}
/**
* Returns pixels of extra space for layout child in invisible area.
*
*/
@RestrictTo(LIBRARY_GROUP_PREFIX)
public int getExtraLayoutSpace() {
return mLayoutManager.getExtraLayoutSpace();
}
/**
* Temporarily slide out child views to bottom (for VerticalGridView) or end
* (for HorizontalGridView). Layout and scrolling will be suppressed until
* {@link #animateIn()} is called.
*/
public void animateOut() {
mLayoutManager.slideOut();
}
/**
* Undo animateOut() and slide in child views.
*/
public void animateIn() {
mLayoutManager.slideIn();
}
@Override
public void scrollToPosition(int position) {
// dont abort the animateOut() animation, just record the position
if (mLayoutManager.isSlidingChildViews()) {
mLayoutManager.setSelectionWithSub(position, 0, 0);
return;
}
super.scrollToPosition(position);
}
@Override
public void smoothScrollToPosition(int position) {
// dont abort the animateOut() animation, just record the position
if (mLayoutManager.isSlidingChildViews()) {
mLayoutManager.setSelectionWithSub(position, 0, 0);
return;
}
super.smoothScrollToPosition(position);
}
/**
* Set custom behavior for smoothScrollBy().
*
* @param behavior Custom behavior of SmoothScrollBy(). Null for default behavior.
*/
public final void setSmoothScrollByBehavior(@Nullable SmoothScrollByBehavior behavior) {
mSmoothScrollByBehavior = behavior;
}
/**
* Returns custom behavior for smoothScrollBy().
*
* @return Custom behavior for SmoothScrollBy(). Null for default behavior.
*/
@Nullable
public SmoothScrollByBehavior getSmoothScrollByBehavior() {
return mSmoothScrollByBehavior;
}
@Override
public void smoothScrollBy(int dx, int dy) {
if (mSmoothScrollByBehavior != null) {
smoothScrollBy(dx, dy,
mSmoothScrollByBehavior.configSmoothScrollByInterpolator(dx, dy),
mSmoothScrollByBehavior.configSmoothScrollByDuration(dx, dy));
} else {
smoothScrollBy(dx, dy, null, UNDEFINED_DURATION);
}
}
@Override
public void smoothScrollBy(int dx, int dy, @Nullable Interpolator interpolator) {
if (mSmoothScrollByBehavior != null) {
smoothScrollBy(dx, dy,
interpolator,
mSmoothScrollByBehavior.configSmoothScrollByDuration(dx, dy));
} else {
smoothScrollBy(dx, dy, interpolator, UNDEFINED_DURATION);
}
}
/**
* Set factor of how slow the smoothScroller should run. For example when set to 2f, the smooth
* scroller is twice slower. The value is 1f by default.
*
* @param smoothScrollSpeedFactor Factor of how slow the smooth scroll is.
*/
public final void setSmoothScrollSpeedFactor(float smoothScrollSpeedFactor) {
mLayoutManager.mSmoothScrollSpeedFactor = smoothScrollSpeedFactor;
}
/**
* @return Factor of how slow the smoothScroller runs. Default value is 1f.
*/
public final float getSmoothScrollSpeedFactor() {
return mLayoutManager.mSmoothScrollSpeedFactor;
}
/**
* When holding DPAD, DPAD events are generated faster than the grid view can scroll. The
* grid view counts unhandled DPAD events and completes the movement after user release DPAD.
* If the value is set too high, the scrolling will last very long after DPAD is released. If
* the value is set too low, it may miss many DPAD events. The default value is 10. If app
* increases {@link #setSmoothScrollSpeedFactor(float)}, it may need decrease the max pending
* DPAD events to avoid scrolling too long after DPAD release.
*
* @param maxPendingMoves Maximum number of pending DPAD events to be remembered.
*/
public final void setSmoothScrollMaxPendingMoves(int maxPendingMoves) {
mLayoutManager.mMaxPendingMoves = maxPendingMoves;
}
/**
* When holding DPAD, DPAD events are generated faster than the grid view can scroll. The
* grid view counts unhandled DPAD events and complete the movement after user release DPAD.
* If the value is set too high, the scrolling will last very long after DPAD is released. If
* the value is set too low, it may miss many DPAD events. The default value is 10. If app
* increases {@link #setSmoothScrollSpeedFactor(float)}, it may need decrease the max pending
* DPAD events to avoid scrolling too long after DPAD release.
*
* @return Maximum number of pending DPAD events to be remembered when smooth scroll cannot
* catch up speed of DPAD events being sent.
*/
public final int getSmoothScrollMaxPendingMoves() {
return mLayoutManager.mMaxPendingMoves;
}
/**
* Sets the number of items to prefetch in
* {@link RecyclerView.LayoutManager#collectInitialPrefetchPositions(int, RecyclerView.LayoutManager.LayoutPrefetchRegistry)},
* which defines how many inner items should be prefetched when this GridView is nested inside
* another RecyclerView.
*
* <p>Set this value to the number of items this inner GridView will display when it is
* first scrolled into the viewport. RecyclerView will attempt to prefetch that number of items
* so they are ready, avoiding jank as the inner GridView is scrolled into the viewport.</p>
*
* <p>For example, take a VerticalGridView of scrolling HorizontalGridViews. The rows always
* have 6 items visible in them (or 7 if not aligned). Passing <code>6</code> to this method
* for each inner GridView will enable RecyclerView's prefetching feature to do create/bind work
* for 6 views within a row early, before it is scrolled on screen, instead of just the default
* 4.</p>
*
* <p>Calling this method does nothing unless the LayoutManager is in a RecyclerView
* nested in another RecyclerView.</p>
*
* <p class="note"><strong>Note:</strong> Setting this value to be larger than the number of
* views that will be visible in this view can incur unnecessary bind work, and an increase to
* the number of Views created and in active use.</p>
*
* @param itemCount Number of items to prefetch
* @see #getInitialPrefetchItemCount()
* @see RecyclerView.LayoutManager#isItemPrefetchEnabled()
* @see RecyclerView.LayoutManager#collectInitialPrefetchPositions(int,
* RecyclerView.LayoutManager.LayoutPrefetchRegistry)
*/
public void setInitialPrefetchItemCount(int itemCount) {
mInitialPrefetchItemCount = itemCount;
}
/**
* Gets the number of items to prefetch in
* {@link RecyclerView.LayoutManager#collectInitialPrefetchPositions(int, RecyclerView.LayoutManager.LayoutPrefetchRegistry)},
* which defines how many inner items should be prefetched when this GridView is nested inside
* another RecyclerView.
*
* @return number of items to prefetch.
* @see RecyclerView.LayoutManager#isItemPrefetchEnabled()
* @see #setInitialPrefetchItemCount(int)
* @see RecyclerView.LayoutManager#collectInitialPrefetchPositions(int,
* RecyclerView.LayoutManager.LayoutPrefetchRegistry)
*/
public int getInitialPrefetchItemCount() {
return mInitialPrefetchItemCount;
}
@Override
public void removeView(@NonNull View view) {
boolean retainFocusForChild = view.hasFocus() && isFocusable();
if (retainFocusForChild) {
// When animation or scrolling removes a focused child, focus to GridView itself to
// avoid losing focus.
mPrivateFlag |= PFLAG_RETAIN_FOCUS_FOR_CHILD;
requestFocus();
}
super.removeView(view);
if (retainFocusForChild) {
mPrivateFlag ^= ~PFLAG_RETAIN_FOCUS_FOR_CHILD;
}
}
@Override
public void removeViewAt(int index) {
boolean retainFocusForChild = getChildAt(index).hasFocus();
if (retainFocusForChild) {
// When animation or scrolling removes a focused child, focus to GridView itself to
// avoid losing focus.
mPrivateFlag |= PFLAG_RETAIN_FOCUS_FOR_CHILD;
requestFocus();
}
super.removeViewAt(index);
if (retainFocusForChild) {
mPrivateFlag ^= ~PFLAG_RETAIN_FOCUS_FOR_CHILD;
}
}
}