You've already forked android_translation_layer
mirror of
https://gitlab.com/android_translation_layer/android_translation_layer.git
synced 2025-10-27 11:48:10 -07:00
This reverts commit b33a470c7b.
This commit was added as fix for layout recreation loops, but this is no
longer a problem, since ViewGroup.detachViewFromParent() has been
improved. The first fix is no longer needed and it seems to cause some
minor regressions, so we revert it.
2178 lines
61 KiB
Java
2178 lines
61 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 onTouchEvent(MotionEvent event) {
|
|
boolean handled = false;
|
|
if (on_touch_listener != null)
|
|
handled = on_touch_listener.onTouch(this, event);
|
|
return handled;
|
|
}
|
|
|
|
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);
|
|
public void setVisibility(int visibility) {
|
|
native_setVisibility(widget, visibility, alpha);
|
|
if ((visibility == View.GONE) != (this.visibility == View.GONE)) {
|
|
requestLayout();
|
|
}
|
|
this.visibility = 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; }
|
|
}
|