Skip to content

Instantly share code, notes, and snippets.

@rharter
Last active February 4, 2018 01:12
Show Gist options
  • Star 6 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save rharter/84baa08cc95028ef01bbcbbc9fa5c11e to your computer and use it in GitHub Desktop.
Save rharter/84baa08cc95028ef01bbcbbc9fa5c11e to your computer and use it in GitHub Desktop.
Extension methods to easily provide all functionality in ViewCompat. This makes it super easy to see when there is a compat method available in code completion right alongside the framework methods.
import android.content.ClipData
import android.graphics.Paint
import android.os.Build
import android.os.Bundle
import android.support.v4.view.*
import android.support.v4.view.accessibility.AccessibilityNodeInfoCompat
import android.support.v4.view.accessibility.AccessibilityNodeProviderCompat
import android.view.*
/**
* Initializes an [AccessibilityNodeInfoCompat] with information
* about this view. The base implementation sets:
*
* * [AccessibilityNodeInfoCompat.setParent],
* * [AccessibilityNodeInfoCompat.setBoundsInParent],
* * [AccessibilityNodeInfoCompat.setBoundsInScreen],
* * [AccessibilityNodeInfoCompat.setPackageName],
* * [AccessibilityNodeInfoCompat.setClassName],
* * [AccessibilityNodeInfoCompat.setContentDescription],
* * [AccessibilityNodeInfoCompat.setEnabled],
* * [AccessibilityNodeInfoCompat.setClickable],
* * [AccessibilityNodeInfoCompat.setFocusable],
* * [AccessibilityNodeInfoCompat.setFocused],
* * [AccessibilityNodeInfoCompat.setLongClickable],
* * [AccessibilityNodeInfoCompat.setSelected],
*
* If an [AccessibilityDelegateCompat] has been specified via calling
* [ViewCompat.setAccessibilityDelegate], its
* [AccessibilityDelegateCompat.onInitializeAccessibilityNodeInfo]
* method is responsible for handling this call.
*
* @param info The instance to initialize.
*/
inline fun View.onInitializeAccessibilityNodeInfoCompat(info: AccessibilityNodeInfoCompat) =
ViewCompat.onInitializeAccessibilityNodeInfo(this, info)
/**
* Sets a delegate for implementing accessibility support via composition
* (as opposed to inheritance). For more details, see
* [AccessibilityDelegateCompat].
*
*
* **Note:** On platform versions prior to
* [API 23][android.os.Build.VERSION_CODES.M], delegate methods on
* views in the `android.widget.*` package are called *before*
* host methods. This prevents certain properties such as class name from
* being modified by overriding
* [AccessibilityDelegateCompat.onInitializeAccessibilityNodeInfo],
* as any changes will be overwritten by the host class.
*
*
* Starting in [API 23][android.os.Build.VERSION_CODES.M], delegate
* methods are called *after* host methods, which all properties to be
* modified without being overwritten by the host class.
*
* @param delegate the object to which accessibility method calls should be
* delegated
* @see AccessibilityDelegateCompat
*/
inline fun View.setAccessibilityDelegateCompat(delegate: AccessibilityDelegateCompat) =
ViewCompat.setAccessibilityDelegate(this, delegate)
/**
* Checks whether provided View has an accessibility delegate attached to it.
*
* @return True if the View has an accessibility delegate
*/
inline fun View.hasAccessibilityDelegateCompat() = ViewCompat.hasAccessibilityDelegate(this)
/**
* Indicates whether the view is currently tracking transient state that the
* app should not need to concern itself with saving and restoring, but that
* the framework should take special note to preserve when possible.
*
* @return true if the view has transient state
*/
inline var View.hasTransientStateCompat
get() = ViewCompat.hasTransientState(this)
set(value) = ViewCompat.setHasTransientState(this, value)
/**
*
* Cause an invalidate to happen on the next animation time step, typically the
* next display frame.
*
*
* This method can be invoked from outside of the UI thread
* only when this View is attached to a window.
*
*/
inline fun View.postInvalidateOnAnimationCompat() = ViewCompat.postInvalidateOnAnimation(this)
/**
*
* Cause an invalidate of the specified area to happen on the next animation
* time step, typically the next display frame.
*
*
* This method can be invoked from outside of the UI thread
* only when this View is attached to a window.
*
* @param left The left coordinate of the rectangle to invalidate.
* @param top The top coordinate of the rectangle to invalidate.
* @param right The right coordinate of the rectangle to invalidate.
* @param bottom The bottom coordinate of the rectangle to invalidate.
*/
inline fun View.postInvalidateOnAnimationCompat(left: Int, top: Int,
right: Int, bottom: Int) =
ViewCompat.postInvalidateOnAnimation(this, left, top, right, bottom)
/**
*
* Causes the Runnable to execute on the next animation time step.
* The runnable will be run on the user interface thread.
*
*
* This method can be invoked from outside of the UI thread
* only when this View is attached to a window.
*
* @param action The Runnable that will be executed.
*/
inline fun View.postOnAnimationCompat(action: Runnable) = ViewCompat.postOnAnimation(this, action)
/**
*
* Causes the Runnable to execute on the next animation time step,
* after the specified amount of time elapses.
* The runnable will be run on the user interface thread.
*
*
* This method can be invoked from outside of the UI thread
* only when this View is attached to a window.
*
* @param action The Runnable that will be executed.
* @param delayMillis The delay (in milliseconds) until the Runnable
* will be executed.
*/
inline fun View.postOnAnimationDelayedCompat(action: Runnable, delayMillis: Long) =
ViewCompat.postOnAnimationDelayed(this, action, delayMillis)
/**
* Gets the mode for determining whether this View is important for accessibility
* which is if it fires accessibility events and if it is reported to
* accessibility services that query the screen.
*
* @return The mode for determining whether a View is important for accessibility.
*
* @see .IMPORTANT_FOR_ACCESSIBILITY_YES
*
* @see .IMPORTANT_FOR_ACCESSIBILITY_NO
*
* @see .IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS
*
* @see .IMPORTANT_FOR_ACCESSIBILITY_AUTO
*/
inline var View.importantForAccessibilityCompat
get() = ViewCompat.getImportantForAccessibility(this)
set(value) = ViewCompat.setImportantForAccessibility(this, value)
/**
* Computes whether this view should be exposed for accessibility. In
* general, views that are interactive or provide information are exposed
* while views that serve only as containers are hidden.
*
*
* If an ancestor of this view has importance
* [.IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS], this method
* returns `false`.
*
*
* Otherwise, the value is computed according to the view's
* [.getImportantForAccessibility] value:
*
* 1. [.IMPORTANT_FOR_ACCESSIBILITY_NO] or
* [.IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS], return `false
` *
* 1. [.IMPORTANT_FOR_ACCESSIBILITY_YES], return `true`
* 1. [.IMPORTANT_FOR_ACCESSIBILITY_AUTO], return `true` if
* view satisfies any of the following:
*
* * Is actionable, e.g. [View.isClickable],
* [View.isLongClickable], or [View.isFocusable]
* * Has an [AccessibilityDelegateCompat]
* * Has an interaction listener, e.g. [View.OnTouchListener],
* [View.OnKeyListener], etc.
* * Is an accessibility live region, e.g.
* [.getAccessibilityLiveRegion] is not
* [.ACCESSIBILITY_LIVE_REGION_NONE].
*
*
*
*
* *Note:* Prior to API 21, this method will always return `true`.
*
* @return Whether the view is exposed for accessibility.
* @see .setImportantForAccessibility
* @see .getImportantForAccessibility
*/
inline val View.isImportantForAccessibilityCompat
get() = ViewCompat.isImportantForAccessibility(this)
/**
* Performs the specified accessibility action on the view. For
* possible accessibility actions look at [AccessibilityNodeInfoCompat].
*
*
* If an [AccessibilityDelegateCompat] has been specified via calling
* [.setAccessibilityDelegate] its
* [AccessibilityDelegateCompat.performAccessibilityAction]
* is responsible for handling this call.
*
*
* @param action The action to perform.
* @param arguments Optional action arguments.
* @return Whether the action was performed.
*/
fun View.performAccessibilityActionCompat(action: Int, arguments: Bundle) =
ViewCompat.performAccessibilityAction(this, action, arguments)
/**
* Gets the provider for managing a virtual view hierarchy rooted at this View
* and reported to [android.accessibilityservice.AccessibilityService]s
* that explore the window content.
*
*
* If this method returns an instance, this instance is responsible for managing
* [AccessibilityNodeInfoCompat]s describing the virtual sub-tree rooted at
* this View including the one representing the View itself. Similarly the returned
* instance is responsible for performing accessibility actions on any virtual
* view or the root view itself.
*
*
*
* If an [AccessibilityDelegateCompat] has been specified via calling
* [.setAccessibilityDelegate] its
* [AccessibilityDelegateCompat.getAccessibilityNodeProvider]
* is responsible for handling this call.
*
*
* @return The provider.
*
* @see AccessibilityNodeProviderCompat
*/
inline val View.accessibilityNodeProviderCompat
get() = ViewCompat.getAccessibilityNodeProvider(this)
/**
* Gets the id of a view for which a given view serves as a label for
* accessibility purposes.
*
* @return The labeled view id.
*/
inline var View.getLabelForCompat
get() = ViewCompat.getLabelFor(this)
set(value) = ViewCompat.setLabelFor(this, value)
/**
* Updates the [Paint] object used with the current layer (used only if the current
* layer type is not set to [View.LAYER_TYPE_NONE]). Changed properties of the Paint
* provided to [.setLayerType]
* will be used the next time the View is redrawn, but
* [.setLayerPaint]
* must be called to ensure that the view gets redrawn immediately.
*
*
* A layer is associated with an optional [android.graphics.Paint]
* instance that controls how the layer is composed on screen. The following
* properties of the paint are taken into account when composing the layer:
*
* * [Translucency (alpha)][android.graphics.Paint.getAlpha]
* * [Blending mode][android.graphics.Paint.getXfermode]
* * [Color filter][android.graphics.Paint.getColorFilter]
*
*
*
* If this view has an alpha value set to < 1.0 by calling
* View#setAlpha(float), the alpha value of the layer's paint is replaced by
* this view's alpha value. Calling View#setAlpha(float) is therefore
* equivalent to setting a hardware layer on this view and providing a paint with
* the desired alpha value.
*
* @param paint The paint used to compose the layer. This argument is optional
* and can be null. It is ignored when the layer type is
* [View.LAYER_TYPE_NONE]
*
* @see .setLayerType
*/
inline fun View.setLayerPaintCompat(paint: Paint) = ViewCompat.setLayerPaint(this, paint)
/**
* Returns the resolved layout direction for this view.
*
* @return [.LAYOUT_DIRECTION_RTL] if the layout direction is RTL or returns
* [.LAYOUT_DIRECTION_LTR] if the layout direction is not RTL.
*
* For compatibility, this will return [.LAYOUT_DIRECTION_LTR] if API version
* is lower than Jellybean MR1 (API 17)
*/
inline var View.getLayoutDirectionCompat
get() = ViewCompat.getLayoutDirection(this)
set(value) = ViewCompat.setLayoutDirection(this, value)
/**
* Gets the parent for accessibility purposes. Note that the parent for
* accessibility is not necessary the immediate parent. It is the first
* predecessor that is important for accessibility.
*
* @return The parent for use in accessibility inspection
*/
inline val View.parentForAccessibilityCompat
get() = ViewCompat.getParentForAccessibility(this)
/**
* Gets the live region mode for the specified View.
*
* @return The live region mode for the view.
*
* @see ViewCompat.setAccessibilityLiveRegion
*/
inline var View.accessibilityLiveRegionCompat
get() = ViewCompat.getAccessibilityLiveRegion(this)
set(value) = ViewCompat.setAccessibilityLiveRegion(this, value)
/**
* Returns the start padding of the specified view depending on its resolved layout direction.
* If there are inset and enabled scrollbars, this value may include the space
* required to display the scrollbars as well.
*
* @return the start padding in pixels
*/
inline fun View.getPaddingStartCompat() = ViewCompat.getPaddingStart(this)
/**
* Returns the end padding of the specified view depending on its resolved layout direction.
* If there are inset and enabled scrollbars, this value may include the space
* required to display the scrollbars as well.
*
* @return the end padding in pixels
*/
inline fun View.getPaddingEndCompat() = ViewCompat.getPaddingEnd(this)
/**
* Sets the relative padding. The view may add on the space required to display
* the scrollbars, depending on the style and visibility of the scrollbars.
* So the values returned from [.getPaddingStart], [View.getPaddingTop],
* [.getPaddingEnd] and [View.getPaddingBottom] may be different
* from the values set in this call.
*
* @param start the start padding in pixels
* @param top the top padding in pixels
* @param end the end padding in pixels
* @param bottom the bottom padding in pixels
*/
inline fun View.setPaddingRelativeCompat(start: Int, top: Int, end: Int, bottom: Int) =
ViewCompat.setPaddingRelative(this, start, top, end, bottom)
/**
* Notify a view that it is being temporarily detached.
*/
inline fun View.dispatchStartTemporaryDetachCompat() =
ViewCompat.dispatchStartTemporaryDetach(this)
/**
* Notify a view that its temporary detach has ended; the view is now reattached.
*/
inline fun View.dispatchFinishTemporaryDetachCompat() =
ViewCompat.dispatchFinishTemporaryDetach(this)
/**
* Returns the minimum width of the view.
*
*
* Prior to API 16, this method may return 0 on some platforms.
*
* @return the minimum width the view will try to be.
*/
inline val View.minimumWidthCompat
get() = ViewCompat.getMinimumWidth(this)
/**
* Returns the minimum height of the view.
*
*
* Prior to API 16, this method may return 0 on some platforms.
*
* @return the minimum height the view will try to be.
*/
inline val View.minimumHeightCompat
get() = ViewCompat.getMinimumHeight(this)
/**
* This method returns a ViewPropertyAnimator object, which can be used to animate
* specific properties on this View.
*
* @return ViewPropertyAnimator The ViewPropertyAnimator associated with this View.
*/
inline fun View.animateCompat() = ViewCompat.animate(this)
/**
* The base elevation of this view relative to its parent, in pixels.
*
* @return The base depth position of the view, in pixels.
*/
inline var View.elevationCompat
get() = ViewCompat.getElevation(this)
set(value) = ViewCompat.setElevation(this, value)
/**
* Sets the depth location of this view relative to its [elevation][.getElevation].
*/
inline var View.translationZCompat
get() = ViewCompat.getTranslationZ(this)
set(value) = ViewCompat.setTranslationZ(this, value)
/**
* Sets the name of the View to be used to identify Views in Transitions.
* Names should be unique in the View hierarchy.
*
* @param transitionName The name of the View to uniquely identify it for Transitions.
*/
inline var View.transitionNameCompat
get() = ViewCompat.getTransitionName(this)
set(value) = ViewCompat.setTransitionName(this, value)
/**
* Returns the current system UI visibility that is currently set for the entire window.
*/
inline val View.windowSystemUiVisibilityCompat
get() = ViewCompat.getWindowSystemUiVisibility(this)
/**
* Ask that a new dispatch of `View.onApplyWindowInsets(WindowInsets)` be performed. This
* falls back to `View.requestFitSystemWindows()` where available.
*/
inline fun View.requestApplyInsetsCompat() = ViewCompat.requestApplyInsets(this)
/**
* Tells the ViewGroup whether to draw its children in the order defined by the method
* `ViewGroup.getChildDrawingOrder(int, int)`.
*
* @param enabled true if the order of the children when drawing is determined by
* [ViewGroup.getChildDrawingOrder], false otherwise
*
*
* Prior to API 7 this will have no effect.
*/
inline fun ViewGroup.setChildrenDrawingOrderEnabledCompat(enabled: Boolean) =
ViewCompat.setChildrenDrawingOrderEnabled(this, enabled)
/**
* Returns true if this view should adapt to fit system window insets. This method will always
* return false before API 16 (Jellybean).
*/
inline val View.fitsSystemWindowsCompat
get() = ViewCompat.getFitsSystemWindows(this)
/**
* Set an [OnApplyWindowInsetsListener] to take over the policy for applying
* window insets to this view. This will only take effect on devices with API 21 or above.
*/
inline fun View.setOnApplyWindowInsetsListenerCompat(listener: OnApplyWindowInsetsListener) =
ViewCompat.setOnApplyWindowInsetsListener(this, listener)
/**
* Called when the view should apply [WindowInsetsCompat] according to its internal policy.
*
*
* Clients may supply an [OnApplyWindowInsetsListener] to a view. If one is set
* it will be called during dispatch instead of this method. The listener may optionally
* call this method from its own implementation if it wishes to apply the view's default
* insets policy in addition to its own.
*
* @param insets Insets to apply
* @return The supplied insets with any applied insets consumed
*/
inline fun View.onApplyWindowInsetsCompat(insets: WindowInsetsCompat) =
ViewCompat.onApplyWindowInsets(this, insets)
/**
* Request to apply the given window insets to this view or another view in its subtree.
*
*
* This method should be called by clients wishing to apply insets corresponding to areas
* obscured by window decorations or overlays. This can include the status and navigation bars,
* action bars, input methods and more. New inset categories may be added in the future.
* The method returns the insets provided minus any that were applied by this view or its
* children.
*
* @param insets Insets to apply
* @return The provided insets minus the insets that were consumed
*/
inline fun View.dispatchApplyWindowInsetsCompat(insets: WindowInsetsCompat) =
ViewCompat.dispatchApplyWindowInsets(this, insets)
/**
* Returns whether this View has content which overlaps.
*
*
* This function, intended to be overridden by specific View types, is an optimization when
* alpha is set on a view. If rendering overlaps in a view with alpha < 1, that view is drawn to
* an offscreen buffer and then composited into place, which can be expensive. If the view has
* no overlapping rendering, the view can draw each primitive with the appropriate alpha value
* directly. An example of overlapping rendering is a TextView with a background image, such as
* a Button. An example of non-overlapping rendering is a TextView with no background, or an
* ImageView with only the foreground image. The default implementation returns true; subclasses
* should override if they have cases which can be optimized.
*
* @return true if the content in this view might overlap, false otherwise.
*/
inline fun View.hasOverlappingRenderingCompat() = ViewCompat.hasOverlappingRendering(this)
/**
* Return if the padding as been set through relative values
* `View.setPaddingRelative(int, int, int, int)` or thru
*
* @return true if the padding is relative or false if it is not.
*/
inline val View.isPaddingRelativeCompat
get() = ViewCompat.isPaddingRelative(this)
/**
* Set the background of the `view` to a given Drawable, or remove the background. If the
* background has padding, `view`'s padding is set to the background's padding. However,
* when a background is removed, this View's padding isn't touched. If setting the padding is
* desired, please use`setPadding(int, int, int, int)`.
*/
inline var View.backgroundCompat
get() = this.background
set(value) = ViewCompat.setBackground(this, value)
/**
* The tint applied to the background drawable, if specified.
*
*
* Only returns meaningful info when running on API v21 or newer, or if `view`
* implements the `TintableBackgroundView` interface.
*/
inline var View.backgroundTintListCompat
get() = ViewCompat.getBackgroundTintList(this)
set(value) = ViewCompat.setBackgroundTintList(this, value)
/**
* The blending mode used to apply the tint to the background
* drawable, if specified.
*
*
* Only returns meaningful info when running on API v21 or newer, or if `view`
* implements the `TintableBackgroundView` interface.
*/
inline var View.backgroundTintModeCompat
get() = ViewCompat.getBackgroundTintMode(this)
set(value) = ViewCompat.setBackgroundTintMode(this, value)
/**
* Enable or disable nested scrolling for this view.
*
*
* If this property is set to true the view will be permitted to initiate nested
* scrolling operations with a compatible parent view in the current hierarchy. If this
* view does not implement nested scrolling this will have no effect. Disabling nested scrolling
* while a nested scroll is in progress has the effect of
* [stopping][.stopNestedScroll] the nested scroll.
*
* @param enabled true to enable nested scrolling, false to disable
*
* @see .isNestedScrollingEnabled
*/
inline var View.isNestedScrollingEnabledCompat
get() = ViewCompat.isNestedScrollingEnabled(this)
set(value) = ViewCompat.setNestedScrollingEnabled(this, value)
/**
* Begin a nestable scroll operation along the given axes.
*
*
* This version of the method just calls [.startNestedScroll] using
* the touch input type.
*
* @param axes Flags consisting of a combination of [ViewCompat.SCROLL_AXIS_HORIZONTAL]
* and/or [ViewCompat.SCROLL_AXIS_VERTICAL].
* @return true if a cooperative parent was found and nested scrolling has been enabled for
* the current gesture.
*/
inline fun View.startNestedScrollCompat(@ViewCompat.ScrollAxis axes: Int) =
ViewCompat.startNestedScroll(this, axes)
/**
* Stop a nested scroll in progress.
*
*
* This version of the method just calls [.stopNestedScroll] using the
* touch input type.
*
* @see .startNestedScroll
*/
inline fun View.stopNestedScrollCompat() = ViewCompat.stopNestedScroll(this)
/**
* Returns true if this view has a nested scrolling parent.
*
*
* This version of the method just calls [.hasNestedScrollingParent]
* using the touch input type.
*
* @return whether this view has a nested scrolling parent
*/
inline fun View.hasNestedScrollingParentCompat() = ViewCompat.hasNestedScrollingParent(this)
/**
* Dispatch one step of a nested scroll in progress.
*
*
* This version of the method just calls
* [.dispatchNestedScroll] using the touch input
* type.
*
* @param dxConsumed Horizontal distance in pixels consumed by this view during this scroll step
* @param dyConsumed Vertical distance in pixels consumed by this view during this scroll step
* @param dxUnconsumed Horizontal scroll distance in pixels not consumed by this view
* @param dyUnconsumed Horizontal scroll distance in pixels not consumed by this view
* @param offsetInWindow Optional. If not null, on return this will contain the offset
* in local view coordinates of this view from before this operation
* to after it completes. View implementations may use this to adjust
* expected input coordinate tracking.
* @return true if the event was dispatched, false if it could not be dispatched.
*/
inline fun View.dispatchNestedScrollCompat(dxConsumed: Int, dyConsumed: Int,
dxUnconsumed: Int, dyUnconsumed: Int,
offsetInWindow: IntArray?) =
ViewCompat.dispatchNestedScroll(this, dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed,
offsetInWindow)
/**
* Dispatch one step of a nested scroll in progress before this view consumes any portion of it.
*
*
* This version of the method just calls
* [.dispatchNestedPreScroll] using the touch input
* type.
*
* @param dx Horizontal scroll distance in pixels
* @param dy Vertical scroll distance in pixels
* @param consumed Output. If not null, consumed[0] will contain the consumed component of dx
* and consumed[1] the consumed dy.
* @param offsetInWindow Optional. If not null, on return this will contain the offset
* in local view coordinates of this view from before this operation
* to after it completes. View implementations may use this to adjust
* expected input coordinate tracking.
* @return true if the parent consumed some or all of the scroll delta
*/
inline fun View.dispatchNestedPreScrollCompat(dx: Int, dy: Int,
consumed: IntArray?, offsetInWindow: IntArray?) =
ViewCompat.dispatchNestedPreScroll(this, dx, dy, consumed, offsetInWindow)
/**
* Begin a nestable scroll operation along the given axes.
*
*
* A view starting a nested scroll promises to abide by the following contract:
*
*
* The view will call startNestedScroll upon initiating a scroll operation. In the case
* of a touch scroll this corresponds to the initial [MotionEvent.ACTION_DOWN].
* In the case of touch scrolling the nested scroll will be terminated automatically in
* the same manner as [ViewParent.requestDisallowInterceptTouchEvent].
* In the event of programmatic scrolling the caller must explicitly call
* [.stopNestedScroll] to indicate the end of the nested scroll.
*
*
* If `startNestedScroll` returns true, a cooperative parent was found.
* If it returns false the caller may ignore the rest of this contract until the next scroll.
* Calling startNestedScroll while a nested scroll is already in progress will return true.
*
*
* At each incremental step of the scroll the caller should invoke
* [dispatchNestedPreScroll][.dispatchNestedPreScroll]
* once it has calculated the requested scrolling delta. If it returns true the nested scrolling
* parent at least partially consumed the scroll and the caller should adjust the amount it
* scrolls by.
*
*
* After applying the remainder of the scroll delta the caller should invoke
* [dispatchNestedScroll][.dispatchNestedScroll], passing
* both the delta consumed and the delta unconsumed. A nested scrolling parent may treat
* these values differently. See
* [NestedScrollingParent.onNestedScroll].
*
*
* @param axes Flags consisting of a combination of [ViewCompat.SCROLL_AXIS_HORIZONTAL]
* and/or [ViewCompat.SCROLL_AXIS_VERTICAL].
* @param type the type of input which cause this scroll event
* @return true if a cooperative parent was found and nested scrolling has been enabled for
* the current gesture.
*
* @see .stopNestedScroll
* @see .dispatchNestedPreScroll
* @see .dispatchNestedScroll
*/
inline fun View.startNestedScrollCompat(@ViewCompat.ScrollAxis axes: Int,
@ViewCompat.NestedScrollType type: Int) =
ViewCompat.startNestedScroll(this, axes, type)
/**
* Stop a nested scroll in progress.
*
*
* Calling this method when a nested scroll is not currently in progress is harmless.
*
* @param type the type of input which cause this scroll event
* @see .startNestedScroll
*/
inline fun View.stopNestedScrollCompat(@ViewCompat.NestedScrollType type: Int) =
ViewCompat.stopNestedScroll(this, type)
/**
* Returns true if this view has a nested scrolling parent.
*
*
* The presence of a nested scrolling parent indicates that this view has initiated
* a nested scroll and it was accepted by an ancestor view further up the view hierarchy.
*
* @param type the type of input which cause this scroll event
* @return whether this view has a nested scrolling parent
*/
inline fun View.hasNestedScrollingParentCompat(@ViewCompat.NestedScrollType type: Int) =
ViewCompat.hasNestedScrollingParent(this, type)
/**
* Dispatch one step of a nested scroll in progress.
*
*
* Implementations of views that support nested scrolling should call this to report
* info about a scroll in progress to the current nested scrolling parent. If a nested scroll
* is not currently in progress or nested scrolling is not
* [enabled][.isNestedScrollingEnabled] for this view this method does nothing.
*
*
* Compatible View implementations should also call
* [dispatchNestedPreScroll][.dispatchNestedPreScroll] before
* consuming a component of the scroll event themselves.
*
* @param dxConsumed Horizontal distance in pixels consumed by this view during this scroll step
* @param dyConsumed Vertical distance in pixels consumed by this view during this scroll step
* @param dxUnconsumed Horizontal scroll distance in pixels not consumed by this view
* @param dyUnconsumed Horizontal scroll distance in pixels not consumed by this view
* @param offsetInWindow Optional. If not null, on return this will contain the offset
* in local view coordinates of this view from before this operation
* to after it completes. View implementations may use this to adjust
* expected input coordinate tracking.
* @param type the type of input which cause this scroll event
* @return true if the event was dispatched, false if it could not be dispatched.
* @see .dispatchNestedPreScroll
*/
inline fun View.dispatchNestedScrollCompat(dxConsumed: Int, dyConsumed: Int,
dxUnconsumed: Int, dyUnconsumed: Int, offsetInWindow: IntArray?,
@ViewCompat.NestedScrollType type: Int) =
ViewCompat.dispatchNestedScroll(this, dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed,
offsetInWindow, type)
/**
* Dispatch one step of a nested scroll in progress before this view consumes any portion of it.
*
*
* Nested pre-scroll events are to nested scroll events what touch intercept is to touch.
* `dispatchNestedPreScroll` offers an opportunity for the parent view in a nested
* scrolling operation to consume some or all of the scroll operation before the child view
* consumes it.
*
* @param dx Horizontal scroll distance in pixels
* @param dy Vertical scroll distance in pixels
* @param consumed Output. If not null, consumed[0] will contain the consumed component of dx
* and consumed[1] the consumed dy.
* @param offsetInWindow Optional. If not null, on return this will contain the offset
* in local view coordinates of this view from before this operation
* to after it completes. View implementations may use this to adjust
* expected input coordinate tracking.
* @param type the type of input which cause this scroll event
* @return true if the parent consumed some or all of the scroll delta
* @see .dispatchNestedScroll
*/
inline fun View.dispatchNestedPreScrollCompat(dx: Int, dy: Int,
consumed: IntArray?, offsetInWindow: IntArray?,
@ViewCompat.NestedScrollType type: Int) =
ViewCompat.dispatchNestedPreScroll(this, dx, dy, consumed, offsetInWindow, type)
/**
* Dispatch a fling to a nested scrolling parent.
*
*
* This method should be used to indicate that a nested scrolling child has detected
* suitable conditions for a fling. Generally this means that a touch scroll has ended with a
* [velocity][VelocityTracker] in the direction of scrolling that meets or exceeds
* the [minimum fling velocity][ViewConfiguration.getScaledMinimumFlingVelocity]
* along a scrollable axis.
*
*
* If a nested scrolling child view would normally fling but it is at the edge of
* its own content, it can use this method to delegate the fling to its nested scrolling
* parent instead. The parent may optionally consume the fling or observe a child fling.
*
* @param velocityX Horizontal fling velocity in pixels per second
* @param velocityY Vertical fling velocity in pixels per second
* @param consumed true if the child consumed the fling, false otherwise
* @return true if the nested scrolling parent consumed or otherwise reacted to the fling
*/
inline fun View.dispatchNestedFlingCompat(velocityX: Float, velocityY: Float,
consumed: Boolean) =
ViewCompat.dispatchNestedFling(this, velocityX, velocityY, consumed)
/**
* Dispatch a fling to a nested scrolling parent before it is processed by this view.
*
*
* Nested pre-fling events are to nested fling events what touch intercept is to touch
* and what nested pre-scroll is to nested scroll. `dispatchNestedPreFling`
* offsets an opportunity for the parent view in a nested fling to fully consume the fling
* before the child view consumes it. If this method returns `true`, a nested
* parent view consumed the fling and this view should not scroll as a result.
*
*
* For a better user experience, only one view in a nested scrolling chain should consume
* the fling at a time. If a parent view consumed the fling this method will return false.
* Custom view implementations should account for this in two ways:
*
*
* * If a custom view is paged and needs to settle to a fixed page-point, do not
* call `dispatchNestedPreFling`; consume the fling and settle to a valid
* position regardless.
* * If a nested parent does consume the fling, this view should not scroll at all,
* even to settle back to a valid idle position.
*
*
*
* Views should also not offer fling velocities to nested parent views along an axis
* where scrolling is not currently supported; a [ScrollView][android.widget.ScrollView]
* should not offer a horizontal fling velocity to its parents since scrolling along that
* axis is not permitted and carrying velocity along that motion does not make sense.
*
* @param velocityX Horizontal fling velocity in pixels per second
* @param velocityY Vertical fling velocity in pixels per second
* @return true if a nested scrolling parent consumed the fling
*/
inline fun View.dispatchNestedPreFlingCompat(velocityX: Float,
velocityY: Float) =
ViewCompat.dispatchNestedPreFling(this, velocityX, velocityY)
/**
* Returns whether the view hierarchy is currently undergoing a layout pass. This
* information is useful to avoid situations such as calling [View.requestLayout]
* during a layout pass.
*
*
* Compatibility:
*
* * API &lt; 18: Always returns `false`
*
*
* @return whether the view hierarchy is currently undergoing a layout pass
*/
inline val View.isInLayoutCompat
get() = ViewCompat.isInLayout(this)
/**
* Returns true if `view` has been through at least one layout since it
* was last attached to or detached from a window.
*/
inline val View.isLaidOutCompat
get() = ViewCompat.isLaidOut(this)
/**
* Returns whether layout direction has been resolved.
*
*
* Compatibility:
*
* * API &lt; 19: Always returns `false`
*
*
* @return true if layout direction has been resolved.
*/
inline val View.isLayoutDirectionResolvedCompat
get() = ViewCompat.isLayoutDirectionResolved(this)
/**
* The visual z position of this view, in pixels. This is equivalent to the
* [translationZ][.setTranslationZ] property plus the current
* [elevation][.getElevation] property.
*
* @return The visual z position of this view, in pixels.
*/
inline var View.zCompat
get() = ViewCompat.getZ(this)
set(value) = ViewCompat.setZ(this, value)
/**
* Offset this view's vertical location by the specified number of pixels.
*
* @param offset the number of pixels to offset the view by
*/
inline fun View.offsetTopAndBottomCompat(offset: Int) = ViewCompat.offsetTopAndBottom(this, offset)
/**
* Offset this view's horizontal location by the specified amount of pixels.
*
* @param offset the number of pixels to offset the view by
*/
inline fun View.offsetLeftAndRightCompat(offset: Int) = ViewCompat.offsetLeftAndRight(this, offset)
/**
* Sets a rectangular area on this view to which the view will be clipped
* when it is drawn. Setting the value to null will remove the clip bounds
* and the view will draw normally, using its full bounds.
*
*
* Prior to API 18 this does nothing.
*
* @param clipBounds The rectangular area, in the local coordinates of
* this view, to which future drawing operations will be clipped.
*/
inline var View.clipBoundsCompat
get() = ViewCompat.getClipBounds(this)
set(value) = ViewCompat.setClipBounds(this, value)
/**
* Returns true if the provided view is currently attached to a window.
*/
inline val View.isAttachedToWindowCompat
get() = ViewCompat.isAttachedToWindow(this)
/**
* Returns whether the provided view has an attached [View.OnClickListener].
*
* @return true if there is a listener, false if there is none.
*/
inline fun View.hasOnClickListenersCompat() = ViewCompat.hasOnClickListeners(this)
/**
* Sets the state of all scroll indicators.
*
*
* See [.setScrollIndicators] for usage information.
*
* @param indicators a bitmask of indicators that should be enabled, or
* `0` to disable all indicators
*
* @see .setScrollIndicators
* @see .getScrollIndicators
*/
inline var View.scrollIndicatorsCompat
get() = ViewCompat.getScrollIndicators(this)
set(value) = ViewCompat.setScrollIndicators(this, value)
/**
* Sets the state of the scroll indicators specified by the mask. To change
* all scroll indicators at once, see [.setScrollIndicators].
*
*
* When a scroll indicator is enabled, it will be displayed if the view
* can scroll in the direction of the indicator.
*
*
* Multiple indicator types may be enabled or disabled by passing the
* logical OR of the desired types. If multiple types are specified, they
* will all be set to the same enabled state.
*
*
* For example, to enable the top scroll indicatorExample: `setScrollIndicators`
*
* @param indicators the indicator direction, or the logical OR of multiple
* indicator directions. One or more of:
*
* * [.SCROLL_INDICATOR_TOP]
* * [.SCROLL_INDICATOR_BOTTOM]
* * [.SCROLL_INDICATOR_LEFT]
* * [.SCROLL_INDICATOR_RIGHT]
* * [.SCROLL_INDICATOR_START]
* * [.SCROLL_INDICATOR_END]
*
*
* @see .setScrollIndicators
* @see .getScrollIndicators
*/
inline fun View.setScrollIndicatorsCompat(@ViewCompat.ScrollIndicators indicators: Int,
@ViewCompat.ScrollIndicators mask: Int) =
ViewCompat.setScrollIndicators(this, indicators, mask)
/**
* Set the pointer icon for the current view.
* @param pointerIcon A PointerIconCompat instance which will be shown when the mouse hovers.
*/
inline fun View.setPointerIconCompat(pointerIcon: PointerIconCompat) =
ViewCompat.setPointerIcon(this, pointerIcon)
/**
* Gets the logical display to which the view's window has been attached.
*
*
* Compatibility:
*
* * API &lt; 17: Returns the default display when the view is attached. Otherwise, null.
*
*
* @return The logical display, or null if the view is not currently attached to a window.
*/
inline val View.displayCompat
get() = ViewCompat.getDisplay(this)
/**
* Sets the tooltip for the view.
*
*
* Prior to API 26 this does nothing. Use TooltipCompat class from v7 appcompat library
* for a compatible tooltip implementation.
*
* @param tooltipText the tooltip text
*/
inline var View.tooltipTextCompat: CharSequence?
get() = if (Build.VERSION.SDK_INT >= 26) this.tooltipText else null
set(value) = ViewCompat.setTooltipText(this, value)
/**
* Start the drag and drop operation.
*/
inline fun View.startDragAndDropCompat(data: ClipData,
shadowBuilder: View.DragShadowBuilder,
localState: Any,
flags: Int) =
ViewCompat.startDragAndDrop(this, data, shadowBuilder, localState, flags)
/**
* Cancel the drag and drop operation.
*/
inline fun View.cancelDragAndDropCompat() = ViewCompat.cancelDragAndDrop(this)
/**
* Update the drag shadow while drag and drop is in progress.
*/
inline fun View.updateDragShadowCompat(shadowBuilder: View.DragShadowBuilder) =
ViewCompat.updateDragShadow(this, shadowBuilder)
/**
* Gets the ID of the next keyboard navigation cluster root.
*
* @return the next keyboard navigation cluster ID, or [View.NO_ID] if the framework
* should decide automatically or API < 26.
*/
inline var View.nextClusterForwardIdCompat
get() = ViewCompat.getNextClusterForwardId(this)
set(value) = ViewCompat.setNextClusterForwardId(this, value)
/**
* Returns whether `view` is a root of a keyboard navigation cluster. Always returns
* `false` on API < 26.
*
* @return `true` if this view is a root of a cluster, or `false` otherwise.
*/
inline var View.isKeyboardNavigationClusterCompat
get() = ViewCompat.isKeyboardNavigationCluster(this)
set(value) = ViewCompat.setKeyboardNavigationCluster(this, value)
/**
* Returns whether `view` should receive focus when the focus is restored for the view
* hierarchy containing it. Returns `false` on API < 26.
*
*
* Focus gets restored for a view hierarchy when the root of the hierarchy gets added to a
* window or serves as a target of cluster navigation.
*
* @return `true` if `view` is the default-focus view, `false` otherwise.
*/
inline var View.isFocusedByDefaultCompat
get() = ViewCompat.isFocusedByDefault(this)
set(value) = ViewCompat.setFocusedByDefault(this, value)
/**
* Find the nearest keyboard navigation cluster in the specified direction.
* This does not actually give focus to that cluster.
*
* @param currentCluster The starting point of the search. `null` means the current
* cluster is not found yet.
* @param direction Direction to look.
*
* @return the nearest keyboard navigation cluster in the specified direction, or `null`
* if one can't be found or if API < 26.
*/
inline fun View.keyboardNavigationClusterSearchCompat(currentCluster: View,
@ViewCompat.FocusDirection direction: Int) =
ViewCompat.keyboardNavigationClusterSearch(this, currentCluster, direction)
/**
* Adds any keyboard navigation cluster roots that are descendants of `view` (
* including `view` if it is a cluster root itself) to `views`. Does nothing
* on API < 26.
*
* @param views collection of keyboard navigation cluster roots found so far.
* @param direction direction to look.
*/
inline fun View.addKeyboardNavigationClustersCompat(views: Collection<View>, direction: Int) =
ViewCompat.addKeyboardNavigationClusters(this, views, direction)
/**
* Gives focus to the default-focus view in the view hierarchy rooted at `view`.
* If the default-focus view cannot be found or if API < 26, this falls back to calling
* [View.requestFocus].
*
* @return `true` if `view` or one of its descendants took focus, `false`
* otherwise.
*/
inline fun View.restoreDefaultFocusCompat() = ViewCompat.restoreDefaultFocus(this)
/**
* Returns true if this view is focusable or if it contains a reachable View
* for which [View.hasExplicitFocusable] returns `true`.
* A "reachable hasExplicitFocusable()" is a view whose parents do not block descendants focus.
* Only [View.VISIBLE] views for which [View.getFocusable] would return
* [View.FOCUSABLE] are considered focusable.
*
*
* This method preserves the pre-[Build.VERSION_CODES.O] behavior of
* [View.hasFocusable] in that only views explicitly set focusable will cause
* this method to return true. A view set to [View.FOCUSABLE_AUTO] that resolves
* to focusable will not.
*
* @return `true` if the view is focusable or if the view contains a focusable
* view, `false` otherwise
*/
inline fun View.hasExplicitFocusableCompat() = ViewCompat.hasExplicitFocusable(this)
@ravidsrk
Copy link

ravidsrk commented Oct 5, 2017

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment