2022-10-02 23:06:56 +02:00
package android.view ;
2023-12-29 23:47:38 +01:00
import android.R ;
2023-09-12 23:18:47 +02:00
import android.animation.StateListAnimator ;
2022-10-02 23:06:56 +02:00
import android.content.Context ;
2023-11-08 21:40:39 +01:00
import android.content.res.ColorStateList ;
2022-11-24 23:10:27 +01:00
import android.content.res.Resources ;
2023-10-30 18:52:07 +01:00
import android.content.res.TypedArray ;
2022-10-02 23:06:56 +02:00
import android.graphics.Canvas ;
2023-08-22 18:08:16 +02:00
import android.graphics.Matrix ;
2023-10-08 17:51:41 +02:00
import android.graphics.Paint ;
2023-06-22 11:45:46 +02:00
import android.graphics.Rect ;
2024-02-03 23:01:57 +01:00
import android.graphics.drawable.ColorDrawable ;
2023-08-17 10:46:24 +02:00
import android.graphics.drawable.Drawable ;
import android.os.Handler ;
2023-01-09 12:07:57 +01:00
import android.os.IBinder ;
2023-08-17 10:46:24 +02:00
import android.os.Looper ;
2023-09-01 12:55:04 +02:00
import android.os.Parcelable ;
2023-06-22 11:45:46 +02:00
import android.util.AttributeSet ;
import android.util.LayoutDirection ;
2023-09-06 17:42:24 +02:00
import android.util.Slog ;
2023-09-01 12:55:04 +02:00
import android.util.SparseArray ;
import android.view.animation.Animation ;
2023-08-17 10:46:24 +02:00
import java.util.ArrayList ;
2022-10-02 23:06:56 +02:00
import java.util.HashMap ;
2023-08-17 10:46:24 +02:00
import java.util.Map ;
2023-09-12 23:18:47 +02:00
import java.util.concurrent.atomic.AtomicInteger ;
2022-10-02 23:06:56 +02:00
public class View extends Object {
2023-06-22 11:45:46 +02:00
// --- constants from android source
2022-10-02 23:06:56 +02:00
2022-10-18 18:35:15 +02:00
/ * *
2023-06-22 11:45:46 +02:00
* The logging tag used by this class with android . util . Log .
* /
2023-09-06 17:42:24 +02:00
protected static final String TAG = " View " ;
2022-10-18 18:35:15 +02:00
/ * *
2023-06-22 11:45:46 +02:00
* When set to true , apps will draw debugging information about their layouts .
*
* @hide
* /
2022-10-18 18:35:15 +02:00
public static final String DEBUG_LAYOUT_PROPERTY = " debug.layout " ;
/ * *
2023-06-22 11:45:46 +02:00
* Used to mark a View that has no ID .
* /
2022-10-18 18:35:15 +02:00
public static final int NO_ID = - 1 ;
/ * *
2023-06-22 11:45:46 +02:00
* Signals that compatibility booleans have been initialized according to
* target SDK versions .
* /
2022-10-18 18:35:15 +02:00
private static boolean sCompatibilityDone = false ;
/ * *
2023-06-22 11:45:46 +02:00
* Use the old ( broken ) way of building MeasureSpecs .
* /
2022-10-18 18:35:15 +02:00
private static boolean sUseBrokenMakeMeasureSpec = false ;
/ * *
2023-06-22 11:45:46 +02:00
* Ignore any optimizations using the measure cache .
* /
2022-10-18 18:35:15 +02:00
private static boolean sIgnoreMeasureCache = false ;
/ * *
2023-06-22 11:45:46 +02:00
* This view does not want keystrokes . Use with TAKES_FOCUS_MASK when
* calling setFlags .
* /
2022-10-18 18:35:15 +02:00
private static final int NOT_FOCUSABLE = 0x00000000 ;
/ * *
2023-06-22 11:45:46 +02:00
* This view wants keystrokes . Use with TAKES_FOCUS_MASK when calling
* setFlags .
* /
2022-10-18 18:35:15 +02:00
private static final int FOCUSABLE = 0x00000001 ;
/ * *
2023-06-22 11:45:46 +02:00
* Mask for use with setFlags indicating bits used for focus .
* /
2022-10-18 18:35:15 +02:00
private static final int FOCUSABLE_MASK = 0x00000001 ;
/ * *
2023-06-22 11:45:46 +02:00
* This view will adjust its padding to fit sytem windows ( e . g . status bar )
* /
2022-10-18 18:35:15 +02:00
private static final int FITS_SYSTEM_WINDOWS = 0x00000002 ;
/ * *
2023-06-22 11:45:46 +02:00
* This view is visible .
* Use with { @link # setVisibility } and < a href = " #attr_android:visibility " > { @code
* android : visibility } .
* /
2022-10-18 18:35:15 +02:00
public static final int VISIBLE = 0x00000000 ;
/ * *
2023-06-22 11:45:46 +02:00
* This view is invisible , but it still takes up space for layout purposes .
* Use with { @link # setVisibility } and < a href = " #attr_android:visibility " > { @code
* android : visibility } .
* /
2022-10-18 18:35:15 +02:00
public static final int INVISIBLE = 0x00000004 ;
/ * *
2023-06-22 11:45:46 +02:00
* This view is invisible , and it doesn ' t take any space for layout
* purposes . Use with { @link # setVisibility } and < a href = " #attr_android:visibility " > { @code
* android : visibility } .
* /
2022-10-18 18:35:15 +02:00
public static final int GONE = 0x00000008 ;
/ * *
2023-06-22 11:45:46 +02:00
* Mask for use with setFlags indicating bits used for visibility .
* { @hide }
* /
2022-10-18 18:35:15 +02:00
static final int VISIBILITY_MASK = 0x0000000C ;
private static final int [ ] VISIBILITY_FLAGS = { VISIBLE , INVISIBLE , GONE } ;
/ * *
2023-06-22 11:45:46 +02:00
* This view is enabled . Interpretation varies by subclass .
* Use with ENABLED_MASK when calling setFlags .
* { @hide }
* /
2022-10-18 18:35:15 +02:00
static final int ENABLED = 0x00000000 ;
/ * *
2023-06-22 11:45:46 +02:00
* This view is disabled . Interpretation varies by subclass .
* Use with ENABLED_MASK when calling setFlags .
* { @hide }
* /
2022-10-18 18:35:15 +02:00
static final int DISABLED = 0x00000020 ;
/ * *
2023-06-22 11:45:46 +02:00
* Mask for use with setFlags indicating bits used for indicating whether
* this view is enabled
* { @hide }
* /
2022-10-18 18:35:15 +02:00
static final int ENABLED_MASK = 0x00000020 ;
/ * *
2023-06-22 11:45:46 +02:00
* This view won ' t draw . { @link # onDraw ( android . graphics . Canvas ) } won ' t be
* called and further optimizations will be performed . It is okay to have
* this flag set and a background . Use with DRAW_MASK when calling setFlags .
* { @hide }
* /
2022-10-18 18:35:15 +02:00
static final int WILL_NOT_DRAW = 0x00000080 ;
/ * *
2023-06-22 11:45:46 +02:00
* Mask for use with setFlags indicating bits used for indicating whether
* this view is will draw
* { @hide }
* /
2022-10-18 18:35:15 +02:00
static final int DRAW_MASK = 0x00000080 ;
/ * *
2023-06-22 11:45:46 +02:00
* < p > This view doesn ' t show scrollbars . < / p >
* { @hide }
* /
2022-10-18 18:35:15 +02:00
static final int SCROLLBARS_NONE = 0x00000000 ;
/ * *
2023-06-22 11:45:46 +02:00
* < p > This view shows horizontal scrollbars . < / p >
* { @hide }
* /
2022-10-18 18:35:15 +02:00
static final int SCROLLBARS_HORIZONTAL = 0x00000100 ;
/ * *
2023-06-22 11:45:46 +02:00
* < p > This view shows vertical scrollbars . < / p >
* { @hide }
* /
2022-10-18 18:35:15 +02:00
static final int SCROLLBARS_VERTICAL = 0x00000200 ;
/ * *
2023-06-22 11:45:46 +02:00
* < p > Mask for use with setFlags indicating bits used for indicating which
* scrollbars are enabled . < / p >
* { @hide }
* /
2022-10-18 18:35:15 +02:00
static final int SCROLLBARS_MASK = 0x00000300 ;
/ * *
2023-06-22 11:45:46 +02:00
* Indicates that the view should filter touches when its window is obscured .
* Refer to the class comments for more information about this security feature .
* { @hide }
* /
2022-10-18 18:35:15 +02:00
static final int FILTER_TOUCHES_WHEN_OBSCURED = 0x00000400 ;
/ * *
2023-06-22 11:45:46 +02:00
* Set for framework elements that use FITS_SYSTEM_WINDOWS , to indicate
* that they are optional and should be skipped if the window has
* requested system UI flags that ignore those insets for layout .
* /
2022-10-18 18:35:15 +02:00
static final int OPTIONAL_FITS_SYSTEM_WINDOWS = 0x00000800 ;
/ * *
2023-06-22 11:45:46 +02:00
* < p > This view doesn ' t show fading edges . < / p >
* { @hide }
* /
2022-10-18 18:35:15 +02:00
static final int FADING_EDGE_NONE = 0x00000000 ;
/ * *
2023-06-22 11:45:46 +02:00
* < p > This view shows horizontal fading edges . < / p >
* { @hide }
* /
2022-10-18 18:35:15 +02:00
static final int FADING_EDGE_HORIZONTAL = 0x00001000 ;
/ * *
2023-06-22 11:45:46 +02:00
* < p > This view shows vertical fading edges . < / p >
* { @hide }
* /
2022-10-18 18:35:15 +02:00
static final int FADING_EDGE_VERTICAL = 0x00002000 ;
/ * *
2023-06-22 11:45:46 +02:00
* < p > Mask for use with setFlags indicating bits used for indicating which
* fading edges are enabled . < / p >
* { @hide }
* /
2022-10-18 18:35:15 +02:00
static final int FADING_EDGE_MASK = 0x00003000 ;
/ * *
2023-06-22 11:45:46 +02:00
* < p > Indicates this view can be clicked . When clickable , a View reacts
* to clicks by notifying the OnClickListener . < p >
* { @hide }
* /
2022-10-18 18:35:15 +02:00
static final int CLICKABLE = 0x00004000 ;
/ * *
2023-06-22 11:45:46 +02:00
* < p > Indicates this view is caching its drawing into a bitmap . < / p >
* { @hide }
* /
2022-10-18 18:35:15 +02:00
static final int DRAWING_CACHE_ENABLED = 0x00008000 ;
/ * *
2023-06-22 11:45:46 +02:00
* < p > Indicates that no icicle should be saved for this view . < p >
* { @hide }
* /
2022-10-18 18:35:15 +02:00
static final int SAVE_DISABLED = 0x000010000 ;
/ * *
2023-06-22 11:45:46 +02:00
* < p > Mask for use with setFlags indicating bits used for the saveEnabled
* property . < / p >
* { @hide }
* /
2022-10-18 18:35:15 +02:00
static final int SAVE_DISABLED_MASK = 0x000010000 ;
/ * *
2023-06-22 11:45:46 +02:00
* < p > Indicates that no drawing cache should ever be created for this view . < p >
* { @hide }
* /
2022-10-18 18:35:15 +02:00
static final int WILL_NOT_CACHE_DRAWING = 0x000020000 ;
/ * *
2023-06-22 11:45:46 +02:00
* < p > Indicates this view can take / keep focus when int touch mode . < / p >
* { @hide }
* /
2022-10-18 18:35:15 +02:00
static final int FOCUSABLE_IN_TOUCH_MODE = 0x00040000 ;
/ * *
2023-06-22 11:45:46 +02:00
* < p > Enables low quality mode for the drawing cache . < / p >
* /
2022-10-18 18:35:15 +02:00
public static final int DRAWING_CACHE_QUALITY_LOW = 0x00080000 ;
/ * *
2023-06-22 11:45:46 +02:00
* < p > Enables high quality mode for the drawing cache . < / p >
* /
2022-10-18 18:35:15 +02:00
public static final int DRAWING_CACHE_QUALITY_HIGH = 0x00100000 ;
/ * *
2023-06-22 11:45:46 +02:00
* < p > Enables automatic quality mode for the drawing cache . < / p >
* /
2022-10-18 18:35:15 +02:00
public static final int DRAWING_CACHE_QUALITY_AUTO = 0x00000000 ;
private static final int [ ] DRAWING_CACHE_QUALITY_FLAGS = {
2023-06-22 11:45:46 +02:00
DRAWING_CACHE_QUALITY_AUTO , DRAWING_CACHE_QUALITY_LOW , DRAWING_CACHE_QUALITY_HIGH } ;
2022-10-18 18:35:15 +02:00
/ * *
2023-06-22 11:45:46 +02:00
* < p > Mask for use with setFlags indicating bits used for the cache
* quality property . < / p >
* { @hide }
* /
2022-10-18 18:35:15 +02:00
static final int DRAWING_CACHE_QUALITY_MASK = 0x00180000 ;
/ * *
2023-06-22 11:45:46 +02:00
* < p >
* Indicates this view can be long clicked . When long clickable , a View
* reacts to long clicks by notifying the OnLongClickListener or showing a
* context menu .
* < / p >
* { @hide }
* /
2022-10-18 18:35:15 +02:00
static final int LONG_CLICKABLE = 0x00200000 ;
/ * *
2023-06-22 11:45:46 +02:00
* < p > Indicates that this view gets its drawable states from its direct parent
* and ignores its original internal states . < / p >
*
* @hide
* /
2022-10-18 18:35:15 +02:00
static final int DUPLICATE_PARENT_STATE = 0x00400000 ;
/ * *
2023-06-22 11:45:46 +02:00
* The scrollbar style to display the scrollbars inside the content area ,
* without increasing the padding . The scrollbars will be overlaid with
* translucency on the view ' s content .
* /
2022-10-18 18:35:15 +02:00
public static final int SCROLLBARS_INSIDE_OVERLAY = 0 ;
/ * *
2023-06-22 11:45:46 +02:00
* The scrollbar style to display the scrollbars inside the padded area ,
* increasing the padding of the view . The scrollbars will not overlap the
* content area of the view .
* /
2022-10-18 18:35:15 +02:00
public static final int SCROLLBARS_INSIDE_INSET = 0x01000000 ;
/ * *
2023-06-22 11:45:46 +02:00
* The scrollbar style to display the scrollbars at the edge of the view ,
* without increasing the padding . The scrollbars will be overlaid with
* translucency .
* /
2022-10-18 18:35:15 +02:00
public static final int SCROLLBARS_OUTSIDE_OVERLAY = 0x02000000 ;
/ * *
2023-06-22 11:45:46 +02:00
* The scrollbar style to display the scrollbars at the edge of the view ,
* increasing the padding of the view . The scrollbars will only overlap the
* background , if any .
* /
2022-10-18 18:35:15 +02:00
public static final int SCROLLBARS_OUTSIDE_INSET = 0x03000000 ;
/ * *
2023-06-22 11:45:46 +02:00
* Mask to check if the scrollbar style is overlay or inset .
* { @hide }
* /
2022-10-18 18:35:15 +02:00
static final int SCROLLBARS_INSET_MASK = 0x01000000 ;
/ * *
2023-06-22 11:45:46 +02:00
* Mask to check if the scrollbar style is inside or outside .
* { @hide }
* /
2022-10-18 18:35:15 +02:00
static final int SCROLLBARS_OUTSIDE_MASK = 0x02000000 ;
/ * *
2023-06-22 11:45:46 +02:00
* Mask for scrollbar style .
* { @hide }
* /
2022-10-18 18:35:15 +02:00
static final int SCROLLBARS_STYLE_MASK = 0x03000000 ;
/ * *
2023-06-22 11:45:46 +02:00
* View flag indicating that the screen should remain on while the
* window containing this view is visible to the user . This effectively
* takes care of automatically setting the WindowManager ' s
* { @link WindowManager . LayoutParams # FLAG_KEEP_SCREEN_ON } .
* /
2022-10-18 18:35:15 +02:00
public static final int KEEP_SCREEN_ON = 0x04000000 ;
/ * *
2023-06-22 11:45:46 +02:00
* View flag indicating whether this view should have sound effects enabled
* for events such as clicking and touching .
* /
2022-10-18 18:35:15 +02:00
public static final int SOUND_EFFECTS_ENABLED = 0x08000000 ;
/ * *
2023-06-22 11:45:46 +02:00
* View flag indicating whether this view should have haptic feedback
* enabled for events such as long presses .
* /
2022-10-18 18:35:15 +02:00
public static final int HAPTIC_FEEDBACK_ENABLED = 0x10000000 ;
/ * *
2023-06-22 11:45:46 +02:00
* < p > Indicates that the view hierarchy should stop saving state when
* it reaches this view . If state saving is initiated immediately at
* the view , it will be allowed .
* { @hide }
* /
2022-10-18 18:35:15 +02:00
static final int PARENT_SAVE_DISABLED = 0x20000000 ;
/ * *
2023-06-22 11:45:46 +02:00
* < p > Mask for use with setFlags indicating bits used for PARENT_SAVE_DISABLED . < / p >
* { @hide }
* /
2022-10-18 18:35:15 +02:00
static final int PARENT_SAVE_DISABLED_MASK = 0x20000000 ;
/ * *
2023-06-22 11:45:46 +02:00
* View flag indicating whether { @link # addFocusables ( ArrayList , int , int ) }
* should add all focusable Views regardless if they are focusable in touch mode .
* /
2022-10-18 18:35:15 +02:00
public static final int FOCUSABLES_ALL = 0x00000000 ;
/ * *
2023-06-22 11:45:46 +02:00
* View flag indicating whether { @link # addFocusables ( ArrayList , int , int ) }
* should add only Views focusable in touch mode .
* /
2022-10-18 18:35:15 +02:00
public static final int FOCUSABLES_TOUCH_MODE = 0x00000001 ;
/ * *
2023-06-22 11:45:46 +02:00
* Use with { @link # focusSearch ( int ) } . Move focus to the previous selectable
* item .
* /
2022-10-18 18:35:15 +02:00
public static final int FOCUS_BACKWARD = 0x00000001 ;
/ * *
2023-06-22 11:45:46 +02:00
* Use with { @link # focusSearch ( int ) } . Move focus to the next selectable
* item .
* /
2022-10-18 18:35:15 +02:00
public static final int FOCUS_FORWARD = 0x00000002 ;
/ * *
2023-06-22 11:45:46 +02:00
* Use with { @link # focusSearch ( int ) } . Move focus to the left .
* /
2022-10-18 18:35:15 +02:00
public static final int FOCUS_LEFT = 0x00000011 ;
/ * *
2023-06-22 11:45:46 +02:00
* Use with { @link # focusSearch ( int ) } . Move focus up .
* /
2022-10-18 18:35:15 +02:00
public static final int FOCUS_UP = 0x00000021 ;
/ * *
2023-06-22 11:45:46 +02:00
* Use with { @link # focusSearch ( int ) } . Move focus to the right .
* /
2022-10-18 18:35:15 +02:00
public static final int FOCUS_RIGHT = 0x00000042 ;
/ * *
2023-06-22 11:45:46 +02:00
* Use with { @link # focusSearch ( int ) } . Move focus down .
* /
2022-10-18 18:35:15 +02:00
public static final int FOCUS_DOWN = 0x00000082 ;
/ * *
2023-06-22 11:45:46 +02:00
* Bits of { @link # getMeasuredWidthAndState ( ) } and
* { @link # getMeasuredWidthAndState ( ) } that provide the actual measured size .
* /
2022-10-18 18:35:15 +02:00
public static final int MEASURED_SIZE_MASK = 0x00ffffff ;
/ * *
2023-06-22 11:45:46 +02:00
* Bits of { @link # getMeasuredWidthAndState ( ) } and
* { @link # getMeasuredWidthAndState ( ) } that provide the additional state bits .
* /
2022-10-18 18:35:15 +02:00
public static final int MEASURED_STATE_MASK = 0xff000000 ;
/ * *
2023-06-22 11:45:46 +02:00
* Bit shift of { @link # MEASURED_STATE_MASK } to get to the height bits
* for functions that combine both width and height into a single int ,
* such as { @link # getMeasuredState ( ) } and the childState argument of
* { @link # resolveSizeAndState ( int , int , int ) } .
* /
2022-10-18 18:35:15 +02:00
public static final int MEASURED_HEIGHT_STATE_SHIFT = 16 ;
/ * *
2023-06-22 11:45:46 +02:00
* Bit of { @link # getMeasuredWidthAndState ( ) } and
* { @link # getMeasuredWidthAndState ( ) } that indicates the measured size
* is smaller that the space the view would like to have .
* /
2022-10-18 18:35:15 +02:00
public static final int MEASURED_STATE_TOO_SMALL = 0x01000000 ;
2022-10-02 23:06:56 +02:00
2023-06-22 11:45:46 +02:00
// --- and some flags
2022-10-02 23:06:56 +02:00
2022-10-18 18:35:15 +02:00
/ * *
2023-06-22 11:45:46 +02:00
* Indicates that this view has reported that it can accept the current drag ' s content .
* Cleared when the drag operation concludes .
* @hide
* /
static final int PFLAG2_DRAG_CAN_ACCEPT = 0x00000001 ;
2022-10-18 18:35:15 +02:00
/ * *
2023-06-22 11:45:46 +02:00
* Indicates that this view is currently directly under the drag location in a
* drag - and - drop operation involving content that it can accept . Cleared when
* the drag exits the view , or when the drag operation concludes .
* @hide
* /
static final int PFLAG2_DRAG_HOVERED = 0x00000002 ;
2022-10-18 18:35:15 +02:00
/ * *
2023-06-22 11:45:46 +02:00
* Horizontal layout direction of this view is from Left to Right .
* Use with { @link # setLayoutDirection } .
* /
2022-10-18 18:35:15 +02:00
public static final int LAYOUT_DIRECTION_LTR = LayoutDirection . LTR ;
/ * *
2023-06-22 11:45:46 +02:00
* Horizontal layout direction of this view is from Right to Left .
* Use with { @link # setLayoutDirection } .
* /
2022-10-18 18:35:15 +02:00
public static final int LAYOUT_DIRECTION_RTL = LayoutDirection . RTL ;
/ * *
2023-06-22 11:45:46 +02:00
* Horizontal layout direction of this view is inherited from its parent .
* Use with { @link # setLayoutDirection } .
* /
2022-10-18 18:35:15 +02:00
public static final int LAYOUT_DIRECTION_INHERIT = LayoutDirection . INHERIT ;
/ * *
2023-06-22 11:45:46 +02:00
* Horizontal layout direction of this view is from deduced from the default language
* script for the locale . Use with { @link # setLayoutDirection } .
* /
2022-10-18 18:35:15 +02:00
public static final int LAYOUT_DIRECTION_LOCALE = LayoutDirection . LOCALE ;
/ * *
2023-06-22 11:45:46 +02:00
* Bit shift to get the horizontal layout direction . ( bits after DRAG_HOVERED )
* @hide
* /
2022-10-18 18:35:15 +02:00
static final int PFLAG2_LAYOUT_DIRECTION_MASK_SHIFT = 2 ;
/ * *
2023-06-22 11:45:46 +02:00
* Mask for use with private flags indicating bits used for horizontal layout direction .
* @hide
* /
2022-10-18 18:35:15 +02:00
static final int PFLAG2_LAYOUT_DIRECTION_MASK = 0x00000003 < < PFLAG2_LAYOUT_DIRECTION_MASK_SHIFT ;
/ * *
2023-06-22 11:45:46 +02:00
* Indicates whether the view horizontal layout direction has been resolved and drawn to the
* right - to - left direction .
* @hide
* /
2022-10-18 18:35:15 +02:00
static final int PFLAG2_LAYOUT_DIRECTION_RESOLVED_RTL = 4 < < PFLAG2_LAYOUT_DIRECTION_MASK_SHIFT ;
/ * *
2023-06-22 11:45:46 +02:00
* Indicates whether the view horizontal layout direction has been resolved .
* @hide
* /
2022-10-18 18:35:15 +02:00
static final int PFLAG2_LAYOUT_DIRECTION_RESOLVED = 8 < < PFLAG2_LAYOUT_DIRECTION_MASK_SHIFT ;
/ * *
2023-06-22 11:45:46 +02:00
* Mask for use with private flags indicating bits used for resolved horizontal layout direction .
* @hide
* /
2022-10-18 18:35:15 +02:00
static final int PFLAG2_LAYOUT_DIRECTION_RESOLVED_MASK = 0x0000000C < < PFLAG2_LAYOUT_DIRECTION_MASK_SHIFT ;
2022-10-02 23:06:56 +02:00
2023-08-12 13:09:33 +02:00
// --- apparently there's more...
@Deprecated public static final int STATUS_BAR_HIDDEN = 1 ; // 0x1
@Deprecated public static final int STATUS_BAR_VISIBLE = 0 ; // 0x0
public static final int SYSTEM_UI_FLAG_FULLSCREEN = 4 ; // 0x4
public static final int SYSTEM_UI_FLAG_HIDE_NAVIGATION = 2 ; // 0x2
public static final int SYSTEM_UI_FLAG_IMMERSIVE = 2048 ; // 0x800
public static final int SYSTEM_UI_FLAG_IMMERSIVE_STICKY = 4096 ; // 0x1000
public static final int SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN = 1024 ; // 0x400
public static final int SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION = 512 ; // 0x200
public static final int SYSTEM_UI_FLAG_LAYOUT_STABLE = 256 ; // 0x100
public static final int SYSTEM_UI_FLAG_LOW_PROFILE = 1 ; // 0x1
public static final int SYSTEM_UI_FLAG_VISIBLE = 0 ; // 0x0
public static final int SYSTEM_UI_LAYOUT_FLAGS = 1536 ; // 0x600
public static final int TEXT_ALIGNMENT_CENTER = 4 ; // 0x4
public static final int TEXT_ALIGNMENT_GRAVITY = 1 ; // 0x1
public static final int TEXT_ALIGNMENT_INHERIT = 0 ; // 0x0
public static final int TEXT_ALIGNMENT_TEXT_END = 3 ; // 0x3
public static final int TEXT_ALIGNMENT_TEXT_START = 2 ; // 0x2
public static final int TEXT_ALIGNMENT_VIEW_END = 6 ; // 0x6
public static final int TEXT_ALIGNMENT_VIEW_START = 5 ; // 0x5
public static final int TEXT_DIRECTION_ANY_RTL = 2 ; // 0x2
public static final int TEXT_DIRECTION_FIRST_STRONG = 1 ; // 0x1
public static final int TEXT_DIRECTION_INHERIT = 0 ; // 0x0
public static final int TEXT_DIRECTION_LOCALE = 5 ; // 0x5
public static final int TEXT_DIRECTION_LTR = 3 ; // 0x3
public static final int TEXT_DIRECTION_RTL = 4 ; // 0x4
2023-06-22 11:45:46 +02:00
// --- end of constants from android source
2022-10-02 23:06:56 +02:00
2023-06-22 11:45:46 +02:00
// --- interfaces from android source
2022-10-18 18:35:15 +02:00
public interface OnTouchListener {
/ * *
* Called when a touch event is dispatched to a view . This allows listeners to
* get a chance to respond before the target view .
*
* @param v The view the touch event has been dispatched to .
* @param event The MotionEvent object containing full information about
* the event .
* @return True if the listener has consumed the event , false otherwise .
* /
boolean onTouch ( View v , MotionEvent event ) ;
}
public interface OnClickListener {
void onClick ( View v ) ;
}
2022-10-02 23:06:56 +02:00
public interface OnAttachStateChangeListener {
// TODO
}
2022-10-26 18:39:04 +02:00
public interface OnGenericMotionListener {
// TODO
}
public interface OnSystemUiVisibilityChangeListener {
// TODO
}
2022-10-02 23:06:56 +02:00
public static interface OnKeyListener {
2023-06-22 11:45:46 +02:00
// TODO
// boolean onKey(View v, int keyCode, KeyEvent event);
}
2023-08-17 10:46:24 +02:00
public interface OnLongClickListener {
// TODO
}
public interface OnHoverListener {
// TODO
}
public interface OnApplyWindowInsetsListener {
// TODO
}
public interface OnLayoutChangeListener {
// TODO
}
2023-08-22 14:41:01 +02:00
public interface OnUnhandledKeyEventListener {
// TODO
}
public interface OnFocusChangeListener {
// TODO
}
2023-08-12 13:09:33 +02:00
public interface OnCreateContextMenuListener {
/ * *
* Called when the context menu for this view is being built . It is not
* safe to hold onto the menu after this method returns .
*
* @param menu The context menu that is being built
* @param v The view for which the context menu is being built
* @param menuInfo Extra information about the item for which the
* context menu should be shown . This information will vary
* depending on the class of v .
* /
// void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo);
}
2023-06-22 11:45:46 +02:00
// --- end of interfaces
// --- subclasses
/ * *
* A MeasureSpec encapsulates the layout requirements passed from parent to child .
* Each MeasureSpec represents a requirement for either the width or the height .
* A MeasureSpec is comprised of a size and a mode . There are three possible
* modes :
* < dl >
* < dt > UNSPECIFIED < / dt >
* < dd >
* The parent has not imposed any constraint on the child . It can be whatever size
* it wants .
* < / dd >
*
* < dt > EXACTLY < / dt >
* < dd >
* The parent has determined an exact size for the child . The child is going to be
* given those bounds regardless of how big it wants to be .
* < / dd >
*
* < dt > AT_MOST < / dt >
* < dd >
* The child can be as large as it wants up to the specified size .
* < / dd >
* < / dl >
*
* MeasureSpecs are implemented as ints to reduce object allocation . This class
* is provided to pack and unpack the & lt ; size , mode & gt ; tuple into the int .
* /
2022-10-18 18:35:15 +02:00
public static class MeasureSpec {
private static final int MODE_SHIFT = 30 ;
2023-06-22 11:45:46 +02:00
private static final int MODE_MASK = 0x3 < < MODE_SHIFT ;
2022-10-18 18:35:15 +02:00
/ * *
* Measure specification mode : The parent has not imposed any constraint
* on the child . It can be whatever size it wants .
* /
public static final int UNSPECIFIED = 0 < < MODE_SHIFT ;
/ * *
* Measure specification mode : The parent has determined an exact size
* for the child . The child is going to be given those bounds regardless
* of how big it wants to be .
* /
2023-06-22 11:45:46 +02:00
public static final int EXACTLY = 1 < < MODE_SHIFT ;
2022-10-18 18:35:15 +02:00
/ * *
* Measure specification mode : The child can be as large as it wants up
* to the specified size .
* /
2023-06-22 11:45:46 +02:00
public static final int AT_MOST = 2 < < MODE_SHIFT ;
2022-10-18 18:35:15 +02:00
/ * *
* Creates a measure specification based on the supplied size and mode .
*
* The mode must always be one of the following :
* < ul >
* < li > { @link android . view . View . MeasureSpec # UNSPECIFIED } < / li >
* < li > { @link android . view . View . MeasureSpec # EXACTLY } < / li >
* < li > { @link android . view . View . MeasureSpec # AT_MOST } < / li >
* < / ul >
*
* < p > < strong > Note : < / strong > On API level 17 and lower , makeMeasureSpec ' s
* implementation was such that the order of arguments did not matter
* and overflow in either value could impact the resulting MeasureSpec .
* { @link android . widget . RelativeLayout } was affected by this bug .
* Apps targeting API levels greater than 17 will get the fixed , more strict
* behavior . < / p >
*
* @param size the size of the measure specification
* @param mode the mode of the measure specification
* @return the measure specification based on size and mode
* /
public static int makeMeasureSpec ( int size , int mode ) {
if ( sUseBrokenMakeMeasureSpec ) {
2023-06-22 11:45:46 +02:00
return size + mode ;
2022-10-18 18:35:15 +02:00
} else {
2023-06-22 11:45:46 +02:00
return ( size & ~ MODE_MASK ) | ( mode & MODE_MASK ) ;
2022-10-18 18:35:15 +02:00
}
}
/ * *
* Extracts the mode from the supplied measure specification .
*
* @param measureSpec the measure specification to extract the mode from
* @return { @link android . view . View . MeasureSpec # UNSPECIFIED } ,
* { @link android . view . View . MeasureSpec # AT_MOST } or
* { @link android . view . View . MeasureSpec # EXACTLY }
* /
public static int getMode ( int measureSpec ) {
return ( measureSpec & MODE_MASK ) ;
}
/ * *
* Extracts the size from the supplied measure specification .
*
* @param measureSpec the measure specification to extract the size from
* @return the size in pixels defined in the supplied measure specification
* /
public static int getSize ( int measureSpec ) {
return ( measureSpec & ~ MODE_MASK ) ;
}
static int adjust ( int measureSpec , int delta ) {
return makeMeasureSpec ( getSize ( measureSpec + delta ) , getMode ( measureSpec ) ) ;
}
/ * *
* Returns a String representation of the specified measure
* specification .
*
* @param measureSpec the measure specification to convert to a String
* @return a String with the following format : " MeasureSpec: MODE SIZE "
* /
public static String toString ( int measureSpec ) {
int mode = getMode ( measureSpec ) ;
int size = getSize ( measureSpec ) ;
StringBuilder sb = new StringBuilder ( " MeasureSpec: " ) ;
if ( mode = = UNSPECIFIED )
2023-06-22 11:45:46 +02:00
sb . append ( " UNSPECIFIED " ) ;
2022-10-18 18:35:15 +02:00
else if ( mode = = EXACTLY )
2023-06-22 11:45:46 +02:00
sb . append ( " EXACTLY " ) ;
2022-10-18 18:35:15 +02:00
else if ( mode = = AT_MOST )
2023-06-22 11:45:46 +02:00
sb . append ( " AT_MOST " ) ;
2022-10-18 18:35:15 +02:00
else
2023-06-22 11:45:46 +02:00
sb . append ( mode ) . append ( " " ) ;
2022-10-18 18:35:15 +02:00
sb . append ( size ) ;
return sb . toString ( ) ;
}
}
2022-10-02 23:06:56 +02:00
2023-06-22 11:45:46 +02:00
// --- end of subclasses
2022-10-02 23:06:56 +02:00
2023-09-12 23:18:47 +02:00
public int id = NO_ID ;
2023-08-12 13:09:33 +02:00
private int system_ui_visibility = 0 ;
2022-10-02 23:06:56 +02:00
public ViewGroup parent ;
public AttributeSet attrs ;
protected ViewGroup . LayoutParams layout_params ;
private Context context ;
2023-08-17 10:46:24 +02:00
private Map < Integer , Object > tags = new HashMap < > ( ) ;
2023-09-01 12:55:04 +02:00
private Object tag ;
2023-09-08 18:32:34 +02:00
int gravity = - 1 ; // fallback gravity for layout childs
2022-10-02 23:06:56 +02:00
2023-08-22 14:18:33 +02:00
int measuredWidth = 0 ;
int measuredHeight = 0 ;
private int left ;
private int top ;
private int right ;
private int bottom ;
2023-09-01 12:13:24 +02:00
private int scrollX = 0 ;
private int scrollY = 0 ;
2023-10-08 17:51:41 +02:00
private boolean attachedToWindow = false ;
2022-10-02 23:06:56 +02:00
public long widget ; // pointer
2023-11-03 18:06:30 +01:00
private int oldWidthMeasureSpec = - 1 ;
private int oldHeightMeasureSpec = - 1 ;
2023-10-31 23:02:11 +01:00
private boolean layoutRequested = true ;
2023-10-28 22:38:43 +02:00
private int oldWidth ;
private int oldHeight ;
2024-03-12 18:19:43 +01:00
protected boolean haveCustomMeasure = true ;
2023-10-28 22:38:43 +02:00
2023-11-12 10:43:28 +01:00
private int visibility = View . VISIBLE ;
private float alpha = 1 . 0f ;
2023-12-29 23:47:38 +01:00
private boolean pressed = false ;
private Drawable background ;
2023-11-12 10:43:28 +01:00
2024-02-15 17:59:58 +01:00
private int minWidth = 0 ;
private int minHeight = 0 ;
2023-07-14 18:02:04 +02:00
public View ( Context context , AttributeSet attrs ) {
2023-08-17 12:59:37 +02:00
this ( context , attrs , 0 ) ;
2022-10-02 23:06:56 +02:00
}
2023-08-17 10:46:24 +02:00
public View ( Context context , AttributeSet attrs , int defStyle ) {
2023-08-17 12:59:37 +02:00
this . context = context ;
widget = native_constructor ( context , attrs ) ;
2023-08-22 14:41:01 +02:00
if ( attrs ! = null ) {
2023-10-30 18:52:07 +01:00
TypedArray a = context . obtainStyledAttributes ( attrs , com . android . internal . R . styleable . View , defStyle , 0 ) ;
2024-03-07 15:48:53 +01:00
this . id = a . getResourceId ( com . android . internal . R . styleable . View_id , View . NO_ID ) ;
2023-10-30 18:52:07 +01:00
if ( a . hasValue ( com . android . internal . R . styleable . View_background ) ) {
2024-02-03 23:01:57 +01:00
Drawable background = a . getDrawable ( com . android . internal . R . styleable . View_background ) ;
2023-10-30 18:52:07 +01:00
2024-02-03 23:01:57 +01:00
if ( background ! = null ) {
if ( background instanceof ColorDrawable ) {
System . out . printf ( " __background__: >%x< \ n " , ( ( ColorDrawable ) background ) . getColor ( ) ) ;
setBackgroundColor ( ( ( ColorDrawable ) background ) . getColor ( ) ) ;
2023-12-30 17:09:55 +01:00
} else {
2024-02-03 23:01:57 +01:00
setBackgroundDrawable ( background ) ;
2023-10-30 18:52:07 +01:00
}
}
}
2024-02-08 16:28:53 +01:00
if ( a . hasValue ( com . android . internal . R . styleable . View_visibility ) ) {
setVisibility ( VISIBILITY_FLAGS [ a . getInt ( com . android . internal . R . styleable . View_visibility , 0 ) ] ) ;
}
2024-02-15 17:59:58 +01:00
if ( a . hasValue ( com . android . internal . R . styleable . View_minWidth ) ) {
minWidth = a . getDimensionPixelSize ( com . android . internal . R . styleable . View_minWidth , 0 ) ;
}
if ( a . hasValue ( com . android . internal . R . styleable . View_minHeight ) ) {
minHeight = a . getDimensionPixelSize ( com . android . internal . R . styleable . View_minHeight , 0 ) ;
}
2023-08-22 14:41:01 +02:00
}
2023-08-17 10:46:24 +02:00
}
2022-10-02 23:06:56 +02:00
public View findViewById ( int id ) {
2024-02-11 12:33:58 +01:00
if ( this . id = = id )
return this ;
else
return null ;
2022-10-02 23:06:56 +02:00
}
public void onDraw ( Canvas canvas ) { }
public View ( Context context ) {
2023-08-17 12:59:37 +02:00
this ( context , null ) ;
2022-10-02 23:06:56 +02:00
}
public final ViewParent getParent ( ) {
return parent ;
}
public void setLayoutParams ( ViewGroup . LayoutParams params ) {
if ( params = = null ) {
throw new NullPointerException ( " Layout parameters cannot be null " ) ;
}
2023-09-08 18:32:34 +02:00
int gravity = params . gravity ;
if ( gravity = = - 1 & & parent ! = null )
gravity = parent . gravity ;
2022-10-02 23:06:56 +02:00
2023-11-08 22:41:46 +01:00
int leftMargin = 0 ;
int topMargin = 0 ;
int rightMargin = 0 ;
int bottomMargin = 0 ;
if ( params instanceof ViewGroup . MarginLayoutParams ) {
leftMargin = ( ( ViewGroup . MarginLayoutParams ) params ) . leftMargin ;
topMargin = ( ( ViewGroup . MarginLayoutParams ) params ) . topMargin ;
rightMargin = ( ( ViewGroup . MarginLayoutParams ) params ) . rightMargin ;
bottomMargin = ( ( ViewGroup . MarginLayoutParams ) params ) . bottomMargin ;
}
native_setLayoutParams ( widget , params . width , params . height , gravity , params . weight , leftMargin , topMargin , rightMargin , bottomMargin ) ;
2022-10-02 23:06:56 +02:00
layout_params = params ;
}
public ViewGroup . LayoutParams getLayoutParams ( ) {
return layout_params ;
}
protected final void setMeasuredDimension ( int measuredWidth , int measuredHeight ) {
2023-08-22 14:18:33 +02:00
this . measuredWidth = measuredWidth ;
this . measuredHeight = measuredHeight ;
2022-10-02 23:06:56 +02:00
}
2022-11-24 23:10:27 +01:00
public Resources getResources ( ) {
return Context . this_application . getResources ( ) ;
}
2023-09-08 18:32:34 +02:00
public void setGravity ( int gravity ) {
this . gravity = gravity ;
}
2023-10-17 21:33:59 +02:00
public boolean onTouchEvent ( MotionEvent event ) {
2023-10-28 16:52:58 +02:00
return false ;
2023-10-17 21:33:59 +02:00
}
2022-10-02 23:06:56 +02:00
public native void setOnTouchListener ( OnTouchListener l ) ;
public native void setOnClickListener ( OnClickListener l ) ;
2022-10-26 18:39:04 +02:00
public /*native*/ void setOnSystemUiVisibilityChangeListener ( OnSystemUiVisibilityChangeListener l ) { }
2022-10-18 18:35:15 +02:00
public native final int getWidth ( ) ;
public native final int getHeight ( ) ;
2022-10-02 23:06:56 +02:00
2023-08-17 12:59:37 +02:00
protected native long native_constructor ( Context context , AttributeSet attrs ) ; // will create a custom GtkWidget with a custom drawing function
2023-11-08 22:41:46 +01:00
public native void native_setLayoutParams ( long widget , int width , int height , int gravity , float weight , int leftMargin , int topMargin , int rightMargin , int bottomMargin ) ;
2023-08-22 13:49:09 +02:00
protected native void native_destructor ( long widget ) ;
2023-10-14 11:06:27 +02:00
/ * *
* We decide between simple widgets which handles MEASURE_SPEC_AT_MOST the same way as
* MEASURE_SPEC_EXACTLY , and complex widgets which handles MEASURE_SPEC_AT_MOST by measuring the content
* /
2024-03-12 18:19:43 +01:00
protected native void native_measure ( long widget , int widthMeasureSpec , int heightMeasureSpec ) ;
2023-08-22 14:18:33 +02:00
protected native void native_layout ( long widget , int l , int t , int r , int b ) ;
protected native void native_requestLayout ( long widget ) ;
2023-12-29 16:55:11 +01:00
protected native void native_setBackgroundDrawable ( long widget , long paintable ) ;
2022-10-02 23:06:56 +02:00
2023-06-22 11:45:46 +02:00
// --- stubs
2022-10-02 23:06:56 +02:00
2022-11-24 23:10:27 +01:00
public void setContentDescription ( CharSequence contentDescription ) {
2023-09-06 17:42:24 +02:00
Slog . w ( TAG , " setContentDescription called with: > " + contentDescription + " < " ) ;
2022-11-24 23:10:27 +01:00
}
2023-07-14 18:02:04 +02:00
public void setId ( int id ) {
2023-08-17 10:46:24 +02:00
this . id = id ;
2023-07-14 18:02:04 +02:00
}
2022-11-24 23:10:27 +01:00
2022-10-02 23:06:56 +02:00
public void setOnKeyListener ( OnKeyListener l ) { }
public void setFocusable ( boolean focusable ) { }
public void setFocusableInTouchMode ( boolean focusableInTouchMode ) { }
2022-10-18 18:35:15 +02:00
public final boolean requestFocus ( ) {
return requestFocus ( View . FOCUS_DOWN ) ;
}
public final boolean requestFocus ( int direction ) {
return requestFocus ( direction , null ) ;
}
public boolean requestFocus ( int direction , Rect previouslyFocusedRect ) {
return true ;
}
2022-10-02 23:06:56 +02:00
2023-08-12 13:09:33 +02:00
public void setSystemUiVisibility ( int visibility ) {
system_ui_visibility = visibility ;
}
public int getSystemUiVisibility ( ) {
return system_ui_visibility ;
} ;
2022-10-02 23:06:56 +02:00
2023-08-22 14:18:33 +02:00
protected void onMeasure ( int widthMeasureSpec , int heightMeasureSpec ) {
2023-10-31 23:02:11 +01:00
if ( haveCustomMeasure ) // calling native_measure here would create infinite loop
setMeasuredDimension ( getDefaultSize ( getSuggestedMinimumWidth ( ) , widthMeasureSpec ) , getDefaultSize ( getSuggestedMinimumHeight ( ) , heightMeasureSpec ) ) ;
else
2024-03-12 18:19:43 +01:00
native_measure ( widget , widthMeasureSpec , heightMeasureSpec ) ;
2023-08-22 14:18:33 +02:00
}
2022-10-02 23:06:56 +02:00
public void setPressed ( boolean pressed ) {
2023-09-06 17:42:24 +02:00
Slog . w ( TAG , " calling setPressed on " + this + " with value: " + pressed ) ;
2023-12-29 23:47:38 +01:00
if ( this . pressed ! = pressed ) {
this . pressed = pressed ;
if ( background ! = null & & background . isStateful ( ) )
background . setState ( getDrawableState ( ) ) ;
}
2022-10-02 23:06:56 +02:00
}
public void setSelected ( boolean selected ) {
2023-09-06 17:42:24 +02:00
Slog . w ( TAG , " calling setSelected on " + this + " with value: " + selected ) ;
2022-10-02 23:06:56 +02:00
}
public ViewTreeObserver getViewTreeObserver ( ) {
return new ViewTreeObserver ( ) ;
}
protected void onFinishInflate ( ) { }
2023-10-28 08:12:05 +02:00
public void invalidate ( Rect dirty ) {
nativeInvalidate ( widget ) ;
}
public void invalidate ( int l , int t , int r , int b ) {
nativeInvalidate ( widget ) ;
}
2023-07-13 22:38:01 +02:00
public void invalidate ( ) {
nativeInvalidate ( widget ) ;
}
private static native void nativeInvalidate ( long widget ) ;
2022-10-02 23:06:56 +02:00
2023-10-30 17:28:38 +01:00
public native void setBackgroundColor ( int color ) ;
2023-11-12 10:43:28 +01:00
public native void native_setVisibility ( long widget , int visibility , float alpha ) ;
2023-11-08 18:11:52 +01:00
public void setVisibility ( int visibility ) {
2023-11-12 10:43:28 +01:00
native_setVisibility ( widget , visibility , alpha ) ;
if ( ( visibility = = View . GONE ) ! = ( this . visibility = = View . GONE ) ) {
requestLayout ( ) ;
}
this . visibility = visibility ;
2023-11-08 18:11:52 +01:00
}
2022-10-02 23:06:56 +02:00
public void setPadding ( int left , int top , int right , int bottom ) { }
2023-12-30 17:09:55 +01:00
public void setBackgroundResource ( int resid ) {
2023-12-29 16:55:11 +01:00
setBackgroundDrawable ( getResources ( ) . getDrawable ( resid ) ) ;
2022-10-02 23:06:56 +02:00
}
public void getHitRect ( Rect outRect ) { }
public final boolean getLocalVisibleRect ( Rect r ) { return false ; }
2023-09-01 12:13:24 +02:00
public final int getScrollX ( ) {
return scrollX ;
}
public final int getScrollY ( ) {
return scrollY ;
}
2022-10-02 23:06:56 +02:00
2023-09-01 12:13:24 +02:00
public void scrollTo ( int x , int y ) {
scrollX = x ;
scrollY = y ;
2023-11-11 11:41:17 +01:00
invalidate ( ) ;
2023-09-01 12:13:24 +02:00
}
2022-10-02 23:06:56 +02:00
2023-08-22 14:41:01 +02:00
protected void onScrollChanged ( int l , int t , int oldl , int oldt ) { }
2022-10-02 23:06:56 +02:00
public void getLocationOnScreen ( int [ ] location ) { // FIXME: actually return the widget's location (and also have the onclick callback convert to window coordinates, because is seems that's what android deals in..)
location [ 0 ] = 0 ;
location [ 1 ] = 0 ;
}
public boolean performHapticFeedback ( int feedbackConstant ) {
return performHapticFeedback ( feedbackConstant , 0 ) ;
}
public boolean performHapticFeedback ( int feedbackConstant , int flags ) {
2023-09-06 17:42:24 +02:00
Slog . v ( TAG , " vibration motor go burrrr " ) ;
2022-10-02 23:06:56 +02:00
return true ; // FIXME why is it not void
}
public int getPaddingLeft ( ) {
return 0 ;
}
public int getPaddingRight ( ) {
return 0 ;
}
public int getPaddingTop ( ) {
return 0 ;
}
public int getPaddingBottom ( ) {
return 0 ;
}
2023-09-12 23:18:47 +02:00
public int getPaddingStart ( ) {
return 0 ;
}
public int getPaddingEnd ( ) {
return 0 ;
}
2023-09-01 12:13:24 +02:00
public void postInvalidate ( ) {
new Handler ( Looper . getMainLooper ( ) ) . post ( new Runnable ( ) {
@Override
public void run ( ) {
2023-10-28 08:12:05 +02:00
invalidate ( ) ;
2023-09-01 12:13:24 +02:00
}
} ) ;
}
2022-10-02 23:06:56 +02:00
2023-10-28 08:12:05 +02:00
public void postInvalidate ( final int left , final int top , final int right , final int bottom ) {
new Handler ( Looper . getMainLooper ( ) ) . post ( new Runnable ( ) {
@Override
public void run ( ) {
invalidate ( left , top , right , bottom ) ;
}
} ) ;
2022-10-02 23:06:56 +02:00
}
2022-11-02 16:40:15 +05:00
2023-06-22 11:45:46 +02:00
public void setOnGenericMotionListener ( View . OnGenericMotionListener l ) { }
2023-01-09 12:07:57 +01:00
public IBinder getWindowToken ( ) {
return new IBinder ( ) ;
}
public void getLocationInWindow ( int [ ] xxx ) { }
public void addOnAttachStateChangeListener ( OnAttachStateChangeListener l ) { }
public Context getContext ( ) {
return this . context ;
}
2023-06-18 11:03:43 +02:00
public void refreshDrawableState ( ) {
}
2023-08-17 10:46:24 +02:00
public void setDescendantFocusability ( int value ) { }
public void setAccessibilityDelegate ( AccessibilityDelegate delegate ) { }
public static class AccessibilityDelegate { }
public Drawable getBackground ( ) {
2023-12-29 23:47:38 +01:00
return background ;
2023-08-17 10:46:24 +02:00
}
public void setClickable ( boolean clickable ) { }
public void setEnabled ( boolean enabled ) { }
public CharSequence getContentDescription ( ) {
return null ;
}
2024-02-27 06:57:22 +01:00
public native void setOnLongClickListener ( OnLongClickListener listener ) ;
2023-08-17 10:46:24 +02:00
public void setLongClickable ( boolean longClickable ) { }
public void setOnHoverListener ( OnHoverListener listener ) { }
2023-08-22 14:18:33 +02:00
public final void measure ( int widthMeasureSpec , int heightMeasureSpec ) {
2023-10-28 22:38:43 +02:00
if ( layoutRequested | | widthMeasureSpec ! = oldWidthMeasureSpec | | heightMeasureSpec ! = oldHeightMeasureSpec ) {
oldWidthMeasureSpec = widthMeasureSpec ;
oldHeightMeasureSpec = heightMeasureSpec ;
onMeasure ( widthMeasureSpec , heightMeasureSpec ) ;
layoutRequested = false ;
}
2023-08-22 14:18:33 +02:00
}
public final int getMeasuredState ( ) {
return 0 ;
}
public static int combineMeasuredStates ( int curState , int newState ) {
return curState | newState ;
}
protected int getSuggestedMinimumHeight ( ) {
2024-02-15 17:59:58 +01:00
return getMinimumHeight ( ) ;
2023-08-22 14:18:33 +02:00
}
protected int getSuggestedMinimumWidth ( ) {
2024-02-15 17:59:58 +01:00
return getMinimumWidth ( ) ;
2023-08-22 14:18:33 +02:00
}
/ * *
* Utility to reconcile a desired size and state , with constraints imposed
* by a MeasureSpec . Will take the desired size , unless a different size
* is imposed by the constraints . The returned value is a compound integer ,
* with the resolved size in the { @link # MEASURED_SIZE_MASK } bits and
* optionally the bit { @link # MEASURED_STATE_TOO_SMALL } set if the resulting
* size is smaller than the size the view wants to be .
*
* @param size How big the view wants to be
* @param measureSpec Constraints imposed by the parent
* @return Size information bit mask as defined by
* { @link # MEASURED_SIZE_MASK } and { @link # MEASURED_STATE_TOO_SMALL } .
* /
public static int resolveSizeAndState ( int size , int measureSpec , int childMeasuredState ) {
int result = size ;
int specMode = MeasureSpec . getMode ( measureSpec ) ;
int specSize = MeasureSpec . getSize ( measureSpec ) ;
switch ( specMode ) {
case MeasureSpec . UNSPECIFIED :
result = size ;
break ;
case MeasureSpec . AT_MOST :
if ( specSize < size ) {
result = specSize | MEASURED_STATE_TOO_SMALL ;
} else {
result = size ;
}
break ;
case MeasureSpec . EXACTLY :
result = specSize ;
break ;
}
return result | ( childMeasuredState & MEASURED_STATE_MASK ) ;
}
2023-08-17 10:46:24 +02:00
2023-09-01 12:55:04 +02:00
public static int resolveSize ( int size , int measureSpec ) {
return resolveSizeAndState ( size , measureSpec , 0 ) & MEASURED_SIZE_MASK ;
}
2023-08-17 10:46:24 +02:00
public final int getMeasuredWidth ( ) {
2023-08-22 14:18:33 +02:00
return this . measuredWidth & MEASURED_SIZE_MASK ;
2023-08-17 10:46:24 +02:00
}
public final int getMeasuredHeight ( ) {
2023-08-22 14:18:33 +02:00
return this . measuredHeight & MEASURED_SIZE_MASK ;
}
protected void onLayout ( boolean changed , int l , int t , int r , int b ) { }
public void layout ( int l , int t , int r , int b ) {
this . left = l ;
this . top = t ;
this . right = r ;
this . bottom = b ;
native_layout ( widget , l , t , r , b ) ;
}
2023-10-28 22:38:43 +02:00
/** Helper function to be called from GTKs LayoutManager via JNI */
private void layoutInternal ( int width , int height ) {
// if the layout is triggered from a native widget, we might not have measured yet
if ( width ! = getMeasuredWidth ( ) | | height ! = getMeasuredHeight ( ) ) {
measure ( width | MeasureSpec . EXACTLY , height | MeasureSpec . EXACTLY ) ;
}
boolean changed = oldWidth ! = width | | oldHeight ! = height ;
2023-10-30 22:37:48 +01:00
if ( changed )
onSizeChanged ( width , height , oldWidth , oldHeight ) ;
2023-10-28 22:38:43 +02:00
onLayout ( changed , 0 , 0 , width , height ) ;
oldWidth = width ;
oldHeight = height ;
}
2023-08-22 14:18:33 +02:00
public int getLeft ( ) {
return left ;
}
public int getTop ( ) {
return top ;
}
public int getRight ( ) {
return right ;
}
public int getBottom ( ) {
return bottom ;
}
public void offsetTopAndBottom ( int offset ) {
layout ( left , top + offset , right , bottom + offset ) ;
2023-08-17 10:46:24 +02:00
}
2023-09-01 12:13:24 +02:00
public void offsetLeftAndRight ( int offset ) {
layout ( left + offset , top , right + offset , bottom ) ;
}
2023-12-29 16:55:11 +01:00
public void setBackgroundDrawable ( Drawable backgroundDrawable ) {
2023-12-29 23:47:38 +01:00
this . background = backgroundDrawable ;
2023-12-29 16:55:11 +01:00
native_setBackgroundDrawable ( widget , backgroundDrawable ! = null ? backgroundDrawable . paintable : 0 ) ;
}
2023-08-17 10:46:24 +02:00
public int getOverScrollMode ( ) { return 0 ; }
public void setFitsSystemWindows ( boolean fitsSystemWindows ) { }
public void setWillNotDraw ( boolean value ) { }
public void setScrollContainer ( boolean isScrollContainer ) { }
public boolean removeCallbacks ( Runnable action ) { return false ; }
2023-08-22 14:18:33 +02:00
public void requestLayout ( ) {
2023-10-28 22:38:43 +02:00
layoutRequested = true ;
2023-11-03 18:06:30 +01:00
if ( parent ! = null & & ! parent . isLayoutRequested ( ) ) {
parent . requestLayout ( ) ;
}
2023-08-22 14:18:33 +02:00
native_requestLayout ( widget ) ;
} ;
2023-08-17 10:46:24 +02:00
public void setOverScrollMode ( int mode ) { }
public int getId ( ) { return id ; }
public boolean postDelayed ( Runnable action , long delayMillis ) {
new Handler ( Looper . getMainLooper ( ) ) . postDelayed ( action , delayMillis ) ;
2023-08-22 14:18:33 +02:00
return true ;
}
2023-08-17 10:46:24 +02:00
public boolean post ( Runnable action ) {
new Handler ( Looper . getMainLooper ( ) ) . post ( action ) ;
2023-08-22 14:18:33 +02:00
return true ;
2023-08-17 10:46:24 +02:00
}
public void setSaveFromParentEnabled ( boolean enabled ) { }
public void setTag ( int key , Object tag ) {
tags . put ( key , tag ) ;
}
public Object getTag ( int key ) {
return tags . get ( key ) ;
}
2023-09-01 12:55:04 +02:00
public void setTag ( Object tag ) {
this . tag = tag ;
}
public Object getTag ( ) {
return tag ;
}
2023-08-17 10:46:24 +02:00
public void addOnLayoutChangeListener ( OnLayoutChangeListener listener ) { }
2023-11-11 11:45:01 +01:00
public void removeOnLayoutChangeListener ( OnLayoutChangeListener listener ) { }
2023-08-17 10:46:24 +02:00
public boolean isSelected ( ) { return false ; }
public void sendAccessibilityEvent ( int eventType ) { }
2024-02-15 17:59:58 +01:00
public void setMinimumHeight ( int minHeight ) {
this . minHeight = minHeight ;
}
public void setMinimumWidth ( int minWidth ) {
this . minWidth = minWidth ;
}
2023-08-17 10:46:24 +02:00
public void setActivated ( boolean activated ) { }
2023-11-12 10:43:28 +01:00
public int getVisibility ( ) { return visibility ; }
2023-08-17 10:46:24 +02:00
public boolean isInEditMode ( ) { return false ; }
2023-08-22 13:49:09 +02:00
@Override
protected void finalize ( ) throws Throwable {
try {
native_destructor ( widget ) ;
} finally {
super . finalize ( ) ;
}
}
2023-08-22 14:41:01 +02:00
2023-12-29 23:47:38 +01:00
public final int [ ] getDrawableState ( ) {
int [ ] state = new int [ 2 ] ;
state [ 0 ] = R . attr . state_enabled ;
if ( pressed ) {
state [ 1 ] = R . attr . state_pressed ;
}
return state ;
}
2023-08-22 14:41:01 +02:00
public float getRotation ( ) { return 0 . f ; }
public void bringToFront ( ) { }
public boolean isEnabled ( ) { return true ; }
public boolean hasFocus ( ) { return false ; }
2023-11-03 18:06:30 +01:00
public boolean isLayoutRequested ( ) { return layoutRequested ; }
2023-08-22 14:41:01 +02:00
public int getBaseline ( ) { return - 1 ; }
public boolean hasFocusable ( ) { return false ; }
public boolean isFocused ( ) { return false ; }
public void clearAnimation ( ) { }
public ViewPropertyAnimator animate ( ) {
2023-10-08 17:51:41 +02:00
return new ViewPropertyAnimator ( this ) ;
2023-08-22 14:41:01 +02:00
}
public float getTranslationX ( ) { return 0 . f ; }
public float getTranslationY ( ) { return 0 . f ; }
public void setTranslationX ( float translationX ) { }
public void setTranslationY ( float translationY ) { }
2023-09-19 23:22:21 +02:00
public void setAlpha ( float alpha ) {
2023-11-12 10:43:28 +01:00
native_setVisibility ( widget , visibility , alpha ) ;
this . alpha = alpha ;
2023-09-19 23:22:21 +02:00
}
2023-08-22 18:08:16 +02:00
public boolean onGenericMotionEvent ( MotionEvent event ) { return false ; }
protected boolean awakenScrollBars ( ) { return false ; }
public Matrix getMatrix ( ) { return new Matrix ( ) ; }
2023-08-23 09:16:45 +02:00
protected static final int [ ] EMPTY_STATE_SET = new int [ 0 ] ;
/ * *
* Utility to return a default size . Uses the supplied size if the
* MeasureSpec imposed no constraints . Will get larger if allowed
* by the MeasureSpec .
*
* @param size Default size for this view
* @param measureSpec Constraints imposed by the parent
* @return The size this view should be .
* /
public static int getDefaultSize ( int size , int measureSpec ) {
int result = size ;
int specMode = MeasureSpec . getMode ( measureSpec ) ;
int specSize = MeasureSpec . getSize ( measureSpec ) ;
switch ( specMode ) {
case MeasureSpec . UNSPECIFIED :
result = size ;
break ;
case MeasureSpec . AT_MOST :
case MeasureSpec . EXACTLY :
result = specSize ;
break ;
}
return result ;
}
2023-09-01 12:13:24 +02:00
2023-09-01 12:55:04 +02:00
public static class BaseSavedState extends AbsSavedState {
}
public void clearFocus ( ) { }
public void setRotation ( float rotation ) { }
public void setScaleX ( float scaleX ) { }
public void setScaleY ( float scaleY ) { }
public static View inflate ( Context context , int resource , ViewGroup root ) {
LayoutInflater factory = LayoutInflater . from ( context ) ;
return factory . inflate ( resource , root ) ;
}
public void saveHierarchyState ( SparseArray < Parcelable > array ) { }
public void setDuplicateParentStateEnabled ( boolean enabled ) { }
public boolean performClick ( ) {
return false ;
}
public void playSoundEffect ( int soundConstant ) { }
2023-09-01 12:13:24 +02:00
public void computeScroll ( ) { }
2023-09-01 12:55:04 +02:00
public void jumpDrawablesToCurrentState ( ) { }
public void setOnFocusChangeListener ( View . OnFocusChangeListener l ) { }
public boolean hasWindowFocus ( ) { return true ; }
public void setSaveEnabled ( boolean enabled ) { }
public boolean willNotDraw ( ) { return false ; }
public void setOnCreateContextMenuListener ( View . OnCreateContextMenuListener l ) { }
public void startAnimation ( Animation animation ) { }
2023-09-08 18:34:48 +02:00
public void getDrawingRect ( Rect rect ) {
rect . left = getScrollX ( ) ;
rect . top = getScrollY ( ) ;
rect . right = getScrollX ( ) + getWidth ( ) ;
rect . bottom = getScrollY ( ) + getHeight ( ) ;
}
2023-09-14 16:05:07 +02:00
public Display getDisplay ( ) {
return new Display ( ) ;
}
2023-09-12 23:18:47 +02:00
private int importantForAccessibility ;
public void setImportantForAccessibility ( int importantForAccessibility ) {
this . importantForAccessibility = importantForAccessibility ;
}
public int getImportantForAccessibility ( ) {
return importantForAccessibility ;
}
public boolean getFitsSystemWindows ( ) { return true ; }
public void setOnApplyWindowInsetsListener ( View . OnApplyWindowInsetsListener l ) { }
public final boolean isFocusable ( ) { return true ; }
public boolean isClickable ( ) { return true ; }
public boolean isLongClickable ( ) { return true ; }
public int getLayoutDirection ( ) { return LAYOUT_DIRECTION_LTR ; }
2023-12-29 23:47:38 +01:00
public void setBackground ( Drawable background ) {
setBackgroundDrawable ( background ) ;
}
2023-09-12 23:18:47 +02:00
private float elevation ;
public void setElevation ( float elevation ) {
this . elevation = elevation ;
}
public float getElevation ( ) {
return elevation ;
}
public boolean isLaidOut ( ) { return true ; }
public void postOnAnimation ( Runnable action ) {
2024-02-25 17:57:02 +01:00
postDelayed ( action , 1000 / 60 ) ;
2023-09-12 23:18:47 +02:00
}
2024-02-17 15:15:05 +01:00
public void postOnAnimationDelayed ( Runnable action , long delayMillis ) {
2024-02-25 17:57:02 +01:00
if ( delayMillis < 1000 / 60 )
delayMillis = 1000 / 60 ;
2024-02-17 15:15:05 +01:00
postDelayed ( action , delayMillis ) ;
}
2023-09-12 23:18:47 +02:00
public void setHorizontalScrollBarEnabled ( boolean enabled ) { }
public void postInvalidateOnAnimation ( ) {
postInvalidate ( ) ;
}
public void setPaddingRelative ( int start , int top , int end , int bottom ) { }
2023-10-08 17:51:41 +02:00
public boolean isAttachedToWindow ( ) { return attachedToWindow ; }
2023-09-12 23:18:47 +02:00
public void requestApplyInsets ( ) { }
public View getRootView ( ) {
View view = this ;
while ( view . parent ! = null ) {
view = view . parent ;
}
return view ;
}
public boolean isShown ( ) { return true ; }
public int getWindowVisibility ( ) { return VISIBLE ; }
2023-11-12 10:43:28 +01:00
public float getAlpha ( ) { return alpha ; }
2023-09-12 23:18:47 +02:00
public View findFocus ( ) { return this ; }
2024-02-15 17:59:58 +01:00
public int getMinimumHeight ( ) { return minHeight ; }
public int getMinimumWidth ( ) { return minWidth ; }
2023-09-12 23:18:47 +02:00
2024-02-26 18:16:30 +01:00
public boolean isNestedScrollingEnabled ( ) { return false ; }
2023-09-12 23:18:47 +02:00
public void setClipToOutline ( boolean clipToOutline ) { }
public boolean hasTransientState ( ) { return false ; }
public final void cancelPendingInputEvents ( ) { }
public ViewOutlineProvider getOutlineProvider ( ) { return new ViewOutlineProvider ( ) ; }
public void setOutlineProvider ( ViewOutlineProvider provider ) { }
public void setStateListAnimator ( StateListAnimator stateListAnimator ) { }
private static final AtomicInteger nextGeneratedId = new AtomicInteger ( 1 ) ;
/ * *
* Generate a value suitable for use in { @link # setId ( int ) } .
* This value will not collide with ID values generated at build time by aapt for R . id .
*
* @return a generated ID value
* /
public static int generateViewId ( ) {
for ( ; ; ) {
final int result = nextGeneratedId . get ( ) ;
// aapt-generated IDs have the high byte nonzero; clamp to the range under that.
int newValue = result + 1 ;
if ( newValue > 0x00FFFFFF ) newValue = 1 ; // Roll over to 1, not 0.
if ( nextGeneratedId . compareAndSet ( result , newValue ) ) {
return result ;
}
}
}
public boolean isLayoutDirectionResolved ( ) { return true ; }
public boolean isPaddingRelative ( ) { return false ; }
public void setForeground ( Drawable foreground ) { }
2023-09-19 23:22:21 +02:00
public boolean canScrollVertically ( int value ) { return true ; }
public boolean isInTouchMode ( ) { return false ; }
public void stopNestedScroll ( ) { }
public long getDrawingTime ( ) {
return System . currentTimeMillis ( ) ;
}
2023-09-21 22:49:36 +02:00
public void setKeepScreenOn ( boolean screenOn ) { }
2023-10-08 17:51:41 +02:00
protected void onAttachedToWindow ( ) {
attachedToWindow = true ;
}
public void setLayerType ( int layerType , Paint paint ) { }
2023-10-30 22:35:31 +01:00
public float getZ ( ) { return 0 . f ; }
2023-10-30 22:37:48 +01:00
protected void onSizeChanged ( int w , int h , int oldw , int oldh ) { }
2023-11-08 21:40:39 +01:00
public void setBackgroundTintList ( ColorStateList tint ) { }
protected int computeHorizontalScrollRange ( ) {
return getWidth ( ) ;
}
protected int computeHorizontalScrollExtent ( ) {
return getWidth ( ) ;
}
2023-11-11 11:45:01 +01:00
protected int computeVerticalScrollRange ( ) {
return getHeight ( ) ;
}
protected int computeVerticalScrollExtent ( ) {
return getHeight ( ) ;
}
2023-12-29 11:09:37 +01:00
public void setAccessibilityLiveRegion ( int mode ) { }
2024-02-04 08:08:49 +01:00
public void invalidateOutline ( ) { }
2024-02-09 16:41:37 +01:00
public int getMeasuredWidthAndState ( ) {
return measuredWidth ;
}
2024-02-17 15:15:05 +01:00
public void forceLayout ( ) {
requestLayout ( ) ;
}
public void removeOnAttachStateChangeListener ( OnAttachStateChangeListener listener ) { }
2024-02-24 18:50:03 +01:00
public boolean onInterceptTouchEvent ( MotionEvent event ) { return false ; }
public boolean dispatchTouchEvent ( MotionEvent event ) { return false ; }
public boolean canScrollHorizontally ( int direction ) { return false ; }
protected native boolean native_getGlobalVisibleRect ( long widget , Rect visibleRect ) ;
public boolean getGlobalVisibleRect ( Rect visibleRect ) {
return native_getGlobalVisibleRect ( widget , visibleRect ) ;
}
2024-03-11 18:23:38 +01:00
public boolean onCheckIsTextEditor ( ) { return false ; }
2022-10-02 23:06:56 +02:00
}