/*
* Copyright (C) 2006 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.view;
import android.animation.AnimatorInflater;
import android.animation.StateListAnimator;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.ClipData;
import android.content.Context;
import android.content.res.ColorStateList;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Insets;
import android.graphics.Interpolator;
import android.graphics.LinearGradient;
import android.graphics.Matrix;
import android.graphics.Outline;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PathMeasure;
import android.graphics.PixelFormat;
import android.graphics.Point;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Region;
import android.graphics.Shader;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.hardware.display.DisplayManagerGlobal;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Parcel;
import android.os.Parcelable;
import android.os.RemoteException;
import android.os.SystemClock;
import android.os.SystemProperties;
import android.os.Trace;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.util.FloatProperty;
import android.util.LayoutDirection;
import android.util.Log;
import android.util.LongSparseLongArray;
import android.util.Pools.SynchronizedPool;
import android.util.Property;
import android.util.SparseArray;
import android.util.SuperNotCalledException;
import android.util.TypedValue;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.AccessibilityIterators.TextSegmentIterator;
import android.view.AccessibilityIterators.CharacterTextSegmentIterator;
import android.view.AccessibilityIterators.WordTextSegmentIterator;
import android.view.AccessibilityIterators.ParagraphTextSegmentIterator;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityEventSource;
import android.view.accessibility.AccessibilityManager;
import android.view.accessibility.AccessibilityNodeInfo;
import android.view.accessibility.AccessibilityNodeProvider;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.view.animation.Transformation;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputConnection;
import android.view.inputmethod.InputMethodManager;
import android.widget.ScrollBarDrawable;
import static android.os.Build.VERSION_CODES.*;
import static java.lang.Math.max;
import com.android.internal.R;
import com.android.internal.util.Predicate;
import com.android.internal.view.menu.MenuBuilder;
import com.google.android.collect.Lists;
import com.google.android.collect.Maps;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.ref.WeakReference;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.atomic.AtomicInteger;
/**
* <p>
* This class represents the basic building block for user interface components. A View
* occupies a rectangular area on the screen and is responsible for drawing and
* event handling. View is the base class for <em>widgets</em>, which are
* used to create interactive UI components (buttons, text fields, etc.). The
* {@link android.view.ViewGroup} subclass is the base class for <em>layouts</em>, which
* are invisible containers that hold other Views (or other ViewGroups) and define
* their layout properties.
* </p>
*
* <div class="special reference">
* <h3>Developer Guides</h3>
* <p>For information about using this class to develop your application's user interface,
* read the <a href="{@docRoot}guide/topics/ui/index.html">User Interface</a> developer guide.
* </div>
*
* <a name="Using"></a>
* <h3>Using Views</h3>
* <p>
* All of the views in a window are arranged in a single tree. You can add views
* either from code or by specifying a tree of views in one or more XML layout
* files. There are many specialized subclasses of views that act as controls or
* are capable of displaying text, images, or other content.
* </p>
* <p>
* Once you have created a tree of views, there are typically a few types of
* common operations you may wish to perform:
* <ul>
* <li><strong>Set properties:</strong> for example setting the text of a
* {@link android.widget.TextView}. The available properties and the methods
* that set them will vary among the different subclasses of views. Note that
* properties that are known at build time can be set in the XML layout
* files.</li>
* <li><strong>Set focus:</strong> The framework will handled moving focus in
* response to user input. To force focus to a specific view, call
* {@link #requestFocus}.</li>
* <li><strong>Set up listeners:</strong> Views allow clients to set listeners
* that will be notified when something interesting happens to the view. For
* example, all views will let you set a listener to be notified when the view
* gains or loses focus. You can register such a listener using
* {@link #setOnFocusChangeListener(android.view.View.OnFocusChangeListener)}.
* Other view subclasses offer more specialized listeners. For example, a Button
* exposes a listener to notify clients when the button is clicked.</li>
* <li><strong>Set visibility:</strong> You can hide or show views using
* {@link #setVisibility(int)}.</li>
* </ul>
* </p>
* <p><em>
* Note: The Android framework is responsible for measuring, laying out and
* drawing views. You should not call methods that perform these actions on
* views yourself unless you are actually implementing a
* {@link android.view.ViewGroup}.
* </em></p>
*
* <a name="Lifecycle"></a>
* <h3>Implementing a Custom View</h3>
*
* <p>
* To implement a custom view, you will usually begin by providing overrides for
* some of the standard methods that the framework calls on all views. You do
* not need to override all of these methods. In fact, you can start by just
* overriding {@link #onDraw(android.graphics.Canvas)}.
* <table border="2" width="85%" align="center" cellpadding="5">
* <thead>
* <tr><th>Category</th> <th>Methods</th> <th>Description</th></tr>
* </thead>
*
* <tbody>
* <tr>
* <td rowspan="2">Creation</td>
* <td>Constructors</td>
* <td>There is a form of the constructor that are called when the view
* is created from code and a form that is called when the view is
* inflated from a layout file. The second form should parse and apply
* any attributes defined in the layout file.
* </td>
* </tr>
* <tr>
* <td><code>{@link #onFinishInflate()}</code></td>
* <td>Called after a view and all of its children has been inflated
* from XML.</td>
* </tr>
*
* <tr>
* <td rowspan="3">Layout</td>
* <td><code>{@link #onMeasure(int, int)}</code></td>
* <td>Called to determine the size requirements for this view and all
* of its children.
* </td>
* </tr>
* <tr>
* <td><code>{@link #onLayout(boolean, int, int, int, int)}</code></td>
* <td>Called when this view should assign a size and position to all
* of its children.
* </td>
* </tr>
* <tr>
* <td><code>{@link #onSizeChanged(int, int, int, int)}</code></td>
* <td>Called when the size of this view has changed.
* </td>
* </tr>
*
* <tr>
* <td>Drawing</td>
* <td><code>{@link #onDraw(android.graphics.Canvas)}</code></td>
* <td>Called when the view should render its content.
* </td>
* </tr>
*
* <tr>
* <td rowspan="4">Event processing</td>
* <td><code>{@link #onKeyDown(int, KeyEvent)}</code></td>
* <td>Called when a new hardware key event occurs.
* </td>
* </tr>
* <tr>
* <td><code>{@link #onKeyUp(int, KeyEvent)}</code></td>
* <td>Called when a hardware key up event occurs.
* </td>
* </tr>
* <tr>
* <td><code>{@link #onTrackballEvent(MotionEvent)}</code></td>
* <td>Called when a trackball motion event occurs.
* </td>
* </tr>
* <tr>
* <td><code>{@link #onTouchEvent(MotionEvent)}</code></td>
* <td>Called when a touch screen motion event occurs.
* </td>
* </tr>
*
* <tr>
* <td rowspan="2">Focus</td>
* <td><code>{@link #onFocusChanged(boolean, int, android.graphics.Rect)}</code></td>
* <td>Called when the view gains or loses focus.
* </td>
* </tr>
*
* <tr>
* <td><code>{@link #onWindowFocusChanged(boolean)}</code></td>
* <td>Called when the window containing the view gains or loses focus.
* </td>
* </tr>
*
* <tr>
* <td rowspan="3">Attaching</td>
* <td><code>{@link #onAttachedToWindow()}</code></td>
* <td>Called when the view is attached to a window.
* </td>
* </tr>
*
* <tr>
* <td><code>{@link #onDetachedFromWindow}</code></td>
* <td>Called when the view is detached from its window.
* </td>
* </tr>
*
* <tr>
* <td><code>{@link #onWindowVisibilityChanged(int)}</code></td>
* <td>Called when the visibility of the window containing the view
* has changed.
* </td>
* </tr>
* </tbody>
*
* </table>
* </p>
*
* <a name="IDs"></a>
* <h3>IDs</h3>
* Views may have an integer id associated with them. These ids are typically
* assigned in the layout XML files, and are used to find specific views within
* the view tree. A common pattern is to:
* <ul>
* <li>Define a Button in the layout file and assign it a unique ID.
* <pre>
* <Button
* android:id="@+id/my_button"
* android:layout_width="wrap_content"
* android:layout_height="wrap_content"
* android:text="@string/my_button_text"/>
* </pre></li>
* <li>From the onCreate method of an Activity, find the Button
* <pre class="prettyprint">
* Button myButton = (Button) findViewById(R.id.my_button);
* </pre></li>
* </ul>
* <p>
* View IDs need not be unique throughout the tree, but it is good practice to
* ensure that they are at least unique within the part of the tree you are
* searching.
* </p>
*
* <a name="Position"></a>
* <h3>Position</h3>
* <p>
* The geometry of a view is that of a rectangle. A view has a location,
* expressed as a pair of <em>left</em> and <em>top</em> coordinates, and
* two dimensions, expressed as a width and a height. The unit for location
* and dimensions is the pixel.
* </p>
*
* <p>
* It is possible to retrieve the location of a view by invoking the methods
* {@link #getLeft()} and {@link #getTop()}. The former returns the left, or X,
* coordinate of the rectangle representing the view. The latter returns the
* top, or Y, coordinate of the rectangle representing the view. These methods
* both return the location of the view relative to its parent. For instance,
* when getLeft() returns 20, that means the view is located 20 pixels to the
* right of the left edge of its direct parent.
* </p>
*
* <p>
* In addition, several convenience methods are offered to avoid unnecessary
* computations, namely {@link #getRight()} and {@link #getBottom()}.
* These methods return the coordinates of the right and bottom edges of the
* rectangle representing the view. For instance, calling {@link #getRight()}
* is similar to the following computation: <code>getLeft() + getWidth()</code>
* (see <a href="#SizePaddingMargins">Size</a> for more information about the width.)
* </p>
*
* <a name="SizePaddingMargins"></a>
* <h3>Size, padding and margins</h3>
* <p>
* The size of a view is expressed with a width and a height. A view actually
* possess two pairs of width and height values.
* </p>
*
* <p>
* The first pair is known as <em>measured width</em> and
* <em>measured height</em>. These dimensions define how big a view wants to be
* within its parent (see <a href="#Layout">Layout</a> for more details.) The
* measured dimensions can be obtained by calling {@link #getMeasuredWidth()}
* and {@link #getMeasuredHeight()}.
* </p>
*
* <p>
* The second pair is simply known as <em>width</em> and <em>height</em>, or
* sometimes <em>drawing width</em> and <em>drawing height</em>. These
* dimensions define the actual size of the view on screen, at drawing time and
* after layout. These values may, but do not have to, be different from the
* measured width and height. The width and height can be obtained by calling
* {@link #getWidth()} and {@link #getHeight()}.
* </p>
*
* <p>
* To measure its dimensions, a view takes into account its padding. The padding
* is expressed in pixels for the left, top, right and bottom parts of the view.
* Padding can be used to offset the content of the view by a specific amount of
* pixels. For instance, a left padding of 2 will push the view's content by
* 2 pixels to the right of the left edge. Padding can be set using the
* {@link #setPadding(int, int, int, int)} or {@link #setPaddingRelative(int, int, int, int)}
* method and queried by calling {@link #getPaddingLeft()}, {@link #getPaddingTop()},
* {@link #getPaddingRight()}, {@link #getPaddingBottom()}, {@link #getPaddingStart()},
* {@link #getPaddingEnd()}.
* </p>
*
* <p>
* Even though a view can define a padding, it does not provide any support for
* margins. However, view groups provide such a support. Refer to
* {@link android.view.ViewGroup} and
* {@link android.view.ViewGroup.MarginLayoutParams} for further information.
* </p>
*
* <a name="Layout"></a>
* <h3>Layout</h3>
* <p>
* Layout is a two pass process: a measure pass and a layout pass. The measuring
* pass is implemented in {@link #measure(int, int)} and is a top-down traversal
* of the view tree. Each view pushes dimension specifications down the tree
* during the recursion. At the end of the measure pass, every view has stored
* its measurements. The second pass happens in
* {@link #layout(int,int,int,int)} and is also top-down. During
* this pass each parent is responsible for positioning all of its children
* using the sizes computed in the measure pass.
* </p>
*
* <p>
* When a view's measure() method returns, its {@link #getMeasuredWidth()} and
* {@link #getMeasuredHeight()} values must be set, along with those for all of
* that view's descendants. A view's measured width and measured height values
* must respect the constraints imposed by the view's parents. This guarantees
* that at the end of the measure pass, all parents accept all of their
* children's measurements. A parent view may call measure() more than once on
* its children. For example, the parent may measure each child once with
* unspecified dimensions to find out how big they want to be, then call
* measure() on them again with actual numbers if the sum of all the children's
* unconstrained sizes is too big or too small.
* </p>
*
* <p>
* The measure pass uses two classes to communicate dimensions. The
* {@link MeasureSpec} class is used by views to tell their parents how they
* want to be measured and positioned. The base LayoutParams class just
* describes how big the view wants to be for both width and height. For each
* dimension, it can specify one of:
* <ul>
* <li> an exact number
* <li>MATCH_PARENT, which means the view wants to be as big as its parent
* (minus padding)
* <li> WRAP_CONTENT, which means that the view wants to be just big enough to
* enclose its content (plus padding).
* </ul>
* There are subclasses of LayoutParams for different subclasses of ViewGroup.
* For example, AbsoluteLayout has its own subclass of LayoutParams which adds
* an X and Y value.
* </p>
*
* <p>
* MeasureSpecs are used to push requirements down the tree from parent to
* child. A MeasureSpec can be in one of three modes:
* <ul>
* <li>UNSPECIFIED: This is used by a parent to determine the desired dimension
* of a child view. For example, a LinearLayout may call measure() on its child
* with the height set to UNSPECIFIED and a width of EXACTLY 240 to find out how
* tall the child view wants to be given a width of 240 pixels.
* <li>EXACTLY: This is used by the parent to impose an exact size on the
* child. The child must use this size, and guarantee that all of its
* descendants will fit within this size.
* <li>AT_MOST: This is used by the parent to impose a maximum size on the
* child. The child must guarantee that it and all of its descendants will fit
* within this size.
* </ul>
* </p>
*
* <p>
* To intiate a layout, call {@link #requestLayout}. This method is typically
* called by a view on itself when it believes that is can no longer fit within
* its current bounds.
* </p>
*
* <a name="Drawing"></a>
* <h3>Drawing</h3>
* <p>
* Drawing is handled by walking the tree and recording the drawing commands of
* any View that needs to update. After this, the drawing commands of the
* entire tree are issued to screen, clipped to the newly damaged area.
* </p>
*
* <p>
* The tree is largely recorded and drawn in order, with parents drawn before
* (i.e., behind) their children, with siblings drawn in the order they appear
* in the tree. If you set a background drawable for a View, then the View will
* draw it before calling back to its <code>onDraw()</code> method. The child
* drawing order can be overridden with
* {@link ViewGroup#setChildrenDrawingOrderEnabled(boolean) custom child drawing order}
* in a ViewGroup, and with {@link #setZ(float)} custom Z values} set on Views.
* </p>
*
* <p>
* To force a view to draw, call {@link #invalidate()}.
* </p>
*
* <a name="EventHandlingThreading"></a>
* <h3>Event Handling and Threading</h3>
* <p>
* The basic cycle of a view is as follows:
* <ol>
* <li>An event comes in and is dispatched to the appropriate view. The view
* handles the event and notifies any listeners.</li>
* <li>If in the course of processing the event, the view's bounds may need
* to be changed, the view will call {@link #requestLayout()}.</li>
* <li>Similarly, if in the course of processing the event the view's appearance
* may need to be changed, the view will call {@link #invalidate()}.</li>
* <li>If either {@link #requestLayout()} or {@link #invalidate()} were called,
* the framework will take care of measuring, laying out, and drawing the tree
* as appropriate.</li>
* </ol>
* </p>
*
* <p><em>Note: The entire view tree is single threaded. You must always be on
* the UI thread when calling any method on any view.</em>
* If you are doing work on other threads and want to update the state of a view
* from that thread, you should use a {@link Handler}.
* </p>
*
* <a name="FocusHandling"></a>
* <h3>Focus Handling</h3>
* <p>
* The framework will handle routine focus movement in response to user input.
* This includes changing the focus as views are removed or hidden, or as new
* views become available. Views indicate their willingness to take focus
* through the {@link #isFocusable} method. To change whether a view can take
* focus, call {@link #setFocusable(boolean)}. When in touch mode (see notes below)
* views indicate whether they still would like focus via {@link #isFocusableInTouchMode}
* and can change this via {@link #setFocusableInTouchMode(boolean)}.
* </p>
* <p>
* Focus movement is based on an algorithm which finds the nearest neighbor in a
* given direction. In rare cases, the default algorithm may not match the
* intended behavior of the developer. In these situations, you can provide
* explicit overrides by using these XML attributes in the layout file:
* <pre>
* nextFocusDown
* nextFocusLeft
* nextFocusRight
* nextFocusUp
* </pre>
* </p>
*
*
* <p>
* To get a particular view to take focus, call {@link #requestFocus()}.
* </p>
*
* <a name="TouchMode"></a>
* <h3>Touch Mode</h3>
* <p>
* When a user is navigating a user interface via directional keys such as a D-pad, it is
* necessary to give focus to actionable items such as buttons so the user can see
* what will take input. If the device has touch capabilities, however, and the user
* begins interacting with the interface by touching it, it is no longer necessary to
* always highlight, or give focus to, a particular view. This motivates a mode
* for interaction named 'touch mode'.
* </p>
* <p>
* For a touch capable device, once the user touches the screen, the device
* will enter touch mode. From this point onward, only views for which
* {@link #isFocusableInTouchMode} is true will be focusable, such as text editing widgets.
* Other views that are touchable, like buttons, will not take focus when touched; they will
* only fire the on click listeners.
* </p>
* <p>
* Any time a user hits a directional key, such as a D-pad direction, the view device will
* exit touch mode, and find a view to take focus, so that the user may resume interacting
* with the user interface without touching the screen again.
* </p>
* <p>
* The touch mode state is maintained across {@link android.app.Activity}s. Call
* {@link #isInTouchMode} to see whether the device is currently in touch mode.
* </p>
*
* <a name="Scrolling"></a>
* <h3>Scrolling</h3>
* <p>
* The framework provides basic support for views that wish to internally
* scroll their content. This includes keeping track of the X and Y scroll
* offset as well as mechanisms for drawing scrollbars. See
* {@link #scrollBy(int, int)}, {@link #scrollTo(int, int)}, and
* {@link #awakenScrollBars()} for more details.
* </p>
*
* <a name="Tags"></a>
* <h3>Tags</h3>
* <p>
* Unlike IDs, tags are not used to identify views. Tags are essentially an
* extra piece of information that can be associated with a view. They are most
* often used as a convenience to store data related to views in the views
* themselves rather than by putting them in a separate structure.
* </p>
*
* <a name="Properties"></a>
* <h3>Properties</h3>
* <p>
* The View class exposes an {@link #ALPHA} property, as well as several transform-related
* properties, such as {@link #TRANSLATION_X} and {@link #TRANSLATION_Y}. These properties are
* available both in the {@link Property} form as well as in similarly-named setter/getter
* methods (such as {@link #setAlpha(float)} for {@link #ALPHA}). These properties can
* be used to set persistent state associated with these rendering-related properties on the view.
* The properties and methods can also be used in conjunction with
* {@link android.animation.Animator Animator}-based animations, described more in the
* <a href="#Animation">Animation</a> section.
* </p>
*
* <a name="Animation"></a>
* <h3>Animation</h3>
* <p>
* Starting with Android 3.0, the preferred way of animating views is to use the
* {@link android.animation} package APIs. These {@link android.animation.Animator Animator}-based
* classes change actual properties of the View object, such as {@link #setAlpha(float) alpha} and
* {@link #setTranslationX(float) translationX}. This behavior is contrasted to that of the pre-3.0
* {@link android.view.animation.Animation Animation}-based classes, which instead animate only
* how the view is drawn on the display. In particular, the {@link ViewPropertyAnimator} class
* makes animating these View properties particularly easy and efficient.
* </p>
* <p>
* Alternatively, you can use the pre-3.0 animation classes to animate how Views are rendered.
* You can attach an {@link Animation} object to a view using
* {@link #setAnimation(Animation)} or
* {@link #startAnimation(Animation)}. The animation can alter the scale,
* rotation, translation and alpha of a view over time. If the animation is
* attached to a view that has children, the animation will affect the entire
* subtree rooted by that node. When an animation is started, the framework will
* take care of redrawing the appropriate views until the animation completes.
* </p>
*
* <a name="Security"></a>
* <h3>Security</h3>
* <p>
* Sometimes it is essential that an application be able to verify that an action
* is being performed with the full knowledge and consent of the user, such as
* granting a permission request, making a purchase or clicking on an advertisement.
* Unfortunately, a malicious application could try to spoof the user into
* performing these actions, unaware, by concealing the intended purpose of the view.
* As a remedy, the framework offers a touch filtering mechanism that can be used to
* improve the security of views that provide access to sensitive functionality.
* </p><p>
* To enable touch filtering, call {@link #setFilterTouchesWhenObscured(boolean)} or set the
* android:filterTouchesWhenObscured layout attribute to true. When enabled, the framework
* will discard touches that are received whenever the view's window is obscured by
* another visible window. As a result, the view will not receive touches whenever a
* toast, dialog or other window appears above the view's window.
* </p><p>
* For more fine-grained control over security, consider overriding the
* {@link #onFilterTouchEventForSecurity(MotionEvent)} method to implement your own
* security policy. See also {@link MotionEvent#FLAG_WINDOW_IS_OBSCURED}.
* </p>
*
* @attr ref android.R.styleable#View_alpha
* @attr ref android.R.styleable#View_background
* @attr ref android.R.styleable#View_clickable
* @attr ref android.R.styleable#View_contentDescription
* @attr ref android.R.styleable#View_drawingCacheQuality
* @attr ref android.R.styleable#View_duplicateParentState
* @attr ref android.R.styleable#View_id
* @attr ref android.R.styleable#View_requiresFadingEdge
* @attr ref android.R.styleable#View_fadeScrollbars
* @attr ref android.R.styleable#View_fadingEdgeLength
* @attr ref android.R.styleable#View_filterTouchesWhenObscured
* @attr ref android.R.styleable#View_fitsSystemWindows
* @attr ref android.R.styleable#View_isScrollContainer
* @attr ref android.R.styleable#View_focusable
* @attr ref android.R.styleable#View_focusableInTouchMode
* @attr ref android.R.styleable#View_hapticFeedbackEnabled
* @attr ref android.R.styleable#View_keepScreenOn
* @attr ref android.R.styleable#View_layerType
* @attr ref android.R.styleable#View_layoutDirection
* @attr ref android.R.styleable#View_longClickable
* @attr ref android.R.styleable#View_minHeight
* @attr ref android.R.styleable#View_minWidth
* @attr ref android.R.styleable#View_nextFocusDown
* @attr ref android.R.styleable#View_nextFocusLeft
* @attr ref android.R.styleable#View_nextFocusRight
* @attr ref android.R.styleable#View_nextFocusUp
* @attr ref android.R.styleable#View_onClick
* @attr ref android.R.styleable#View_padding
* @attr ref android.R.styleable#View_paddingBottom
* @attr ref android.R.styleable#View_paddingLeft
* @attr ref android.R.styleable#View_paddingRight
* @attr ref android.R.styleable#View_paddingTop
* @attr ref android.R.styleable#View_paddingStart
* @attr ref android.R.styleable#View_paddingEnd
* @attr ref android.R.styleable#View_saveEnabled
* @attr ref android.R.styleable#View_rotation
* @attr ref android.R.styleable#View_rotationX
* @attr ref android.R.styleable#View_rotationY
* @attr ref android.R.styleable#View_scaleX
* @attr ref android.R.styleable#View_scaleY
* @attr ref android.R.styleable#View_scrollX
* @attr ref android.R.styleable#View_scrollY
* @attr ref android.R.styleable#View_scrollbarSize
* @attr ref android.R.styleable#View_scrollbarStyle
* @attr ref android.R.styleable#View_scrollbars
* @attr ref android.R.styleable#View_scrollbarDefaultDelayBeforeFade
* @attr ref android.R.styleable#View_scrollbarFadeDuration
* @attr ref android.R.styleable#View_scrollbarTrackHorizontal
* @attr ref android.R.styleable#View_scrollbarThumbHorizontal
* @attr ref android.R.styleable#View_scrollbarThumbVertical
* @attr ref android.R.styleable#View_scrollbarTrackVertical
* @attr ref android.R.styleable#View_scrollbarAlwaysDrawHorizontalTrack
* @attr ref android.R.styleable#View_scrollbarAlwaysDrawVerticalTrack
* @attr ref android.R.styleable#View_stateListAnimator
* @attr ref android.R.styleable#View_transitionName
* @attr ref android.R.styleable#View_soundEffectsEnabled
* @attr ref android.R.styleable#View_tag
* @attr ref android.R.styleable#View_textAlignment
* @attr ref android.R.styleable#View_textDirection
* @attr ref android.R.styleable#View_transformPivotX
* @attr ref android.R.styleable#View_transformPivotY
* @attr ref android.R.styleable#View_translationX
* @attr ref android.R.styleable#View_translationY
* @attr ref android.R.styleable#View_translationZ
* @attr ref android.R.styleable#View_visibility
*
* @see android.view.ViewGroup
*/
public class View implements Drawable.Callback, KeyEvent.Callback,
AccessibilityEventSource {
private static final boolean DBG = false;
/**
* The logging tag used by this class with android.util.Log.
*/
protected static final String VIEW_LOG_TAG = "View";
/**
* When set to true, apps will draw debugging information about their layouts.
*
* @hide
*/
public static final String DEBUG_LAYOUT_PROPERTY = "debug.layout";
/**
* When set to true, this view will save its attribute data.
*
* @hide
*/
public static boolean mDebugViewAttributes = false;
/**
* 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;
/** @hide */
@IntDef({VISIBLE, INVISIBLE, GONE})
@Retention(RetentionPolicy.SOURCE)
public @interface Visibility {}
/**
* 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;
/** @hide */
@Retention(RetentionPolicy.SOURCE)
@IntDef({DRAWING_CACHE_QUALITY_LOW, DRAWING_CACHE_QUALITY_HIGH, DRAWING_CACHE_QUALITY_AUTO})
public @interface DrawingCacheQuality {}
/**
* <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;
/** @hide */
@IntDef({
SCROLLBARS_INSIDE_OVERLAY,
SCROLLBARS_INSIDE_INSET,
SCROLLBARS_OUTSIDE_OVERLAY,
SCROLLBARS_OUTSIDE_INSET
})
@Retention(RetentionPolicy.SOURCE)
public @interface ScrollBarStyle {}
/**
* 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;
/** @hide */
@IntDef(flag = true,
value = {
FOCUSABLES_ALL,
FOCUSABLES_TOUCH_MODE
})
@Retention(RetentionPolicy.SOURCE)
public @interface FocusableMode {}
/**
* 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;
/** @hide */
@IntDef({
FOCUS_BACKWARD,
FOCUS_FORWARD,
FOCUS_LEFT,
FOCUS_UP,
FOCUS_RIGHT,
FOCUS_DOWN
})
@Retention(RetentionPolicy.SOURCE)
public @interface FocusDirection {}
/** @hide */
@IntDef({
FOCUS_LEFT,
FOCUS_UP,
FOCUS_RIGHT,
FOCUS_DOWN
})
@Retention(RetentionPolicy.SOURCE)
public @interface FocusRealDirection {} // Like @FocusDirection, but without forward/backward
/**
* 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;
/**
* Base View state sets
*/
// Singles
/**
* Indicates the view has no states set. States are used with
* {@link android.graphics.drawable.Drawable} to change the drawing of the
* view depending on its state.
*
* @see android.graphics.drawable.Drawable
* @see #getDrawableState()
*/
protected static final int[] EMPTY_STATE_SET;
/**
* Indicates the view is enabled. States are used with
* {@link android.graphics.drawable.Drawable} to change the drawing of the
* view depending on its state.
*
* @see android.graphics.drawable.Drawable
* @see #getDrawableState()
*/
protected static final int[] ENABLED_STATE_SET;
/**
* Indicates the view is focused. States are used with
* {@link android.graphics.drawable.Drawable} to change the drawing of the
* view depending on its state.
*
* @see android.graphics.drawable.Drawable
* @see #getDrawableState()
*/
protected static final int[] FOCUSED_STATE_SET;
/**
* Indicates the view is selected. States are used with
* {@link android.graphics.drawable.Drawable} to change the drawing of the
* view depending on its state.
*
* @see android.graphics.drawable.Drawable
* @see #getDrawableState()
*/
protected static final int[] SELECTED_STATE_SET;
/**
* Indicates the view is pressed. States are used with
* {@link android.graphics.drawable.Drawable} to change the drawing of the
* view depending on its state.
*
* @see android.graphics.drawable.Drawable
* @see #getDrawableState()
*/
protected static final int[] PRESSED_STATE_SET;
/**
* Indicates the view's window has focus. States are used with
* {@link android.graphics.drawable.Drawable} to change the drawing of the
* view depending on its state.
*
* @see android.graphics.drawable.Drawable
* @see #getDrawableState()
*/
protected static final int[] WINDOW_FOCUSED_STATE_SET;
// Doubles
/**
* Indicates the view is enabled and has the focus.
*
* @see #ENABLED_STATE_SET
* @see #FOCUSED_STATE_SET
*/
protected static final int[] ENABLED_FOCUSED_STATE_SET;
/**
* Indicates the view is enabled and selected.
*
* @see #ENABLED_STATE_SET
* @see #SELECTED_STATE_SET
*/
protected static final int[] ENABLED_SELECTED_STATE_SET;
/**
* Indicates the view is enabled and that its window has focus.
*
* @see #ENABLED_STATE_SET
* @see #WINDOW_FOCUSED_STATE_SET
*/
protected static final int[] ENABLED_WINDOW_FOCUSED_STATE_SET;
/**
* Indicates the view is focused and selected.
*
* @see #FOCUSED_STATE_SET
* @see #SELECTED_STATE_SET
*/
protected static final int[] FOCUSED_SELECTED_STATE_SET;
/**
* Indicates the view has the focus and that its window has the focus.
*
* @see #FOCUSED_STATE_SET
* @see #WINDOW_FOCUSED_STATE_SET
*/
protected static final int[] FOCUSED_WINDOW_FOCUSED_STATE_SET;
/**
* Indicates the view is selected and that its window has the focus.
*
* @see #SELECTED_STATE_SET
* @see #WINDOW_FOCUSED_STATE_SET
*/
protected static final int[] SELECTED_WINDOW_FOCUSED_STATE_SET;
// Triples
/**
* Indicates the view is enabled, focused and selected.
*
* @see #ENABLED_STATE_SET
* @see #FOCUSED_STATE_SET
* @see #SELECTED_STATE_SET
*/
protected static final int[] ENABLED_FOCUSED_SELECTED_STATE_SET;
/**
* Indicates the view is enabled, focused and its window has the focus.
*
* @see #ENABLED_STATE_SET
* @see #FOCUSED_STATE_SET
* @see #WINDOW_FOCUSED_STATE_SET
*/
protected static final int[] ENABLED_FOCUSED_WINDOW_FOCUSED_STATE_SET;
/**
* Indicates the view is enabled, selected and its window has the focus.
*
* @see #ENABLED_STATE_SET
* @see #SELECTED_STATE_SET
* @see #WINDOW_FOCUSED_STATE_SET
*/
protected static final int[] ENABLED_SELECTED_WINDOW_FOCUSED_STATE_SET;
/**
* Indicates the view is focused, selected and its window has the focus.
*
* @see #FOCUSED_STATE_SET
* @see #SELECTED_STATE_SET
* @see #WINDOW_FOCUSED_STATE_SET
*/
protected static final int[] FOCUSED_SELECTED_WINDOW_FOCUSED_STATE_SET;
/**
* Indicates the view is enabled, focused, selected and its window
* has the focus.
*
* @see #ENABLED_STATE_SET
* @see #FOCUSED_STATE_SET
* @see #SELECTED_STATE_SET
* @see #WINDOW_FOCUSED_STATE_SET
*/
protected static final int[] ENABLED_FOCUSED_SELECTED_WINDOW_FOCUSED_STATE_SET;
/**
* Indicates the view is pressed and its window has the focus.
*
* @see #PRESSED_STATE_SET
* @see #WINDOW_FOCUSED_STATE_SET
*/
protected static final int[] PRESSED_WINDOW_FOCUSED_STATE_SET;
/**
* Indicates the view is pressed and selected.
*
* @see #PRESSED_STATE_SET
* @see #SELECTED_STATE_SET
*/
protected static final int[] PRESSED_SELECTED_STATE_SET;
/**
* Indicates the view is pressed, selected and its window has the focus.
*
* @see #PRESSED_STATE_SET
* @see #SELECTED_STATE_SET
* @see #WINDOW_FOCUSED_STATE_SET
*/
protected static final int[] PRESSED_SELECTED_WINDOW_FOCUSED_STATE_SET;
/**
* Indicates the view is pressed and focused.
*
* @see #PRESSED_STATE_SET
* @see #FOCUSED_STATE_SET
*/
protected static final int[] PRESSED_FOCUSED_STATE_SET;
/**
* Indicates the view is pressed, focused and its window has the focus.
*
* @see #PRESSED_STATE_SET
* @see #FOCUSED_STATE_SET
* @see #WINDOW_FOCUSED_STATE_SET
*/
protected static final int[] PRESSED_FOCUSED_WINDOW_FOCUSED_STATE_SET;
/**
* Indicates the view is pressed, focused and selected.
*
* @see #PRESSED_STATE_SET
* @see #SELECTED_STATE_SET
* @see #FOCUSED_STATE_SET
*/
protected static final int[] PRESSED_FOCUSED_SELECTED_STATE_SET;
/**
* Indicates the view is pressed, focused, selected and its window has the focus.
*
* @see #PRESSED_STATE_SET
* @see #FOCUSED_STATE_SET
* @see #SELECTED_STATE_SET
* @see #WINDOW_FOCUSED_STATE_SET
*/
protected static final int[] PRESSED_FOCUSED_SELECTED_WINDOW_FOCUSED_STATE_SET;
/**
* Indicates the view is pressed and enabled.
*
* @see #PRESSED_STATE_SET
* @see #ENABLED_STATE_SET
*/
protected static final int[] PRESSED_ENABLED_STATE_SET;
/**
* Indicates the view is pressed, enabled and its window has the focus.
*
* @see #PRESSED_STATE_SET
* @see #ENABLED_STATE_SET
* @see #WINDOW_FOCUSED_STATE_SET
*/
protected static final int[] PRESSED_ENABLED_WINDOW_FOCUSED_STATE_SET;
/**
* Indicates the view is pressed, enabled and selected.
*
* @see #PRESSED_STATE_SET
* @see #ENABLED_STATE_SET
* @see #SELECTED_STATE_SET
*/
protected static final int[] PRESSED_ENABLED_SELECTED_STATE_SET;
/**
* Indicates the view is pressed, enabled, selected and its window has the
* focus.
*
* @see #PRESSED_STATE_SET
* @see #ENABLED_STATE_SET
* @see #SELECTED_STATE_SET
* @see #WINDOW_FOCUSED_STATE_SET
*/
protected static final int[] PRESSED_ENABLED_SELECTED_WINDOW_FOCUSED_STATE_SET;
/**
* Indicates the view is pressed, enabled and focused.
*
* @see #PRESSED_STATE_SET
* @see #ENABLED_STATE_SET
* @see #FOCUSED_STATE_SET
*/
protected static final int[] PRESSED_ENABLED_FOCUSED_STATE_SET;
/**
* Indicates the view is pressed, enabled, focused and its window has the
* focus.
*
* @see #PRESSED_STATE_SET
* @see #ENABLED_STATE_SET
* @see #FOCUSED_STATE_SET
* @see #WINDOW_FOCUSED_STATE_SET
*/
protected static final int[] PRESSED_ENABLED_FOCUSED_WINDOW_FOCUSED_STATE_SET;
/**
* Indicates the view is pressed, enabled, focused and selected.
*
* @see #PRESSED_STATE_SET
* @see #ENABLED_STATE_SET
* @see #SELECTED_STATE_SET
* @see #FOCUSED_STATE_SET
*/
protected static final int[] PRESSED_ENABLED_FOCUSED_SELECTED_STATE_SET;
/**
* Indicates the view is pressed, enabled, focused, selected and its window
* has the focus.
*
* @see #PRESSED_STATE_SET
* @see #ENABLED_STATE_SET
* @see #SELECTED_STATE_SET
* @see #FOCUSED_STATE_SET
* @see #WINDOW_FOCUSED_STATE_SET
*/
protected static final int[] PRESSED_ENABLED_FOCUSED_SELECTED_WINDOW_FOCUSED_STATE_SET;
/**
* The order here is very important to {@link #getDrawableState()}
*/
private static final int[][] VIEW_STATE_SETS;
static final int VIEW_STATE_WINDOW_FOCUSED = 1;
static final int VIEW_STATE_SELECTED = 1 << 1;
static final int VIEW_STATE_FOCUSED = 1 << 2;
static final int VIEW_STATE_ENABLED = 1 << 3;
static final int VIEW_STATE_PRESSED = 1 << 4;
static final int VIEW_STATE_ACTIVATED = 1 << 5;
static final int VIEW_STATE_ACCELERATED = 1 << 6;
static final int VIEW_STATE_HOVERED = 1 << 7;
static final int VIEW_STATE_DRAG_CAN_ACCEPT = 1 << 8;
static final int VIEW_STATE_DRAG_HOVERED = 1 << 9;
static final int[] VIEW_STATE_IDS = new int[] {
R.attr.state_window_focused, VIEW_STATE_WINDOW_FOCUSED,
R.attr.state_selected, VIEW_STATE_SELECTED,
R.attr.state_focused, VIEW_STATE_FOCUSED,
R.attr.state_enabled, VIEW_STATE_ENABLED,
R.attr.state_pressed, VIEW_STATE_PRESSED,
R.attr.state_activated, VIEW_STATE_ACTIVATED,
R.attr.state_accelerated, VIEW_STATE_ACCELERATED,
R.attr.state_hovered, VIEW_STATE_HOVERED,
R.attr.state_drag_can_accept, VIEW_STATE_DRAG_CAN_ACCEPT,
R.attr.state_drag_hovered, VIEW_STATE_DRAG_HOVERED
};
static {
if ((VIEW_STATE_IDS.length/2) != R.styleable.ViewDrawableStates.length) {
throw new IllegalStateException(
"VIEW_STATE_IDs array length does not match ViewDrawableStates style array");
}
int[] orderedIds = new int[VIEW_STATE_IDS.length];
for (int i = 0; i < R.styleable.ViewDrawableStates.length; i++) {
int viewState = R.styleable.ViewDrawableStates[i];
for (int j = 0; j<VIEW_STATE_IDS.length; j += 2) {
if (VIEW_STATE_IDS[j] == viewState) {
orderedIds[i * 2] = viewState;
orderedIds[i * 2 + 1] = VIEW_STATE_IDS[j + 1];
}
}
}
final int NUM_BITS = VIEW_STATE_IDS.length / 2;
VIEW_STATE_SETS = new int[1 << NUM_BITS][];
for (int i = 0; i < VIEW_STATE_SETS.length; i++) {
int numBits = Integer.bitCount(i);
int[] set = new int[numBits];
int pos = 0;
for (int j = 0; j < orderedIds.length; j += 2) {
if ((i & orderedIds[j+1]) != 0) {
set[pos++] = orderedIds[j];
}
}
VIEW_STATE_SETS[i] = set;
}
EMPTY_STATE_SET = VIEW_STATE_SETS[0];
WINDOW_FOCUSED_STATE_SET = VIEW_STATE_SETS[VIEW_STATE_WINDOW_FOCUSED];
SELECTED_STATE_SET = VIEW_STATE_SETS[VIEW_STATE_SELECTED];
SELECTED_WINDOW_FOCUSED_STATE_SET = VIEW_STATE_SETS[
VIEW_STATE_WINDOW_FOCUSED | VIEW_STATE_SELECTED];
FOCUSED_STATE_SET = VIEW_STATE_SETS[VIEW_STATE_FOCUSED];
FOCUSED_WINDOW_FOCUSED_STATE_SET = VIEW_STATE_SETS[
VIEW_STATE_WINDOW_FOCUSED | VIEW_STATE_FOCUSED];
FOCUSED_SELECTED_STATE_SET = VIEW_STATE_SETS[
VIEW_STATE_SELECTED | VIEW_STATE_FOCUSED];
FOCUSED_SELECTED_WINDOW_FOCUSED_STATE_SET = VIEW_STATE_SETS[
VIEW_STATE_WINDOW_FOCUSED | VIEW_STATE_SELECTED
| VIEW_STATE_FOCUSED];
ENABLED_STATE_SET = VIEW_STATE_SETS[VIEW_STATE_ENABLED];
ENABLED_WINDOW_FOCUSED_STATE_SET = VIEW_STATE_SETS[
VIEW_STATE_WINDOW_FOCUSED | VIEW_STATE_ENABLED];
ENABLED_SELECTED_STATE_SET = VIEW_STATE_SETS[
VIEW_STATE_SELECTED | VIEW_STATE_ENABLED];
ENABLED_SELECTED_WINDOW_FOCUSED_STATE_SET = VIEW_STATE_SETS[
VIEW_STATE_WINDOW_FOCUSED | VIEW_STATE_SELECTED
| VIEW_STATE_ENABLED];
ENABLED_FOCUSED_STATE_SET = VIEW_STATE_SETS[
VIEW_STATE_FOCUSED | VIEW_STATE_ENABLED];
ENABLED_FOCUSED_WINDOW_FOCUSED_STATE_SET = VIEW_STATE_SETS[
VIEW_STATE_WINDOW_FOCUSED | VIEW_STATE_FOCUSED
| VIEW_STATE_ENABLED];
ENABLED_FOCUSED_SELECTED_STATE_SET = VIEW_STATE_SETS[
VIEW_STATE_SELECTED | VIEW_STATE_FOCUSED
| VIEW_STATE_ENABLED];
ENABLED_FOCUSED_SELECTED_WINDOW_FOCUSED_STATE_SET = VIEW_STATE_SETS[
VIEW_STATE_WINDOW_FOCUSED | VIEW_STATE_SELECTED
| VIEW_STATE_FOCUSED| VIEW_STATE_ENABLED];
PRESSED_STATE_SET = VIEW_STATE_SETS[VIEW_STATE_PRESSED];
PRESSED_WINDOW_FOCUSED_STATE_SET = VIEW_STATE_SETS[
VIEW_STATE_WINDOW_FOCUSED | VIEW_STATE_PRESSED];
PRESSED_SELECTED_STATE_SET = VIEW_STATE_SETS[
VIEW_STATE_SELECTED | VIEW_STATE_PRESSED];
PRESSED_SELECTED_WINDOW_FOCUSED_STATE_SET = VIEW_STATE_SETS[
VIEW_STATE_WINDOW_FOCUSED | VIEW_STATE_SELECTED
| VIEW_STATE_PRESSED];
PRESSED_FOCUSED_STATE_SET = VIEW_STATE_SETS[
VIEW_STATE_FOCUSED | VIEW_STATE_PRESSED];
PRESSED_FOCUSED_WINDOW_FOCUSED_STATE_SET = VIEW_STATE_SETS[
VIEW_STATE_WINDOW_FOCUSED | VIEW_STATE_FOCUSED
| VIEW_STATE_PRESSED];
PRESSED_FOCUSED_SELECTED_STATE_SET = VIEW_STATE_SETS[
VIEW_STATE_SELECTED | VIEW_STATE_FOCUSED
| VIEW_STATE_PRESSED];
PRESSED_FOCUSED_SELECTED_WINDOW_FOCUSED_STATE_SET = VIEW_STATE_SETS[
VIEW_STATE_WINDOW_FOCUSED | VIEW_STATE_SELECTED
| VIEW_STATE_FOCUSED | VIEW_STATE_PRESSED];
PRESSED_ENABLED_STATE_SET = VIEW_STATE_SETS[
VIEW_STATE_ENABLED | VIEW_STATE_PRESSED];
PRESSED_ENABLED_WINDOW_FOCUSED_STATE_SET = VIEW_STATE_SETS[
VIEW_STATE_WINDOW_FOCUSED | VIEW_STATE_ENABLED
| VIEW_STATE_PRESSED];
PRESSED_ENABLED_SELECTED_STATE_SET = VIEW_STATE_SETS[
VIEW_STATE_SELECTED | VIEW_STATE_ENABLED
| VIEW_STATE_PRESSED];
PRESSED_ENABLED_SELECTED_WINDOW_FOCUSED_STATE_SET = VIEW_STATE_SETS[
VIEW_STATE_WINDOW_FOCUSED | VIEW_STATE_SELECTED
| VIEW_STATE_ENABLED | VIEW_STATE_PRESSED];
PRESSED_ENABLED_FOCUSED_STATE_SET = VIEW_STATE_SETS[
VIEW_STATE_FOCUSED | VIEW_STATE_ENABLED
| VIEW_STATE_PRESSED];
PRESSED_ENABLED_FOCUSED_WINDOW_FOCUSED_STATE_SET = VIEW_STATE_SETS[
VIEW_STATE_WINDOW_FOCUSED | VIEW_STATE_FOCUSED
| VIEW_STATE_ENABLED | VIEW_STATE_PRESSED];
PRESSED_ENABLED_FOCUSED_SELECTED_STATE_SET = VIEW_STATE_SETS[
VIEW_STATE_SELECTED | VIEW_STATE_FOCUSED
| VIEW_STATE_ENABLED | VIEW_STATE_PRESSED];
PRESSED_ENABLED_FOCUSED_SELECTED_WINDOW_FOCUSED_STATE_SET = VIEW_STATE_SETS[
VIEW_STATE_WINDOW_FOCUSED | VIEW_STATE_SELECTED
| VIEW_STATE_FOCUSED| VIEW_STATE_ENABLED
| VIEW_STATE_PRESSED];
}
/**
* Accessibility event types that are dispatched for text population.
*/
private static final int POPULATING_ACCESSIBILITY_EVENT_TYPES =
AccessibilityEvent.TYPE_VIEW_CLICKED
| AccessibilityEvent.TYPE_VIEW_LONG_CLICKED
| AccessibilityEvent.TYPE_VIEW_SELECTED
| AccessibilityEvent.TYPE_VIEW_FOCUSED
| AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED
| AccessibilityEvent.TYPE_VIEW_HOVER_ENTER
| AccessibilityEvent.TYPE_VIEW_HOVER_EXIT
| AccessibilityEvent.TYPE_VIEW_TEXT_CHANGED
| AccessibilityEvent.TYPE_VIEW_TEXT_SELECTION_CHANGED
| AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED
| AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY;
/**
* Temporary Rect currently for use in setBackground(). This will probably
* be extended in the future to hold our own class with more than just
* a Rect. :)
*/
static final ThreadLocal<Rect> sThreadLocal = new ThreadLocal<Rect>();
/**
* Map used to store views' tags.
*/
private SparseArray<Object> mKeyedTags;
/**
* The next available accessibility id.
*/
private static int sNextAccessibilityViewId;
/**
* The animation currently associated with this view.
* @hide
*/
protected Animation mCurrentAnimation = null;
/**
* Width as measured during measure pass.
* {@hide}
*/
@ViewDebug.ExportedProperty(category = "measurement")
int mMeasuredWidth;
/**
* Height as measured during measure pass.
* {@hide}
*/
@ViewDebug.ExportedProperty(category = "measurement")
int mMeasuredHeight;
/**
* Flag to indicate that this view was marked INVALIDATED, or had its display list
* invalidated, prior to the current drawing iteration. If true, the view must re-draw
* its display list. This flag, used only when hw accelerated, allows us to clear the
* flag while retaining this information until it's needed (at getDisplayList() time and
* in drawChild(), when we decide to draw a view's children's display lists into our own).
*
* {@hide}
*/
boolean mRecreateDisplayList = false;
/**
* The view's identifier.
* {@hide}
*
* @see #setId(int)
* @see #getId()
*/
@ViewDebug.ExportedProperty(resolveId = true)
int mID = NO_ID;
/**
* The stable ID of this view for accessibility purposes.
*/
int mAccessibilityViewId = NO_ID;
private int mAccessibilityCursorPosition = ACCESSIBILITY_CURSOR_POSITION_UNDEFINED;
SendViewStateChangedAccessibilityEvent mSendViewStateChangedAccessibilityEvent;
/**
* The view's tag.
* {@hide}
*
* @see #setTag(Object)
* @see #getTag()
*/
protected Object mTag = null;
// for mPrivateFlags:
/** {@hide} */
static final int PFLAG_WANTS_FOCUS = 0x00000001;
/** {@hide} */
static final int PFLAG_FOCUSED = 0x00000002;
/** {@hide} */
static final int PFLAG_SELECTED = 0x00000004;
/** {@hide} */
static final int PFLAG_IS_ROOT_NAMESPACE = 0x00000008;
/** {@hide} */
static final int PFLAG_HAS_BOUNDS = 0x00000010;
/** {@hide} */
static final int PFLAG_DRAWN = 0x00000020;
/**
* When this flag is set, this view is running an animation on behalf of its
* children and should therefore not cancel invalidate requests, even if they
* lie outside of this view's bounds.
*
* {@hide}
*/
static final int PFLAG_DRAW_ANIMATION = 0x00000040;
/** {@hide} */
static final int PFLAG_SKIP_DRAW = 0x00000080;
/** {@hide} */
static final int PFLAG_ONLY_DRAWS_BACKGROUND = 0x00000100;
/** {@hide} */
static final int PFLAG_REQUEST_TRANSPARENT_REGIONS = 0x00000200;
/** {@hide} */
static final int PFLAG_DRAWABLE_STATE_DIRTY = 0x00000400;
/** {@hide} */
static final int PFLAG_MEASURED_DIMENSION_SET = 0x00000800;
/** {@hide} */
static final int PFLAG_FORCE_LAYOUT = 0x00001000;
/** {@hide} */
static final int PFLAG_LAYOUT_REQUIRED = 0x00002000;
private static final int PFLAG_PRESSED = 0x00004000;
/** {@hide} */
static final int PFLAG_DRAWING_CACHE_VALID = 0x00008000;
/**
* Flag used to indicate that this view should be drawn once more (and only once
* more) after its animation has completed.
* {@hide}
*/
static final int PFLAG_ANIMATION_STARTED = 0x00010000;
private static final int PFLAG_SAVE_STATE_CALLED = 0x00020000;
/**
* Indicates that the View returned true when onSetAlpha() was called and that
* the alpha must be restored.
* {@hide}
*/
static final int PFLAG_ALPHA_SET = 0x00040000;
/**
* Set by {@link #setScrollContainer(boolean)}.
*/
static final int PFLAG_SCROLL_CONTAINER = 0x00080000;
/**
* Set by {@link #setScrollContainer(boolean)}.
*/
static final int PFLAG_SCROLL_CONTAINER_ADDED = 0x00100000;
/**
* View flag indicating whether this view was invalidated (fully or partially.)
*
* @hide
*/
static final int PFLAG_DIRTY = 0x00200000;
/**
* View flag indicating whether this view was invalidated by an opaque
* invalidate request.
*
* @hide
*/
static final int PFLAG_DIRTY_OPAQUE = 0x00400000;
/**
* Mask for {@link #PFLAG_DIRTY} and {@link #PFLAG_DIRTY_OPAQUE}.
*
* @hide
*/
static final int PFLAG_DIRTY_MASK = 0x00600000;
/**
* Indicates whether the background is opaque.
*
* @hide
*/
static final int PFLAG_OPAQUE_BACKGROUND = 0x00800000;
/**
* Indicates whether the scrollbars are opaque.
*
* @hide
*/
static final int PFLAG_OPAQUE_SCROLLBARS = 0x01000000;
/**
* Indicates whether the view is opaque.
*
* @hide
*/
static final int PFLAG_OPAQUE_MASK = 0x01800000;
/**
* Indicates a prepressed state;
* the short time between ACTION_DOWN and recognizing
* a 'real' press. Prepressed is used to recognize quick taps
* even when they are shorter than ViewConfiguration.getTapTimeout().
*
* @hide
*/
private static final int PFLAG_PREPRESSED = 0x02000000;
/**
* Indicates whether the view is temporarily detached.
*
* @hide
*/
static final int PFLAG_CANCEL_NEXT_UP_EVENT = 0x04000000;
/**
* Indicates that we should awaken scroll bars once attached
*
* @hide
*/
private static final int PFLAG_AWAKEN_SCROLL_BARS_ON_ATTACH = 0x08000000;
/**
* Indicates that the view has received HOVER_ENTER. Cleared on HOVER_EXIT.
* @hide
*/
private static final int PFLAG_HOVERED = 0x10000000;
/**
* no longer needed, should be reused
*/
private static final int PFLAG_DOES_NOTHING_REUSE_PLEASE = 0x20000000;
/** {@hide} */
static final int PFLAG_ACTIVATED = 0x40000000;
/**
* Indicates that this view was specifically invalidated, not just dirtied because some
* child view was invalidated. The flag is used to determine when we need to recreate
* a view's display list (as opposed to just returning a reference to its existing
* display list).
*
* @hide
*/
static final int PFLAG_INVALIDATED = 0x80000000;
/**
* Masks for mPrivateFlags2, as generated by dumpFlags():
*
* |-------|-------|-------|-------|
* 1 PFLAG2_DRAG_CAN_ACCEPT
* 1 PFLAG2_DRAG_HOVERED
* 11 PFLAG2_LAYOUT_DIRECTION_MASK
* 1 PFLAG2_LAYOUT_DIRECTION_RESOLVED_RTL
* 1 PFLAG2_LAYOUT_DIRECTION_RESOLVED
* 11 PFLAG2_LAYOUT_DIRECTION_RESOLVED_MASK
* 1 PFLAG2_TEXT_DIRECTION_FLAGS[1]
* 1 PFLAG2_TEXT_DIRECTION_FLAGS[2]
* 11 PFLAG2_TEXT_DIRECTION_FLAGS[3]
* 1 PFLAG2_TEXT_DIRECTION_FLAGS[4]
* 1 1 PFLAG2_TEXT_DIRECTION_FLAGS[5]
* 111 PFLAG2_TEXT_DIRECTION_MASK
* 1 PFLAG2_TEXT_DIRECTION_RESOLVED
* 1 PFLAG2_TEXT_DIRECTION_RESOLVED_DEFAULT
* 111 PFLAG2_TEXT_DIRECTION_RESOLVED_MASK
* 1 PFLAG2_TEXT_ALIGNMENT_FLAGS[1]
* 1 PFLAG2_TEXT_ALIGNMENT_FLAGS[2]
* 11 PFLAG2_TEXT_ALIGNMENT_FLAGS[3]
* 1 PFLAG2_TEXT_ALIGNMENT_FLAGS[4]
* 1 1 PFLAG2_TEXT_ALIGNMENT_FLAGS[5]
* 11 PFLAG2_TEXT_ALIGNMENT_FLAGS[6]
* 111 PFLAG2_TEXT_ALIGNMENT_MASK
* 1 PFLAG2_TEXT_ALIGNMENT_RESOLVED
* 1 PFLAG2_TEXT_ALIGNMENT_RESOLVED_DEFAULT
* 111 PFLAG2_TEXT_ALIGNMENT_RESOLVED_MASK
* 111 PFLAG2_IMPORTANT_FOR_ACCESSIBILITY_MASK
* 11 PFLAG2_ACCESSIBILITY_LIVE_REGION_MASK
* 1 PFLAG2_ACCESSIBILITY_FOCUSED
* 1 PFLAG2_SUBTREE_ACCESSIBILITY_STATE_CHANGED
* 1 PFLAG2_VIEW_QUICK_REJECTED
* 1 PFLAG2_PADDING_RESOLVED
* 1 PFLAG2_DRAWABLE_RESOLVED
* 1 PFLAG2_HAS_TRANSIENT_STATE
* |-------|-------|-------|-------|
*/
/**
* 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;
/** @hide */
@IntDef({
LAYOUT_DIRECTION_LTR,
LAYOUT_DIRECTION_RTL,
LAYOUT_DIRECTION_INHERIT,
LAYOUT_DIRECTION_LOCALE
})
@Retention(RetentionPolicy.SOURCE)
// Not called LayoutDirection to avoid conflict with android.util.LayoutDirection
public @interface LayoutDir {}
/** @hide */
@IntDef({
LAYOUT_DIRECTION_LTR,
LAYOUT_DIRECTION_RTL
})
@Retention(RetentionPolicy.SOURCE)
public @interface ResolvedLayoutDir {}
/**
* 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;
/*
* Array of horizontal layout direction flags for mapping attribute "layoutDirection" to correct
* flag value.
* @hide
*/
private static final int[] LAYOUT_DIRECTION_FLAGS = {
LAYOUT_DIRECTION_LTR,
LAYOUT_DIRECTION_RTL,
LAYOUT_DIRECTION_INHERIT,
LAYOUT_DIRECTION_LOCALE
};
/**
* Default horizontal layout direction.
*/
private static final int LAYOUT_DIRECTION_DEFAULT = LAYOUT_DIRECTION_INHERIT;
/**
* Default horizontal layout direction.
* @hide
*/
static final int LAYOUT_DIRECTION_RESOLVED_DEFAULT = LAYOUT_DIRECTION_LTR;
/**
* Text direction is inherited thru {@link ViewGroup}
*/
public static final int TEXT_DIRECTION_INHERIT = 0;
/**
* Text direction is using "first strong algorithm". The first strong directional character
* determines the paragraph direction. If there is no strong directional character, the
* paragraph direction is the view's resolved layout direction.
*/
public static final int TEXT_DIRECTION_FIRST_STRONG = 1;
/**
* Text direction is using "any-RTL" algorithm. The paragraph direction is RTL if it contains
* any strong RTL character, otherwise it is LTR if it contains any strong LTR characters.
* If there are neither, the paragraph direction is the view's resolved layout direction.
*/
public static final int TEXT_DIRECTION_ANY_RTL = 2;
/**
* Text direction is forced to LTR.
*/
public static final int TEXT_DIRECTION_LTR = 3;
/**
* Text direction is forced to RTL.
*/
public static final int TEXT_DIRECTION_RTL = 4;
/**
* Text direction is coming from the system Locale.
*/
public static final int TEXT_DIRECTION_LOCALE = 5;
/**
* Default text direction is inherited
*/
private static final int TEXT_DIRECTION_DEFAULT = TEXT_DIRECTION_INHERIT;
/**
* Default resolved text direction
* @hide
*/
static final int TEXT_DIRECTION_RESOLVED_DEFAULT = TEXT_DIRECTION_FIRST_STRONG;
/**
* Bit shift to get the horizontal layout direction. (bits after LAYOUT_DIRECTION_RESOLVED)
* @hide
*/
static final int PFLAG2_TEXT_DIRECTION_MASK_SHIFT = 6;
/**
* Mask for use with private flags indicating bits used for text direction.
* @hide
*/
static final int PFLAG2_TEXT_DIRECTION_MASK = 0x00000007
<< PFLAG2_TEXT_DIRECTION_MASK_SHIFT;
/**
* Array of text direction flags for mapping attribute "textDirection" to correct
* flag value.
* @hide
*/
private static final int[] PFLAG2_TEXT_DIRECTION_FLAGS = {
TEXT_DIRECTION_INHERIT << PFLAG2_TEXT_DIRECTION_MASK_SHIFT,
TEXT_DIRECTION_FIRST_STRONG << PFLAG2_TEXT_DIRECTION_MASK_SHIFT,
TEXT_DIRECTION_ANY_RTL << PFLAG2_TEXT_DIRECTION_MASK_SHIFT,
TEXT_DIRECTION_LTR << PFLAG2_TEXT_DIRECTION_MASK_SHIFT,
TEXT_DIRECTION_RTL << PFLAG2_TEXT_DIRECTION_MASK_SHIFT,
TEXT_DIRECTION_LOCALE << PFLAG2_TEXT_DIRECTION_MASK_SHIFT
};
/**
* Indicates whether the view text direction has been resolved.
* @hide
*/
static final int PFLAG2_TEXT_DIRECTION_RESOLVED = 0x00000008
<< PFLAG2_TEXT_DIRECTION_MASK_SHIFT;
/**
* Bit shift to get the horizontal layout direction. (bits after DRAG_HOVERED)
* @hide
*/
static final int PFLAG2_TEXT_DIRECTION_RESOLVED_MASK_SHIFT = 10;
/**
* Mask for use with private flags indicating bits used for resolved text direction.
* @hide
*/
static final int PFLAG2_TEXT_DIRECTION_RESOLVED_MASK = 0x00000007
<< PFLAG2_TEXT_DIRECTION_RESOLVED_MASK_SHIFT;
/**
* Indicates whether the view text direction has been resolved to the "first strong" heuristic.
* @hide
*/
static final int PFLAG2_TEXT_DIRECTION_RESOLVED_DEFAULT =
TEXT_DIRECTION_RESOLVED_DEFAULT << PFLAG2_TEXT_DIRECTION_RESOLVED_MASK_SHIFT;
/** @hide */
@IntDef({
TEXT_ALIGNMENT_INHERIT,
TEXT_ALIGNMENT_GRAVITY,
TEXT_ALIGNMENT_CENTER,
TEXT_ALIGNMENT_TEXT_START,
TEXT_ALIGNMENT_TEXT_END,
TEXT_ALIGNMENT_VIEW_START,
TEXT_ALIGNMENT_VIEW_END
})
@Retention(RetentionPolicy.SOURCE)
public @interface TextAlignment {}
/**
* Default text alignment. The text alignment of this View is inherited from its parent.
* Use with {@link #setTextAlignment(int)}
*/
public static final int TEXT_ALIGNMENT_INHERIT = 0;
/**
* Default for the root view. The gravity determines the text alignment, ALIGN_NORMAL,
* ALIGN_CENTER, or ALIGN_OPPOSITE, which are relative to each paragraphâ |