mirror of
https://gitlab.com/android_translation_layer/android_translation_layer.git
synced 2025-04-28 12:17:57 +03:00
2199 lines
62 KiB
Java
2199 lines
62 KiB
Java
package android.view;
|
|
|
|
import android.R;
|
|
import android.animation.StateListAnimator;
|
|
import android.content.Context;
|
|
import android.content.res.ColorStateList;
|
|
import android.content.res.Resources;
|
|
import android.content.res.TypedArray;
|
|
import android.graphics.Canvas;
|
|
import android.graphics.GskCanvas;
|
|
import android.graphics.Matrix;
|
|
import android.graphics.Paint;
|
|
import android.graphics.Point;
|
|
import android.graphics.PorterDuff;
|
|
import android.graphics.Rect;
|
|
import android.graphics.drawable.ColorDrawable;
|
|
import android.graphics.drawable.Drawable;
|
|
import android.os.Binder;
|
|
import android.os.Bundle;
|
|
import android.os.Handler;
|
|
import android.os.IBinder;
|
|
import android.os.Looper;
|
|
import android.os.Parcelable;
|
|
import android.os.SystemClock;
|
|
import android.os.Vibrator;
|
|
import android.util.AttributeSet;
|
|
import android.util.FloatProperty;
|
|
import android.util.LayoutDirection;
|
|
import android.util.Property;
|
|
import android.util.Slog;
|
|
import android.util.SparseArray;
|
|
import android.view.animation.Animation;
|
|
|
|
import java.lang.CharSequence;
|
|
import java.util.ArrayList;
|
|
import java.util.HashMap;
|
|
import java.util.Map;
|
|
import java.util.Objects;
|
|
import java.util.concurrent.atomic.AtomicInteger;
|
|
|
|
class WindowId {}
|
|
|
|
public class View implements Drawable.Callback {
|
|
|
|
// --- constants from android source
|
|
|
|
/**
|
|
* The logging tag used by this class with android.util.Log.
|
|
*/
|
|
protected static final String TAG = "View";
|
|
|
|
/**
|
|
* When set to true, apps will draw debugging information about their layouts.
|
|
*
|
|
* @hide
|
|
*/
|
|
public static final String DEBUG_LAYOUT_PROPERTY = "debug.layout";
|
|
|
|
/**
|
|
* Used to mark a View that has no ID.
|
|
*/
|
|
public static final int NO_ID = -1;
|
|
|
|
/**
|
|
* Signals that compatibility booleans have been initialized according to
|
|
* target SDK versions.
|
|
*/
|
|
private static boolean sCompatibilityDone = false;
|
|
|
|
/**
|
|
* Use the old (broken) way of building MeasureSpecs.
|
|
*/
|
|
private static boolean sUseBrokenMakeMeasureSpec = false;
|
|
|
|
/**
|
|
* Ignore any optimizations using the measure cache.
|
|
*/
|
|
private static boolean sIgnoreMeasureCache = false;
|
|
|
|
/**
|
|
* This view does not want keystrokes. Use with TAKES_FOCUS_MASK when
|
|
* calling setFlags.
|
|
*/
|
|
private static final int NOT_FOCUSABLE = 0x00000000;
|
|
|
|
/**
|
|
* This view wants keystrokes. Use with TAKES_FOCUS_MASK when calling
|
|
* setFlags.
|
|
*/
|
|
private static final int FOCUSABLE = 0x00000001;
|
|
|
|
/**
|
|
* Mask for use with setFlags indicating bits used for focus.
|
|
*/
|
|
private static final int FOCUSABLE_MASK = 0x00000001;
|
|
|
|
/**
|
|
* This view will adjust its padding to fit sytem windows (e.g. status bar)
|
|
*/
|
|
private static final int FITS_SYSTEM_WINDOWS = 0x00000002;
|
|
|
|
/**
|
|
* This view is visible.
|
|
* Use with {@link #setVisibility} and <a href="#attr_android:visibility">{@code
|
|
* android:visibility}.
|
|
*/
|
|
public static final int VISIBLE = 0x00000000;
|
|
|
|
/**
|
|
* 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}.
|
|
*/
|
|
public static final int INVISIBLE = 0x00000004;
|
|
|
|
/**
|
|
* 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}.
|
|
*/
|
|
public static final int GONE = 0x00000008;
|
|
|
|
/**
|
|
* Mask for use with setFlags indicating bits used for visibility.
|
|
* {@hide}
|
|
*/
|
|
static final int VISIBILITY_MASK = 0x0000000C;
|
|
|
|
private static final int[] VISIBILITY_FLAGS = {VISIBLE, INVISIBLE, GONE};
|
|
|
|
/**
|
|
* This view is enabled. Interpretation varies by subclass.
|
|
* Use with ENABLED_MASK when calling setFlags.
|
|
* {@hide}
|
|
*/
|
|
static final int ENABLED = 0x00000000;
|
|
|
|
/**
|
|
* This view is disabled. Interpretation varies by subclass.
|
|
* Use with ENABLED_MASK when calling setFlags.
|
|
* {@hide}
|
|
*/
|
|
static final int DISABLED = 0x00000020;
|
|
|
|
/**
|
|
* Mask for use with setFlags indicating bits used for indicating whether
|
|
* this view is enabled
|
|
* {@hide}
|
|
*/
|
|
static final int ENABLED_MASK = 0x00000020;
|
|
|
|
/**
|
|
* 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}
|
|
*/
|
|
static final int WILL_NOT_DRAW = 0x00000080;
|
|
|
|
/**
|
|
* Mask for use with setFlags indicating bits used for indicating whether
|
|
* this view is will draw
|
|
* {@hide}
|
|
*/
|
|
static final int DRAW_MASK = 0x00000080;
|
|
|
|
/**
|
|
* <p>This view doesn't show scrollbars.</p>
|
|
* {@hide}
|
|
*/
|
|
static final int SCROLLBARS_NONE = 0x00000000;
|
|
|
|
/**
|
|
* <p>This view shows horizontal scrollbars.</p>
|
|
* {@hide}
|
|
*/
|
|
static final int SCROLLBARS_HORIZONTAL = 0x00000100;
|
|
|
|
/**
|
|
* <p>This view shows vertical scrollbars.</p>
|
|
* {@hide}
|
|
*/
|
|
static final int SCROLLBARS_VERTICAL = 0x00000200;
|
|
|
|
/**
|
|
* <p>Mask for use with setFlags indicating bits used for indicating which
|
|
* scrollbars are enabled.</p>
|
|
* {@hide}
|
|
*/
|
|
static final int SCROLLBARS_MASK = 0x00000300;
|
|
|
|
/**
|
|
* 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}
|
|
*/
|
|
static final int FILTER_TOUCHES_WHEN_OBSCURED = 0x00000400;
|
|
|
|
/**
|
|
* 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.
|
|
*/
|
|
static final int OPTIONAL_FITS_SYSTEM_WINDOWS = 0x00000800;
|
|
|
|
/**
|
|
* <p>This view doesn't show fading edges.</p>
|
|
* {@hide}
|
|
*/
|
|
static final int FADING_EDGE_NONE = 0x00000000;
|
|
|
|
/**
|
|
* <p>This view shows horizontal fading edges.</p>
|
|
* {@hide}
|
|
*/
|
|
static final int FADING_EDGE_HORIZONTAL = 0x00001000;
|
|
|
|
/**
|
|
* <p>This view shows vertical fading edges.</p>
|
|
* {@hide}
|
|
*/
|
|
static final int FADING_EDGE_VERTICAL = 0x00002000;
|
|
|
|
/**
|
|
* <p>Mask for use with setFlags indicating bits used for indicating which
|
|
* fading edges are enabled.</p>
|
|
* {@hide}
|
|
*/
|
|
static final int FADING_EDGE_MASK = 0x00003000;
|
|
|
|
/**
|
|
* <p>Indicates this view can be clicked. When clickable, a View reacts
|
|
* to clicks by notifying the OnClickListener.<p>
|
|
* {@hide}
|
|
*/
|
|
static final int CLICKABLE = 0x00004000;
|
|
|
|
/**
|
|
* <p>Indicates this view is caching its drawing into a bitmap.</p>
|
|
* {@hide}
|
|
*/
|
|
static final int DRAWING_CACHE_ENABLED = 0x00008000;
|
|
|
|
/**
|
|
* <p>Indicates that no icicle should be saved for this view.<p>
|
|
* {@hide}
|
|
*/
|
|
static final int SAVE_DISABLED = 0x000010000;
|
|
|
|
/**
|
|
* <p>Mask for use with setFlags indicating bits used for the saveEnabled
|
|
* property.</p>
|
|
* {@hide}
|
|
*/
|
|
static final int SAVE_DISABLED_MASK = 0x000010000;
|
|
|
|
/**
|
|
* <p>Indicates that no drawing cache should ever be created for this view.<p>
|
|
* {@hide}
|
|
*/
|
|
static final int WILL_NOT_CACHE_DRAWING = 0x000020000;
|
|
|
|
/**
|
|
* <p>Indicates this view can take / keep focus when int touch mode.</p>
|
|
* {@hide}
|
|
*/
|
|
static final int FOCUSABLE_IN_TOUCH_MODE = 0x00040000;
|
|
|
|
/**
|
|
* <p>Enables low quality mode for the drawing cache.</p>
|
|
*/
|
|
public static final int DRAWING_CACHE_QUALITY_LOW = 0x00080000;
|
|
|
|
/**
|
|
* <p>Enables high quality mode for the drawing cache.</p>
|
|
*/
|
|
public static final int DRAWING_CACHE_QUALITY_HIGH = 0x00100000;
|
|
|
|
/**
|
|
* <p>Enables automatic quality mode for the drawing cache.</p>
|
|
*/
|
|
public static final int DRAWING_CACHE_QUALITY_AUTO = 0x00000000;
|
|
|
|
private static final int[] DRAWING_CACHE_QUALITY_FLAGS = {
|
|
DRAWING_CACHE_QUALITY_AUTO, DRAWING_CACHE_QUALITY_LOW, DRAWING_CACHE_QUALITY_HIGH};
|
|
|
|
/**
|
|
* <p>Mask for use with setFlags indicating bits used for the cache
|
|
* quality property.</p>
|
|
* {@hide}
|
|
*/
|
|
static final int DRAWING_CACHE_QUALITY_MASK = 0x00180000;
|
|
|
|
/**
|
|
* <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}
|
|
*/
|
|
static final int LONG_CLICKABLE = 0x00200000;
|
|
|
|
/**
|
|
* <p>Indicates that this view gets its drawable states from its direct parent
|
|
* and ignores its original internal states.</p>
|
|
*
|
|
* @hide
|
|
*/
|
|
static final int DUPLICATE_PARENT_STATE = 0x00400000;
|
|
|
|
/**
|
|
* 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.
|
|
*/
|
|
public static final int SCROLLBARS_INSIDE_OVERLAY = 0;
|
|
|
|
/**
|
|
* 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.
|
|
*/
|
|
public static final int SCROLLBARS_INSIDE_INSET = 0x01000000;
|
|
|
|
/**
|
|
* The scrollbar style to display the scrollbars at the edge of the view,
|
|
* without increasing the padding. The scrollbars will be overlaid with
|
|
* translucency.
|
|
*/
|
|
public static final int SCROLLBARS_OUTSIDE_OVERLAY = 0x02000000;
|
|
|
|
/**
|
|
* 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.
|
|
*/
|
|
public static final int SCROLLBARS_OUTSIDE_INSET = 0x03000000;
|
|
|
|
/**
|
|
* Mask to check if the scrollbar style is overlay or inset.
|
|
* {@hide}
|
|
*/
|
|
static final int SCROLLBARS_INSET_MASK = 0x01000000;
|
|
|
|
/**
|
|
* Mask to check if the scrollbar style is inside or outside.
|
|
* {@hide}
|
|
*/
|
|
static final int SCROLLBARS_OUTSIDE_MASK = 0x02000000;
|
|
|
|
/**
|
|
* Mask for scrollbar style.
|
|
* {@hide}
|
|
*/
|
|
static final int SCROLLBARS_STYLE_MASK = 0x03000000;
|
|
|
|
/**
|
|
* 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}.
|
|
*/
|
|
public static final int KEEP_SCREEN_ON = 0x04000000;
|
|
|
|
/**
|
|
* View flag indicating whether this view should have sound effects enabled
|
|
* for events such as clicking and touching.
|
|
*/
|
|
public static final int SOUND_EFFECTS_ENABLED = 0x08000000;
|
|
|
|
/**
|
|
* View flag indicating whether this view should have haptic feedback
|
|
* enabled for events such as long presses.
|
|
*/
|
|
public static final int HAPTIC_FEEDBACK_ENABLED = 0x10000000;
|
|
|
|
/**
|
|
* <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}
|
|
*/
|
|
static final int PARENT_SAVE_DISABLED = 0x20000000;
|
|
|
|
/**
|
|
* <p>Mask for use with setFlags indicating bits used for PARENT_SAVE_DISABLED.</p>
|
|
* {@hide}
|
|
*/
|
|
static final int PARENT_SAVE_DISABLED_MASK = 0x20000000;
|
|
|
|
/**
|
|
* View flag indicating whether {@link #addFocusables(ArrayList, int, int)}
|
|
* should add all focusable Views regardless if they are focusable in touch mode.
|
|
*/
|
|
public static final int FOCUSABLES_ALL = 0x00000000;
|
|
|
|
/**
|
|
* View flag indicating whether {@link #addFocusables(ArrayList, int, int)}
|
|
* should add only Views focusable in touch mode.
|
|
*/
|
|
public static final int FOCUSABLES_TOUCH_MODE = 0x00000001;
|
|
|
|
/**
|
|
* Use with {@link #focusSearch(int)}. Move focus to the previous selectable
|
|
* item.
|
|
*/
|
|
public static final int FOCUS_BACKWARD = 0x00000001;
|
|
|
|
/**
|
|
* Use with {@link #focusSearch(int)}. Move focus to the next selectable
|
|
* item.
|
|
*/
|
|
public static final int FOCUS_FORWARD = 0x00000002;
|
|
|
|
/**
|
|
* Use with {@link #focusSearch(int)}. Move focus to the left.
|
|
*/
|
|
public static final int FOCUS_LEFT = 0x00000011;
|
|
|
|
/**
|
|
* Use with {@link #focusSearch(int)}. Move focus up.
|
|
*/
|
|
public static final int FOCUS_UP = 0x00000021;
|
|
|
|
/**
|
|
* Use with {@link #focusSearch(int)}. Move focus to the right.
|
|
*/
|
|
public static final int FOCUS_RIGHT = 0x00000042;
|
|
|
|
/**
|
|
* Use with {@link #focusSearch(int)}. Move focus down.
|
|
*/
|
|
public static final int FOCUS_DOWN = 0x00000082;
|
|
|
|
/**
|
|
* Bits of {@link #getMeasuredWidthAndState()} and
|
|
* {@link #getMeasuredWidthAndState()} that provide the actual measured size.
|
|
*/
|
|
public static final int MEASURED_SIZE_MASK = 0x00ffffff;
|
|
|
|
/**
|
|
* Bits of {@link #getMeasuredWidthAndState()} and
|
|
* {@link #getMeasuredWidthAndState()} that provide the additional state bits.
|
|
*/
|
|
public static final int MEASURED_STATE_MASK = 0xff000000;
|
|
|
|
/**
|
|
* 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)}.
|
|
*/
|
|
public static final int MEASURED_HEIGHT_STATE_SHIFT = 16;
|
|
|
|
/**
|
|
* Bit of {@link #getMeasuredWidthAndState()} and
|
|
* {@link #getMeasuredWidthAndState()} that indicates the measured size
|
|
* is smaller that the space the view would like to have.
|
|
*/
|
|
public static final int MEASURED_STATE_TOO_SMALL = 0x01000000;
|
|
|
|
// --- and some flags
|
|
|
|
/**
|
|
* 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;
|
|
|
|
/**
|
|
* 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;
|
|
|
|
/**
|
|
* Horizontal layout direction of this view is from Left to Right.
|
|
* Use with {@link #setLayoutDirection}.
|
|
*/
|
|
public static final int LAYOUT_DIRECTION_LTR = LayoutDirection.LTR;
|
|
|
|
/**
|
|
* Horizontal layout direction of this view is from Right to Left.
|
|
* Use with {@link #setLayoutDirection}.
|
|
*/
|
|
public static final int LAYOUT_DIRECTION_RTL = LayoutDirection.RTL;
|
|
|
|
/**
|
|
* Horizontal layout direction of this view is inherited from its parent.
|
|
* Use with {@link #setLayoutDirection}.
|
|
*/
|
|
public static final int LAYOUT_DIRECTION_INHERIT = LayoutDirection.INHERIT;
|
|
|
|
/**
|
|
* Horizontal layout direction of this view is from deduced from the default language
|
|
* script for the locale. Use with {@link #setLayoutDirection}.
|
|
*/
|
|
public static final int LAYOUT_DIRECTION_LOCALE = LayoutDirection.LOCALE;
|
|
|
|
/**
|
|
* Bit shift to get the horizontal layout direction. (bits after DRAG_HOVERED)
|
|
* @hide
|
|
*/
|
|
static final int PFLAG2_LAYOUT_DIRECTION_MASK_SHIFT = 2;
|
|
|
|
/**
|
|
* Mask for use with private flags indicating bits used for horizontal layout direction.
|
|
* @hide
|
|
*/
|
|
static final int PFLAG2_LAYOUT_DIRECTION_MASK = 0x00000003 << PFLAG2_LAYOUT_DIRECTION_MASK_SHIFT;
|
|
|
|
/**
|
|
* Indicates whether the view horizontal layout direction has been resolved and drawn to the
|
|
* right-to-left direction.
|
|
* @hide
|
|
*/
|
|
static final int PFLAG2_LAYOUT_DIRECTION_RESOLVED_RTL = 4 << PFLAG2_LAYOUT_DIRECTION_MASK_SHIFT;
|
|
|
|
/**
|
|
* Indicates whether the view horizontal layout direction has been resolved.
|
|
* @hide
|
|
*/
|
|
static final int PFLAG2_LAYOUT_DIRECTION_RESOLVED = 8 << PFLAG2_LAYOUT_DIRECTION_MASK_SHIFT;
|
|
|
|
/**
|
|
* Mask for use with private flags indicating bits used for resolved horizontal layout direction.
|
|
* @hide
|
|
*/
|
|
static final int PFLAG2_LAYOUT_DIRECTION_RESOLVED_MASK = 0x0000000C << PFLAG2_LAYOUT_DIRECTION_MASK_SHIFT;
|
|
|
|
// --- 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
|
|
|
|
public static final Property<View, Float> SCALE_X = new FloatProperty<View>("scaleX") {
|
|
@Override
|
|
public void setValue(View object, float value) {
|
|
object.setScaleX(value);
|
|
}
|
|
@Override
|
|
public Float get(View object) {
|
|
return object.getScaleX();
|
|
}
|
|
};
|
|
|
|
public static final Property<View, Float> SCALE_Y = new FloatProperty<View>("scaleY") {
|
|
@Override
|
|
public void setValue(View object, float value) {
|
|
object.setScaleY(value);
|
|
}
|
|
@Override
|
|
public Float get(View object) {
|
|
return object.getScaleY();
|
|
}
|
|
};
|
|
|
|
// --- end of constants from android source
|
|
|
|
// --- interfaces from android source
|
|
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);
|
|
}
|
|
|
|
public interface OnAttachStateChangeListener {
|
|
public void onViewAttachedToWindow(View v);
|
|
public void onViewDetachedFromWindow(View v);
|
|
}
|
|
|
|
public interface OnGenericMotionListener {
|
|
// TODO
|
|
}
|
|
|
|
public interface OnSystemUiVisibilityChangeListener {
|
|
// TODO
|
|
}
|
|
|
|
public static interface OnKeyListener {
|
|
boolean onKey(View v, int keyCode, KeyEvent event);
|
|
}
|
|
|
|
public interface OnLongClickListener {
|
|
public boolean onLongClick(View v);
|
|
}
|
|
|
|
public interface OnHoverListener {
|
|
// TODO
|
|
}
|
|
|
|
public interface OnApplyWindowInsetsListener {
|
|
// TODO
|
|
}
|
|
|
|
public interface OnLayoutChangeListener {
|
|
// TODO
|
|
}
|
|
|
|
public interface OnUnhandledKeyEventListener {
|
|
// TODO
|
|
}
|
|
|
|
public interface OnFocusChangeListener {
|
|
// TODO
|
|
}
|
|
|
|
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);
|
|
}
|
|
|
|
public interface OnDragListener {}
|
|
// --- 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 <size, mode> tuple into the int.
|
|
*/
|
|
public static class MeasureSpec {
|
|
private static final int MODE_SHIFT = 30;
|
|
private static final int MODE_MASK = 0x3 << MODE_SHIFT;
|
|
|
|
/**
|
|
* 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.
|
|
*/
|
|
public static final int EXACTLY = 1 << MODE_SHIFT;
|
|
|
|
/**
|
|
* Measure specification mode: The child can be as large as it wants up
|
|
* to the specified size.
|
|
*/
|
|
public static final int AT_MOST = 2 << MODE_SHIFT;
|
|
|
|
/**
|
|
* 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) {
|
|
return size + mode;
|
|
} else {
|
|
return (size & ~MODE_MASK) | (mode & MODE_MASK);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 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)
|
|
sb.append("UNSPECIFIED ");
|
|
else if (mode == EXACTLY)
|
|
sb.append("EXACTLY ");
|
|
else if (mode == AT_MOST)
|
|
sb.append("AT_MOST ");
|
|
else
|
|
sb.append(mode).append(" ");
|
|
|
|
sb.append(size);
|
|
return sb.toString();
|
|
}
|
|
}
|
|
|
|
// --- end of subclasses
|
|
|
|
public int id = NO_ID;
|
|
private int system_ui_visibility = 0;
|
|
public ViewParent parent;
|
|
public AttributeSet attrs;
|
|
protected ViewGroup.LayoutParams layout_params;
|
|
private Context context;
|
|
private Map<Integer,Object> tags = new HashMap<>();
|
|
private Object tag;
|
|
int gravity = -1; // fallback gravity for layout childs
|
|
|
|
int measuredWidth = 0;
|
|
int measuredHeight = 0;
|
|
|
|
private int left;
|
|
private int top;
|
|
private int right;
|
|
private int bottom;
|
|
|
|
private int scrollX = 0;
|
|
private int scrollY = 0;
|
|
|
|
private boolean attachedToWindow = false;
|
|
|
|
public long widget; // pointer
|
|
|
|
private int oldWidthMeasureSpec = -1;
|
|
private int oldHeightMeasureSpec = -1;
|
|
private boolean layoutRequested = true;
|
|
private int oldWidth;
|
|
private int oldHeight;
|
|
protected boolean haveCustomMeasure = true;
|
|
|
|
private int visibility = View.VISIBLE;
|
|
private float alpha = 1.0f;
|
|
private boolean pressed = false;
|
|
private Drawable background;
|
|
|
|
private int minWidth = 0;
|
|
private int minHeight = 0;
|
|
|
|
protected int paddingLeft = 0;
|
|
protected int paddingTop = 0;
|
|
protected int paddingRight = 0;
|
|
protected int paddingBottom = 0;
|
|
|
|
public static final Property<View, Float> TRANSLATION_X = new Property<View, Float>(Float.class, "translationX") {
|
|
@Override
|
|
public Float get(View object) {
|
|
return 0.f;
|
|
}
|
|
};
|
|
|
|
public static final Property<View, Float> TRANSLATION_Y = new Property<View, Float>(Float.class, "translationY") {
|
|
@Override
|
|
public Float get(View object) {
|
|
return 0.f;
|
|
}
|
|
};
|
|
|
|
public static final Property<View, Float> TRANSLATION_Z = new Property<View, Float>(Float.class, "translationZ") {
|
|
@Override
|
|
public Float get(View object) {
|
|
return 0.f;
|
|
}
|
|
};
|
|
|
|
public static final Property<View, Float> ALPHA = new Property<View, Float>(Float.class, "alpha") {
|
|
@Override
|
|
public Float get(View object) {
|
|
return object.getAlpha();
|
|
}
|
|
@Override
|
|
public void set(View object, Float value) {
|
|
object.setAlpha(value);
|
|
}
|
|
};
|
|
|
|
public View(Context context, AttributeSet attrs) {
|
|
this(context, attrs, 0);
|
|
}
|
|
|
|
public View(Context context, AttributeSet attrs, int defStyle) {
|
|
this(context, attrs, defStyle, 0);
|
|
}
|
|
|
|
public View(Context context, AttributeSet attrs, int defStyle, int defStyleRes) {
|
|
this.context = context;
|
|
|
|
widget = native_constructor(context, attrs);
|
|
|
|
TypedArray a = context.obtainStyledAttributes(attrs, com.android.internal.R.styleable.View, defStyle, defStyleRes);
|
|
this.id = a.getResourceId(com.android.internal.R.styleable.View_id, View.NO_ID);
|
|
if (a.hasValue(com.android.internal.R.styleable.View_background)) {
|
|
try {
|
|
Drawable background = a.getDrawable(com.android.internal.R.styleable.View_background);
|
|
|
|
if(background != null) {
|
|
if(background instanceof ColorDrawable) {
|
|
setBackgroundColor(((ColorDrawable)background).getColor());
|
|
} else {
|
|
setBackgroundDrawable(background);
|
|
}
|
|
}
|
|
} catch (Exception e) { e.printStackTrace(); }
|
|
}
|
|
if (a.hasValue(com.android.internal.R.styleable.View_visibility)) {
|
|
setVisibility(VISIBILITY_FLAGS[a.getInt(com.android.internal.R.styleable.View_visibility, 0)]);
|
|
}
|
|
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);
|
|
}
|
|
|
|
int padding = a.getDimensionPixelSize(com.android.internal.R.styleable.View_padding, -1);
|
|
|
|
int paddingVertical = a.getDimensionPixelSize(com.android.internal.R.styleable.View_paddingVertical, -1);
|
|
int paddingHorizontal = a.getDimensionPixelSize(com.android.internal.R.styleable.View_paddingHorizontal, -1);
|
|
|
|
int paddingStart = a.getDimensionPixelSize(com.android.internal.R.styleable.View_paddingStart, -1);
|
|
int paddingEnd = a.getDimensionPixelSize(com.android.internal.R.styleable.View_paddingEnd, -1);
|
|
|
|
if(padding >= 0) {
|
|
paddingLeft = padding;
|
|
paddingTop = padding;
|
|
paddingRight = padding;
|
|
paddingBottom = padding;
|
|
} else {
|
|
if(paddingVertical >= 0) {
|
|
paddingTop = paddingVertical;
|
|
paddingBottom = paddingVertical;
|
|
} else {
|
|
paddingTop = a.getDimensionPixelSize(com.android.internal.R.styleable.View_paddingTop, 0);
|
|
paddingBottom = a.getDimensionPixelSize(com.android.internal.R.styleable.View_paddingBottom, 0);
|
|
}
|
|
|
|
if(paddingHorizontal >= 0) {
|
|
paddingLeft = paddingHorizontal;
|
|
paddingRight = paddingHorizontal;
|
|
} else {
|
|
paddingLeft = a.getDimensionPixelSize(com.android.internal.R.styleable.View_paddingLeft, 0);
|
|
paddingRight = a.getDimensionPixelSize(com.android.internal.R.styleable.View_paddingRight, 0);
|
|
|
|
if(paddingStart >= 0) {
|
|
paddingLeft = paddingStart;
|
|
}
|
|
|
|
if(paddingEnd >= 0) {
|
|
paddingRight = paddingEnd;
|
|
}
|
|
}
|
|
}
|
|
|
|
native_setPadding(widget, paddingLeft, paddingTop, paddingRight, paddingBottom);
|
|
|
|
if (a.hasValue(com.android.internal.R.styleable.View_tag)) {
|
|
tag = a.getText(com.android.internal.R.styleable.View_tag);
|
|
}
|
|
if(a.hasValue(com.android.internal.R.styleable.View_textAlignment)) {
|
|
int textAlignment = a.getInt(com.android.internal.R.styleable.View_textAlignment, 0);
|
|
setTextAlignment(textAlignment);
|
|
}
|
|
|
|
a.recycle();
|
|
onCreateDrawableState(0);
|
|
}
|
|
|
|
protected int[] onCreateDrawableState(int extraSpace) {
|
|
return new int[0];
|
|
}
|
|
|
|
protected static int[] mergeDrawableStates(int[] curState, int[] newState) {
|
|
return new int[0];
|
|
}
|
|
|
|
public View findViewById(int id) {
|
|
if (this.id == id)
|
|
return this;
|
|
else
|
|
return null;
|
|
}
|
|
|
|
public void onDraw(Canvas canvas) {
|
|
if (canvas instanceof GskCanvas)
|
|
native_drawContent(widget, ((GskCanvas)canvas).snapshot);
|
|
}
|
|
|
|
protected void dispatchDraw(Canvas canvas) {
|
|
if (canvas instanceof GskCanvas)
|
|
native_drawChildren(widget, ((GskCanvas)canvas).snapshot);
|
|
}
|
|
public void draw(Canvas canvas) {
|
|
if (canvas instanceof GskCanvas)
|
|
native_drawBackground(widget, ((GskCanvas)canvas).snapshot);
|
|
onDraw(canvas);
|
|
// HACK: catch non critical exceptions happening in some composeUI apps
|
|
try {
|
|
dispatchDraw(canvas);
|
|
} catch (IllegalArgumentException e) {
|
|
e.printStackTrace();
|
|
}
|
|
}
|
|
|
|
public View(Context context) {
|
|
this(context, null);
|
|
}
|
|
|
|
public final ViewParent getParent() {
|
|
return parent;
|
|
}
|
|
|
|
public void setLayoutParams(ViewGroup.LayoutParams params) {
|
|
if (params == null) {
|
|
throw new NullPointerException("Layout parameters cannot be null");
|
|
}
|
|
|
|
int gravity = params.gravity;
|
|
if (gravity == -1 && parent instanceof View)
|
|
gravity = ((View)parent).gravity;
|
|
|
|
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);
|
|
|
|
layout_params = params;
|
|
}
|
|
|
|
public ViewGroup.LayoutParams getLayoutParams() {
|
|
return layout_params;
|
|
}
|
|
|
|
protected final void setMeasuredDimension(int measuredWidth, int measuredHeight) {
|
|
this.measuredWidth = measuredWidth;
|
|
this.measuredHeight = measuredHeight;
|
|
}
|
|
|
|
public Resources getResources() {
|
|
return Context.this_application.getResources();
|
|
}
|
|
|
|
public void setGravity(int gravity) {
|
|
this.gravity = gravity;
|
|
}
|
|
|
|
private OnTouchListener on_touch_listener = null;
|
|
|
|
public boolean onTouchEventInternal(MotionEvent event) {
|
|
boolean handled = false;
|
|
if (on_touch_listener != null)
|
|
handled = on_touch_listener.onTouch(this, event);
|
|
|
|
if (!handled)
|
|
handled = onTouchEvent(event);
|
|
|
|
return handled;
|
|
}
|
|
|
|
public boolean onTouchEvent(MotionEvent event) {
|
|
return false;
|
|
}
|
|
|
|
public void setOnTouchListener(OnTouchListener l) {
|
|
nativeSetOnTouchListener(widget);
|
|
on_touch_listener = l;
|
|
}
|
|
protected native void nativeSetOnTouchListener(long widget);
|
|
private OnClickListener on_click_listener = null;
|
|
public void setOnClickListener(OnClickListener l) {
|
|
nativeSetOnClickListener(widget);
|
|
on_click_listener = l;
|
|
}
|
|
protected native void nativeSetOnClickListener(long widget);
|
|
public /*native*/ void setOnSystemUiVisibilityChangeListener(OnSystemUiVisibilityChangeListener l) {}
|
|
public native final int getWidth();
|
|
public native final int getHeight();
|
|
|
|
protected native long native_constructor(Context context, AttributeSet attrs); // will create a custom GtkWidget with a custom drawing function
|
|
public native void native_setLayoutParams(long widget, int width, int height, int gravity, float weight, int leftMargin, int topMargin, int rightMargin, int bottomMargin);
|
|
protected native void native_destructor(long widget);
|
|
/**
|
|
* 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
|
|
*/
|
|
protected native void native_measure(long widget, int widthMeasureSpec, int heightMeasureSpec);
|
|
protected native void native_layout(long widget, int l, int t, int r, int b);
|
|
protected native void native_requestLayout(long widget);
|
|
protected native void native_setBackgroundDrawable(long widget, long paintable);
|
|
protected native void native_queueAllocate(long widget);
|
|
|
|
protected native void native_addClass(long widget, String className);
|
|
protected native void native_removeClass(long widget, String className);
|
|
|
|
protected native void native_addClasses(long widget, String[] classNames);
|
|
protected native void native_removeClasses(long widget, String[] classNames);
|
|
|
|
protected native void native_drawBackground(long widget, long snapshot);
|
|
protected native void native_drawContent(long widget, long snapshot);
|
|
protected void native_drawChildren(long widget, long snapshot) {} // override in ViewGroup
|
|
|
|
// --- stubs
|
|
|
|
public void setContentDescription(CharSequence contentDescription) {}
|
|
|
|
public void setId(int id) {
|
|
this.id = id;
|
|
}
|
|
|
|
public void setOnKeyListener(OnKeyListener l) {}
|
|
|
|
public void setFocusable(boolean focusable) {}
|
|
public void setFocusable(int focusable) {}
|
|
public void setFocusableInTouchMode(boolean focusableInTouchMode) {}
|
|
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) {
|
|
nativeRequestFocus(widget, direction);
|
|
return true;
|
|
}
|
|
private native void nativeRequestFocus(long widget, int direction);
|
|
|
|
private native void nativeSetFullscreen(long widget, boolean fullscreen);
|
|
|
|
public void setSystemUiVisibility(int visibility) {
|
|
nativeSetFullscreen(widget, (visibility & View.SYSTEM_UI_FLAG_FULLSCREEN) != 0);
|
|
system_ui_visibility = visibility;
|
|
}
|
|
public int getSystemUiVisibility() {
|
|
return system_ui_visibility;
|
|
};
|
|
|
|
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
|
if (haveCustomMeasure) // calling native_measure here would create infinite loop
|
|
setMeasuredDimension(getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec), getDefaultSize(getSuggestedMinimumHeight(), heightMeasureSpec));
|
|
else
|
|
native_measure(widget, widthMeasureSpec, heightMeasureSpec);
|
|
}
|
|
|
|
public void setPressed(boolean pressed) {
|
|
Slog.w(TAG, "calling setPressed on " + this + " with value: " + pressed);
|
|
if (this.pressed != pressed) {
|
|
this.pressed = pressed;
|
|
if (background != null && background.isStateful())
|
|
background.setState(getDrawableState());
|
|
}
|
|
}
|
|
|
|
public void setSelected(boolean selected) {}
|
|
|
|
public ViewTreeObserver getViewTreeObserver() {
|
|
return new ViewTreeObserver();
|
|
}
|
|
|
|
protected void onFinishInflate() {}
|
|
|
|
public void invalidateDrawable(Drawable drawable) {
|
|
nativeInvalidate(widget);
|
|
}
|
|
|
|
public void scheduleDrawable(Drawable drawable, Runnable runnable, long time) {
|
|
postDelayed(runnable, time - SystemClock.uptimeMillis());
|
|
}
|
|
|
|
public void unscheduleDrawable(Drawable drawable, Runnable runnable) {
|
|
/* TODO */
|
|
}
|
|
|
|
public void unscheduleDrawable(Drawable drawable) {}
|
|
|
|
public void invalidate(Rect dirty) {
|
|
nativeInvalidate(widget);
|
|
}
|
|
public void invalidate(int l, int t, int r, int b) {
|
|
nativeInvalidate(widget);
|
|
}
|
|
public void invalidate() {
|
|
nativeInvalidate(widget);
|
|
}
|
|
private static native void nativeInvalidate(long widget);
|
|
|
|
public native void setBackgroundColor(int color);
|
|
public native void native_setVisibility(long widget, int visibility, float alpha);
|
|
|
|
protected void onVisibilityChanged(View changedView, int visibility) {
|
|
}
|
|
|
|
protected void dispatchVisibilityChanged(View changedView, int visibility) {
|
|
onVisibilityChanged(changedView, visibility);
|
|
}
|
|
|
|
public void setVisibility(int visibility) {
|
|
native_setVisibility(widget, visibility, alpha);
|
|
if ((visibility == View.GONE) != (this.visibility == View.GONE)) {
|
|
requestLayout();
|
|
}
|
|
this.visibility = visibility;
|
|
dispatchVisibilityChanged(this, visibility);
|
|
}
|
|
|
|
public void setPadding(int left, int top, int right, int bottom) {
|
|
paddingLeft = left;
|
|
paddingTop = top;
|
|
paddingRight = right;
|
|
paddingBottom = bottom;
|
|
native_setPadding(widget, left, top, right, bottom);
|
|
}
|
|
public native void native_setPadding(long widget, int left, int top, int right, int bottom);
|
|
|
|
public void setBackgroundResource(int resid) {
|
|
setBackgroundDrawable(resid == 0 ? null : getResources().getDrawable(resid));
|
|
}
|
|
|
|
public void getHitRect(Rect outRect) {
|
|
outRect.set(left, top, right, bottom);
|
|
}
|
|
public final boolean getLocalVisibleRect(Rect r) { return false; }
|
|
|
|
public final int getScrollX() {
|
|
return scrollX;
|
|
}
|
|
public final int getScrollY() {
|
|
return scrollY;
|
|
}
|
|
|
|
public void scrollTo(int x, int y) {
|
|
scrollX = x;
|
|
scrollY = y;
|
|
invalidate();
|
|
}
|
|
|
|
protected void onScrollChanged(int l, int t, int oldl, int oldt) {}
|
|
|
|
public void getLocationOnScreen(int[] location) {
|
|
Rect rect = new Rect();
|
|
getGlobalVisibleRect(rect);
|
|
location[0] = rect.left;
|
|
location[1] = rect.top;
|
|
}
|
|
|
|
public boolean performHapticFeedback(int feedbackConstant) {
|
|
return performHapticFeedback(feedbackConstant, 0);
|
|
}
|
|
|
|
public boolean performHapticFeedback(int feedbackConstant, int flags) {
|
|
// arbitrary; TODO: better mimic what AOSP does
|
|
Vibrator vibrator = (Vibrator)getContext().getSystemService("vibrator");
|
|
vibrator.vibrate(10);
|
|
return true; // FIXME why is it not void
|
|
}
|
|
|
|
public int getPaddingLeft() {
|
|
return paddingLeft;
|
|
}
|
|
|
|
public int getPaddingRight() {
|
|
return paddingRight;
|
|
}
|
|
|
|
public int getPaddingTop() {
|
|
return paddingTop;
|
|
}
|
|
|
|
public int getPaddingBottom() {
|
|
return paddingBottom;
|
|
}
|
|
|
|
public int getPaddingStart() {
|
|
return paddingLeft;
|
|
}
|
|
|
|
public int getPaddingEnd() {
|
|
return paddingRight;
|
|
}
|
|
|
|
public void postInvalidate() {
|
|
new Handler(Looper.getMainLooper()).post(new Runnable() {
|
|
@Override
|
|
public void run() {
|
|
invalidate();
|
|
}
|
|
});
|
|
}
|
|
|
|
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);
|
|
}
|
|
});
|
|
}
|
|
|
|
public void setOnGenericMotionListener(View.OnGenericMotionListener l) {}
|
|
|
|
public IBinder getWindowToken() {
|
|
return new Binder();
|
|
}
|
|
|
|
public void getLocationInWindow(int[] location) {
|
|
getLocationOnScreen(location);
|
|
}
|
|
|
|
public void addOnAttachStateChangeListener(OnAttachStateChangeListener l) {
|
|
onAttachStateChangeListener = l;
|
|
}
|
|
|
|
public Context getContext() {
|
|
return this.context;
|
|
}
|
|
|
|
public void refreshDrawableState() {
|
|
}
|
|
|
|
public void setDescendantFocusability(int value) {}
|
|
|
|
public void setAccessibilityDelegate(AccessibilityDelegate delegate) {}
|
|
|
|
public static class AccessibilityDelegate {
|
|
public void sendAccessibilityEvent(View view, int eventType) {}
|
|
}
|
|
|
|
public Drawable getBackground() {
|
|
return background;
|
|
}
|
|
|
|
public void setClickable(boolean clickable) {}
|
|
|
|
public void setEnabled(boolean enabled) {}
|
|
|
|
public CharSequence getContentDescription() {
|
|
return null;
|
|
}
|
|
|
|
private OnLongClickListener on_long_click_listener = null;
|
|
public boolean performLongClick(float x, float y) {
|
|
if (on_long_click_listener != null) {
|
|
return on_long_click_listener.onLongClick(this);
|
|
}
|
|
return false;
|
|
}
|
|
public void setOnLongClickListener(OnLongClickListener listener) {
|
|
nativeSetOnLongClickListener(widget);
|
|
on_long_click_listener = listener;
|
|
}
|
|
protected native void nativeSetOnLongClickListener(long widget);
|
|
|
|
public void setLongClickable(boolean longClickable) {}
|
|
|
|
public void setOnHoverListener(OnHoverListener listener) {}
|
|
|
|
public final void measure(int widthMeasureSpec, int heightMeasureSpec) {
|
|
if (layoutRequested || widthMeasureSpec != oldWidthMeasureSpec || heightMeasureSpec != oldHeightMeasureSpec) {
|
|
oldWidthMeasureSpec = widthMeasureSpec;
|
|
oldHeightMeasureSpec = heightMeasureSpec;
|
|
onMeasure(widthMeasureSpec, heightMeasureSpec);
|
|
layoutRequested = false;
|
|
}
|
|
}
|
|
|
|
public final int getMeasuredState() {
|
|
return 0;
|
|
}
|
|
|
|
public static int combineMeasuredStates(int curState, int newState) {
|
|
return curState | newState;
|
|
}
|
|
|
|
protected int getSuggestedMinimumHeight() {
|
|
return getMinimumHeight();
|
|
}
|
|
protected int getSuggestedMinimumWidth() {
|
|
return getMinimumWidth();
|
|
}
|
|
|
|
/**
|
|
* 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);
|
|
}
|
|
|
|
public static int resolveSize(int size, int measureSpec) {
|
|
return resolveSizeAndState(size, measureSpec, 0) & MEASURED_SIZE_MASK;
|
|
}
|
|
|
|
public final int getMeasuredWidth() {
|
|
return this.measuredWidth & MEASURED_SIZE_MASK;
|
|
}
|
|
|
|
public final int getMeasuredHeight() {
|
|
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);
|
|
}
|
|
|
|
/** 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;
|
|
if (changed)
|
|
onSizeChanged(width, height, oldWidth, oldHeight);
|
|
bottom = top + height;
|
|
right = left + width;
|
|
onLayout(changed, 0, 0, width, height);
|
|
oldWidth = width;
|
|
oldHeight = height;
|
|
}
|
|
|
|
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);
|
|
}
|
|
|
|
public void offsetLeftAndRight(int offset) {
|
|
layout(left + offset, top, right + offset, bottom);
|
|
}
|
|
|
|
public void setBackgroundDrawable(Drawable backgroundDrawable) {
|
|
this.background = backgroundDrawable;
|
|
if(backgroundDrawable != null)
|
|
backgroundDrawable.setCallback(this);
|
|
native_setBackgroundDrawable(widget, backgroundDrawable != null ? backgroundDrawable.paintable : 0);
|
|
}
|
|
|
|
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;}
|
|
|
|
public void requestLayout() {
|
|
layoutRequested = true;
|
|
if (parent instanceof View && !parent.isLayoutRequested()) {
|
|
((View)parent).requestLayout();
|
|
}
|
|
native_requestLayout(widget);
|
|
};
|
|
|
|
public void setOverScrollMode(int mode) {}
|
|
|
|
public int getId() {return id;}
|
|
public String getIdName() {
|
|
if(this.id == View.NO_ID) {
|
|
return "NO_ID";
|
|
}
|
|
|
|
try {
|
|
return getResources().getResourceName(this.id);
|
|
} catch (Resources.NotFoundException e) {
|
|
return "NOT_FOUND";
|
|
}
|
|
|
|
}
|
|
public String getAllSuperClasses() {
|
|
StringBuilder sb = new StringBuilder();
|
|
Class<?> currentClass = getClass();
|
|
|
|
sb.append(currentClass.getCanonicalName());
|
|
currentClass = currentClass.getSuperclass();
|
|
while (currentClass != null) {
|
|
sb.append(" << ").append(currentClass.getCanonicalName());
|
|
currentClass = currentClass.getSuperclass();
|
|
}
|
|
return sb.toString();
|
|
}
|
|
|
|
public boolean postDelayed(Runnable action, long delayMillis) {
|
|
new Handler(Looper.getMainLooper()).postDelayed(action, delayMillis);
|
|
return true;
|
|
}
|
|
|
|
public boolean post(Runnable action) {
|
|
new Handler(Looper.getMainLooper()).post(action);
|
|
return true;
|
|
}
|
|
|
|
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);
|
|
}
|
|
|
|
public void setTag(Object tag) {
|
|
this.tag = tag;
|
|
}
|
|
public Object getTag() {
|
|
return tag;
|
|
}
|
|
|
|
public void addOnLayoutChangeListener(OnLayoutChangeListener listener) {}
|
|
public void removeOnLayoutChangeListener(OnLayoutChangeListener listener) {}
|
|
|
|
public boolean isSelected() {return false;}
|
|
|
|
public void sendAccessibilityEvent(int eventType) {}
|
|
|
|
public void setMinimumHeight(int minHeight) {
|
|
this.minHeight = minHeight;
|
|
}
|
|
public void setMinimumWidth(int minWidth) {
|
|
this.minWidth = minWidth;
|
|
}
|
|
|
|
public void setActivated (boolean activated) {}
|
|
|
|
public int getVisibility() {return visibility;}
|
|
|
|
public boolean isInEditMode() {return false;}
|
|
|
|
@Override
|
|
@SuppressWarnings("deprecation")
|
|
protected void finalize() throws Throwable {
|
|
try {
|
|
native_destructor(widget);
|
|
} finally {
|
|
super.finalize();
|
|
}
|
|
}
|
|
|
|
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;
|
|
}
|
|
|
|
public float getRotation() {return 0.f;}
|
|
|
|
public void bringToFront() {}
|
|
|
|
public boolean isEnabled() {return true;}
|
|
public boolean hasFocus() {return false;}
|
|
public boolean isLayoutRequested() {return layoutRequested;}
|
|
public int getBaseline() {return -1;}
|
|
public boolean hasFocusable() {return false;}
|
|
private static native boolean nativeIsFocused(long widget);
|
|
public boolean isFocused() {
|
|
return nativeIsFocused(widget);
|
|
}
|
|
|
|
public void clearAnimation() {}
|
|
|
|
private ViewPropertyAnimator viewPropertyAnimator;
|
|
public ViewPropertyAnimator animate() {
|
|
if (viewPropertyAnimator == null)
|
|
viewPropertyAnimator = new ViewPropertyAnimator(this);
|
|
return viewPropertyAnimator;
|
|
}
|
|
|
|
public float getTranslationX() {return 0.f;}
|
|
public float getTranslationY() {return 0.f;}
|
|
public void setTranslationX(float translationX) {}
|
|
public void setTranslationY(float translationY) {
|
|
// CoordinatorLayout abuses this method to trigger a layout pass
|
|
if (getClass().getName().equals("androidx.coordinatorlayout.widget.CoordinatorLayout"))
|
|
native_queueAllocate(widget);
|
|
}
|
|
|
|
public void setX(float x) {
|
|
setTranslationX(x - left);
|
|
}
|
|
|
|
|
|
public void setY(float y) {
|
|
setTranslationY(y - top);
|
|
}
|
|
|
|
|
|
public void setAlpha(float alpha) {
|
|
native_setVisibility(widget, visibility, alpha);
|
|
this.alpha = alpha;
|
|
}
|
|
|
|
public boolean onGenericMotionEvent(MotionEvent event) {return false;}
|
|
|
|
protected boolean awakenScrollBars() {return false;}
|
|
|
|
protected native boolean native_getMatrix(long widget, long matrix);
|
|
public Matrix getMatrix() {
|
|
return Matrix.IDENTITY_MATRIX;
|
|
}
|
|
|
|
protected static final int[] EMPTY_STATE_SET = new int[0];
|
|
|
|
protected static final int[] PRESSED_ENABLED_STATE_SET = new int[]{R.attr.state_pressed, R.attr.state_enabled};
|
|
|
|
protected static final int[] SELECTED_STATE_SET = new int[]{R.attr.state_selected};
|
|
|
|
/**
|
|
* 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;
|
|
}
|
|
|
|
public static class BaseSavedState extends AbsSavedState {
|
|
}
|
|
|
|
public void clearFocus() {}
|
|
|
|
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() {
|
|
if (on_click_listener != null) {
|
|
on_click_listener.onClick(this);
|
|
return true;
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
public void playSoundEffect(int soundConstant) {}
|
|
|
|
public void computeScroll() {}
|
|
|
|
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) {}
|
|
|
|
protected void onAnimationStart() {}
|
|
|
|
protected void onAnimationEnd() {}
|
|
|
|
public void startAnimation(Animation animation) {
|
|
onAnimationStart();
|
|
animation.start();
|
|
onAnimationEnd();
|
|
}
|
|
|
|
public void getDrawingRect(Rect rect) {
|
|
rect.left = getScrollX();
|
|
rect.top = getScrollY();
|
|
rect.right = getScrollX() + getWidth();
|
|
rect.bottom = getScrollY() + getHeight();
|
|
}
|
|
|
|
public Display getDisplay() {
|
|
return new Display();
|
|
}
|
|
|
|
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;}
|
|
|
|
public void setBackground(Drawable background) {
|
|
setBackgroundDrawable(background);
|
|
}
|
|
|
|
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) {
|
|
postDelayed(action, 1000 / 60);
|
|
}
|
|
|
|
public void postOnAnimationDelayed(Runnable action, long delayMillis) {
|
|
if (delayMillis < 1000 / 60)
|
|
delayMillis = 1000 / 60;
|
|
postDelayed(action, delayMillis);
|
|
}
|
|
|
|
public void setHorizontalScrollBarEnabled(boolean enabled) {}
|
|
|
|
public void setVerticalScrollBarEnabled(boolean enabled) {}
|
|
|
|
|
|
public void postInvalidateOnAnimation() {
|
|
postInvalidate();
|
|
}
|
|
|
|
public void setPaddingRelative(int start, int top, int end, int bottom) {}
|
|
|
|
public boolean isAttachedToWindow() {return attachedToWindow;}
|
|
|
|
public void requestApplyInsets() {}
|
|
|
|
public View getRootView() {
|
|
View view = this;
|
|
while (view.parent instanceof View) {
|
|
view = (View)view.parent;
|
|
}
|
|
return view;
|
|
}
|
|
|
|
public boolean isShown() {return true;}
|
|
|
|
public int getWindowVisibility() {return VISIBLE;}
|
|
|
|
public float getAlpha() {return alpha;}
|
|
|
|
public View findFocus() {return this;}
|
|
|
|
public int getMinimumHeight() {return minHeight;}
|
|
public int getMinimumWidth() {return minWidth;}
|
|
|
|
public boolean isNestedScrollingEnabled() {return false;}
|
|
|
|
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) {}
|
|
|
|
public boolean canScrollVertically(int value) {return false;}
|
|
|
|
public boolean isInTouchMode() {return false;}
|
|
|
|
public void stopNestedScroll() {}
|
|
|
|
public long getDrawingTime() {
|
|
return System.currentTimeMillis();
|
|
}
|
|
|
|
private boolean keepScreenOn = false;
|
|
private static native void native_keep_screen_on(long widget, boolean keepScreenOn);
|
|
public void setKeepScreenOn(boolean screenOn) {
|
|
if (attachedToWindow && keepScreenOn != screenOn)
|
|
native_keep_screen_on(widget, screenOn);
|
|
keepScreenOn = screenOn;
|
|
}
|
|
|
|
protected void onAttachedToWindow () {
|
|
attachedToWindow = true;
|
|
if (onAttachStateChangeListener != null) {
|
|
onAttachStateChangeListener.onViewAttachedToWindow(this);
|
|
}
|
|
if (keepScreenOn)
|
|
native_keep_screen_on(widget, true);
|
|
}
|
|
protected void onDetachedFromWindow() {
|
|
if (onAttachStateChangeListener != null) {
|
|
onAttachStateChangeListener.onViewDetachedFromWindow(this);
|
|
}
|
|
if (keepScreenOn)
|
|
native_keep_screen_on(widget, false);
|
|
}
|
|
|
|
void detachFromWindowInternal() {
|
|
onDetachedFromWindow();
|
|
attachedToWindow = false;
|
|
}
|
|
public void attachToWindowInternal() {
|
|
onAttachedToWindow();
|
|
}
|
|
|
|
public void setLayerType(int layerType, Paint paint) {}
|
|
|
|
public float getZ() {return 0.f;}
|
|
|
|
protected void onSizeChanged(int w, int h, int oldw, int oldh) {}
|
|
|
|
public void setBackgroundTintList(ColorStateList tint) {}
|
|
|
|
protected int computeHorizontalScrollRange() {
|
|
return getWidth();
|
|
}
|
|
|
|
protected int computeHorizontalScrollExtent() {
|
|
return getWidth();
|
|
}
|
|
|
|
protected int computeVerticalScrollRange() {
|
|
return getHeight();
|
|
}
|
|
|
|
protected int computeVerticalScrollExtent() {
|
|
return getHeight();
|
|
}
|
|
|
|
public void setAccessibilityLiveRegion(int mode) {}
|
|
|
|
public void invalidateOutline() {}
|
|
|
|
public int getMeasuredWidthAndState() {
|
|
return measuredWidth;
|
|
}
|
|
|
|
public void forceLayout() {
|
|
new Handler(Looper.getMainLooper()).post(new Runnable() {
|
|
@Override
|
|
public void run() {
|
|
requestLayout();
|
|
}
|
|
});
|
|
}
|
|
|
|
private OnAttachStateChangeListener onAttachStateChangeListener;
|
|
public void removeOnAttachStateChangeListener(OnAttachStateChangeListener listener) {
|
|
if (onAttachStateChangeListener == listener) {
|
|
onAttachStateChangeListener = null;
|
|
}
|
|
}
|
|
|
|
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);
|
|
}
|
|
|
|
public boolean onCheckIsTextEditor() {return false;}
|
|
|
|
public boolean hasOnClickListeners() {return false;}
|
|
|
|
public void setTextAlignment(int textAlignment) {
|
|
String[] classesToRemove = {"ATL-text-align-left", "ATL-text-align-center", "ATL-text-align-right"};
|
|
native_removeClasses(widget, classesToRemove);
|
|
|
|
switch(textAlignment) {
|
|
case TEXT_ALIGNMENT_CENTER:
|
|
native_addClass(widget, "ATL-text-align-center");
|
|
break;
|
|
case TEXT_ALIGNMENT_TEXT_START:
|
|
case TEXT_ALIGNMENT_VIEW_START:
|
|
native_addClass(widget, "ATL-text-align-left");
|
|
break;
|
|
case TEXT_ALIGNMENT_TEXT_END:
|
|
case TEXT_ALIGNMENT_VIEW_END:
|
|
native_addClass(widget, "ATL-text-align-right");
|
|
break;
|
|
}
|
|
}
|
|
|
|
public void setHapticFeedbackEnabled(boolean hapticFeedbackEnabled) {}
|
|
|
|
public StateListAnimator getStateListAnimator() {return null;}
|
|
|
|
public void requestFitSystemWindows() {}
|
|
|
|
public boolean isPressed() {return false;}
|
|
|
|
public void getWindowVisibleDisplayFrame(Rect rect) {}
|
|
|
|
public void setRotation(float rotation) {}
|
|
public void setRotationX(float deg) {}
|
|
public void setRotationY(float deg) {}
|
|
|
|
public float getRotationX() {return 0.f;}
|
|
public float getRotationY() {return 0.f;}
|
|
|
|
public void setScaleX(float scaleX) {}
|
|
public void setScaleY(float scaleY) {}
|
|
|
|
public float getScaleX() {return 1.f;}
|
|
public float getScaleY() {return 1.f;}
|
|
|
|
public void setPivotX(float pivot_x) {}
|
|
public void setPivotY(float pivot_y) {}
|
|
|
|
public float getPivotX() {return 0.f;}
|
|
public float getPivotY() {return 0.f;}
|
|
|
|
public float getTranslationZ() {return 0.f;}
|
|
|
|
public void setTranslationZ(float translationZ) {}
|
|
|
|
public int getWindowSystemUiVisibility() {
|
|
return 0;
|
|
}
|
|
|
|
public void setScrollIndicators(int indicators, int mask) {}
|
|
|
|
public void setLayoutDirection(int layoutDirection) {}
|
|
|
|
public ColorStateList getBackgroundTintList() {return null;}
|
|
|
|
public PorterDuff.Mode getBackgroundTintMode() {return null;}
|
|
|
|
public String getTransitionName() {return null;}
|
|
|
|
public WindowId getWindowId() {return null;}
|
|
|
|
public boolean isInLayout() {
|
|
return false; // FIXME
|
|
}
|
|
|
|
public void setTextDirection(int textDirection) {}
|
|
|
|
public Drawable getForeground() {return null;}
|
|
|
|
public void setScrollbarFadingEnabled(boolean fadeEnabled) {}
|
|
|
|
public void setScrollBarStyle(int style) {}
|
|
|
|
public void setVerticalScrollbarPosition(int position) {}
|
|
|
|
public void setNestedScrollingEnabled(boolean enabled) {}
|
|
|
|
public void setTouchDelegate(TouchDelegate touchDelegate) {}
|
|
|
|
public void setOnDragListener(OnDragListener onDragListener) {}
|
|
|
|
public void setTransitionName(String transitionName) {}
|
|
|
|
public Animation getAnimation() {return null;}
|
|
|
|
public ViewOverlay getOverlay() {
|
|
return new ViewOverlay();
|
|
}
|
|
|
|
public void cancelLongPress() {}
|
|
|
|
public int getTextAlignment() {return 0;}
|
|
|
|
public float getY() {return 0.f;}
|
|
|
|
public View findViewWithTag(Object tag) {
|
|
if (Objects.equals(tag, this.tag))
|
|
return this;
|
|
else
|
|
return null;
|
|
}
|
|
|
|
public void setTooltipText(CharSequence tooltip) {}
|
|
|
|
public int getImportantForAutofill() {return 0;}
|
|
|
|
public void setImportantForAutofill(int flag) {}
|
|
|
|
public void setDefaultFocusHighlightEnabled(boolean enabled) {}
|
|
|
|
public void setHorizontalFadingEdgeEnabled(boolean horizontalFadingEdgeEnabled) {}
|
|
|
|
public Handler getHandler() {
|
|
return new Handler(Looper.getMainLooper());
|
|
}
|
|
|
|
public boolean isHardwareAccelerated() {
|
|
return false;
|
|
}
|
|
|
|
public void setClipBounds(Rect clipBounds) {}
|
|
|
|
public boolean getClipToOutline() {return false;}
|
|
|
|
public void setLeft(int left) {
|
|
layout(left, top, right, bottom);
|
|
}
|
|
|
|
public void setTop(int top) {
|
|
layout(left, top, right, bottom);
|
|
}
|
|
|
|
public void setRight(int right) {
|
|
layout(left, top, right, bottom);
|
|
}
|
|
|
|
public void setBottom(int bottom) {
|
|
layout(left, top, right, bottom);
|
|
}
|
|
|
|
public void setCameraDistance(float distance) {}
|
|
|
|
public boolean requestRectangleOnScreen(Rect rectangle, boolean immediate) {return false;}
|
|
|
|
public boolean requestRectangleOnScreen(Rect rectangle) {return false;}
|
|
|
|
public boolean onKeyDown(int keyCode, KeyEvent event) {
|
|
return false;
|
|
}
|
|
|
|
public boolean dispatchKeyEvent(KeyEvent event) {
|
|
if (event.getAction() == KeyEvent.ACTION_DOWN)
|
|
return onKeyDown(event.getKeyCode(), event);
|
|
else
|
|
return false;
|
|
}
|
|
|
|
public WindowInsets getRootWindowInsets() {return null;}
|
|
|
|
public PointerIcon getPointerIcon() {return null;}
|
|
|
|
public void setPointerIcon(PointerIcon pointerIcon) {}
|
|
|
|
public IBinder getApplicationWindowToken() {return null;}
|
|
|
|
public int getVerticalFadingEdgeLength() {return 0;}
|
|
public int getVerticalScrollbarWidth() {return 0;}
|
|
|
|
public void saveAttributeDataForStyleable(Context ctxt, int[] styleable, AttributeSet attrs, TypedArray t, int defStyleAttr, int defStyleRes) {}
|
|
|
|
public final View requireViewById(int id) {
|
|
View view = findViewById(id);
|
|
if (view == null)
|
|
throw new IllegalArgumentException("ID does not reference a View inside this View");
|
|
return view;
|
|
}
|
|
public float getTransitionAlpha() {
|
|
return 1.0f;
|
|
}
|
|
|
|
public void onWindowFocusChanged(boolean hasFocus) {}
|
|
|
|
public void setAnimation(Animation animation) {}
|
|
|
|
public boolean performAccessibilityAction(int action, Bundle arguments) { return false; }
|
|
|
|
public boolean isDirty() { return false; }
|
|
|
|
public float getX() { return getLeft(); }
|
|
|
|
public boolean getGlobalVisibleRect(Rect visibleRect, Point globalOffset) {
|
|
boolean result = native_getGlobalVisibleRect(widget, visibleRect);
|
|
globalOffset.set(visibleRect.left, visibleRect.top);
|
|
return result;
|
|
}
|
|
|
|
public void restoreHierarchyState(SparseArray<Parcelable> container) {}
|
|
|
|
public boolean isHovered() { return false; }
|
|
|
|
public void scrollBy(int x, int y) {
|
|
scrollTo(scrollX + x, scrollY + y);
|
|
}
|
|
}
|