19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/*
29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2006 The Android Open Source Project
39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License.
69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at
79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and
149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License.
159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage android.view;
189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1921cd1389d2ef218b20994b617c57af120841a57fChet Haaseimport android.animation.LayoutTransition;
209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.Context;
21e36d6e277e49475076b7872d36ea6a5c5b996e9dDianne Hackbornimport android.content.res.Configuration;
229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.res.TypedArray;
239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.graphics.Bitmap;
249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.graphics.Canvas;
2510ca24a97cefc14fca1b26f59e627f487b3b108bPhilip Milneimport android.graphics.Color;
2610ca24a97cefc14fca1b26f59e627f487b3b108bPhilip Milneimport android.graphics.Insets;
276e34636749217654f43221885afb7a29bb5ca96aAdam Powellimport android.graphics.Matrix;
289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.graphics.Paint;
29a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tateimport android.graphics.PointF;
309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.graphics.Rect;
319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.graphics.RectF;
3275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganovimport android.graphics.Region;
33995e77431982f9a320451dbe6132a62e69f73babJeff Brownimport android.os.Build;
349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Parcelable;
359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.SystemClock;
369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.AttributeSet;
379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.Log;
38be922dc976b1ce1735dcc0cf49509a2149766c96Svetoslav Ganovimport android.util.Pools.SynchronizedPool;
399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.SparseArray;
4075986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganovimport android.view.accessibility.AccessibilityEvent;
4177e9a28e2faa36f127231b842476d47f9823a83aAlan Viveretteimport android.view.accessibility.AccessibilityManager;
428643aa0179e598e78d938c59035389054535a229Svetoslav Ganovimport android.view.accessibility.AccessibilityNodeInfo;
439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.animation.Animation;
449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.animation.AnimationUtils;
459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.animation.LayoutAnimationController;
469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.animation.Transformation;
47cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt
480211a0a10d20ec99bd78905ea9cd2960f7beb4c8Romain Guyimport com.android.internal.R;
490211a0a10d20ec99bd78905ea9cd2960f7beb4c8Romain Guyimport com.android.internal.util.Predicate;
509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.ArrayList;
524213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganovimport java.util.Collections;
5386cab1bd52197d6fa60786413fad9788d9236762Christopher Tateimport java.util.HashSet;
549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
550072f64939b37a4d84940656c2180ad2e0594ff4Fabrice Di Meglioimport static android.os.Build.VERSION_CODES.JELLY_BEAN_MR1;
560072f64939b37a4d84940656c2180ad2e0594ff4Fabrice Di Meglio
579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/**
589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>
599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * A <code>ViewGroup</code> is a special view that can contain other views
609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * (called children.) The view group is the base class for layouts and views
619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * containers. This class also defines the
629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link android.view.ViewGroup.LayoutParams} class which serves as the base
639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * class for layouts parameters.
649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </p>
659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>
679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Also see {@link LayoutParams} for layout attributes.
689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </p>
69d6a463a9f23b3901bf729f2f27a6bb8f78b95248Romain Guy *
70558459fe85f56f29a6ed6a4d0adb4a0bd6665884Joe Fernandez * <div class="special reference">
71558459fe85f56f29a6ed6a4d0adb4a0bd6665884Joe Fernandez * <h3>Developer Guides</h3>
72558459fe85f56f29a6ed6a4d0adb4a0bd6665884Joe Fernandez * <p>For more information about creating user interface layouts, read the
73558459fe85f56f29a6ed6a4d0adb4a0bd6665884Joe Fernandez * <a href="{@docRoot}guide/topics/ui/declaring-layout.html">XML Layouts</a> developer
74558459fe85f56f29a6ed6a4d0adb4a0bd6665884Joe Fernandez * guide.</p></div>
75558459fe85f56f29a6ed6a4d0adb4a0bd6665884Joe Fernandez *
767caab0ff2d4a09a1aa5f5c1d8479c386584cc26eDianne Hackborn * <p>Here is a complete implementation of a custom ViewGroup that implements
777caab0ff2d4a09a1aa5f5c1d8479c386584cc26eDianne Hackborn * a simple {@link android.widget.FrameLayout} along with the ability to stack
787caab0ff2d4a09a1aa5f5c1d8479c386584cc26eDianne Hackborn * children in left and right gutters.</p>
797caab0ff2d4a09a1aa5f5c1d8479c386584cc26eDianne Hackborn *
807caab0ff2d4a09a1aa5f5c1d8479c386584cc26eDianne Hackborn * {@sample development/samples/ApiDemos/src/com/example/android/apis/view/CustomLayout.java
817caab0ff2d4a09a1aa5f5c1d8479c386584cc26eDianne Hackborn *      Complete}
827caab0ff2d4a09a1aa5f5c1d8479c386584cc26eDianne Hackborn *
837caab0ff2d4a09a1aa5f5c1d8479c386584cc26eDianne Hackborn * <p>If you are implementing XML layout attributes as shown in the example, this is the
847caab0ff2d4a09a1aa5f5c1d8479c386584cc26eDianne Hackborn * corresponding definition for them that would go in <code>res/values/attrs.xml</code>:</p>
857caab0ff2d4a09a1aa5f5c1d8479c386584cc26eDianne Hackborn *
867caab0ff2d4a09a1aa5f5c1d8479c386584cc26eDianne Hackborn * {@sample development/samples/ApiDemos/res/values/attrs.xml CustomLayout}
877caab0ff2d4a09a1aa5f5c1d8479c386584cc26eDianne Hackborn *
887caab0ff2d4a09a1aa5f5c1d8479c386584cc26eDianne Hackborn * <p>Finally the layout manager can be used in an XML layout like so:</p>
897caab0ff2d4a09a1aa5f5c1d8479c386584cc26eDianne Hackborn *
907caab0ff2d4a09a1aa5f5c1d8479c386584cc26eDianne Hackborn * {@sample development/samples/ApiDemos/res/layout/custom_layout.xml Complete}
917caab0ff2d4a09a1aa5f5c1d8479c386584cc26eDianne Hackborn *
92d6a463a9f23b3901bf729f2f27a6bb8f78b95248Romain Guy * @attr ref android.R.styleable#ViewGroup_clipChildren
93d6a463a9f23b3901bf729f2f27a6bb8f78b95248Romain Guy * @attr ref android.R.styleable#ViewGroup_clipToPadding
94d6a463a9f23b3901bf729f2f27a6bb8f78b95248Romain Guy * @attr ref android.R.styleable#ViewGroup_layoutAnimation
95d6a463a9f23b3901bf729f2f27a6bb8f78b95248Romain Guy * @attr ref android.R.styleable#ViewGroup_animationCache
96d6a463a9f23b3901bf729f2f27a6bb8f78b95248Romain Guy * @attr ref android.R.styleable#ViewGroup_persistentDrawingCache
97d6a463a9f23b3901bf729f2f27a6bb8f78b95248Romain Guy * @attr ref android.R.styleable#ViewGroup_alwaysDrawnWithCache
98d6a463a9f23b3901bf729f2f27a6bb8f78b95248Romain Guy * @attr ref android.R.styleable#ViewGroup_addStatesFromChildren
99d6a463a9f23b3901bf729f2f27a6bb8f78b95248Romain Guy * @attr ref android.R.styleable#ViewGroup_descendantFocusability
10013cc1207fab68adc5c7da0bf3b365196e26a273eChet Haase * @attr ref android.R.styleable#ViewGroup_animateLayoutChanges
10127a8508ee1236ded652cd452b93884a9193654fcScott Main * @attr ref android.R.styleable#ViewGroup_splitMotionEvents
10227a8508ee1236ded652cd452b93884a9193654fcScott Main * @attr ref android.R.styleable#ViewGroup_layoutMode
1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic abstract class ViewGroup extends View implements ViewParent, ViewManager {
105539ee8716b4f81260bab2e9f3dc5d88d81c99985Adam Powell    private static final String TAG = "ViewGroup";
10621cd1389d2ef218b20994b617c57af120841a57fChet Haase
1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static final boolean DBG = false;
1087b7578184567f4e4f0740ce935cc192765410ccaPhilip Milne    /** @hide */
1097b7578184567f4e4f0740ce935cc192765410ccaPhilip Milne    public static boolean DEBUG_DRAW = false;
110cea45132e3d5d32a6fc737abf10b8893a50f465bGilles Debunne
1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Views which have been hidden or removed which need to be animated on
1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * their way out.
1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * This field should be made private, so it is hidden from the SDK.
1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@hide}
1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected ArrayList<View> mDisappearingChildren;
1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Listener used to propagate events indicating when children are added
1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * and/or removed from a view group.
1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * This field should be made private, so it is hidden from the SDK.
1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@hide}
1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected OnHierarchyChangeListener mOnHierarchyChangeListener;
1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // The view contained within this ViewGroup that has or contains focus.
1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private View mFocused;
1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1304846032ac7be7c28c7cfeb3096b8cb656312a382Chet Haase    /**
1314846032ac7be7c28c7cfeb3096b8cb656312a382Chet Haase     * A Transformation used when drawing children, to
1324846032ac7be7c28c7cfeb3096b8cb656312a382Chet Haase     * apply on the child being drawn.
1334846032ac7be7c28c7cfeb3096b8cb656312a382Chet Haase     */
134f69913056b8c6000ff0306573a97971702e8d35aRomain Guy    private Transformation mChildTransformation;
1354846032ac7be7c28c7cfeb3096b8cb656312a382Chet Haase
1364846032ac7be7c28c7cfeb3096b8cb656312a382Chet Haase    /**
1374846032ac7be7c28c7cfeb3096b8cb656312a382Chet Haase     * Used to track the current invalidation region.
1384846032ac7be7c28c7cfeb3096b8cb656312a382Chet Haase     */
13964a48c1d3daca9e0565f2aa4d56f6e94ea073d9bChet Haase    RectF mInvalidateRegion;
1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1414846032ac7be7c28c7cfeb3096b8cb656312a382Chet Haase    /**
1424846032ac7be7c28c7cfeb3096b8cb656312a382Chet Haase     * A Transformation used to calculate a correct
1434846032ac7be7c28c7cfeb3096b8cb656312a382Chet Haase     * invalidation area when the application is autoscaled.
1444846032ac7be7c28c7cfeb3096b8cb656312a382Chet Haase     */
14564a48c1d3daca9e0565f2aa4d56f6e94ea073d9bChet Haase    Transformation mInvalidationTransformation;
1464846032ac7be7c28c7cfeb3096b8cb656312a382Chet Haase
147a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate    // View currently under an ongoing drag
148a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate    private View mCurrentDragView;
149a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate
15086cab1bd52197d6fa60786413fad9788d9236762Christopher Tate    // Metadata about the ongoing drag
15186cab1bd52197d6fa60786413fad9788d9236762Christopher Tate    private DragEvent mCurrentDrag;
15286cab1bd52197d6fa60786413fad9788d9236762Christopher Tate    private HashSet<View> mDragNotifiedChildren;
15386cab1bd52197d6fa60786413fad9788d9236762Christopher Tate
154a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate    // Does this group have a child that can accept the current drag payload?
155a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate    private boolean mChildAcceptsDrag;
156a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate
157a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate    // Used during drag dispatch
1586410c0aaf13c9aec606b90ee942f2ac2d98b1609Romain Guy    private PointF mLocalPoint;
159a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate
1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // Layout animation
1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private LayoutAnimationController mLayoutAnimationController;
1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private Animation.AnimationListener mAnimationListener;
1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
16420e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown    // First touch target in the linked list of touch targets.
16520e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown    private TouchTarget mFirstTouchTarget;
16620e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown
16703ab0c7231a5c534b86eca28d875c6026ae09564Joe Onorato    // For debugging only.  You can see these in hierarchyviewer.
168e95003e4a15eea2d5f93950fc46f99ff2b9c973aRomain Guy    @SuppressWarnings({"FieldCanBeLocal", "UnusedDeclaration"})
16903ab0c7231a5c534b86eca28d875c6026ae09564Joe Onorato    @ViewDebug.ExportedProperty(category = "events")
17003ab0c7231a5c534b86eca28d875c6026ae09564Joe Onorato    private long mLastTouchDownTime;
17103ab0c7231a5c534b86eca28d875c6026ae09564Joe Onorato    @ViewDebug.ExportedProperty(category = "events")
17203ab0c7231a5c534b86eca28d875c6026ae09564Joe Onorato    private int mLastTouchDownIndex = -1;
173e95003e4a15eea2d5f93950fc46f99ff2b9c973aRomain Guy    @SuppressWarnings({"FieldCanBeLocal", "UnusedDeclaration"})
17403ab0c7231a5c534b86eca28d875c6026ae09564Joe Onorato    @ViewDebug.ExportedProperty(category = "events")
17503ab0c7231a5c534b86eca28d875c6026ae09564Joe Onorato    private float mLastTouchDownX;
176e95003e4a15eea2d5f93950fc46f99ff2b9c973aRomain Guy    @SuppressWarnings({"FieldCanBeLocal", "UnusedDeclaration"})
17703ab0c7231a5c534b86eca28d875c6026ae09564Joe Onorato    @ViewDebug.ExportedProperty(category = "events")
17803ab0c7231a5c534b86eca28d875c6026ae09564Joe Onorato    private float mLastTouchDownY;
17903ab0c7231a5c534b86eca28d875c6026ae09564Joe Onorato
18087b7f805b94f5df53343264509f6d606d96dfb05Jeff Brown    // First hover target in the linked list of hover targets.
18187b7f805b94f5df53343264509f6d606d96dfb05Jeff Brown    // The hover targets are children which have received ACTION_HOVER_ENTER.
18287b7f805b94f5df53343264509f6d606d96dfb05Jeff Brown    // They might not have actually handled the hover event, but we will
18387b7f805b94f5df53343264509f6d606d96dfb05Jeff Brown    // continue sending hover events to them as long as the pointer remains over
18487b7f805b94f5df53343264509f6d606d96dfb05Jeff Brown    // their bounds and the view group does not intercept hover.
18587b7f805b94f5df53343264509f6d606d96dfb05Jeff Brown    private HoverTarget mFirstHoverTarget;
186a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown
18710b6290c5f15ae512a2f6b5bf8d95bd2527c7235Jeff Brown    // True if the view group itself received a hover event.
18810b6290c5f15ae512a2f6b5bf8d95bd2527c7235Jeff Brown    // It might not have actually handled the hover event.
18910b6290c5f15ae512a2f6b5bf8d95bd2527c7235Jeff Brown    private boolean mHoveredSelf;
19010b6290c5f15ae512a2f6b5bf8d95bd2527c7235Jeff Brown
1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Internal flags.
1938506ab4ac062d0e1ccde136e5e2f4081560e0c11Romain Guy     *
1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * This field should be made private, so it is hidden from the SDK.
1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@hide}
1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1972440e670de0294bdf64592849613db9b8f00ee11Romain Guy    @ViewDebug.ExportedProperty(flagMapping = {
1982440e670de0294bdf64592849613db9b8f00ee11Romain Guy            @ViewDebug.FlagToString(mask = FLAG_CLIP_CHILDREN, equals = FLAG_CLIP_CHILDREN,
1992440e670de0294bdf64592849613db9b8f00ee11Romain Guy                    name = "CLIP_CHILDREN"),
2002440e670de0294bdf64592849613db9b8f00ee11Romain Guy            @ViewDebug.FlagToString(mask = FLAG_CLIP_TO_PADDING, equals = FLAG_CLIP_TO_PADDING,
2012440e670de0294bdf64592849613db9b8f00ee11Romain Guy                    name = "CLIP_TO_PADDING"),
2022440e670de0294bdf64592849613db9b8f00ee11Romain Guy            @ViewDebug.FlagToString(mask = FLAG_PADDING_NOT_NULL, equals = FLAG_PADDING_NOT_NULL,
2032440e670de0294bdf64592849613db9b8f00ee11Romain Guy                    name = "PADDING_NOT_NULL")
2042440e670de0294bdf64592849613db9b8f00ee11Romain Guy    })
2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected int mGroupFlags;
2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2077b7578184567f4e4f0740ce935cc192765410ccaPhilip Milne    /**
2087b7578184567f4e4f0740ce935cc192765410ccaPhilip Milne     * Either {@link #LAYOUT_MODE_CLIP_BOUNDS} or {@link #LAYOUT_MODE_OPTICAL_BOUNDS}.
2091557fd7809078e421f751efc7d2539b3efdc54b2Philip Milne     */
210cfb631b0e56b7c6b9ca11e1a0553b7896b64b1c1Philip Milne    private int mLayoutMode = LAYOUT_MODE_UNDEFINED;
2111557fd7809078e421f751efc7d2539b3efdc54b2Philip Milne
21233f6beb10f98e8ba96250e284876d607055d278dRomain Guy    /**
21333f6beb10f98e8ba96250e284876d607055d278dRomain Guy     * NOTE: If you change the flags below make sure to reflect the changes
21433f6beb10f98e8ba96250e284876d607055d278dRomain Guy     *       the DisplayList class
21533f6beb10f98e8ba96250e284876d607055d278dRomain Guy     */
21633f6beb10f98e8ba96250e284876d607055d278dRomain Guy
2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // When set, ViewGroup invalidates only the child's rectangle
2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // Set by default
21964a48c1d3daca9e0565f2aa4d56f6e94ea073d9bChet Haase    static final int FLAG_CLIP_CHILDREN = 0x1;
2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // When set, ViewGroup excludes the padding area from the invalidate rectangle
2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // Set by default
2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static final int FLAG_CLIP_TO_PADDING = 0x2;
2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // When set, dispatchDraw() will invoke invalidate(); this is set by drawChild() when
2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // a child needs to be invalidated and FLAG_OPTIMIZE_INVALIDATE is set
22764a48c1d3daca9e0565f2aa4d56f6e94ea073d9bChet Haase    static final int FLAG_INVALIDATE_REQUIRED  = 0x4;
2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // When set, dispatchDraw() will run the layout animation and unset the flag
2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static final int FLAG_RUN_ANIMATION = 0x8;
2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // When set, there is either no layout animation on the ViewGroup or the layout
2339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // animation is over
2349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // Set by default
23564a48c1d3daca9e0565f2aa4d56f6e94ea073d9bChet Haase    static final int FLAG_ANIMATION_DONE = 0x10;
2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // If set, this ViewGroup has padding; if unset there is no padding and we don't need
2389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // to clip it, even if FLAG_CLIP_TO_PADDING is set
2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static final int FLAG_PADDING_NOT_NULL = 0x20;
2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // When set, this ViewGroup caches its children in a Bitmap before starting a layout animation
2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // Set by default
2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static final int FLAG_ANIMATION_CACHE = 0x40;
2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // When set, this ViewGroup converts calls to invalidate(Rect) to invalidate() during a
2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // layout animation; this avoid clobbering the hierarchy
2479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // Automatically set when the layout animation starts, depending on the animation's
2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // characteristics
24964a48c1d3daca9e0565f2aa4d56f6e94ea073d9bChet Haase    static final int FLAG_OPTIMIZE_INVALIDATE = 0x80;
2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // When set, the next call to drawChild() will clear mChildTransformation's matrix
25264a48c1d3daca9e0565f2aa4d56f6e94ea073d9bChet Haase    static final int FLAG_CLEAR_TRANSFORMATION = 0x100;
2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // When set, this ViewGroup invokes mAnimationListener.onAnimationEnd() and removes
2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // the children's Bitmap caches if necessary
2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // This flag is set when the layout animation is over (after FLAG_ANIMATION_DONE is set)
2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static final int FLAG_NOTIFY_ANIMATION_LISTENER = 0x200;
2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * When set, the drawing method will call {@link #getChildDrawingOrder(int, int)}
2619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * to get the index of the child to draw for that iteration.
262293451e4f005a26386db873f5192f86585cc79bcRomain Guy     *
263293451e4f005a26386db873f5192f86585cc79bcRomain Guy     * @hide
2649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected static final int FLAG_USE_CHILD_DRAWING_ORDER = 0x400;
2668506ab4ac062d0e1ccde136e5e2f4081560e0c11Romain Guy
2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * When set, this ViewGroup supports static transformations on children; this causes
2699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@link #getChildStaticTransformation(View, android.view.animation.Transformation)} to be
2709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * invoked when a child is drawn.
2719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
2729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Any subclass overriding
2739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@link #getChildStaticTransformation(View, android.view.animation.Transformation)} should
2749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * set this flags in {@link #mGroupFlags}.
2758506ab4ac062d0e1ccde136e5e2f4081560e0c11Romain Guy     *
2769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@hide}
2779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected static final int FLAG_SUPPORT_STATIC_TRANSFORMATIONS = 0x800;
2799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // When the previous drawChild() invocation used an alpha value that was lower than
2819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // 1.0 and set it in mCachePaint
28264a48c1d3daca9e0565f2aa4d56f6e94ea073d9bChet Haase    static final int FLAG_ALPHA_LOWER_THAN_ONE = 0x1000;
2839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * When set, this ViewGroup's drawable states also include those
2869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * of its children.
2879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static final int FLAG_ADD_STATES_FROM_CHILDREN = 0x2000;
2899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * When set, this ViewGroup tries to always draw its children using their drawing cache.
2929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
29364a48c1d3daca9e0565f2aa4d56f6e94ea073d9bChet Haase    static final int FLAG_ALWAYS_DRAWN_WITH_CACHE = 0x4000;
2949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * When set, and if FLAG_ALWAYS_DRAWN_WITH_CACHE is not set, this ViewGroup will try to
2979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * draw its children with their drawing cache.
2989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
29964a48c1d3daca9e0565f2aa4d56f6e94ea073d9bChet Haase    static final int FLAG_CHILDREN_DRAWN_WITH_CACHE = 0x8000;
3009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
3029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * When set, this group will go through its list of children to notify them of
3039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * any drawable state change.
3049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
3059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static final int FLAG_NOTIFY_CHILDREN_ON_DRAWABLE_STATE_CHANGE = 0x10000;
3069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static final int FLAG_MASK_FOCUSABILITY = 0x60000;
3089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
3109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * This view will get focus before any of its descendants.
3119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
3129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static final int FOCUS_BEFORE_DESCENDANTS = 0x20000;
3139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
3159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * This view will get focus only if none of its descendants want it.
3169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
3179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static final int FOCUS_AFTER_DESCENDANTS = 0x40000;
3189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
3209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * This view will block any of its descendants from getting focus, even
3219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * if they are focusable.
3229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
3239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static final int FOCUS_BLOCK_DESCENDANTS = 0x60000;
3249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
3269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Used to map between enum in attrubutes and flag values.
3279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
3289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static final int[] DESCENDANT_FOCUSABILITY_FLAGS =
3299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            {FOCUS_BEFORE_DESCENDANTS, FOCUS_AFTER_DESCENDANTS,
3309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    FOCUS_BLOCK_DESCENDANTS};
3319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
3339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * When set, this ViewGroup should not intercept touch events.
334110486f932510fb49bfeff978b0b0e0237ee0656Adam Powell     * {@hide}
3359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
336110486f932510fb49bfeff978b0b0e0237ee0656Adam Powell    protected static final int FLAG_DISALLOW_INTERCEPT = 0x80000;
3378506ab4ac062d0e1ccde136e5e2f4081560e0c11Romain Guy
3389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
3392b342f0a76f3237e97f15dc2f4e8a0b72dd7c023Adam Powell     * When set, this ViewGroup will split MotionEvents to multiple child Views when appropriate.
3402b342f0a76f3237e97f15dc2f4e8a0b72dd7c023Adam Powell     */
341f37df070ea84c353ff8bed4b2591932126d7e2caAdam Powell    private static final int FLAG_SPLIT_MOTION_EVENTS = 0x200000;
3422b342f0a76f3237e97f15dc2f4e8a0b72dd7c023Adam Powell
3432b342f0a76f3237e97f15dc2f4e8a0b72dd7c023Adam Powell    /**
3444b86788003b3ddc968d0681d5ed4e5da07e4a65aAdam Powell     * When set, this ViewGroup will not dispatch onAttachedToWindow calls
3454b86788003b3ddc968d0681d5ed4e5da07e4a65aAdam Powell     * to children when adding new views. This is used to prevent multiple
3464b86788003b3ddc968d0681d5ed4e5da07e4a65aAdam Powell     * onAttached calls when a ViewGroup adds children in its own onAttached method.
3474b86788003b3ddc968d0681d5ed4e5da07e4a65aAdam Powell     */
3484b86788003b3ddc968d0681d5ed4e5da07e4a65aAdam Powell    private static final int FLAG_PREVENT_DISPATCH_ATTACHED_TO_WINDOW = 0x400000;
3494b86788003b3ddc968d0681d5ed4e5da07e4a65aAdam Powell
3504b86788003b3ddc968d0681d5ed4e5da07e4a65aAdam Powell    /**
351cfb631b0e56b7c6b9ca11e1a0553b7896b64b1c1Philip Milne     * When true, indicates that a layoutMode has been explicitly set, either with
352cfb631b0e56b7c6b9ca11e1a0553b7896b64b1c1Philip Milne     * an explicit call to {@link #setLayoutMode(int)} in code or from an XML resource.
353cfb631b0e56b7c6b9ca11e1a0553b7896b64b1c1Philip Milne     * This distinguishes the situation in which a layout mode was inherited from
354cfb631b0e56b7c6b9ca11e1a0553b7896b64b1c1Philip Milne     * one of the ViewGroup's ancestors and cached locally.
355cfb631b0e56b7c6b9ca11e1a0553b7896b64b1c1Philip Milne     */
356cfb631b0e56b7c6b9ca11e1a0553b7896b64b1c1Philip Milne    private static final int FLAG_LAYOUT_MODE_WAS_EXPLICITLY_SET = 0x800000;
357cfb631b0e56b7c6b9ca11e1a0553b7896b64b1c1Philip Milne
358cfb631b0e56b7c6b9ca11e1a0553b7896b64b1c1Philip Milne    /**
3599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Indicates which types of drawing caches are to be kept in memory.
3609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * This field should be made private, so it is hidden from the SDK.
3619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@hide}
3629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
3639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected int mPersistentDrawingCache;
3649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
3669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Used to indicate that no drawing cache should be kept in memory.
3679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
3689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static final int PERSISTENT_NO_CACHE = 0x0;
3699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
3719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Used to indicate that the animation drawing cache should be kept in memory.
3729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
3739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static final int PERSISTENT_ANIMATION_CACHE = 0x1;
3749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
3769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Used to indicate that the scrolling drawing cache should be kept in memory.
3779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
3789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static final int PERSISTENT_SCROLLING_CACHE = 0x2;
3799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
3819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Used to indicate that all drawing caches should be kept in memory.
3829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
3839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static final int PERSISTENT_ALL_CACHES = 0x3;
3849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3851557fd7809078e421f751efc7d2539b3efdc54b2Philip Milne    // Layout Modes
3861557fd7809078e421f751efc7d2539b3efdc54b2Philip Milne
387cfb631b0e56b7c6b9ca11e1a0553b7896b64b1c1Philip Milne    private static final int LAYOUT_MODE_UNDEFINED = -1;
388cfb631b0e56b7c6b9ca11e1a0553b7896b64b1c1Philip Milne
3891557fd7809078e421f751efc7d2539b3efdc54b2Philip Milne    /**
3901557fd7809078e421f751efc7d2539b3efdc54b2Philip Milne     * This constant is a {@link #setLayoutMode(int) layoutMode}.
3917a23b49a8ceb07d3fa12c45fd42cd16131fd746aPhilip Milne     * Clip bounds are the raw values of {@link #getLeft() left}, {@link #getTop() top},
3921557fd7809078e421f751efc7d2539b3efdc54b2Philip Milne     * {@link #getRight() right} and {@link #getBottom() bottom}.
3931557fd7809078e421f751efc7d2539b3efdc54b2Philip Milne     */
3947b7578184567f4e4f0740ce935cc192765410ccaPhilip Milne    public static final int LAYOUT_MODE_CLIP_BOUNDS = 0;
3951557fd7809078e421f751efc7d2539b3efdc54b2Philip Milne
3961557fd7809078e421f751efc7d2539b3efdc54b2Philip Milne    /**
3971557fd7809078e421f751efc7d2539b3efdc54b2Philip Milne     * This constant is a {@link #setLayoutMode(int) layoutMode}.
3987a23b49a8ceb07d3fa12c45fd42cd16131fd746aPhilip Milne     * Optical bounds describe where a widget appears to be. They sit inside the clip
3997a23b49a8ceb07d3fa12c45fd42cd16131fd746aPhilip Milne     * bounds which need to cover a larger area to allow other effects,
4007a23b49a8ceb07d3fa12c45fd42cd16131fd746aPhilip Milne     * such as shadows and glows, to be drawn.
4011557fd7809078e421f751efc7d2539b3efdc54b2Philip Milne     */
4027b7578184567f4e4f0740ce935cc192765410ccaPhilip Milne    public static final int LAYOUT_MODE_OPTICAL_BOUNDS = 1;
4037b7578184567f4e4f0740ce935cc192765410ccaPhilip Milne
4047b7578184567f4e4f0740ce935cc192765410ccaPhilip Milne    /** @hide */
405cfb631b0e56b7c6b9ca11e1a0553b7896b64b1c1Philip Milne    public static int LAYOUT_MODE_DEFAULT = LAYOUT_MODE_CLIP_BOUNDS;
4061557fd7809078e421f751efc7d2539b3efdc54b2Philip Milne
4079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
4089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * We clip to padding when FLAG_CLIP_TO_PADDING and FLAG_PADDING_NOT_NULL
4099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * are set at the same time.
4109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
4119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected static final int CLIP_TO_PADDING_MASK = FLAG_CLIP_TO_PADDING | FLAG_PADDING_NOT_NULL;
4129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // Index of the child's left position in the mLocation array
4149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static final int CHILD_LEFT_INDEX = 0;
4159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // Index of the child's top position in the mLocation array
4169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static final int CHILD_TOP_INDEX = 1;
4179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // Child views of this ViewGroup
4199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private View[] mChildren;
4209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // Number of valid children in the mChildren array, the rest should be null or not
4219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // considered as children
422b989502e5cf44d65c6dddc0179b6d9b6e61ef7fdChet Haase    private int mChildrenCount;
4239c0874408cfc6f6f4e4561973ca5ae52a5982db7Chet Haase
424b989502e5cf44d65c6dddc0179b6d9b6e61ef7fdChet Haase    // Whether layout calls are currently being suppressed, controlled by calls to
425b989502e5cf44d65c6dddc0179b6d9b6e61ef7fdChet Haase    // suppressLayout()
426b989502e5cf44d65c6dddc0179b6d9b6e61ef7fdChet Haase    boolean mSuppressLayout = false;
4279c0874408cfc6f6f4e4561973ca5ae52a5982db7Chet Haase
428b989502e5cf44d65c6dddc0179b6d9b6e61ef7fdChet Haase    // Whether any layout calls have actually been suppressed while mSuppressLayout
429b989502e5cf44d65c6dddc0179b6d9b6e61ef7fdChet Haase    // has been true. This tracks whether we need to issue a requestLayout() when
430b989502e5cf44d65c6dddc0179b6d9b6e61ef7fdChet Haase    // layout is later re-enabled.
431b989502e5cf44d65c6dddc0179b6d9b6e61ef7fdChet Haase    private boolean mLayoutCalledWhileSuppressed = false;
4329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static final int ARRAY_INITIAL_CAPACITY = 12;
4349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static final int ARRAY_CAPACITY_INCREMENT = 12;
4359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
436cbc6774ef0285956da74193e5d217738e7411830Romain Guy    private static Paint sDebugPaint;
437cbc6774ef0285956da74193e5d217738e7411830Romain Guy    private static float[] sDebugLines;
438604f440dfd6e5ee857f1e71d12c635d4ee1afcbcPhilip Milne
4399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // Used to draw cached views
44064a48c1d3daca9e0565f2aa4d56f6e94ea073d9bChet Haase    Paint mCachePaint;
4419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
44221cd1389d2ef218b20994b617c57af120841a57fChet Haase    // Used to animate add/remove changes in layout
44321cd1389d2ef218b20994b617c57af120841a57fChet Haase    private LayoutTransition mTransition;
44421cd1389d2ef218b20994b617c57af120841a57fChet Haase
44521cd1389d2ef218b20994b617c57af120841a57fChet Haase    // The set of views that are currently being transitioned. This list is used to track views
44621cd1389d2ef218b20994b617c57af120841a57fChet Haase    // being removed that should not actually be removed from the parent yet because they are
44721cd1389d2ef218b20994b617c57af120841a57fChet Haase    // being animated.
44821cd1389d2ef218b20994b617c57af120841a57fChet Haase    private ArrayList<View> mTransitioningViews;
44921cd1389d2ef218b20994b617c57af120841a57fChet Haase
4505e25c2c14593caee5638603120553ae1ec530f85Chet Haase    // List of children changing visibility. This is used to potentially keep rendering
4515e25c2c14593caee5638603120553ae1ec530f85Chet Haase    // views during a transition when they otherwise would have become gone/invisible
4525e25c2c14593caee5638603120553ae1ec530f85Chet Haase    private ArrayList<View> mVisibilityChangingChildren;
4535e25c2c14593caee5638603120553ae1ec530f85Chet Haase
454539ee8716b4f81260bab2e9f3dc5d88d81c99985Adam Powell    // Indicates how many of this container's child subtrees contain transient state
455539ee8716b4f81260bab2e9f3dc5d88d81c99985Adam Powell    @ViewDebug.ExportedProperty(category = "layout")
456539ee8716b4f81260bab2e9f3dc5d88d81c99985Adam Powell    private int mChildCountWithTransientState = 0;
457539ee8716b4f81260bab2e9f3dc5d88d81c99985Adam Powell
4589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public ViewGroup(Context context) {
4599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        super(context);
4609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        initViewGroup();
4619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public ViewGroup(Context context, AttributeSet attrs) {
4649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        super(context, attrs);
4659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        initViewGroup();
4669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        initFromAttributes(context, attrs);
4679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public ViewGroup(Context context, AttributeSet attrs, int defStyle) {
4709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        super(context, attrs, defStyle);
4719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        initViewGroup();
4729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        initFromAttributes(context, attrs);
4739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
47510ca24a97cefc14fca1b26f59e627f487b3b108bPhilip Milne    private boolean debugDraw() {
4767b7578184567f4e4f0740ce935cc192765410ccaPhilip Milne        return DEBUG_DRAW || mAttachInfo != null && mAttachInfo.mDebugLayout;
47710ca24a97cefc14fca1b26f59e627f487b3b108bPhilip Milne    }
47810ca24a97cefc14fca1b26f59e627f487b3b108bPhilip Milne
4799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private void initViewGroup() {
4809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // ViewGroup doesn't draw by default
48110ca24a97cefc14fca1b26f59e627f487b3b108bPhilip Milne        if (!debugDraw()) {
48210ca24a97cefc14fca1b26f59e627f487b3b108bPhilip Milne            setFlags(WILL_NOT_DRAW, DRAW_MASK);
48310ca24a97cefc14fca1b26f59e627f487b3b108bPhilip Milne        }
4849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mGroupFlags |= FLAG_CLIP_CHILDREN;
4859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mGroupFlags |= FLAG_CLIP_TO_PADDING;
4869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mGroupFlags |= FLAG_ANIMATION_DONE;
4879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mGroupFlags |= FLAG_ANIMATION_CACHE;
4889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mGroupFlags |= FLAG_ALWAYS_DRAWN_WITH_CACHE;
4899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
490995e77431982f9a320451dbe6132a62e69f73babJeff Brown        if (mContext.getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.HONEYCOMB) {
491995e77431982f9a320451dbe6132a62e69f73babJeff Brown            mGroupFlags |= FLAG_SPLIT_MOTION_EVENTS;
492995e77431982f9a320451dbe6132a62e69f73babJeff Brown        }
493995e77431982f9a320451dbe6132a62e69f73babJeff Brown
4949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        setDescendantFocusability(FOCUS_BEFORE_DESCENDANTS);
4959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mChildren = new View[ARRAY_INITIAL_CAPACITY];
4979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mChildrenCount = 0;
4989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mPersistentDrawingCache = PERSISTENT_SCROLLING_CACHE;
5009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private void initFromAttributes(Context context, AttributeSet attrs) {
5039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        TypedArray a = context.obtainStyledAttributes(attrs,
5049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                R.styleable.ViewGroup);
5059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final int N = a.getIndexCount();
5079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (int i = 0; i < N; i++) {
5089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            int attr = a.getIndex(i);
5099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            switch (attr) {
5109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case R.styleable.ViewGroup_clipChildren:
5119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    setClipChildren(a.getBoolean(attr, true));
5129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    break;
5139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case R.styleable.ViewGroup_clipToPadding:
5149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    setClipToPadding(a.getBoolean(attr, true));
5159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    break;
5169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case R.styleable.ViewGroup_animationCache:
5179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    setAnimationCacheEnabled(a.getBoolean(attr, true));
5189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    break;
5199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case R.styleable.ViewGroup_persistentDrawingCache:
5209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    setPersistentDrawingCache(a.getInt(attr, PERSISTENT_SCROLLING_CACHE));
5219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    break;
5229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case R.styleable.ViewGroup_addStatesFromChildren:
5239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    setAddStatesFromChildren(a.getBoolean(attr, false));
5249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    break;
5259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case R.styleable.ViewGroup_alwaysDrawnWithCache:
5269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    setAlwaysDrawnWithCacheEnabled(a.getBoolean(attr, true));
5279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    break;
5289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case R.styleable.ViewGroup_layoutAnimation:
5299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    int id = a.getResourceId(attr, -1);
5309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (id > 0) {
5319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        setLayoutAnimation(AnimationUtils.loadLayoutAnimation(mContext, id));
5329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
5339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    break;
5349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case R.styleable.ViewGroup_descendantFocusability:
5359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    setDescendantFocusability(DESCENDANT_FOCUSABILITY_FLAGS[a.getInt(attr, 0)]);
5369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    break;
5372b342f0a76f3237e97f15dc2f4e8a0b72dd7c023Adam Powell                case R.styleable.ViewGroup_splitMotionEvents:
5382b342f0a76f3237e97f15dc2f4e8a0b72dd7c023Adam Powell                    setMotionEventSplittingEnabled(a.getBoolean(attr, false));
5392b342f0a76f3237e97f15dc2f4e8a0b72dd7c023Adam Powell                    break;
54013cc1207fab68adc5c7da0bf3b365196e26a273eChet Haase                case R.styleable.ViewGroup_animateLayoutChanges:
54113cc1207fab68adc5c7da0bf3b365196e26a273eChet Haase                    boolean animateLayoutChanges = a.getBoolean(attr, false);
54213cc1207fab68adc5c7da0bf3b365196e26a273eChet Haase                    if (animateLayoutChanges) {
54313cc1207fab68adc5c7da0bf3b365196e26a273eChet Haase                        setLayoutTransition(new LayoutTransition());
54413cc1207fab68adc5c7da0bf3b365196e26a273eChet Haase                    }
54513cc1207fab68adc5c7da0bf3b365196e26a273eChet Haase                    break;
5467b7578184567f4e4f0740ce935cc192765410ccaPhilip Milne                case R.styleable.ViewGroup_layoutMode:
547cfb631b0e56b7c6b9ca11e1a0553b7896b64b1c1Philip Milne                    setLayoutMode(a.getInt(attr, LAYOUT_MODE_UNDEFINED));
5487b7578184567f4e4f0740ce935cc192765410ccaPhilip Milne                    break;
5499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
5509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        a.recycle();
5539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
5569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Gets the descendant focusability of this view group.  The descendant
5579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * focusability defines the relationship between this view group and its
5589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * descendants when looking for a view to take focus in
5599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@link #requestFocus(int, android.graphics.Rect)}.
5609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
5619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return one of {@link #FOCUS_BEFORE_DESCENDANTS}, {@link #FOCUS_AFTER_DESCENDANTS},
5629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *   {@link #FOCUS_BLOCK_DESCENDANTS}.
5639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
564bea95162ca25bd00b0479d93739b6283795c3986Konstantin Lopyrev    @ViewDebug.ExportedProperty(category = "focus", mapping = {
5659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        @ViewDebug.IntToString(from = FOCUS_BEFORE_DESCENDANTS, to = "FOCUS_BEFORE_DESCENDANTS"),
5669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        @ViewDebug.IntToString(from = FOCUS_AFTER_DESCENDANTS, to = "FOCUS_AFTER_DESCENDANTS"),
5679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        @ViewDebug.IntToString(from = FOCUS_BLOCK_DESCENDANTS, to = "FOCUS_BLOCK_DESCENDANTS")
5689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    })
5699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public int getDescendantFocusability() {
5709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mGroupFlags & FLAG_MASK_FOCUSABILITY;
5719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
5749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Set the descendant focusability of this view group. This defines the relationship
5759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * between this view group and its descendants when looking for a view to
5769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * take focus in {@link #requestFocus(int, android.graphics.Rect)}.
5779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
5789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param focusability one of {@link #FOCUS_BEFORE_DESCENDANTS}, {@link #FOCUS_AFTER_DESCENDANTS},
5799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *   {@link #FOCUS_BLOCK_DESCENDANTS}.
5809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
5819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setDescendantFocusability(int focusability) {
5829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        switch (focusability) {
5839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case FOCUS_BEFORE_DESCENDANTS:
5849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case FOCUS_AFTER_DESCENDANTS:
5859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case FOCUS_BLOCK_DESCENDANTS:
5869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                break;
5879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            default:
5889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                throw new IllegalArgumentException("must be one of FOCUS_BEFORE_DESCENDANTS, "
5899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        + "FOCUS_AFTER_DESCENDANTS, FOCUS_BLOCK_DESCENDANTS");
5909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mGroupFlags &= ~FLAG_MASK_FOCUSABILITY;
5929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mGroupFlags |= (focusability & FLAG_MASK_FOCUSABILITY);
5939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
5969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@inheritDoc}
5979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
5989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
5999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    void handleFocusGainInternal(int direction, Rect previouslyFocusedRect) {
6009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mFocused != null) {
6019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mFocused.unFocus();
6029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mFocused = null;
6039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        super.handleFocusGainInternal(direction, previouslyFocusedRect);
6059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
6069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
6089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@inheritDoc}
6099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
6109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void requestChildFocus(View child, View focused) {
6119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (DBG) {
6129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            System.out.println(this + " requestChildFocus()");
6139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (getDescendantFocusability() == FOCUS_BLOCK_DESCENDANTS) {
6159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return;
6169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Unfocus us, if necessary
6199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        super.unFocus();
6209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // We had a previous notion of who had focus. Clear it.
6229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mFocused != child) {
6239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (mFocused != null) {
6249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mFocused.unFocus();
6259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
6269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mFocused = child;
6289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mParent != null) {
6309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mParent.requestChildFocus(this, focused);
6319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
6339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
6359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@inheritDoc}
6369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
6379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void focusableViewAvailable(View v) {
6389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mParent != null
6399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // shortcut: don't report a new focusable view if we block our descendants from
6409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // getting focus
6419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                && (getDescendantFocusability() != FOCUS_BLOCK_DESCENDANTS)
6429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // shortcut: don't report a new focusable view if we already are focused
6439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // (and we don't prefer our descendants)
6449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                //
6459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // note: knowing that mFocused is non-null is not a good enough reason
6469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // to break the traversal since in that case we'd actually have to find
6479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // the focused view and make sure it wasn't FOCUS_AFTER_DESCENDANTS and
648c6cc0f8c19d9eccf408a443fa2bf668af261dcd0Joe Onorato                // an ancestor of v; this will get checked for at ViewAncestor
6499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                && !(isFocused() && getDescendantFocusability() != FOCUS_AFTER_DESCENDANTS)) {
6509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mParent.focusableViewAvailable(v);
6519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
6539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
6559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@inheritDoc}
6569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
6579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean showContextMenuForChild(View originalView) {
6589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mParent != null && mParent.showContextMenuForChild(originalView);
6599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
6609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
6626e34636749217654f43221885afb7a29bb5ca96aAdam Powell     * {@inheritDoc}
6636e34636749217654f43221885afb7a29bb5ca96aAdam Powell     */
6646e34636749217654f43221885afb7a29bb5ca96aAdam Powell    public ActionMode startActionModeForChild(View originalView, ActionMode.Callback callback) {
6656e34636749217654f43221885afb7a29bb5ca96aAdam Powell        return mParent != null ? mParent.startActionModeForChild(originalView, callback) : null;
6666e34636749217654f43221885afb7a29bb5ca96aAdam Powell    }
6676e34636749217654f43221885afb7a29bb5ca96aAdam Powell
6686e34636749217654f43221885afb7a29bb5ca96aAdam Powell    /**
6699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Find the nearest view in the specified direction that wants to take
6709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * focus.
6719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
6729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param focused The view that currently has focus
6739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param direction One of FOCUS_UP, FOCUS_DOWN, FOCUS_LEFT, and
6749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *        FOCUS_RIGHT, or 0 for not applicable.
6759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
6769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public View focusSearch(View focused, int direction) {
67727e2da7c171afa39358bbead18fbe3e6b8ea6637Svetoslav Ganov        if (isRootNamespace()) {
6789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // root namespace means we should consider ourselves the top of the
6799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // tree for focus searching; otherwise we could be focus searching
6809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // into other tabs.  see LocalActivityManager and TabHost for more info
6819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return FocusFinder.getInstance().findNextFocus(this, focused, direction);
6829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else if (mParent != null) {
6839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return mParent.focusSearch(focused, direction);
6849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return null;
6869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
6879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
6899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@inheritDoc}
6909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
6919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean requestChildRectangleOnScreen(View child, Rect rectangle, boolean immediate) {
6929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return false;
6939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
6949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
6969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@inheritDoc}
6979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
6984213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov    @Override
699736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov    public boolean requestSendAccessibilityEvent(View child, AccessibilityEvent event) {
7004213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov        ViewParent parent = mParent;
701736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov        if (parent == null) {
702736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov            return false;
703736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov        }
704736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov        final boolean propagate = onRequestSendAccessibilityEvent(child, event);
705736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov        if (!propagate) {
706736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov            return false;
707736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov        }
708736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov        return parent.requestSendAccessibilityEvent(this, event);
709736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov    }
710736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov
711736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov    /**
712736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov     * Called when a child has requested sending an {@link AccessibilityEvent} and
713736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov     * gives an opportunity to its parent to augment the event.
714031d9c1389de2b9dac7f175af0b962e24b21d5beSvetoslav Ganov     * <p>
7152fcbbd0363633765e1ab5b9890ccb807002370e8Adam Powell     * If an {@link android.view.View.AccessibilityDelegate} has been specified via calling
7162fcbbd0363633765e1ab5b9890ccb807002370e8Adam Powell     * {@link android.view.View#setAccessibilityDelegate(android.view.View.AccessibilityDelegate)} its
7172fcbbd0363633765e1ab5b9890ccb807002370e8Adam Powell     * {@link android.view.View.AccessibilityDelegate#onRequestSendAccessibilityEvent(ViewGroup, View, AccessibilityEvent)}
718031d9c1389de2b9dac7f175af0b962e24b21d5beSvetoslav Ganov     * is responsible for handling this call.
719031d9c1389de2b9dac7f175af0b962e24b21d5beSvetoslav Ganov     * </p>
720736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov     *
721736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov     * @param child The child which requests sending the event.
722736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov     * @param event The event to be sent.
723736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov     * @return True if the event should be sent.
724736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov     *
725736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov     * @see #requestSendAccessibilityEvent(View, AccessibilityEvent)
726736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov     */
727736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov    public boolean onRequestSendAccessibilityEvent(View child, AccessibilityEvent event) {
728031d9c1389de2b9dac7f175af0b962e24b21d5beSvetoslav Ganov        if (mAccessibilityDelegate != null) {
729031d9c1389de2b9dac7f175af0b962e24b21d5beSvetoslav Ganov            return mAccessibilityDelegate.onRequestSendAccessibilityEvent(this, child, event);
730031d9c1389de2b9dac7f175af0b962e24b21d5beSvetoslav Ganov        } else {
731031d9c1389de2b9dac7f175af0b962e24b21d5beSvetoslav Ganov            return onRequestSendAccessibilityEventInternal(child, event);
732031d9c1389de2b9dac7f175af0b962e24b21d5beSvetoslav Ganov        }
733031d9c1389de2b9dac7f175af0b962e24b21d5beSvetoslav Ganov    }
734031d9c1389de2b9dac7f175af0b962e24b21d5beSvetoslav Ganov
735031d9c1389de2b9dac7f175af0b962e24b21d5beSvetoslav Ganov    /**
736031d9c1389de2b9dac7f175af0b962e24b21d5beSvetoslav Ganov     * @see #onRequestSendAccessibilityEvent(View, AccessibilityEvent)
737031d9c1389de2b9dac7f175af0b962e24b21d5beSvetoslav Ganov     *
738031d9c1389de2b9dac7f175af0b962e24b21d5beSvetoslav Ganov     * Note: Called from the default {@link View.AccessibilityDelegate}.
739031d9c1389de2b9dac7f175af0b962e24b21d5beSvetoslav Ganov     */
740031d9c1389de2b9dac7f175af0b962e24b21d5beSvetoslav Ganov    boolean onRequestSendAccessibilityEventInternal(View child, AccessibilityEvent event) {
741736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov        return true;
742736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov    }
743736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov
744736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov    /**
745539ee8716b4f81260bab2e9f3dc5d88d81c99985Adam Powell     * Called when a child view has changed whether or not it is tracking transient state.
746539ee8716b4f81260bab2e9f3dc5d88d81c99985Adam Powell     */
747539ee8716b4f81260bab2e9f3dc5d88d81c99985Adam Powell    public void childHasTransientStateChanged(View child, boolean childHasTransientState) {
748539ee8716b4f81260bab2e9f3dc5d88d81c99985Adam Powell        final boolean oldHasTransientState = hasTransientState();
749539ee8716b4f81260bab2e9f3dc5d88d81c99985Adam Powell        if (childHasTransientState) {
750539ee8716b4f81260bab2e9f3dc5d88d81c99985Adam Powell            mChildCountWithTransientState++;
751539ee8716b4f81260bab2e9f3dc5d88d81c99985Adam Powell        } else {
752539ee8716b4f81260bab2e9f3dc5d88d81c99985Adam Powell            mChildCountWithTransientState--;
753539ee8716b4f81260bab2e9f3dc5d88d81c99985Adam Powell        }
754539ee8716b4f81260bab2e9f3dc5d88d81c99985Adam Powell
755539ee8716b4f81260bab2e9f3dc5d88d81c99985Adam Powell        final boolean newHasTransientState = hasTransientState();
756539ee8716b4f81260bab2e9f3dc5d88d81c99985Adam Powell        if (mParent != null && oldHasTransientState != newHasTransientState) {
757539ee8716b4f81260bab2e9f3dc5d88d81c99985Adam Powell            try {
758539ee8716b4f81260bab2e9f3dc5d88d81c99985Adam Powell                mParent.childHasTransientStateChanged(this, newHasTransientState);
759539ee8716b4f81260bab2e9f3dc5d88d81c99985Adam Powell            } catch (AbstractMethodError e) {
760539ee8716b4f81260bab2e9f3dc5d88d81c99985Adam Powell                Log.e(TAG, mParent.getClass().getSimpleName() +
761539ee8716b4f81260bab2e9f3dc5d88d81c99985Adam Powell                        " does not fully implement ViewParent", e);
762539ee8716b4f81260bab2e9f3dc5d88d81c99985Adam Powell            }
763539ee8716b4f81260bab2e9f3dc5d88d81c99985Adam Powell        }
764539ee8716b4f81260bab2e9f3dc5d88d81c99985Adam Powell    }
765539ee8716b4f81260bab2e9f3dc5d88d81c99985Adam Powell
766539ee8716b4f81260bab2e9f3dc5d88d81c99985Adam Powell    @Override
767539ee8716b4f81260bab2e9f3dc5d88d81c99985Adam Powell    public boolean hasTransientState() {
768539ee8716b4f81260bab2e9f3dc5d88d81c99985Adam Powell        return mChildCountWithTransientState > 0 || super.hasTransientState();
769539ee8716b4f81260bab2e9f3dc5d88d81c99985Adam Powell    }
770539ee8716b4f81260bab2e9f3dc5d88d81c99985Adam Powell
771539ee8716b4f81260bab2e9f3dc5d88d81c99985Adam Powell    /**
772736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov     * {@inheritDoc}
773736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov     */
7749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
7759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean dispatchUnhandledMove(View focused, int direction) {
7769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mFocused != null &&
7779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mFocused.dispatchUnhandledMove(focused, direction);
7789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
7799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
7819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@inheritDoc}
7829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
7839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void clearChildFocus(View child) {
7849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (DBG) {
7859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            System.out.println(this + " clearChildFocus()");
7869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
7879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mFocused = null;
7899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mParent != null) {
7909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mParent.clearChildFocus(this);
7919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
7929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
7939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
7959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@inheritDoc}
7969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
7979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
7989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void clearFocus() {
799b36a0ac9709e9e1c7098559c0435cfbdc09e6c46Svetoslav Ganov        if (DBG) {
800b36a0ac9709e9e1c7098559c0435cfbdc09e6c46Svetoslav Ganov            System.out.println(this + " clearFocus()");
801b36a0ac9709e9e1c7098559c0435cfbdc09e6c46Svetoslav Ganov        }
802b36a0ac9709e9e1c7098559c0435cfbdc09e6c46Svetoslav Ganov        if (mFocused == null) {
803b36a0ac9709e9e1c7098559c0435cfbdc09e6c46Svetoslav Ganov            super.clearFocus();
804b36a0ac9709e9e1c7098559c0435cfbdc09e6c46Svetoslav Ganov        } else {
805b552d89e901225e2b6aa2602e874ab984c638415Svetoslav Ganov            View focused = mFocused;
806b36a0ac9709e9e1c7098559c0435cfbdc09e6c46Svetoslav Ganov            mFocused = null;
807b552d89e901225e2b6aa2602e874ab984c638415Svetoslav Ganov            focused.clearFocus();
8089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
8099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
8109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
8129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@inheritDoc}
8139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
8149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
8159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    void unFocus() {
8169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (DBG) {
8179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            System.out.println(this + " unFocus()");
8189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
819b36a0ac9709e9e1c7098559c0435cfbdc09e6c46Svetoslav Ganov        if (mFocused == null) {
820b36a0ac9709e9e1c7098559c0435cfbdc09e6c46Svetoslav Ganov            super.unFocus();
821b36a0ac9709e9e1c7098559c0435cfbdc09e6c46Svetoslav Ganov        } else {
8229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mFocused.unFocus();
823b36a0ac9709e9e1c7098559c0435cfbdc09e6c46Svetoslav Ganov            mFocused = null;
8249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
8259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
8269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
8289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Returns the focused child of this view, if any. The child may have focus
8299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * or contain focus.
8309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
8319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return the focused child or null.
8329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
8339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public View getFocusedChild() {
8349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mFocused;
8359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
8369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
8389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Returns true if this view has or contains focus
8399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
8409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return true if this view has or contains focus
8419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
8429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
8439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean hasFocus() {
8444702a856973a553deb82f71b1d3b6c3db5dbf4baDianne Hackborn        return (mPrivateFlags & PFLAG_FOCUSED) != 0 || mFocused != null;
8459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
8469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /*
8489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * (non-Javadoc)
8499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
8509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see android.view.View#findFocus()
8519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
8529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
8539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public View findFocus() {
8549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (DBG) {
8559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            System.out.println("Find focus in " + this + ": flags="
8569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    + isFocused() + ", child=" + mFocused);
8579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
8589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (isFocused()) {
8609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return this;
8619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
8629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mFocused != null) {
8649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return mFocused.findFocus();
8659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
8669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return null;
8679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
8689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
8709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@inheritDoc}
8719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
8729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
8739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean hasFocusable() {
8749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if ((mViewFlags & VISIBILITY_MASK) != VISIBLE) {
8759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return false;
8769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
8779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (isFocusable()) {
8799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return true;
8809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
8819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final int descendantFocusability = getDescendantFocusability();
8839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (descendantFocusability != FOCUS_BLOCK_DESCENDANTS) {
8849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            final int count = mChildrenCount;
8859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            final View[] children = mChildren;
8869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            for (int i = 0; i < count; i++) {
8889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                final View child = children[i];
8899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (child.hasFocusable()) {
8909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    return true;
8919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
8929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
8939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
8949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return false;
8969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
8979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
8999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@inheritDoc}
9009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
9019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
90275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov    public void addFocusables(ArrayList<View> views, int direction, int focusableMode) {
9039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final int focusableCount = views.size();
9049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final int descendantFocusability = getDescendantFocusability();
9069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
90727e2da7c171afa39358bbead18fbe3e6b8ea6637Svetoslav Ganov        if (descendantFocusability != FOCUS_BLOCK_DESCENDANTS) {
9089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            final int count = mChildrenCount;
9099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            final View[] children = mChildren;
9109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            for (int i = 0; i < count; i++) {
9129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                final View child = children[i];
9139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if ((child.mViewFlags & VISIBILITY_MASK) == VISIBLE) {
91475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov                    child.addFocusables(views, direction, focusableMode);
9159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
9169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
9179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
9189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // we add ourselves (if focusable) in all cases except for when we are
9209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // FOCUS_AFTER_DESCENDANTS and there are some descendants focusable.  this is
9219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // to avoid the focus search finding layouts when a more precise search
9229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // among the focusable children would be more interesting.
923e5dfa47d84668376b84074c04570fb961870adebSvetoslav Ganov        if (descendantFocusability != FOCUS_AFTER_DESCENDANTS
9249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // No focusable descendants
92527e2da7c171afa39358bbead18fbe3e6b8ea6637Svetoslav Ganov                || (focusableCount == views.size())) {
92675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov            super.addFocusables(views, direction, focusableMode);
9279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
9289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
9299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9308643aa0179e598e78d938c59035389054535a229Svetoslav Ganov    @Override
931ea515aeafa01de6f50c854ee381b972ef2478284Svetoslav Ganov    public void findViewsWithText(ArrayList<View> outViews, CharSequence text, int flags) {
932ea515aeafa01de6f50c854ee381b972ef2478284Svetoslav Ganov        super.findViewsWithText(outViews, text, flags);
9338643aa0179e598e78d938c59035389054535a229Svetoslav Ganov        final int childrenCount = mChildrenCount;
9348643aa0179e598e78d938c59035389054535a229Svetoslav Ganov        final View[] children = mChildren;
9358643aa0179e598e78d938c59035389054535a229Svetoslav Ganov        for (int i = 0; i < childrenCount; i++) {
9368643aa0179e598e78d938c59035389054535a229Svetoslav Ganov            View child = children[i];
937ea515aeafa01de6f50c854ee381b972ef2478284Svetoslav Ganov            if ((child.mViewFlags & VISIBILITY_MASK) == VISIBLE
9384702a856973a553deb82f71b1d3b6c3db5dbf4baDianne Hackborn                    && (child.mPrivateFlags & PFLAG_IS_ROOT_NAMESPACE) == 0) {
939ea515aeafa01de6f50c854ee381b972ef2478284Svetoslav Ganov                child.findViewsWithText(outViews, text, flags);
9408643aa0179e598e78d938c59035389054535a229Svetoslav Ganov            }
9418643aa0179e598e78d938c59035389054535a229Svetoslav Ganov        }
9428643aa0179e598e78d938c59035389054535a229Svetoslav Ganov    }
9438643aa0179e598e78d938c59035389054535a229Svetoslav Ganov
9445b578daac9cea174b15fcd13528270270aadd8a2Svetoslav    /** @hide */
9452cdedffcfa5594f9d516fa235d5edf4d4f92c21dSvetoslav Ganov    @Override
9465b578daac9cea174b15fcd13528270270aadd8a2Svetoslav    public View findViewByAccessibilityIdTraversal(int accessibilityId) {
9472cdedffcfa5594f9d516fa235d5edf4d4f92c21dSvetoslav Ganov        View foundView = super.findViewByAccessibilityIdTraversal(accessibilityId);
9482cdedffcfa5594f9d516fa235d5edf4d4f92c21dSvetoslav Ganov        if (foundView != null) {
9492cdedffcfa5594f9d516fa235d5edf4d4f92c21dSvetoslav Ganov            return foundView;
9502cdedffcfa5594f9d516fa235d5edf4d4f92c21dSvetoslav Ganov        }
9512cdedffcfa5594f9d516fa235d5edf4d4f92c21dSvetoslav Ganov        final int childrenCount = mChildrenCount;
9522cdedffcfa5594f9d516fa235d5edf4d4f92c21dSvetoslav Ganov        final View[] children = mChildren;
9532cdedffcfa5594f9d516fa235d5edf4d4f92c21dSvetoslav Ganov        for (int i = 0; i < childrenCount; i++) {
9542cdedffcfa5594f9d516fa235d5edf4d4f92c21dSvetoslav Ganov            View child = children[i];
9552cdedffcfa5594f9d516fa235d5edf4d4f92c21dSvetoslav Ganov            foundView = child.findViewByAccessibilityIdTraversal(accessibilityId);
9562cdedffcfa5594f9d516fa235d5edf4d4f92c21dSvetoslav Ganov            if (foundView != null) {
9572cdedffcfa5594f9d516fa235d5edf4d4f92c21dSvetoslav Ganov                return foundView;
9582cdedffcfa5594f9d516fa235d5edf4d4f92c21dSvetoslav Ganov            }
9592cdedffcfa5594f9d516fa235d5edf4d4f92c21dSvetoslav Ganov        }
9602cdedffcfa5594f9d516fa235d5edf4d4f92c21dSvetoslav Ganov        return null;
9612cdedffcfa5594f9d516fa235d5edf4d4f92c21dSvetoslav Ganov    }
9622cdedffcfa5594f9d516fa235d5edf4d4f92c21dSvetoslav Ganov
9639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
9649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@inheritDoc}
9659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
9669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
9679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void dispatchWindowFocusChanged(boolean hasFocus) {
9689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        super.dispatchWindowFocusChanged(hasFocus);
9699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final int count = mChildrenCount;
9709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final View[] children = mChildren;
9719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (int i = 0; i < count; i++) {
9729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            children[i].dispatchWindowFocusChanged(hasFocus);
9739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
9749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
9759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
9779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@inheritDoc}
9789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
9799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
9809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void addTouchables(ArrayList<View> views) {
9819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        super.addTouchables(views);
9829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final int count = mChildrenCount;
9849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final View[] children = mChildren;
9859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (int i = 0; i < count; i++) {
9879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            final View child = children[i];
9889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if ((child.mViewFlags & VISIBILITY_MASK) == VISIBLE) {
9899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                child.addTouchables(views);
9909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
9919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
9929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
9933a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn
9943a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn    /**
9953a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn     * @hide
9963a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn     */
9973a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn    @Override
9983a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn    public void makeOptionalFitsSystemWindows() {
9993a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn        super.makeOptionalFitsSystemWindows();
10003a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn        final int count = mChildrenCount;
10013a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn        final View[] children = mChildren;
10023a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn        for (int i = 0; i < count; i++) {
10033a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn            children[i].makeOptionalFitsSystemWindows();
10043a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn        }
10053a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn    }
10063a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn
100743c9cdffb619f93d9d4525dffd05701dc9c8c4bfRomain Guy    /**
100843c9cdffb619f93d9d4525dffd05701dc9c8c4bfRomain Guy     * {@inheritDoc}
100943c9cdffb619f93d9d4525dffd05701dc9c8c4bfRomain Guy     */
101043c9cdffb619f93d9d4525dffd05701dc9c8c4bfRomain Guy    @Override
101143c9cdffb619f93d9d4525dffd05701dc9c8c4bfRomain Guy    public void dispatchDisplayHint(int hint) {
101243c9cdffb619f93d9d4525dffd05701dc9c8c4bfRomain Guy        super.dispatchDisplayHint(hint);
101343c9cdffb619f93d9d4525dffd05701dc9c8c4bfRomain Guy        final int count = mChildrenCount;
101443c9cdffb619f93d9d4525dffd05701dc9c8c4bfRomain Guy        final View[] children = mChildren;
101543c9cdffb619f93d9d4525dffd05701dc9c8c4bfRomain Guy        for (int i = 0; i < count; i++) {
101643c9cdffb619f93d9d4525dffd05701dc9c8c4bfRomain Guy            children[i].dispatchDisplayHint(hint);
101743c9cdffb619f93d9d4525dffd05701dc9c8c4bfRomain Guy        }
101843c9cdffb619f93d9d4525dffd05701dc9c8c4bfRomain Guy    }
10199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
10210d29936ec3b5545a415e8d032150ea987aab36e3Chet Haase     * Called when a view's visibility has changed. Notify the parent to take any appropriate
10220d29936ec3b5545a415e8d032150ea987aab36e3Chet Haase     * action.
10230d29936ec3b5545a415e8d032150ea987aab36e3Chet Haase     *
10240d29936ec3b5545a415e8d032150ea987aab36e3Chet Haase     * @param child The view whose visibility has changed
10250d29936ec3b5545a415e8d032150ea987aab36e3Chet Haase     * @param oldVisibility The previous visibility value (GONE, INVISIBLE, or VISIBLE).
10260d29936ec3b5545a415e8d032150ea987aab36e3Chet Haase     * @param newVisibility The new visibility value (GONE, INVISIBLE, or VISIBLE).
10275e25c2c14593caee5638603120553ae1ec530f85Chet Haase     * @hide
10285e25c2c14593caee5638603120553ae1ec530f85Chet Haase     */
10290d29936ec3b5545a415e8d032150ea987aab36e3Chet Haase    protected void onChildVisibilityChanged(View child, int oldVisibility, int newVisibility) {
10305e25c2c14593caee5638603120553ae1ec530f85Chet Haase        if (mTransition != null) {
10310d29936ec3b5545a415e8d032150ea987aab36e3Chet Haase            if (newVisibility == VISIBLE) {
10320d29936ec3b5545a415e8d032150ea987aab36e3Chet Haase                mTransition.showChild(this, child, oldVisibility);
10335e25c2c14593caee5638603120553ae1ec530f85Chet Haase            } else {
10340d29936ec3b5545a415e8d032150ea987aab36e3Chet Haase                mTransition.hideChild(this, child, newVisibility);
10355e25c2c14593caee5638603120553ae1ec530f85Chet Haase                if (mTransitioningViews != null && mTransitioningViews.contains(child)) {
1036ddbb346e5a08c94dca44d681af53f0d9dc75cadfChet Haase                    // Only track this on disappearing views - appearing views are already visible
1037ddbb346e5a08c94dca44d681af53f0d9dc75cadfChet Haase                    // and don't need special handling during drawChild()
1038ddbb346e5a08c94dca44d681af53f0d9dc75cadfChet Haase                    if (mVisibilityChangingChildren == null) {
1039ddbb346e5a08c94dca44d681af53f0d9dc75cadfChet Haase                        mVisibilityChangingChildren = new ArrayList<View>();
1040ddbb346e5a08c94dca44d681af53f0d9dc75cadfChet Haase                    }
1041ddbb346e5a08c94dca44d681af53f0d9dc75cadfChet Haase                    mVisibilityChangingChildren.add(child);
10425e25c2c14593caee5638603120553ae1ec530f85Chet Haase                    addDisappearingView(child);
10435e25c2c14593caee5638603120553ae1ec530f85Chet Haase                }
10445e25c2c14593caee5638603120553ae1ec530f85Chet Haase            }
10455e25c2c14593caee5638603120553ae1ec530f85Chet Haase        }
104686cab1bd52197d6fa60786413fad9788d9236762Christopher Tate
104786cab1bd52197d6fa60786413fad9788d9236762Christopher Tate        // in all cases, for drags
104886cab1bd52197d6fa60786413fad9788d9236762Christopher Tate        if (mCurrentDrag != null) {
10490d29936ec3b5545a415e8d032150ea987aab36e3Chet Haase            if (newVisibility == VISIBLE) {
105086cab1bd52197d6fa60786413fad9788d9236762Christopher Tate                notifyChildOfDrag(child);
105186cab1bd52197d6fa60786413fad9788d9236762Christopher Tate            }
105286cab1bd52197d6fa60786413fad9788d9236762Christopher Tate        }
10535e25c2c14593caee5638603120553ae1ec530f85Chet Haase    }
10545e25c2c14593caee5638603120553ae1ec530f85Chet Haase
10555e25c2c14593caee5638603120553ae1ec530f85Chet Haase    /**
10569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@inheritDoc}
10579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
10589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
1059326d808b858359464b2ffeb84f2e0a8e0c79b600Adam Powell    protected void dispatchVisibilityChanged(View changedView, int visibility) {
1060326d808b858359464b2ffeb84f2e0a8e0c79b600Adam Powell        super.dispatchVisibilityChanged(changedView, visibility);
1061326d808b858359464b2ffeb84f2e0a8e0c79b600Adam Powell        final int count = mChildrenCount;
1062326d808b858359464b2ffeb84f2e0a8e0c79b600Adam Powell        final View[] children = mChildren;
1063326d808b858359464b2ffeb84f2e0a8e0c79b600Adam Powell        for (int i = 0; i < count; i++) {
1064326d808b858359464b2ffeb84f2e0a8e0c79b600Adam Powell            children[i].dispatchVisibilityChanged(changedView, visibility);
1065326d808b858359464b2ffeb84f2e0a8e0c79b600Adam Powell        }
1066326d808b858359464b2ffeb84f2e0a8e0c79b600Adam Powell    }
1067326d808b858359464b2ffeb84f2e0a8e0c79b600Adam Powell
1068326d808b858359464b2ffeb84f2e0a8e0c79b600Adam Powell    /**
1069326d808b858359464b2ffeb84f2e0a8e0c79b600Adam Powell     * {@inheritDoc}
1070326d808b858359464b2ffeb84f2e0a8e0c79b600Adam Powell     */
1071326d808b858359464b2ffeb84f2e0a8e0c79b600Adam Powell    @Override
10729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void dispatchWindowVisibilityChanged(int visibility) {
10739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        super.dispatchWindowVisibilityChanged(visibility);
10749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final int count = mChildrenCount;
10759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final View[] children = mChildren;
10769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (int i = 0; i < count; i++) {
10779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            children[i].dispatchWindowVisibilityChanged(visibility);
10789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
10799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
10809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
10829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@inheritDoc}
1083e36d6e277e49475076b7872d36ea6a5c5b996e9dDianne Hackborn     */
1084e36d6e277e49475076b7872d36ea6a5c5b996e9dDianne Hackborn    @Override
1085e36d6e277e49475076b7872d36ea6a5c5b996e9dDianne Hackborn    public void dispatchConfigurationChanged(Configuration newConfig) {
1086e36d6e277e49475076b7872d36ea6a5c5b996e9dDianne Hackborn        super.dispatchConfigurationChanged(newConfig);
1087e36d6e277e49475076b7872d36ea6a5c5b996e9dDianne Hackborn        final int count = mChildrenCount;
1088e36d6e277e49475076b7872d36ea6a5c5b996e9dDianne Hackborn        final View[] children = mChildren;
1089e36d6e277e49475076b7872d36ea6a5c5b996e9dDianne Hackborn        for (int i = 0; i < count; i++) {
1090e36d6e277e49475076b7872d36ea6a5c5b996e9dDianne Hackborn            children[i].dispatchConfigurationChanged(newConfig);
1091e36d6e277e49475076b7872d36ea6a5c5b996e9dDianne Hackborn        }
1092e36d6e277e49475076b7872d36ea6a5c5b996e9dDianne Hackborn    }
1093e36d6e277e49475076b7872d36ea6a5c5b996e9dDianne Hackborn
1094e36d6e277e49475076b7872d36ea6a5c5b996e9dDianne Hackborn    /**
1095e36d6e277e49475076b7872d36ea6a5c5b996e9dDianne Hackborn     * {@inheritDoc}
10969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
10979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void recomputeViewAttributes(View child) {
1098664644d9e012aa2a28ac96f305b1ce6499ec8806Joe Onorato        if (mAttachInfo != null && !mAttachInfo.mRecomputeGlobalAttributes) {
1099664644d9e012aa2a28ac96f305b1ce6499ec8806Joe Onorato            ViewParent parent = mParent;
1100664644d9e012aa2a28ac96f305b1ce6499ec8806Joe Onorato            if (parent != null) parent.recomputeViewAttributes(this);
1101664644d9e012aa2a28ac96f305b1ce6499ec8806Joe Onorato        }
11029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
11038506ab4ac062d0e1ccde136e5e2f4081560e0c11Romain Guy
11049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
11053a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn    void dispatchCollectViewAttributes(AttachInfo attachInfo, int visibility) {
11063a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn        if ((visibility & VISIBILITY_MASK) == VISIBLE) {
11073a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn            super.dispatchCollectViewAttributes(attachInfo, visibility);
11083a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn            final int count = mChildrenCount;
11093a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn            final View[] children = mChildren;
11103a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn            for (int i = 0; i < count; i++) {
11113a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn                final View child = children[i];
11123a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn                child.dispatchCollectViewAttributes(attachInfo,
11133a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn                        visibility | (child.mViewFlags&VISIBILITY_MASK));
11143a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn            }
11159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
11169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
11179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
11199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@inheritDoc}
11209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
11219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void bringChildToFront(View child) {
11229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int index = indexOfChild(child);
11239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (index >= 0) {
11249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            removeFromArray(index);
11259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            addInArray(child, mChildrenCount);
11269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            child.mParent = this;
1127cb96db8d144a01aa41ec396247c548d8aa496131Chet Haase            requestLayout();
1128cb96db8d144a01aa41ec396247c548d8aa496131Chet Haase            invalidate();
11299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
11309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
11319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11326410c0aaf13c9aec606b90ee942f2ac2d98b1609Romain Guy    private PointF getLocalPoint() {
11336410c0aaf13c9aec606b90ee942f2ac2d98b1609Romain Guy        if (mLocalPoint == null) mLocalPoint = new PointF();
11346410c0aaf13c9aec606b90ee942f2ac2d98b1609Romain Guy        return mLocalPoint;
11356410c0aaf13c9aec606b90ee942f2ac2d98b1609Romain Guy    }
11366410c0aaf13c9aec606b90ee942f2ac2d98b1609Romain Guy
11379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
11389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@inheritDoc}
1139a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate     */
11408a7259bdc2bd70b7d26998b1c552ab45e69cebb1Steve Block    // TODO: Write real docs
1141a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate    @Override
1142a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate    public boolean dispatchDragEvent(DragEvent event) {
1143a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate        boolean retval = false;
1144a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate        final float tx = event.mX;
1145a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate        final float ty = event.mY;
1146a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate
11476dd005b48138708762bfade0081d031a2a4a3822Dianne Hackborn        ViewRootImpl root = getViewRootImpl();
1148a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate
1149a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate        // Dispatch down the view hierarchy
11506410c0aaf13c9aec606b90ee942f2ac2d98b1609Romain Guy        final PointF localPoint = getLocalPoint();
11516410c0aaf13c9aec606b90ee942f2ac2d98b1609Romain Guy
1152a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate        switch (event.mAction) {
1153a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate        case DragEvent.ACTION_DRAG_STARTED: {
1154a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate            // clear state to recalculate which views we drag over
11559d1ab883293b047b654935b84d0803c8c383be91Chris Tate            mCurrentDragView = null;
1156a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate
115786cab1bd52197d6fa60786413fad9788d9236762Christopher Tate            // Set up our tracking of drag-started notifications
115886cab1bd52197d6fa60786413fad9788d9236762Christopher Tate            mCurrentDrag = DragEvent.obtain(event);
115986cab1bd52197d6fa60786413fad9788d9236762Christopher Tate            if (mDragNotifiedChildren == null) {
116086cab1bd52197d6fa60786413fad9788d9236762Christopher Tate                mDragNotifiedChildren = new HashSet<View>();
116186cab1bd52197d6fa60786413fad9788d9236762Christopher Tate            } else {
116286cab1bd52197d6fa60786413fad9788d9236762Christopher Tate                mDragNotifiedChildren.clear();
116386cab1bd52197d6fa60786413fad9788d9236762Christopher Tate            }
116486cab1bd52197d6fa60786413fad9788d9236762Christopher Tate
1165a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate            // Now dispatch down to our children, caching the responses
1166a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate            mChildAcceptsDrag = false;
1167a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate            final int count = mChildrenCount;
1168a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate            final View[] children = mChildren;
1169a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate            for (int i = 0; i < count; i++) {
11702c095f367779ef32130c72849936a2e3013c8492Christopher Tate                final View child = children[i];
11713d4bf17f49b82355b3b82d8bdaec4d65c4293bc9Christopher Tate                child.mPrivateFlags2 &= ~View.DRAG_MASK;
11722c095f367779ef32130c72849936a2e3013c8492Christopher Tate                if (child.getVisibility() == VISIBLE) {
117386cab1bd52197d6fa60786413fad9788d9236762Christopher Tate                    final boolean handled = notifyChildOfDrag(children[i]);
11742c095f367779ef32130c72849936a2e3013c8492Christopher Tate                    if (handled) {
11752c095f367779ef32130c72849936a2e3013c8492Christopher Tate                        mChildAcceptsDrag = true;
11762c095f367779ef32130c72849936a2e3013c8492Christopher Tate                    }
1177a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate                }
1178a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate            }
1179a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate
1180a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate            // Return HANDLED if one of our children can accept the drag
1181a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate            if (mChildAcceptsDrag) {
1182a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate                retval = true;
1183a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate            }
1184a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate        } break;
1185a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate
1186a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate        case DragEvent.ACTION_DRAG_ENDED: {
118786cab1bd52197d6fa60786413fad9788d9236762Christopher Tate            // Release the bookkeeping now that the drag lifecycle has ended
11881fc014fd0051a48083c6d469c2a4f22da1aa15e4Christopher Tate            if (mDragNotifiedChildren != null) {
11891fc014fd0051a48083c6d469c2a4f22da1aa15e4Christopher Tate                for (View child : mDragNotifiedChildren) {
11901fc014fd0051a48083c6d469c2a4f22da1aa15e4Christopher Tate                    // If a child was notified about an ongoing drag, it's told that it's over
11911fc014fd0051a48083c6d469c2a4f22da1aa15e4Christopher Tate                    child.dispatchDragEvent(event);
11923d4bf17f49b82355b3b82d8bdaec4d65c4293bc9Christopher Tate                    child.mPrivateFlags2 &= ~View.DRAG_MASK;
11933d4bf17f49b82355b3b82d8bdaec4d65c4293bc9Christopher Tate                    child.refreshDrawableState();
11941fc014fd0051a48083c6d469c2a4f22da1aa15e4Christopher Tate                }
11951fc014fd0051a48083c6d469c2a4f22da1aa15e4Christopher Tate
11961fc014fd0051a48083c6d469c2a4f22da1aa15e4Christopher Tate                mDragNotifiedChildren.clear();
1197e9accff210c25b0a4946925db699874331c8cb61Christopher Tate                if (mCurrentDrag != null) {
1198e9accff210c25b0a4946925db699874331c8cb61Christopher Tate                    mCurrentDrag.recycle();
1199e9accff210c25b0a4946925db699874331c8cb61Christopher Tate                    mCurrentDrag = null;
1200e9accff210c25b0a4946925db699874331c8cb61Christopher Tate                }
12011fc014fd0051a48083c6d469c2a4f22da1aa15e4Christopher Tate            }
120286cab1bd52197d6fa60786413fad9788d9236762Christopher Tate
1203a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate            // We consider drag-ended to have been handled if one of our children
1204a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate            // had offered to handle the drag.
1205a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate            if (mChildAcceptsDrag) {
1206a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate                retval = true;
1207a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate            }
1208a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate        } break;
1209a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate
1210a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate        case DragEvent.ACTION_DRAG_LOCATION: {
1211a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate            // Find the [possibly new] drag target
12126410c0aaf13c9aec606b90ee942f2ac2d98b1609Romain Guy            final View target = findFrontmostDroppableChildAt(event.mX, event.mY, localPoint);
1213a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate
1214a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate            // If we've changed apparent drag target, tell the view root which view
12159d1ab883293b047b654935b84d0803c8c383be91Chris Tate            // we're over now [for purposes of the eventual drag-recipient-changed
12169d1ab883293b047b654935b84d0803c8c383be91Chris Tate            // notifications to the framework] and tell the new target that the drag
12179d1ab883293b047b654935b84d0803c8c383be91Chris Tate            // has entered its bounds.  The root will see setDragFocus() calls all
12189d1ab883293b047b654935b84d0803c8c383be91Chris Tate            // the way down to the final leaf view that is handling the LOCATION event
12199d1ab883293b047b654935b84d0803c8c383be91Chris Tate            // before reporting the new potential recipient to the framework.
1220a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate            if (mCurrentDragView != target) {
12219d1ab883293b047b654935b84d0803c8c383be91Chris Tate                root.setDragFocus(target);
12229d1ab883293b047b654935b84d0803c8c383be91Chris Tate
12239d1ab883293b047b654935b84d0803c8c383be91Chris Tate                final int action = event.mAction;
12249d1ab883293b047b654935b84d0803c8c383be91Chris Tate                // If we've dragged off of a child view, send it the EXITED message
12259d1ab883293b047b654935b84d0803c8c383be91Chris Tate                if (mCurrentDragView != null) {
12263d4bf17f49b82355b3b82d8bdaec4d65c4293bc9Christopher Tate                    final View view = mCurrentDragView;
12279d1ab883293b047b654935b84d0803c8c383be91Chris Tate                    event.mAction = DragEvent.ACTION_DRAG_EXITED;
12283d4bf17f49b82355b3b82d8bdaec4d65c4293bc9Christopher Tate                    view.dispatchDragEvent(event);
12294702a856973a553deb82f71b1d3b6c3db5dbf4baDianne Hackborn                    view.mPrivateFlags2 &= ~View.PFLAG2_DRAG_HOVERED;
12303d4bf17f49b82355b3b82d8bdaec4d65c4293bc9Christopher Tate                    view.refreshDrawableState();
12319d1ab883293b047b654935b84d0803c8c383be91Chris Tate                }
1232a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate                mCurrentDragView = target;
12339d1ab883293b047b654935b84d0803c8c383be91Chris Tate
12349d1ab883293b047b654935b84d0803c8c383be91Chris Tate                // If we've dragged over a new child view, send it the ENTERED message
12359d1ab883293b047b654935b84d0803c8c383be91Chris Tate                if (target != null) {
12369d1ab883293b047b654935b84d0803c8c383be91Chris Tate                    event.mAction = DragEvent.ACTION_DRAG_ENTERED;
12379d1ab883293b047b654935b84d0803c8c383be91Chris Tate                    target.dispatchDragEvent(event);
12384702a856973a553deb82f71b1d3b6c3db5dbf4baDianne Hackborn                    target.mPrivateFlags2 |= View.PFLAG2_DRAG_HOVERED;
12393d4bf17f49b82355b3b82d8bdaec4d65c4293bc9Christopher Tate                    target.refreshDrawableState();
12409d1ab883293b047b654935b84d0803c8c383be91Chris Tate                }
12419d1ab883293b047b654935b84d0803c8c383be91Chris Tate                event.mAction = action;  // restore the event's original state
1242a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate            }
12432c095f367779ef32130c72849936a2e3013c8492Christopher Tate
1244a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate            // Dispatch the actual drag location notice, localized into its coordinates
1245a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate            if (target != null) {
12466410c0aaf13c9aec606b90ee942f2ac2d98b1609Romain Guy                event.mX = localPoint.x;
12476410c0aaf13c9aec606b90ee942f2ac2d98b1609Romain Guy                event.mY = localPoint.y;
1248a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate
1249a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate                retval = target.dispatchDragEvent(event);
1250a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate
1251a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate                event.mX = tx;
1252a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate                event.mY = ty;
1253a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate            }
1254a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate        } break;
1255a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate
12569d1ab883293b047b654935b84d0803c8c383be91Chris Tate        /* Entered / exited dispatch
12579d1ab883293b047b654935b84d0803c8c383be91Chris Tate         *
12589d1ab883293b047b654935b84d0803c8c383be91Chris Tate         * DRAG_ENTERED is not dispatched downwards from ViewGroup.  The reason for this is
12599d1ab883293b047b654935b84d0803c8c383be91Chris Tate         * that we're about to get the corresponding LOCATION event, which we will use to
12609d1ab883293b047b654935b84d0803c8c383be91Chris Tate         * determine which of our children is the new target; at that point we will
12619d1ab883293b047b654935b84d0803c8c383be91Chris Tate         * push a DRAG_ENTERED down to the new target child [which may itself be a ViewGroup].
12629d1ab883293b047b654935b84d0803c8c383be91Chris Tate         *
12639d1ab883293b047b654935b84d0803c8c383be91Chris Tate         * DRAG_EXITED *is* dispatched all the way down immediately: once we know the
12649d1ab883293b047b654935b84d0803c8c383be91Chris Tate         * drag has left this ViewGroup, we know by definition that every contained subview
12659d1ab883293b047b654935b84d0803c8c383be91Chris Tate         * is also no longer under the drag point.
12669d1ab883293b047b654935b84d0803c8c383be91Chris Tate         */
12679d1ab883293b047b654935b84d0803c8c383be91Chris Tate
12689d1ab883293b047b654935b84d0803c8c383be91Chris Tate        case DragEvent.ACTION_DRAG_EXITED: {
12699d1ab883293b047b654935b84d0803c8c383be91Chris Tate            if (mCurrentDragView != null) {
12703d4bf17f49b82355b3b82d8bdaec4d65c4293bc9Christopher Tate                final View view = mCurrentDragView;
12713d4bf17f49b82355b3b82d8bdaec4d65c4293bc9Christopher Tate                view.dispatchDragEvent(event);
12724702a856973a553deb82f71b1d3b6c3db5dbf4baDianne Hackborn                view.mPrivateFlags2 &= ~View.PFLAG2_DRAG_HOVERED;
12733d4bf17f49b82355b3b82d8bdaec4d65c4293bc9Christopher Tate                view.refreshDrawableState();
12743d4bf17f49b82355b3b82d8bdaec4d65c4293bc9Christopher Tate
12759d1ab883293b047b654935b84d0803c8c383be91Chris Tate                mCurrentDragView = null;
12769d1ab883293b047b654935b84d0803c8c383be91Chris Tate            }
12779d1ab883293b047b654935b84d0803c8c383be91Chris Tate        } break;
12789d1ab883293b047b654935b84d0803c8c383be91Chris Tate
1279a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate        case DragEvent.ACTION_DROP: {
12802c095f367779ef32130c72849936a2e3013c8492Christopher Tate            if (ViewDebug.DEBUG_DRAG) Log.d(View.VIEW_LOG_TAG, "Drop event: " + event);
12816410c0aaf13c9aec606b90ee942f2ac2d98b1609Romain Guy            View target = findFrontmostDroppableChildAt(event.mX, event.mY, localPoint);
1282a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate            if (target != null) {
12835ada6cb0591c1106e3591a3b7adcdc77a1322209Christopher Tate                if (ViewDebug.DEBUG_DRAG) Log.d(View.VIEW_LOG_TAG, "   dispatch drop to " + target);
12846410c0aaf13c9aec606b90ee942f2ac2d98b1609Romain Guy                event.mX = localPoint.x;
12856410c0aaf13c9aec606b90ee942f2ac2d98b1609Romain Guy                event.mY = localPoint.y;
1286a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate                retval = target.dispatchDragEvent(event);
1287a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate                event.mX = tx;
1288a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate                event.mY = ty;
12895ada6cb0591c1106e3591a3b7adcdc77a1322209Christopher Tate            } else {
12905ada6cb0591c1106e3591a3b7adcdc77a1322209Christopher Tate                if (ViewDebug.DEBUG_DRAG) {
12915ada6cb0591c1106e3591a3b7adcdc77a1322209Christopher Tate                    Log.d(View.VIEW_LOG_TAG, "   not dropped on an accepting view");
12925ada6cb0591c1106e3591a3b7adcdc77a1322209Christopher Tate                }
1293a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate            }
1294a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate        } break;
1295a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate        }
1296a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate
1297a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate        // If none of our children could handle the event, try here
1298a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate        if (!retval) {
129932affef4f86961c57d9ba14572ec65dc2a5451deChris Tate            // Call up to the View implementation that dispatches to installed listeners
130032affef4f86961c57d9ba14572ec65dc2a5451deChris Tate            retval = super.dispatchDragEvent(event);
1301a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate        }
1302a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate        return retval;
1303a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate    }
1304a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate
1305a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate    // Find the frontmost child view that lies under the given point, and calculate
1306a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate    // the position within its own local coordinate system.
1307a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate    View findFrontmostDroppableChildAt(float x, float y, PointF outLocalPoint) {
1308a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate        final int count = mChildrenCount;
1309a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate        final View[] children = mChildren;
1310a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate        for (int i = count - 1; i >= 0; i--) {
1311a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate            final View child = children[i];
13123d4bf17f49b82355b3b82d8bdaec4d65c4293bc9Christopher Tate            if (!child.canAcceptDrag()) {
1313a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate                continue;
1314a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate            }
1315a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate
13162c095f367779ef32130c72849936a2e3013c8492Christopher Tate            if (isTransformedTouchPointInView(x, y, child, outLocalPoint)) {
1317a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate                return child;
1318a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate            }
1319a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate        }
1320a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate        return null;
1321a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate    }
1322a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate
132386cab1bd52197d6fa60786413fad9788d9236762Christopher Tate    boolean notifyChildOfDrag(View child) {
132486cab1bd52197d6fa60786413fad9788d9236762Christopher Tate        if (ViewDebug.DEBUG_DRAG) {
132586cab1bd52197d6fa60786413fad9788d9236762Christopher Tate            Log.d(View.VIEW_LOG_TAG, "Sending drag-started to view: " + child);
132686cab1bd52197d6fa60786413fad9788d9236762Christopher Tate        }
132786cab1bd52197d6fa60786413fad9788d9236762Christopher Tate
13283d4bf17f49b82355b3b82d8bdaec4d65c4293bc9Christopher Tate        boolean canAccept = false;
132986cab1bd52197d6fa60786413fad9788d9236762Christopher Tate        if (! mDragNotifiedChildren.contains(child)) {
133086cab1bd52197d6fa60786413fad9788d9236762Christopher Tate            mDragNotifiedChildren.add(child);
13313d4bf17f49b82355b3b82d8bdaec4d65c4293bc9Christopher Tate            canAccept = child.dispatchDragEvent(mCurrentDrag);
13323d4bf17f49b82355b3b82d8bdaec4d65c4293bc9Christopher Tate            if (canAccept && !child.canAcceptDrag()) {
13334702a856973a553deb82f71b1d3b6c3db5dbf4baDianne Hackborn                child.mPrivateFlags2 |= View.PFLAG2_DRAG_CAN_ACCEPT;
13343d4bf17f49b82355b3b82d8bdaec4d65c4293bc9Christopher Tate                child.refreshDrawableState();
13353d4bf17f49b82355b3b82d8bdaec4d65c4293bc9Christopher Tate            }
133686cab1bd52197d6fa60786413fad9788d9236762Christopher Tate        }
13373d4bf17f49b82355b3b82d8bdaec4d65c4293bc9Christopher Tate        return canAccept;
133886cab1bd52197d6fa60786413fad9788d9236762Christopher Tate    }
133986cab1bd52197d6fa60786413fad9788d9236762Christopher Tate
1340664644d9e012aa2a28ac96f305b1ce6499ec8806Joe Onorato    @Override
13413a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn    public void dispatchWindowSystemUiVisiblityChanged(int visible) {
13423a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn        super.dispatchWindowSystemUiVisiblityChanged(visible);
13433a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn
13443a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn        final int count = mChildrenCount;
13453a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn        final View[] children = mChildren;
13463a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn        for (int i=0; i <count; i++) {
13473a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn            final View child = children[i];
13483a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn            child.dispatchWindowSystemUiVisiblityChanged(visible);
13493a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn        }
13503a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn    }
13513a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn
13523a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn    @Override
1353664644d9e012aa2a28ac96f305b1ce6499ec8806Joe Onorato    public void dispatchSystemUiVisibilityChanged(int visible) {
1354664644d9e012aa2a28ac96f305b1ce6499ec8806Joe Onorato        super.dispatchSystemUiVisibilityChanged(visible);
1355664644d9e012aa2a28ac96f305b1ce6499ec8806Joe Onorato
1356664644d9e012aa2a28ac96f305b1ce6499ec8806Joe Onorato        final int count = mChildrenCount;
1357664644d9e012aa2a28ac96f305b1ce6499ec8806Joe Onorato        final View[] children = mChildren;
1358664644d9e012aa2a28ac96f305b1ce6499ec8806Joe Onorato        for (int i=0; i <count; i++) {
1359664644d9e012aa2a28ac96f305b1ce6499ec8806Joe Onorato            final View child = children[i];
1360664644d9e012aa2a28ac96f305b1ce6499ec8806Joe Onorato            child.dispatchSystemUiVisibilityChanged(visible);
1361664644d9e012aa2a28ac96f305b1ce6499ec8806Joe Onorato        }
1362664644d9e012aa2a28ac96f305b1ce6499ec8806Joe Onorato    }
1363664644d9e012aa2a28ac96f305b1ce6499ec8806Joe Onorato
13649a230e01a1237749a8a19a5de8d46531b0c8ca6aDianne Hackborn    @Override
1365cf67578c7f99492273a8f8446dd18ddc5af2ae76Dianne Hackborn    boolean updateLocalSystemUiVisibility(int localValue, int localChanges) {
1366cf67578c7f99492273a8f8446dd18ddc5af2ae76Dianne Hackborn        boolean changed = super.updateLocalSystemUiVisibility(localValue, localChanges);
13679a230e01a1237749a8a19a5de8d46531b0c8ca6aDianne Hackborn
13689a230e01a1237749a8a19a5de8d46531b0c8ca6aDianne Hackborn        final int count = mChildrenCount;
13699a230e01a1237749a8a19a5de8d46531b0c8ca6aDianne Hackborn        final View[] children = mChildren;
13709a230e01a1237749a8a19a5de8d46531b0c8ca6aDianne Hackborn        for (int i=0; i <count; i++) {
13719a230e01a1237749a8a19a5de8d46531b0c8ca6aDianne Hackborn            final View child = children[i];
1372cf67578c7f99492273a8f8446dd18ddc5af2ae76Dianne Hackborn            changed |= child.updateLocalSystemUiVisibility(localValue, localChanges);
13739a230e01a1237749a8a19a5de8d46531b0c8ca6aDianne Hackborn        }
1374cf67578c7f99492273a8f8446dd18ddc5af2ae76Dianne Hackborn        return changed;
13759a230e01a1237749a8a19a5de8d46531b0c8ca6aDianne Hackborn    }
13769a230e01a1237749a8a19a5de8d46531b0c8ca6aDianne Hackborn
1377a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate    /**
1378a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate     * {@inheritDoc}
13799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
13809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
13819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean dispatchKeyEventPreIme(KeyEvent event) {
13824702a856973a553deb82f71b1d3b6c3db5dbf4baDianne Hackborn        if ((mPrivateFlags & (PFLAG_FOCUSED | PFLAG_HAS_BOUNDS))
13834702a856973a553deb82f71b1d3b6c3db5dbf4baDianne Hackborn                == (PFLAG_FOCUSED | PFLAG_HAS_BOUNDS)) {
13849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return super.dispatchKeyEventPreIme(event);
13854702a856973a553deb82f71b1d3b6c3db5dbf4baDianne Hackborn        } else if (mFocused != null && (mFocused.mPrivateFlags & PFLAG_HAS_BOUNDS)
13864702a856973a553deb82f71b1d3b6c3db5dbf4baDianne Hackborn                == PFLAG_HAS_BOUNDS) {
13879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return mFocused.dispatchKeyEventPreIme(event);
13889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
13899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return false;
13909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
13919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
13929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
13939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@inheritDoc}
13949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
13959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
13969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean dispatchKeyEvent(KeyEvent event) {
139721bc5c917d4ee2a9b2b8173091e6bba85eaff899Jeff Brown        if (mInputEventConsistencyVerifier != null) {
139821bc5c917d4ee2a9b2b8173091e6bba85eaff899Jeff Brown            mInputEventConsistencyVerifier.onKeyEvent(event, 1);
139921bc5c917d4ee2a9b2b8173091e6bba85eaff899Jeff Brown        }
140021bc5c917d4ee2a9b2b8173091e6bba85eaff899Jeff Brown
14014702a856973a553deb82f71b1d3b6c3db5dbf4baDianne Hackborn        if ((mPrivateFlags & (PFLAG_FOCUSED | PFLAG_HAS_BOUNDS))
14024702a856973a553deb82f71b1d3b6c3db5dbf4baDianne Hackborn                == (PFLAG_FOCUSED | PFLAG_HAS_BOUNDS)) {
1403bbdc50b102faf52768ac3028bc49e027ff140656Jeff Brown            if (super.dispatchKeyEvent(event)) {
1404bbdc50b102faf52768ac3028bc49e027ff140656Jeff Brown                return true;
1405bbdc50b102faf52768ac3028bc49e027ff140656Jeff Brown            }
14064702a856973a553deb82f71b1d3b6c3db5dbf4baDianne Hackborn        } else if (mFocused != null && (mFocused.mPrivateFlags & PFLAG_HAS_BOUNDS)
14074702a856973a553deb82f71b1d3b6c3db5dbf4baDianne Hackborn                == PFLAG_HAS_BOUNDS) {
1408bbdc50b102faf52768ac3028bc49e027ff140656Jeff Brown            if (mFocused.dispatchKeyEvent(event)) {
1409bbdc50b102faf52768ac3028bc49e027ff140656Jeff Brown                return true;
1410bbdc50b102faf52768ac3028bc49e027ff140656Jeff Brown            }
1411bbdc50b102faf52768ac3028bc49e027ff140656Jeff Brown        }
1412bbdc50b102faf52768ac3028bc49e027ff140656Jeff Brown
1413bbdc50b102faf52768ac3028bc49e027ff140656Jeff Brown        if (mInputEventConsistencyVerifier != null) {
1414bbdc50b102faf52768ac3028bc49e027ff140656Jeff Brown            mInputEventConsistencyVerifier.onUnhandledEvent(event, 1);
14159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
14169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return false;
14179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
14189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
14199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
14209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@inheritDoc}
14219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
14229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
14239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean dispatchKeyShortcutEvent(KeyEvent event) {
14244702a856973a553deb82f71b1d3b6c3db5dbf4baDianne Hackborn        if ((mPrivateFlags & (PFLAG_FOCUSED | PFLAG_HAS_BOUNDS))
14254702a856973a553deb82f71b1d3b6c3db5dbf4baDianne Hackborn                == (PFLAG_FOCUSED | PFLAG_HAS_BOUNDS)) {
14269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return super.dispatchKeyShortcutEvent(event);
14274702a856973a553deb82f71b1d3b6c3db5dbf4baDianne Hackborn        } else if (mFocused != null && (mFocused.mPrivateFlags & PFLAG_HAS_BOUNDS)
14284702a856973a553deb82f71b1d3b6c3db5dbf4baDianne Hackborn                == PFLAG_HAS_BOUNDS) {
14299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return mFocused.dispatchKeyShortcutEvent(event);
14309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
14319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return false;
14329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
14339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
14349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
14359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@inheritDoc}
14369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
14379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
14389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean dispatchTrackballEvent(MotionEvent event) {
143921bc5c917d4ee2a9b2b8173091e6bba85eaff899Jeff Brown        if (mInputEventConsistencyVerifier != null) {
144021bc5c917d4ee2a9b2b8173091e6bba85eaff899Jeff Brown            mInputEventConsistencyVerifier.onTrackballEvent(event, 1);
144121bc5c917d4ee2a9b2b8173091e6bba85eaff899Jeff Brown        }
144221bc5c917d4ee2a9b2b8173091e6bba85eaff899Jeff Brown
14434702a856973a553deb82f71b1d3b6c3db5dbf4baDianne Hackborn        if ((mPrivateFlags & (PFLAG_FOCUSED | PFLAG_HAS_BOUNDS))
14444702a856973a553deb82f71b1d3b6c3db5dbf4baDianne Hackborn                == (PFLAG_FOCUSED | PFLAG_HAS_BOUNDS)) {
1445bbdc50b102faf52768ac3028bc49e027ff140656Jeff Brown            if (super.dispatchTrackballEvent(event)) {
1446bbdc50b102faf52768ac3028bc49e027ff140656Jeff Brown                return true;
1447bbdc50b102faf52768ac3028bc49e027ff140656Jeff Brown            }
14484702a856973a553deb82f71b1d3b6c3db5dbf4baDianne Hackborn        } else if (mFocused != null && (mFocused.mPrivateFlags & PFLAG_HAS_BOUNDS)
14494702a856973a553deb82f71b1d3b6c3db5dbf4baDianne Hackborn                == PFLAG_HAS_BOUNDS) {
1450bbdc50b102faf52768ac3028bc49e027ff140656Jeff Brown            if (mFocused.dispatchTrackballEvent(event)) {
1451bbdc50b102faf52768ac3028bc49e027ff140656Jeff Brown                return true;
1452bbdc50b102faf52768ac3028bc49e027ff140656Jeff Brown            }
1453bbdc50b102faf52768ac3028bc49e027ff140656Jeff Brown        }
1454bbdc50b102faf52768ac3028bc49e027ff140656Jeff Brown
1455bbdc50b102faf52768ac3028bc49e027ff140656Jeff Brown        if (mInputEventConsistencyVerifier != null) {
1456bbdc50b102faf52768ac3028bc49e027ff140656Jeff Brown            mInputEventConsistencyVerifier.onUnhandledEvent(event, 1);
14579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
14589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return false;
14599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
14609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
146110b6290c5f15ae512a2f6b5bf8d95bd2527c7235Jeff Brown    /**
146210b6290c5f15ae512a2f6b5bf8d95bd2527c7235Jeff Brown     * {@inheritDoc}
146310b6290c5f15ae512a2f6b5bf8d95bd2527c7235Jeff Brown     */
1464a9489274d67b540804aafb587a226f7c2ae4464dRomain Guy    @SuppressWarnings({"ConstantConditions"})
14659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
1466a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown    protected boolean dispatchHoverEvent(MotionEvent event) {
1467a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown        final int action = event.getAction();
1468a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown
146910b6290c5f15ae512a2f6b5bf8d95bd2527c7235Jeff Brown        // First check whether the view group wants to intercept the hover event.
147010b6290c5f15ae512a2f6b5bf8d95bd2527c7235Jeff Brown        final boolean interceptHover = onInterceptHoverEvent(event);
147110b6290c5f15ae512a2f6b5bf8d95bd2527c7235Jeff Brown        event.setAction(action); // restore action in case it was changed
147210b6290c5f15ae512a2f6b5bf8d95bd2527c7235Jeff Brown
147387b7f805b94f5df53343264509f6d606d96dfb05Jeff Brown        MotionEvent eventNoHistory = event;
147487b7f805b94f5df53343264509f6d606d96dfb05Jeff Brown        boolean handled = false;
147587b7f805b94f5df53343264509f6d606d96dfb05Jeff Brown
147687b7f805b94f5df53343264509f6d606d96dfb05Jeff Brown        // Send events to the hovered children and build a new list of hover targets until
147787b7f805b94f5df53343264509f6d606d96dfb05Jeff Brown        // one is found that handles the event.
147887b7f805b94f5df53343264509f6d606d96dfb05Jeff Brown        HoverTarget firstOldHoverTarget = mFirstHoverTarget;
147987b7f805b94f5df53343264509f6d606d96dfb05Jeff Brown        mFirstHoverTarget = null;
148010b6290c5f15ae512a2f6b5bf8d95bd2527c7235Jeff Brown        if (!interceptHover && action != MotionEvent.ACTION_HOVER_EXIT) {
1481a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown            final float x = event.getX();
1482a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown            final float y = event.getY();
148333bbfd2232ea9eaae9a9d87a05a95a430f09bd83Jeff Brown            final int childrenCount = mChildrenCount;
148433bbfd2232ea9eaae9a9d87a05a95a430f09bd83Jeff Brown            if (childrenCount != 0) {
14850e5e9aa8e5528d4a09b861f10b599ee7a1cf7a32Svetoslav                final boolean customChildOrder = isChildrenDrawingOrderEnabled();
148633bbfd2232ea9eaae9a9d87a05a95a430f09bd83Jeff Brown                final View[] children = mChildren;
148787b7f805b94f5df53343264509f6d606d96dfb05Jeff Brown                HoverTarget lastHoverTarget = null;
148833bbfd2232ea9eaae9a9d87a05a95a430f09bd83Jeff Brown                for (int i = childrenCount - 1; i >= 0; i--) {
14890e5e9aa8e5528d4a09b861f10b599ee7a1cf7a32Svetoslav                    final int childIndex = customChildOrder
14900e5e9aa8e5528d4a09b861f10b599ee7a1cf7a32Svetoslav                            ? getChildDrawingOrder(childrenCount, i) : i;
14910e5e9aa8e5528d4a09b861f10b599ee7a1cf7a32Svetoslav                    final View child = children[childIndex];
149287b7f805b94f5df53343264509f6d606d96dfb05Jeff Brown                    if (!canViewReceivePointerEvents(child)
149387b7f805b94f5df53343264509f6d606d96dfb05Jeff Brown                            || !isTransformedTouchPointInView(x, y, child, null)) {
149487b7f805b94f5df53343264509f6d606d96dfb05Jeff Brown                        continue;
149587b7f805b94f5df53343264509f6d606d96dfb05Jeff Brown                    }
149687b7f805b94f5df53343264509f6d606d96dfb05Jeff Brown
149787b7f805b94f5df53343264509f6d606d96dfb05Jeff Brown                    // Obtain a hover target for this child.  Dequeue it from the
149887b7f805b94f5df53343264509f6d606d96dfb05Jeff Brown                    // old hover target list if the child was previously hovered.
149987b7f805b94f5df53343264509f6d606d96dfb05Jeff Brown                    HoverTarget hoverTarget = firstOldHoverTarget;
150087b7f805b94f5df53343264509f6d606d96dfb05Jeff Brown                    final boolean wasHovered;
150187b7f805b94f5df53343264509f6d606d96dfb05Jeff Brown                    for (HoverTarget predecessor = null; ;) {
150287b7f805b94f5df53343264509f6d606d96dfb05Jeff Brown                        if (hoverTarget == null) {
150387b7f805b94f5df53343264509f6d606d96dfb05Jeff Brown                            hoverTarget = HoverTarget.obtain(child);
150487b7f805b94f5df53343264509f6d606d96dfb05Jeff Brown                            wasHovered = false;
150587b7f805b94f5df53343264509f6d606d96dfb05Jeff Brown                            break;
150687b7f805b94f5df53343264509f6d606d96dfb05Jeff Brown                        }
150787b7f805b94f5df53343264509f6d606d96dfb05Jeff Brown
150887b7f805b94f5df53343264509f6d606d96dfb05Jeff Brown                        if (hoverTarget.child == child) {
150987b7f805b94f5df53343264509f6d606d96dfb05Jeff Brown                            if (predecessor != null) {
151087b7f805b94f5df53343264509f6d606d96dfb05Jeff Brown                                predecessor.next = hoverTarget.next;
151187b7f805b94f5df53343264509f6d606d96dfb05Jeff Brown                            } else {
151287b7f805b94f5df53343264509f6d606d96dfb05Jeff Brown                                firstOldHoverTarget = hoverTarget.next;
151387b7f805b94f5df53343264509f6d606d96dfb05Jeff Brown                            }
151487b7f805b94f5df53343264509f6d606d96dfb05Jeff Brown                            hoverTarget.next = null;
151587b7f805b94f5df53343264509f6d606d96dfb05Jeff Brown                            wasHovered = true;
151687b7f805b94f5df53343264509f6d606d96dfb05Jeff Brown                            break;
151787b7f805b94f5df53343264509f6d606d96dfb05Jeff Brown                        }
151887b7f805b94f5df53343264509f6d606d96dfb05Jeff Brown
151987b7f805b94f5df53343264509f6d606d96dfb05Jeff Brown                        predecessor = hoverTarget;
152087b7f805b94f5df53343264509f6d606d96dfb05Jeff Brown                        hoverTarget = hoverTarget.next;
152187b7f805b94f5df53343264509f6d606d96dfb05Jeff Brown                    }
152287b7f805b94f5df53343264509f6d606d96dfb05Jeff Brown
152387b7f805b94f5df53343264509f6d606d96dfb05Jeff Brown                    // Enqueue the hover target onto the new hover target list.
152487b7f805b94f5df53343264509f6d606d96dfb05Jeff Brown                    if (lastHoverTarget != null) {
152587b7f805b94f5df53343264509f6d606d96dfb05Jeff Brown                        lastHoverTarget.next = hoverTarget;
152687b7f805b94f5df53343264509f6d606d96dfb05Jeff Brown                    } else {
152787b7f805b94f5df53343264509f6d606d96dfb05Jeff Brown                        mFirstHoverTarget = hoverTarget;
152887b7f805b94f5df53343264509f6d606d96dfb05Jeff Brown                    }
15298725f36a76bdf85d7197e64fb725b67e993c6ce7Sangkyu Lee                    lastHoverTarget = hoverTarget;
153087b7f805b94f5df53343264509f6d606d96dfb05Jeff Brown
153187b7f805b94f5df53343264509f6d606d96dfb05Jeff Brown                    // Dispatch the event to the child.
153287b7f805b94f5df53343264509f6d606d96dfb05Jeff Brown                    if (action == MotionEvent.ACTION_HOVER_ENTER) {
153387b7f805b94f5df53343264509f6d606d96dfb05Jeff Brown                        if (!wasHovered) {
153487b7f805b94f5df53343264509f6d606d96dfb05Jeff Brown                            // Send the enter as is.
153587b7f805b94f5df53343264509f6d606d96dfb05Jeff Brown                            handled |= dispatchTransformedGenericPointerEvent(
153687b7f805b94f5df53343264509f6d606d96dfb05Jeff Brown                                    event, child); // enter
153787b7f805b94f5df53343264509f6d606d96dfb05Jeff Brown                        }
153887b7f805b94f5df53343264509f6d606d96dfb05Jeff Brown                    } else if (action == MotionEvent.ACTION_HOVER_MOVE) {
153987b7f805b94f5df53343264509f6d606d96dfb05Jeff Brown                        if (!wasHovered) {
154087b7f805b94f5df53343264509f6d606d96dfb05Jeff Brown                            // Synthesize an enter from a move.
154187b7f805b94f5df53343264509f6d606d96dfb05Jeff Brown                            eventNoHistory = obtainMotionEventNoHistoryOrSelf(eventNoHistory);
154287b7f805b94f5df53343264509f6d606d96dfb05Jeff Brown                            eventNoHistory.setAction(MotionEvent.ACTION_HOVER_ENTER);
154387b7f805b94f5df53343264509f6d606d96dfb05Jeff Brown                            handled |= dispatchTransformedGenericPointerEvent(
154487b7f805b94f5df53343264509f6d606d96dfb05Jeff Brown                                    eventNoHistory, child); // enter
154587b7f805b94f5df53343264509f6d606d96dfb05Jeff Brown                            eventNoHistory.setAction(action);
154687b7f805b94f5df53343264509f6d606d96dfb05Jeff Brown
154787b7f805b94f5df53343264509f6d606d96dfb05Jeff Brown                            handled |= dispatchTransformedGenericPointerEvent(
154887b7f805b94f5df53343264509f6d606d96dfb05Jeff Brown                                    eventNoHistory, child); // move
154987b7f805b94f5df53343264509f6d606d96dfb05Jeff Brown                        } else {
155087b7f805b94f5df53343264509f6d606d96dfb05Jeff Brown                            // Send the move as is.
155187b7f805b94f5df53343264509f6d606d96dfb05Jeff Brown                            handled |= dispatchTransformedGenericPointerEvent(event, child);
155287b7f805b94f5df53343264509f6d606d96dfb05Jeff Brown                        }
155387b7f805b94f5df53343264509f6d606d96dfb05Jeff Brown                    }
155487b7f805b94f5df53343264509f6d606d96dfb05Jeff Brown                    if (handled) {
155510b6290c5f15ae512a2f6b5bf8d95bd2527c7235Jeff Brown                        break;
155633bbfd2232ea9eaae9a9d87a05a95a430f09bd83Jeff Brown                    }
155710b6290c5f15ae512a2f6b5bf8d95bd2527c7235Jeff Brown                }
155810b6290c5f15ae512a2f6b5bf8d95bd2527c7235Jeff Brown            }
155910b6290c5f15ae512a2f6b5bf8d95bd2527c7235Jeff Brown        }
156033bbfd2232ea9eaae9a9d87a05a95a430f09bd83Jeff Brown
156187b7f805b94f5df53343264509f6d606d96dfb05Jeff Brown        // Send exit events to all previously hovered children that are no longer hovered.
156287b7f805b94f5df53343264509f6d606d96dfb05Jeff Brown        while (firstOldHoverTarget != null) {
156387b7f805b94f5df53343264509f6d606d96dfb05Jeff Brown            final View child = firstOldHoverTarget.child;
156410b6290c5f15ae512a2f6b5bf8d95bd2527c7235Jeff Brown
156587b7f805b94f5df53343264509f6d606d96dfb05Jeff Brown            // Exit the old hovered child.
156687b7f805b94f5df53343264509f6d606d96dfb05Jeff Brown            if (action == MotionEvent.ACTION_HOVER_EXIT) {
156787b7f805b94f5df53343264509f6d606d96dfb05Jeff Brown                // Send the exit as is.
156887b7f805b94f5df53343264509f6d606d96dfb05Jeff Brown                handled |= dispatchTransformedGenericPointerEvent(
156987b7f805b94f5df53343264509f6d606d96dfb05Jeff Brown                        event, child); // exit
157087b7f805b94f5df53343264509f6d606d96dfb05Jeff Brown            } else {
157187b7f805b94f5df53343264509f6d606d96dfb05Jeff Brown                // Synthesize an exit from a move or enter.
157287b7f805b94f5df53343264509f6d606d96dfb05Jeff Brown                // Ignore the result because hover focus has moved to a different view.
157387b7f805b94f5df53343264509f6d606d96dfb05Jeff Brown                if (action == MotionEvent.ACTION_HOVER_MOVE) {
157410b6290c5f15ae512a2f6b5bf8d95bd2527c7235Jeff Brown                    dispatchTransformedGenericPointerEvent(
157587b7f805b94f5df53343264509f6d606d96dfb05Jeff Brown                            event, child); // move
157610b6290c5f15ae512a2f6b5bf8d95bd2527c7235Jeff Brown                }
157787b7f805b94f5df53343264509f6d606d96dfb05Jeff Brown                eventNoHistory = obtainMotionEventNoHistoryOrSelf(eventNoHistory);
157887b7f805b94f5df53343264509f6d606d96dfb05Jeff Brown                eventNoHistory.setAction(MotionEvent.ACTION_HOVER_EXIT);
157987b7f805b94f5df53343264509f6d606d96dfb05Jeff Brown                dispatchTransformedGenericPointerEvent(
158087b7f805b94f5df53343264509f6d606d96dfb05Jeff Brown                        eventNoHistory, child); // exit
158187b7f805b94f5df53343264509f6d606d96dfb05Jeff Brown                eventNoHistory.setAction(action);
158210b6290c5f15ae512a2f6b5bf8d95bd2527c7235Jeff Brown            }
158310b6290c5f15ae512a2f6b5bf8d95bd2527c7235Jeff Brown
158487b7f805b94f5df53343264509f6d606d96dfb05Jeff Brown            final HoverTarget nextOldHoverTarget = firstOldHoverTarget.next;
158587b7f805b94f5df53343264509f6d606d96dfb05Jeff Brown            firstOldHoverTarget.recycle();
158687b7f805b94f5df53343264509f6d606d96dfb05Jeff Brown            firstOldHoverTarget = nextOldHoverTarget;
158710b6290c5f15ae512a2f6b5bf8d95bd2527c7235Jeff Brown        }
158810b6290c5f15ae512a2f6b5bf8d95bd2527c7235Jeff Brown
158987b7f805b94f5df53343264509f6d606d96dfb05Jeff Brown        // Send events to the view group itself if no children have handled it.
159010b6290c5f15ae512a2f6b5bf8d95bd2527c7235Jeff Brown        boolean newHoveredSelf = !handled;
159110b6290c5f15ae512a2f6b5bf8d95bd2527c7235Jeff Brown        if (newHoveredSelf == mHoveredSelf) {
159210b6290c5f15ae512a2f6b5bf8d95bd2527c7235Jeff Brown            if (newHoveredSelf) {
159310b6290c5f15ae512a2f6b5bf8d95bd2527c7235Jeff Brown                // Send event to the view group as before.
159410b6290c5f15ae512a2f6b5bf8d95bd2527c7235Jeff Brown                handled |= super.dispatchHoverEvent(event);
159510b6290c5f15ae512a2f6b5bf8d95bd2527c7235Jeff Brown            }
159610b6290c5f15ae512a2f6b5bf8d95bd2527c7235Jeff Brown        } else {
159710b6290c5f15ae512a2f6b5bf8d95bd2527c7235Jeff Brown            if (mHoveredSelf) {
159810b6290c5f15ae512a2f6b5bf8d95bd2527c7235Jeff Brown                // Exit the view group.
159910b6290c5f15ae512a2f6b5bf8d95bd2527c7235Jeff Brown                if (action == MotionEvent.ACTION_HOVER_EXIT) {
160010b6290c5f15ae512a2f6b5bf8d95bd2527c7235Jeff Brown                    // Send the exit as is.
160110b6290c5f15ae512a2f6b5bf8d95bd2527c7235Jeff Brown                    handled |= super.dispatchHoverEvent(event); // exit
160210b6290c5f15ae512a2f6b5bf8d95bd2527c7235Jeff Brown                } else {
160310b6290c5f15ae512a2f6b5bf8d95bd2527c7235Jeff Brown                    // Synthesize an exit from a move or enter.
160410b6290c5f15ae512a2f6b5bf8d95bd2527c7235Jeff Brown                    // Ignore the result because hover focus is moving to a different view.
160510b6290c5f15ae512a2f6b5bf8d95bd2527c7235Jeff Brown                    if (action == MotionEvent.ACTION_HOVER_MOVE) {
160610b6290c5f15ae512a2f6b5bf8d95bd2527c7235Jeff Brown                        super.dispatchHoverEvent(event); // move
160710b6290c5f15ae512a2f6b5bf8d95bd2527c7235Jeff Brown                    }
160810b6290c5f15ae512a2f6b5bf8d95bd2527c7235Jeff Brown                    eventNoHistory = obtainMotionEventNoHistoryOrSelf(eventNoHistory);
160910b6290c5f15ae512a2f6b5bf8d95bd2527c7235Jeff Brown                    eventNoHistory.setAction(MotionEvent.ACTION_HOVER_EXIT);
161010b6290c5f15ae512a2f6b5bf8d95bd2527c7235Jeff Brown                    super.dispatchHoverEvent(eventNoHistory); // exit
161110b6290c5f15ae512a2f6b5bf8d95bd2527c7235Jeff Brown                    eventNoHistory.setAction(action);
161210b6290c5f15ae512a2f6b5bf8d95bd2527c7235Jeff Brown                }
161310b6290c5f15ae512a2f6b5bf8d95bd2527c7235Jeff Brown                mHoveredSelf = false;
161410b6290c5f15ae512a2f6b5bf8d95bd2527c7235Jeff Brown            }
161510b6290c5f15ae512a2f6b5bf8d95bd2527c7235Jeff Brown
161610b6290c5f15ae512a2f6b5bf8d95bd2527c7235Jeff Brown            if (newHoveredSelf) {
161710b6290c5f15ae512a2f6b5bf8d95bd2527c7235Jeff Brown                // Enter the view group.
161810b6290c5f15ae512a2f6b5bf8d95bd2527c7235Jeff Brown                if (action == MotionEvent.ACTION_HOVER_ENTER) {
161910b6290c5f15ae512a2f6b5bf8d95bd2527c7235Jeff Brown                    // Send the enter as is.
162010b6290c5f15ae512a2f6b5bf8d95bd2527c7235Jeff Brown                    handled |= super.dispatchHoverEvent(event); // enter
162110b6290c5f15ae512a2f6b5bf8d95bd2527c7235Jeff Brown                    mHoveredSelf = true;
162210b6290c5f15ae512a2f6b5bf8d95bd2527c7235Jeff Brown                } else if (action == MotionEvent.ACTION_HOVER_MOVE) {
162310b6290c5f15ae512a2f6b5bf8d95bd2527c7235Jeff Brown                    // Synthesize an enter from a move.
162410b6290c5f15ae512a2f6b5bf8d95bd2527c7235Jeff Brown                    eventNoHistory = obtainMotionEventNoHistoryOrSelf(eventNoHistory);
162510b6290c5f15ae512a2f6b5bf8d95bd2527c7235Jeff Brown                    eventNoHistory.setAction(MotionEvent.ACTION_HOVER_ENTER);
162610b6290c5f15ae512a2f6b5bf8d95bd2527c7235Jeff Brown                    handled |= super.dispatchHoverEvent(eventNoHistory); // enter
162710b6290c5f15ae512a2f6b5bf8d95bd2527c7235Jeff Brown                    eventNoHistory.setAction(action);
162810b6290c5f15ae512a2f6b5bf8d95bd2527c7235Jeff Brown
162910b6290c5f15ae512a2f6b5bf8d95bd2527c7235Jeff Brown                    handled |= super.dispatchHoverEvent(eventNoHistory); // move
163010b6290c5f15ae512a2f6b5bf8d95bd2527c7235Jeff Brown                    mHoveredSelf = true;
1631a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown                }
1632a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown            }
1633a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown        }
163433bbfd2232ea9eaae9a9d87a05a95a430f09bd83Jeff Brown
1635a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown        // Recycle the copy of the event that we made.
1636a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown        if (eventNoHistory != event) {
1637a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown            eventNoHistory.recycle();
1638a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown        }
163933bbfd2232ea9eaae9a9d87a05a95a430f09bd83Jeff Brown
1640a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown        // Done.
1641a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown        return handled;
1642a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown    }
1643a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown
164459a422e90035ce5df45c526607db2d3303e3112eJeff Brown    private void exitHoverTargets() {
164559a422e90035ce5df45c526607db2d3303e3112eJeff Brown        if (mHoveredSelf || mFirstHoverTarget != null) {
164659a422e90035ce5df45c526607db2d3303e3112eJeff Brown            final long now = SystemClock.uptimeMillis();
164759a422e90035ce5df45c526607db2d3303e3112eJeff Brown            MotionEvent event = MotionEvent.obtain(now, now,
164859a422e90035ce5df45c526607db2d3303e3112eJeff Brown                    MotionEvent.ACTION_HOVER_EXIT, 0.0f, 0.0f, 0);
164959a422e90035ce5df45c526607db2d3303e3112eJeff Brown            event.setSource(InputDevice.SOURCE_TOUCHSCREEN);
165059a422e90035ce5df45c526607db2d3303e3112eJeff Brown            dispatchHoverEvent(event);
165159a422e90035ce5df45c526607db2d3303e3112eJeff Brown            event.recycle();
165259a422e90035ce5df45c526607db2d3303e3112eJeff Brown        }
165359a422e90035ce5df45c526607db2d3303e3112eJeff Brown    }
165459a422e90035ce5df45c526607db2d3303e3112eJeff Brown
165559a422e90035ce5df45c526607db2d3303e3112eJeff Brown    private void cancelHoverTarget(View view) {
165659a422e90035ce5df45c526607db2d3303e3112eJeff Brown        HoverTarget predecessor = null;
165759a422e90035ce5df45c526607db2d3303e3112eJeff Brown        HoverTarget target = mFirstHoverTarget;
165859a422e90035ce5df45c526607db2d3303e3112eJeff Brown        while (target != null) {
165959a422e90035ce5df45c526607db2d3303e3112eJeff Brown            final HoverTarget next = target.next;
166059a422e90035ce5df45c526607db2d3303e3112eJeff Brown            if (target.child == view) {
166159a422e90035ce5df45c526607db2d3303e3112eJeff Brown                if (predecessor == null) {
166259a422e90035ce5df45c526607db2d3303e3112eJeff Brown                    mFirstHoverTarget = next;
166359a422e90035ce5df45c526607db2d3303e3112eJeff Brown                } else {
166459a422e90035ce5df45c526607db2d3303e3112eJeff Brown                    predecessor.next = next;
166559a422e90035ce5df45c526607db2d3303e3112eJeff Brown                }
166659a422e90035ce5df45c526607db2d3303e3112eJeff Brown                target.recycle();
166759a422e90035ce5df45c526607db2d3303e3112eJeff Brown
166859a422e90035ce5df45c526607db2d3303e3112eJeff Brown                final long now = SystemClock.uptimeMillis();
166959a422e90035ce5df45c526607db2d3303e3112eJeff Brown                MotionEvent event = MotionEvent.obtain(now, now,
167059a422e90035ce5df45c526607db2d3303e3112eJeff Brown                        MotionEvent.ACTION_HOVER_EXIT, 0.0f, 0.0f, 0);
167159a422e90035ce5df45c526607db2d3303e3112eJeff Brown                event.setSource(InputDevice.SOURCE_TOUCHSCREEN);
167259a422e90035ce5df45c526607db2d3303e3112eJeff Brown                view.dispatchHoverEvent(event);
167359a422e90035ce5df45c526607db2d3303e3112eJeff Brown                event.recycle();
167459a422e90035ce5df45c526607db2d3303e3112eJeff Brown                return;
167559a422e90035ce5df45c526607db2d3303e3112eJeff Brown            }
167659a422e90035ce5df45c526607db2d3303e3112eJeff Brown            predecessor = target;
167759a422e90035ce5df45c526607db2d3303e3112eJeff Brown            target = next;
167859a422e90035ce5df45c526607db2d3303e3112eJeff Brown        }
167959a422e90035ce5df45c526607db2d3303e3112eJeff Brown    }
168059a422e90035ce5df45c526607db2d3303e3112eJeff Brown
168187b7f805b94f5df53343264509f6d606d96dfb05Jeff Brown    /** @hide */
168287b7f805b94f5df53343264509f6d606d96dfb05Jeff Brown    @Override
168387b7f805b94f5df53343264509f6d606d96dfb05Jeff Brown    protected boolean hasHoveredChild() {
168487b7f805b94f5df53343264509f6d606d96dfb05Jeff Brown        return mFirstHoverTarget != null;
168587b7f805b94f5df53343264509f6d606d96dfb05Jeff Brown    }
168687b7f805b94f5df53343264509f6d606d96dfb05Jeff Brown
16874213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov    @Override
16884213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov    public void addChildrenForAccessibility(ArrayList<View> childrenForAccessibility) {
168976f287e416ded85734b610f316e38d243d2ddb09Svetoslav Ganov        ChildListForAccessibility children = ChildListForAccessibility.obtain(this, true);
169076f287e416ded85734b610f316e38d243d2ddb09Svetoslav Ganov        try {
169176f287e416ded85734b610f316e38d243d2ddb09Svetoslav Ganov            final int childrenCount = children.getChildCount();
169276f287e416ded85734b610f316e38d243d2ddb09Svetoslav Ganov            for (int i = 0; i < childrenCount; i++) {
169376f287e416ded85734b610f316e38d243d2ddb09Svetoslav Ganov                View child = children.getChildAt(i);
1694c406be9036643ebe41bafcd94fe4aa861b4e4f4fSvetoslav Ganov                if ((child.mViewFlags & VISIBILITY_MASK) == VISIBLE) {
169576f287e416ded85734b610f316e38d243d2ddb09Svetoslav Ganov                    if (child.includeForAccessibility()) {
169676f287e416ded85734b610f316e38d243d2ddb09Svetoslav Ganov                        childrenForAccessibility.add(child);
169776f287e416ded85734b610f316e38d243d2ddb09Svetoslav Ganov                    } else {
169876f287e416ded85734b610f316e38d243d2ddb09Svetoslav Ganov                        child.addChildrenForAccessibility(childrenForAccessibility);
169976f287e416ded85734b610f316e38d243d2ddb09Svetoslav Ganov                    }
17004213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov                }
17014213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov            }
170276f287e416ded85734b610f316e38d243d2ddb09Svetoslav Ganov        } finally {
170376f287e416ded85734b610f316e38d243d2ddb09Svetoslav Ganov            children.recycle();
17044213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov        }
17054213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov    }
17064213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov
17074213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov    /**
170810b6290c5f15ae512a2f6b5bf8d95bd2527c7235Jeff Brown     * Implement this method to intercept hover events before they are handled
170910b6290c5f15ae512a2f6b5bf8d95bd2527c7235Jeff Brown     * by child views.
171010b6290c5f15ae512a2f6b5bf8d95bd2527c7235Jeff Brown     * <p>
171110b6290c5f15ae512a2f6b5bf8d95bd2527c7235Jeff Brown     * This method is called before dispatching a hover event to a child of
171210b6290c5f15ae512a2f6b5bf8d95bd2527c7235Jeff Brown     * the view group or to the view group's own {@link #onHoverEvent} to allow
171310b6290c5f15ae512a2f6b5bf8d95bd2527c7235Jeff Brown     * the view group a chance to intercept the hover event.
171410b6290c5f15ae512a2f6b5bf8d95bd2527c7235Jeff Brown     * This method can also be used to watch all pointer motions that occur within
171510b6290c5f15ae512a2f6b5bf8d95bd2527c7235Jeff Brown     * the bounds of the view group even when the pointer is hovering over
171610b6290c5f15ae512a2f6b5bf8d95bd2527c7235Jeff Brown     * a child of the view group rather than over the view group itself.
171710b6290c5f15ae512a2f6b5bf8d95bd2527c7235Jeff Brown     * </p><p>
171810b6290c5f15ae512a2f6b5bf8d95bd2527c7235Jeff Brown     * The view group can prevent its children from receiving hover events by
171910b6290c5f15ae512a2f6b5bf8d95bd2527c7235Jeff Brown     * implementing this method and returning <code>true</code> to indicate
172010b6290c5f15ae512a2f6b5bf8d95bd2527c7235Jeff Brown     * that it would like to intercept hover events.  The view group must
172110b6290c5f15ae512a2f6b5bf8d95bd2527c7235Jeff Brown     * continuously return <code>true</code> from {@link #onInterceptHoverEvent}
172210b6290c5f15ae512a2f6b5bf8d95bd2527c7235Jeff Brown     * for as long as it wishes to continue intercepting hover events from
172310b6290c5f15ae512a2f6b5bf8d95bd2527c7235Jeff Brown     * its children.
172410b6290c5f15ae512a2f6b5bf8d95bd2527c7235Jeff Brown     * </p><p>
172510b6290c5f15ae512a2f6b5bf8d95bd2527c7235Jeff Brown     * Interception preserves the invariant that at most one view can be
172610b6290c5f15ae512a2f6b5bf8d95bd2527c7235Jeff Brown     * hovered at a time by transferring hover focus from the currently hovered
172710b6290c5f15ae512a2f6b5bf8d95bd2527c7235Jeff Brown     * child to the view group or vice-versa as needed.
172810b6290c5f15ae512a2f6b5bf8d95bd2527c7235Jeff Brown     * </p><p>
172910b6290c5f15ae512a2f6b5bf8d95bd2527c7235Jeff Brown     * If this method returns <code>true</code> and a child is already hovered, then the
173010b6290c5f15ae512a2f6b5bf8d95bd2527c7235Jeff Brown     * child view will first receive a hover exit event and then the view group
173110b6290c5f15ae512a2f6b5bf8d95bd2527c7235Jeff Brown     * itself will receive a hover enter event in {@link #onHoverEvent}.
173210b6290c5f15ae512a2f6b5bf8d95bd2527c7235Jeff Brown     * Likewise, if this method had previously returned <code>true</code> to intercept hover
173310b6290c5f15ae512a2f6b5bf8d95bd2527c7235Jeff Brown     * events and instead returns <code>false</code> while the pointer is hovering
173410b6290c5f15ae512a2f6b5bf8d95bd2527c7235Jeff Brown     * within the bounds of one of a child, then the view group will first receive a
173510b6290c5f15ae512a2f6b5bf8d95bd2527c7235Jeff Brown     * hover exit event in {@link #onHoverEvent} and then the hovered child will
173610b6290c5f15ae512a2f6b5bf8d95bd2527c7235Jeff Brown     * receive a hover enter event.
173710b6290c5f15ae512a2f6b5bf8d95bd2527c7235Jeff Brown     * </p><p>
173810b6290c5f15ae512a2f6b5bf8d95bd2527c7235Jeff Brown     * The default implementation always returns false.
173910b6290c5f15ae512a2f6b5bf8d95bd2527c7235Jeff Brown     * </p>
174010b6290c5f15ae512a2f6b5bf8d95bd2527c7235Jeff Brown     *
174110b6290c5f15ae512a2f6b5bf8d95bd2527c7235Jeff Brown     * @param event The motion event that describes the hover.
174210b6290c5f15ae512a2f6b5bf8d95bd2527c7235Jeff Brown     * @return True if the view group would like to intercept the hover event
174310b6290c5f15ae512a2f6b5bf8d95bd2527c7235Jeff Brown     * and prevent its children from receiving it.
174410b6290c5f15ae512a2f6b5bf8d95bd2527c7235Jeff Brown     */
174510b6290c5f15ae512a2f6b5bf8d95bd2527c7235Jeff Brown    public boolean onInterceptHoverEvent(MotionEvent event) {
1746736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov        return false;
1747736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov    }
1748736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov
1749a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown    private static MotionEvent obtainMotionEventNoHistoryOrSelf(MotionEvent event) {
1750a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown        if (event.getHistorySize() == 0) {
1751a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown            return event;
1752a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown        }
1753a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown        return MotionEvent.obtainNoHistory(event);
1754a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown    }
1755a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown
175610b6290c5f15ae512a2f6b5bf8d95bd2527c7235Jeff Brown    /**
175710b6290c5f15ae512a2f6b5bf8d95bd2527c7235Jeff Brown     * {@inheritDoc}
175810b6290c5f15ae512a2f6b5bf8d95bd2527c7235Jeff Brown     */
1759a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown    @Override
1760a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown    protected boolean dispatchGenericPointerEvent(MotionEvent event) {
1761a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown        // Send the event to the child under the pointer.
1762a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown        final int childrenCount = mChildrenCount;
1763a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown        if (childrenCount != 0) {
1764a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown            final View[] children = mChildren;
1765a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown            final float x = event.getX();
1766a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown            final float y = event.getY();
1767a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown
1768a6478a3a130c3680bc6d8fa6490ac805fa15bdd2Adam Powell            final boolean customOrder = isChildrenDrawingOrderEnabled();
1769a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown            for (int i = childrenCount - 1; i >= 0; i--) {
1770a6478a3a130c3680bc6d8fa6490ac805fa15bdd2Adam Powell                final int childIndex = customOrder ? getChildDrawingOrder(childrenCount, i) : i;
1771a6478a3a130c3680bc6d8fa6490ac805fa15bdd2Adam Powell                final View child = children[childIndex];
1772a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown                if (!canViewReceivePointerEvents(child)
1773a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown                        || !isTransformedTouchPointInView(x, y, child, null)) {
1774a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown                    continue;
177533bbfd2232ea9eaae9a9d87a05a95a430f09bd83Jeff Brown                }
177633bbfd2232ea9eaae9a9d87a05a95a430f09bd83Jeff Brown
1777a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown                if (dispatchTransformedGenericPointerEvent(event, child)) {
1778a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown                    return true;
1779a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown                }
1780a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown            }
178133bbfd2232ea9eaae9a9d87a05a95a430f09bd83Jeff Brown        }
178233bbfd2232ea9eaae9a9d87a05a95a430f09bd83Jeff Brown
1783a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown        // No child handled the event.  Send it to this view group.
1784a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown        return super.dispatchGenericPointerEvent(event);
1785a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown    }
1786a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown
178710b6290c5f15ae512a2f6b5bf8d95bd2527c7235Jeff Brown    /**
178810b6290c5f15ae512a2f6b5bf8d95bd2527c7235Jeff Brown     * {@inheritDoc}
178910b6290c5f15ae512a2f6b5bf8d95bd2527c7235Jeff Brown     */
1790a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown    @Override
1791a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown    protected boolean dispatchGenericFocusedEvent(MotionEvent event) {
179233bbfd2232ea9eaae9a9d87a05a95a430f09bd83Jeff Brown        // Send the event to the focused child or to this view group if it has focus.
17934702a856973a553deb82f71b1d3b6c3db5dbf4baDianne Hackborn        if ((mPrivateFlags & (PFLAG_FOCUSED | PFLAG_HAS_BOUNDS))
17944702a856973a553deb82f71b1d3b6c3db5dbf4baDianne Hackborn                == (PFLAG_FOCUSED | PFLAG_HAS_BOUNDS)) {
1795a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown            return super.dispatchGenericFocusedEvent(event);
17964702a856973a553deb82f71b1d3b6c3db5dbf4baDianne Hackborn        } else if (mFocused != null && (mFocused.mPrivateFlags & PFLAG_HAS_BOUNDS)
17974702a856973a553deb82f71b1d3b6c3db5dbf4baDianne Hackborn                == PFLAG_HAS_BOUNDS) {
1798cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown            return mFocused.dispatchGenericMotionEvent(event);
17999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
18009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return false;
18019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
18029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
18039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1804a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown     * Dispatches a generic pointer event to a child, taking into account
1805a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown     * transformations that apply to the child.
1806a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown     *
1807a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown     * @param event The event to send.
1808a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown     * @param child The view to send the event to.
1809a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown     * @return {@code true} if the child handled the event.
1810a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown     */
1811a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown    private boolean dispatchTransformedGenericPointerEvent(MotionEvent event, View child) {
1812a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown        final float offsetX = mScrollX - child.mLeft;
1813a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown        final float offsetY = mScrollY - child.mTop;
1814a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown
1815a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown        boolean handled;
1816a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown        if (!child.hasIdentityMatrix()) {
1817a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown            MotionEvent transformedEvent = MotionEvent.obtain(event);
1818a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown            transformedEvent.offsetLocation(offsetX, offsetY);
1819a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown            transformedEvent.transform(child.getInverseMatrix());
1820a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown            handled = child.dispatchGenericMotionEvent(transformedEvent);
1821a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown            transformedEvent.recycle();
1822a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown        } else {
1823a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown            event.offsetLocation(offsetX, offsetY);
1824a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown            handled = child.dispatchGenericMotionEvent(event);
1825a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown            event.offsetLocation(-offsetX, -offsetY);
1826a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown        }
1827a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown        return handled;
1828a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown    }
1829a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown
1830a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown    /**
18319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@inheritDoc}
18329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
18339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
18349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean dispatchTouchEvent(MotionEvent ev) {
183521bc5c917d4ee2a9b2b8173091e6bba85eaff899Jeff Brown        if (mInputEventConsistencyVerifier != null) {
183621bc5c917d4ee2a9b2b8173091e6bba85eaff899Jeff Brown            mInputEventConsistencyVerifier.onTouchEvent(ev, 1);
183721bc5c917d4ee2a9b2b8173091e6bba85eaff899Jeff Brown        }
183821bc5c917d4ee2a9b2b8173091e6bba85eaff899Jeff Brown
1839bbdc50b102faf52768ac3028bc49e027ff140656Jeff Brown        boolean handled = false;
1840bbdc50b102faf52768ac3028bc49e027ff140656Jeff Brown        if (onFilterTouchEventForSecurity(ev)) {
1841bbdc50b102faf52768ac3028bc49e027ff140656Jeff Brown            final int action = ev.getAction();
1842bbdc50b102faf52768ac3028bc49e027ff140656Jeff Brown            final int actionMasked = action & MotionEvent.ACTION_MASK;
1843bbdc50b102faf52768ac3028bc49e027ff140656Jeff Brown
1844bbdc50b102faf52768ac3028bc49e027ff140656Jeff Brown            // Handle an initial down.
1845bbdc50b102faf52768ac3028bc49e027ff140656Jeff Brown            if (actionMasked == MotionEvent.ACTION_DOWN) {
1846bbdc50b102faf52768ac3028bc49e027ff140656Jeff Brown                // Throw away all previous state when starting a new touch gesture.
1847bbdc50b102faf52768ac3028bc49e027ff140656Jeff Brown                // The framework may have dropped the up or cancel event for the previous gesture
1848bbdc50b102faf52768ac3028bc49e027ff140656Jeff Brown                // due to an app switch, ANR, or some other state change.
1849bbdc50b102faf52768ac3028bc49e027ff140656Jeff Brown                cancelAndClearTouchTargets(ev);
1850bbdc50b102faf52768ac3028bc49e027ff140656Jeff Brown                resetTouchState();
1851816c3be1d7e27ee91ad4e87d39a208dbdc27c8f9Adam Powell            }
185220e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown
1853bbdc50b102faf52768ac3028bc49e027ff140656Jeff Brown            // Check for interception.
1854bbdc50b102faf52768ac3028bc49e027ff140656Jeff Brown            final boolean intercepted;
185520e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown            if (actionMasked == MotionEvent.ACTION_DOWN
1856bbdc50b102faf52768ac3028bc49e027ff140656Jeff Brown                    || mFirstTouchTarget != null) {
1857bbdc50b102faf52768ac3028bc49e027ff140656Jeff Brown                final boolean disallowIntercept = (mGroupFlags & FLAG_DISALLOW_INTERCEPT) != 0;
1858bbdc50b102faf52768ac3028bc49e027ff140656Jeff Brown                if (!disallowIntercept) {
1859bbdc50b102faf52768ac3028bc49e027ff140656Jeff Brown                    intercepted = onInterceptTouchEvent(ev);
1860bbdc50b102faf52768ac3028bc49e027ff140656Jeff Brown                    ev.setAction(action); // restore action in case it was changed
1861bbdc50b102faf52768ac3028bc49e027ff140656Jeff Brown                } else {
1862bbdc50b102faf52768ac3028bc49e027ff140656Jeff Brown                    intercepted = false;
1863bbdc50b102faf52768ac3028bc49e027ff140656Jeff Brown                }
1864bbdc50b102faf52768ac3028bc49e027ff140656Jeff Brown            } else {
1865bbdc50b102faf52768ac3028bc49e027ff140656Jeff Brown                // There are no touch targets and this action is not an initial down
1866bbdc50b102faf52768ac3028bc49e027ff140656Jeff Brown                // so this view group continues to intercept touches.
1867bbdc50b102faf52768ac3028bc49e027ff140656Jeff Brown                intercepted = true;
1868bbdc50b102faf52768ac3028bc49e027ff140656Jeff Brown            }
186920e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown
1870bbdc50b102faf52768ac3028bc49e027ff140656Jeff Brown            // Check for cancelation.
1871bbdc50b102faf52768ac3028bc49e027ff140656Jeff Brown            final boolean canceled = resetCancelNextUpFlag(this)
1872bbdc50b102faf52768ac3028bc49e027ff140656Jeff Brown                    || actionMasked == MotionEvent.ACTION_CANCEL;
1873bbdc50b102faf52768ac3028bc49e027ff140656Jeff Brown
1874bbdc50b102faf52768ac3028bc49e027ff140656Jeff Brown            // Update list of touch targets for pointer down, if needed.
1875bbdc50b102faf52768ac3028bc49e027ff140656Jeff Brown            final boolean split = (mGroupFlags & FLAG_SPLIT_MOTION_EVENTS) != 0;
1876bbdc50b102faf52768ac3028bc49e027ff140656Jeff Brown            TouchTarget newTouchTarget = null;
1877bbdc50b102faf52768ac3028bc49e027ff140656Jeff Brown            boolean alreadyDispatchedToNewTouchTarget = false;
1878bbdc50b102faf52768ac3028bc49e027ff140656Jeff Brown            if (!canceled && !intercepted) {
1879bbdc50b102faf52768ac3028bc49e027ff140656Jeff Brown                if (actionMasked == MotionEvent.ACTION_DOWN
1880bbdc50b102faf52768ac3028bc49e027ff140656Jeff Brown                        || (split && actionMasked == MotionEvent.ACTION_POINTER_DOWN)
1881bbdc50b102faf52768ac3028bc49e027ff140656Jeff Brown                        || actionMasked == MotionEvent.ACTION_HOVER_MOVE) {
1882bbdc50b102faf52768ac3028bc49e027ff140656Jeff Brown                    final int actionIndex = ev.getActionIndex(); // always 0 for down
1883bbdc50b102faf52768ac3028bc49e027ff140656Jeff Brown                    final int idBitsToAssign = split ? 1 << ev.getPointerId(actionIndex)
1884bbdc50b102faf52768ac3028bc49e027ff140656Jeff Brown                            : TouchTarget.ALL_POINTER_IDS;
1885bbdc50b102faf52768ac3028bc49e027ff140656Jeff Brown
1886bbdc50b102faf52768ac3028bc49e027ff140656Jeff Brown                    // Clean up earlier touch targets for this pointer id in case they
1887bbdc50b102faf52768ac3028bc49e027ff140656Jeff Brown                    // have become out of sync.
1888bbdc50b102faf52768ac3028bc49e027ff140656Jeff Brown                    removePointersFromTouchTargets(idBitsToAssign);
1889bbdc50b102faf52768ac3028bc49e027ff140656Jeff Brown
1890bbdc50b102faf52768ac3028bc49e027ff140656Jeff Brown                    final int childrenCount = mChildrenCount;
18919c17fe693deb0cc84099b619185472f192c2b52dChet Haase                    if (newTouchTarget == null && childrenCount != 0) {
1892edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase                        final float x = ev.getX(actionIndex);
1893edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase                        final float y = ev.getY(actionIndex);
1894bbdc50b102faf52768ac3028bc49e027ff140656Jeff Brown                        // Find a child that can receive the event.
1895bbdc50b102faf52768ac3028bc49e027ff140656Jeff Brown                        // Scan children from front to back.
1896bbdc50b102faf52768ac3028bc49e027ff140656Jeff Brown                        final View[] children = mChildren;
1897bbdc50b102faf52768ac3028bc49e027ff140656Jeff Brown
1898a6478a3a130c3680bc6d8fa6490ac805fa15bdd2Adam Powell                        final boolean customOrder = isChildrenDrawingOrderEnabled();
1899bbdc50b102faf52768ac3028bc49e027ff140656Jeff Brown                        for (int i = childrenCount - 1; i >= 0; i--) {
1900a6478a3a130c3680bc6d8fa6490ac805fa15bdd2Adam Powell                            final int childIndex = customOrder ?
1901a6478a3a130c3680bc6d8fa6490ac805fa15bdd2Adam Powell                                    getChildDrawingOrder(childrenCount, i) : i;
1902a6478a3a130c3680bc6d8fa6490ac805fa15bdd2Adam Powell                            final View child = children[childIndex];
1903bbdc50b102faf52768ac3028bc49e027ff140656Jeff Brown                            if (!canViewReceivePointerEvents(child)
1904bbdc50b102faf52768ac3028bc49e027ff140656Jeff Brown                                    || !isTransformedTouchPointInView(x, y, child, null)) {
1905bbdc50b102faf52768ac3028bc49e027ff140656Jeff Brown                                continue;
1906bbdc50b102faf52768ac3028bc49e027ff140656Jeff Brown                            }
1907bbdc50b102faf52768ac3028bc49e027ff140656Jeff Brown
1908bbdc50b102faf52768ac3028bc49e027ff140656Jeff Brown                            newTouchTarget = getTouchTarget(child);
1909bbdc50b102faf52768ac3028bc49e027ff140656Jeff Brown                            if (newTouchTarget != null) {
1910bbdc50b102faf52768ac3028bc49e027ff140656Jeff Brown                                // Child is already receiving touch within its bounds.
1911bbdc50b102faf52768ac3028bc49e027ff140656Jeff Brown                                // Give it the new pointer in addition to the ones it is handling.
1912bbdc50b102faf52768ac3028bc49e027ff140656Jeff Brown                                newTouchTarget.pointerIdBits |= idBitsToAssign;
1913bbdc50b102faf52768ac3028bc49e027ff140656Jeff Brown                                break;
1914bbdc50b102faf52768ac3028bc49e027ff140656Jeff Brown                            }
1915bbdc50b102faf52768ac3028bc49e027ff140656Jeff Brown
1916bbdc50b102faf52768ac3028bc49e027ff140656Jeff Brown                            resetCancelNextUpFlag(child);
1917bbdc50b102faf52768ac3028bc49e027ff140656Jeff Brown                            if (dispatchTransformedTouchEvent(ev, false, child, idBitsToAssign)) {
1918bbdc50b102faf52768ac3028bc49e027ff140656Jeff Brown                                // Child wants to receive touch within its bounds.
1919bbdc50b102faf52768ac3028bc49e027ff140656Jeff Brown                                mLastTouchDownTime = ev.getDownTime();
1920a6478a3a130c3680bc6d8fa6490ac805fa15bdd2Adam Powell                                mLastTouchDownIndex = childIndex;
1921bbdc50b102faf52768ac3028bc49e027ff140656Jeff Brown                                mLastTouchDownX = ev.getX();
1922bbdc50b102faf52768ac3028bc49e027ff140656Jeff Brown                                mLastTouchDownY = ev.getY();
1923bbdc50b102faf52768ac3028bc49e027ff140656Jeff Brown                                newTouchTarget = addTouchTarget(child, idBitsToAssign);
1924bbdc50b102faf52768ac3028bc49e027ff140656Jeff Brown                                alreadyDispatchedToNewTouchTarget = true;
1925bbdc50b102faf52768ac3028bc49e027ff140656Jeff Brown                                break;
1926bbdc50b102faf52768ac3028bc49e027ff140656Jeff Brown                            }
192720e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown                        }
192820e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown                    }
192920e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown
1930bbdc50b102faf52768ac3028bc49e027ff140656Jeff Brown                    if (newTouchTarget == null && mFirstTouchTarget != null) {
1931bbdc50b102faf52768ac3028bc49e027ff140656Jeff Brown                        // Did not find a child to receive the event.
1932bbdc50b102faf52768ac3028bc49e027ff140656Jeff Brown                        // Assign the pointer to the least recently added target.
1933bbdc50b102faf52768ac3028bc49e027ff140656Jeff Brown                        newTouchTarget = mFirstTouchTarget;
1934bbdc50b102faf52768ac3028bc49e027ff140656Jeff Brown                        while (newTouchTarget.next != null) {
1935bbdc50b102faf52768ac3028bc49e027ff140656Jeff Brown                            newTouchTarget = newTouchTarget.next;
1936bbdc50b102faf52768ac3028bc49e027ff140656Jeff Brown                        }
1937bbdc50b102faf52768ac3028bc49e027ff140656Jeff Brown                        newTouchTarget.pointerIdBits |= idBitsToAssign;
193820e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown                    }
193920e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown                }
19409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
194120e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown
1942bbdc50b102faf52768ac3028bc49e027ff140656Jeff Brown            // Dispatch to touch targets.
1943bbdc50b102faf52768ac3028bc49e027ff140656Jeff Brown            if (mFirstTouchTarget == null) {
1944bbdc50b102faf52768ac3028bc49e027ff140656Jeff Brown                // No touch targets so treat this as an ordinary view.
1945bbdc50b102faf52768ac3028bc49e027ff140656Jeff Brown                handled = dispatchTransformedTouchEvent(ev, canceled, null,
1946bbdc50b102faf52768ac3028bc49e027ff140656Jeff Brown                        TouchTarget.ALL_POINTER_IDS);
1947bbdc50b102faf52768ac3028bc49e027ff140656Jeff Brown            } else {
1948bbdc50b102faf52768ac3028bc49e027ff140656Jeff Brown                // Dispatch to touch targets, excluding the new touch target if we already
1949bbdc50b102faf52768ac3028bc49e027ff140656Jeff Brown                // dispatched to it.  Cancel touch targets if necessary.
1950bbdc50b102faf52768ac3028bc49e027ff140656Jeff Brown                TouchTarget predecessor = null;
1951bbdc50b102faf52768ac3028bc49e027ff140656Jeff Brown                TouchTarget target = mFirstTouchTarget;
1952bbdc50b102faf52768ac3028bc49e027ff140656Jeff Brown                while (target != null) {
1953bbdc50b102faf52768ac3028bc49e027ff140656Jeff Brown                    final TouchTarget next = target.next;
1954bbdc50b102faf52768ac3028bc49e027ff140656Jeff Brown                    if (alreadyDispatchedToNewTouchTarget && target == newTouchTarget) {
195520e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown                        handled = true;
1956bbdc50b102faf52768ac3028bc49e027ff140656Jeff Brown                    } else {
1957bbdc50b102faf52768ac3028bc49e027ff140656Jeff Brown                        final boolean cancelChild = resetCancelNextUpFlag(target.child)
19589c17fe693deb0cc84099b619185472f192c2b52dChet Haase                                || intercepted;
1959bbdc50b102faf52768ac3028bc49e027ff140656Jeff Brown                        if (dispatchTransformedTouchEvent(ev, cancelChild,
1960bbdc50b102faf52768ac3028bc49e027ff140656Jeff Brown                                target.child, target.pointerIdBits)) {
1961bbdc50b102faf52768ac3028bc49e027ff140656Jeff Brown                            handled = true;
1962bbdc50b102faf52768ac3028bc49e027ff140656Jeff Brown                        }
1963bbdc50b102faf52768ac3028bc49e027ff140656Jeff Brown                        if (cancelChild) {
1964bbdc50b102faf52768ac3028bc49e027ff140656Jeff Brown                            if (predecessor == null) {
1965bbdc50b102faf52768ac3028bc49e027ff140656Jeff Brown                                mFirstTouchTarget = next;
1966bbdc50b102faf52768ac3028bc49e027ff140656Jeff Brown                            } else {
1967bbdc50b102faf52768ac3028bc49e027ff140656Jeff Brown                                predecessor.next = next;
1968bbdc50b102faf52768ac3028bc49e027ff140656Jeff Brown                            }
1969bbdc50b102faf52768ac3028bc49e027ff140656Jeff Brown                            target.recycle();
1970bbdc50b102faf52768ac3028bc49e027ff140656Jeff Brown                            target = next;
1971bbdc50b102faf52768ac3028bc49e027ff140656Jeff Brown                            continue;
19729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        }
19739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
1974bbdc50b102faf52768ac3028bc49e027ff140656Jeff Brown                    predecessor = target;
1975bbdc50b102faf52768ac3028bc49e027ff140656Jeff Brown                    target = next;
19769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
19779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
19788506ab4ac062d0e1ccde136e5e2f4081560e0c11Romain Guy
1979bbdc50b102faf52768ac3028bc49e027ff140656Jeff Brown            // Update list of touch targets for pointer up or cancel, if needed.
1980bbdc50b102faf52768ac3028bc49e027ff140656Jeff Brown            if (canceled
1981bbdc50b102faf52768ac3028bc49e027ff140656Jeff Brown                    || actionMasked == MotionEvent.ACTION_UP
1982bbdc50b102faf52768ac3028bc49e027ff140656Jeff Brown                    || actionMasked == MotionEvent.ACTION_HOVER_MOVE) {
1983bbdc50b102faf52768ac3028bc49e027ff140656Jeff Brown                resetTouchState();
1984bbdc50b102faf52768ac3028bc49e027ff140656Jeff Brown            } else if (split && actionMasked == MotionEvent.ACTION_POINTER_UP) {
1985bbdc50b102faf52768ac3028bc49e027ff140656Jeff Brown                final int actionIndex = ev.getActionIndex();
1986bbdc50b102faf52768ac3028bc49e027ff140656Jeff Brown                final int idBitsToRemove = 1 << ev.getPointerId(actionIndex);
1987bbdc50b102faf52768ac3028bc49e027ff140656Jeff Brown                removePointersFromTouchTargets(idBitsToRemove);
1988bbdc50b102faf52768ac3028bc49e027ff140656Jeff Brown            }
198920e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown        }
19909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1991bbdc50b102faf52768ac3028bc49e027ff140656Jeff Brown        if (!handled && mInputEventConsistencyVerifier != null) {
1992bbdc50b102faf52768ac3028bc49e027ff140656Jeff Brown            mInputEventConsistencyVerifier.onUnhandledEvent(ev, 1);
1993bbdc50b102faf52768ac3028bc49e027ff140656Jeff Brown        }
199420e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown        return handled;
199520e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown    }
199620e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown
1997469b1dbeaf7d3267d1b43af4e7391b49eac10ee0Romain Guy    /**
1998469b1dbeaf7d3267d1b43af4e7391b49eac10ee0Romain Guy     * Resets all touch state in preparation for a new cycle.
1999469b1dbeaf7d3267d1b43af4e7391b49eac10ee0Romain Guy     */
2000469b1dbeaf7d3267d1b43af4e7391b49eac10ee0Romain Guy    private void resetTouchState() {
200120e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown        clearTouchTargets();
200220e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown        resetCancelNextUpFlag(this);
200320e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown        mGroupFlags &= ~FLAG_DISALLOW_INTERCEPT;
200420e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown    }
200520e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown
2006469b1dbeaf7d3267d1b43af4e7391b49eac10ee0Romain Guy    /**
2007469b1dbeaf7d3267d1b43af4e7391b49eac10ee0Romain Guy     * Resets the cancel next up flag.
2008469b1dbeaf7d3267d1b43af4e7391b49eac10ee0Romain Guy     * Returns true if the flag was previously set.
2009469b1dbeaf7d3267d1b43af4e7391b49eac10ee0Romain Guy     */
2010a998dff5d49a423aaf7097aa8f96bf5bdc681d25Romain Guy    private static boolean resetCancelNextUpFlag(View view) {
20114702a856973a553deb82f71b1d3b6c3db5dbf4baDianne Hackborn        if ((view.mPrivateFlags & PFLAG_CANCEL_NEXT_UP_EVENT) != 0) {
20124702a856973a553deb82f71b1d3b6c3db5dbf4baDianne Hackborn            view.mPrivateFlags &= ~PFLAG_CANCEL_NEXT_UP_EVENT;
201320e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown            return true;
20149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
201520e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown        return false;
201620e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown    }
20178506ab4ac062d0e1ccde136e5e2f4081560e0c11Romain Guy
2018469b1dbeaf7d3267d1b43af4e7391b49eac10ee0Romain Guy    /**
2019469b1dbeaf7d3267d1b43af4e7391b49eac10ee0Romain Guy     * Clears all touch targets.
2020469b1dbeaf7d3267d1b43af4e7391b49eac10ee0Romain Guy     */
2021469b1dbeaf7d3267d1b43af4e7391b49eac10ee0Romain Guy    private void clearTouchTargets() {
202220e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown        TouchTarget target = mFirstTouchTarget;
202320e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown        if (target != null) {
202420e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown            do {
202520e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown                TouchTarget next = target.next;
202620e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown                target.recycle();
202720e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown                target = next;
202820e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown            } while (target != null);
202920e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown            mFirstTouchTarget = null;
203020e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown        }
203120e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown    }
203220e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown
2033469b1dbeaf7d3267d1b43af4e7391b49eac10ee0Romain Guy    /**
2034469b1dbeaf7d3267d1b43af4e7391b49eac10ee0Romain Guy     * Cancels and clears all touch targets.
2035469b1dbeaf7d3267d1b43af4e7391b49eac10ee0Romain Guy     */
2036469b1dbeaf7d3267d1b43af4e7391b49eac10ee0Romain Guy    private void cancelAndClearTouchTargets(MotionEvent event) {
203720e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown        if (mFirstTouchTarget != null) {
203820e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown            boolean syntheticEvent = false;
203920e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown            if (event == null) {
204020e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown                final long now = SystemClock.uptimeMillis();
204120e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown                event = MotionEvent.obtain(now, now,
204220e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown                        MotionEvent.ACTION_CANCEL, 0.0f, 0.0f, 0);
20432fdbc5a0c499752285630336f0ef538d4a50e60eJeff Brown                event.setSource(InputDevice.SOURCE_TOUCHSCREEN);
204420e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown                syntheticEvent = true;
20458afa515936e78ccfc5563ca9164dc9a50ca73db4Romain Guy            }
20469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
204720e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown            for (TouchTarget target = mFirstTouchTarget; target != null; target = target.next) {
204820e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown                resetCancelNextUpFlag(target.child);
204920e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown                dispatchTransformedTouchEvent(event, true, target.child, target.pointerIdBits);
20509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
205120e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown            clearTouchTargets();
20529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
205320e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown            if (syntheticEvent) {
205420e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown                event.recycle();
205520e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown            }
20569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
205720e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown    }
20589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2059469b1dbeaf7d3267d1b43af4e7391b49eac10ee0Romain Guy    /**
2060469b1dbeaf7d3267d1b43af4e7391b49eac10ee0Romain Guy     * Gets the touch target for specified child view.
2061469b1dbeaf7d3267d1b43af4e7391b49eac10ee0Romain Guy     * Returns null if not found.
2062469b1dbeaf7d3267d1b43af4e7391b49eac10ee0Romain Guy     */
2063469b1dbeaf7d3267d1b43af4e7391b49eac10ee0Romain Guy    private TouchTarget getTouchTarget(View child) {
206420e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown        for (TouchTarget target = mFirstTouchTarget; target != null; target = target.next) {
206520e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown            if (target.child == child) {
206620e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown                return target;
206720e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown            }
20688afa515936e78ccfc5563ca9164dc9a50ca73db4Romain Guy        }
206920e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown        return null;
207020e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown    }
20718afa515936e78ccfc5563ca9164dc9a50ca73db4Romain Guy
2072469b1dbeaf7d3267d1b43af4e7391b49eac10ee0Romain Guy    /**
2073469b1dbeaf7d3267d1b43af4e7391b49eac10ee0Romain Guy     * Adds a touch target for specified child to the beginning of the list.
2074469b1dbeaf7d3267d1b43af4e7391b49eac10ee0Romain Guy     * Assumes the target child is not already present.
2075469b1dbeaf7d3267d1b43af4e7391b49eac10ee0Romain Guy     */
2076469b1dbeaf7d3267d1b43af4e7391b49eac10ee0Romain Guy    private TouchTarget addTouchTarget(View child, int pointerIdBits) {
207720e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown        TouchTarget target = TouchTarget.obtain(child, pointerIdBits);
207820e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown        target.next = mFirstTouchTarget;
207920e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown        mFirstTouchTarget = target;
208020e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown        return target;
208120e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown    }
208220e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown
2083469b1dbeaf7d3267d1b43af4e7391b49eac10ee0Romain Guy    /**
2084469b1dbeaf7d3267d1b43af4e7391b49eac10ee0Romain Guy     * Removes the pointer ids from consideration.
2085469b1dbeaf7d3267d1b43af4e7391b49eac10ee0Romain Guy     */
2086469b1dbeaf7d3267d1b43af4e7391b49eac10ee0Romain Guy    private void removePointersFromTouchTargets(int pointerIdBits) {
208720e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown        TouchTarget predecessor = null;
208820e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown        TouchTarget target = mFirstTouchTarget;
208920e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown        while (target != null) {
209020e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown            final TouchTarget next = target.next;
209120e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown            if ((target.pointerIdBits & pointerIdBits) != 0) {
209220e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown                target.pointerIdBits &= ~pointerIdBits;
209320e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown                if (target.pointerIdBits == 0) {
209420e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown                    if (predecessor == null) {
209520e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown                        mFirstTouchTarget = next;
209620e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown                    } else {
209720e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown                        predecessor.next = next;
209820e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown                    }
209920e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown                    target.recycle();
210020e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown                    target = next;
210120e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown                    continue;
210220e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown                }
210320e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown            }
210420e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown            predecessor = target;
210520e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown            target = next;
21069b073948cfb84c0dd04f8a94ee1f7f263f027c83Adam Cohen        }
21079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
21089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
210959a422e90035ce5df45c526607db2d3303e3112eJeff Brown    private void cancelTouchTarget(View view) {
211059a422e90035ce5df45c526607db2d3303e3112eJeff Brown        TouchTarget predecessor = null;
211159a422e90035ce5df45c526607db2d3303e3112eJeff Brown        TouchTarget target = mFirstTouchTarget;
211259a422e90035ce5df45c526607db2d3303e3112eJeff Brown        while (target != null) {
211359a422e90035ce5df45c526607db2d3303e3112eJeff Brown            final TouchTarget next = target.next;
211459a422e90035ce5df45c526607db2d3303e3112eJeff Brown            if (target.child == view) {
211559a422e90035ce5df45c526607db2d3303e3112eJeff Brown                if (predecessor == null) {
211659a422e90035ce5df45c526607db2d3303e3112eJeff Brown                    mFirstTouchTarget = next;
211759a422e90035ce5df45c526607db2d3303e3112eJeff Brown                } else {
211859a422e90035ce5df45c526607db2d3303e3112eJeff Brown                    predecessor.next = next;
211959a422e90035ce5df45c526607db2d3303e3112eJeff Brown                }
212059a422e90035ce5df45c526607db2d3303e3112eJeff Brown                target.recycle();
212159a422e90035ce5df45c526607db2d3303e3112eJeff Brown
212259a422e90035ce5df45c526607db2d3303e3112eJeff Brown                final long now = SystemClock.uptimeMillis();
212359a422e90035ce5df45c526607db2d3303e3112eJeff Brown                MotionEvent event = MotionEvent.obtain(now, now,
212459a422e90035ce5df45c526607db2d3303e3112eJeff Brown                        MotionEvent.ACTION_CANCEL, 0.0f, 0.0f, 0);
212559a422e90035ce5df45c526607db2d3303e3112eJeff Brown                event.setSource(InputDevice.SOURCE_TOUCHSCREEN);
212659a422e90035ce5df45c526607db2d3303e3112eJeff Brown                view.dispatchTouchEvent(event);
212759a422e90035ce5df45c526607db2d3303e3112eJeff Brown                event.recycle();
212859a422e90035ce5df45c526607db2d3303e3112eJeff Brown                return;
212959a422e90035ce5df45c526607db2d3303e3112eJeff Brown            }
213059a422e90035ce5df45c526607db2d3303e3112eJeff Brown            predecessor = target;
213159a422e90035ce5df45c526607db2d3303e3112eJeff Brown            target = next;
213259a422e90035ce5df45c526607db2d3303e3112eJeff Brown        }
213359a422e90035ce5df45c526607db2d3303e3112eJeff Brown    }
213459a422e90035ce5df45c526607db2d3303e3112eJeff Brown
2135469b1dbeaf7d3267d1b43af4e7391b49eac10ee0Romain Guy    /**
2136a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown     * Returns true if a child view can receive pointer events.
2137a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown     * @hide
2138a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown     */
2139a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown    private static boolean canViewReceivePointerEvents(View child) {
2140a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown        return (child.mViewFlags & VISIBILITY_MASK) == VISIBLE
2141a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown                || child.getAnimation() != null;
2142a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown    }
2143a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown
2144a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown    /**
2145469b1dbeaf7d3267d1b43af4e7391b49eac10ee0Romain Guy     * Returns true if a child view contains the specified point when transformed
214620e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown     * into its coordinate space.
2147469b1dbeaf7d3267d1b43af4e7391b49eac10ee0Romain Guy     * Child must not be null.
2148a32edd4b4c894f4fb3d9fd7e9d5b80321df79e20Adam Cohen     * @hide
2149469b1dbeaf7d3267d1b43af4e7391b49eac10ee0Romain Guy     */
2150a32edd4b4c894f4fb3d9fd7e9d5b80321df79e20Adam Cohen    protected boolean isTransformedTouchPointInView(float x, float y, View child,
21512c095f367779ef32130c72849936a2e3013c8492Christopher Tate            PointF outLocalPoint) {
215220e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown        float localX = x + mScrollX - child.mLeft;
215320e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown        float localY = y + mScrollY - child.mTop;
215420e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown        if (! child.hasIdentityMatrix() && mAttachInfo != null) {
21552b342f0a76f3237e97f15dc2f4e8a0b72dd7c023Adam Powell            final float[] localXY = mAttachInfo.mTmpTransformLocation;
21562b342f0a76f3237e97f15dc2f4e8a0b72dd7c023Adam Powell            localXY[0] = localX;
21572b342f0a76f3237e97f15dc2f4e8a0b72dd7c023Adam Powell            localXY[1] = localY;
21582b342f0a76f3237e97f15dc2f4e8a0b72dd7c023Adam Powell            child.getInverseMatrix().mapPoints(localXY);
21592b342f0a76f3237e97f15dc2f4e8a0b72dd7c023Adam Powell            localX = localXY[0];
21602b342f0a76f3237e97f15dc2f4e8a0b72dd7c023Adam Powell            localY = localXY[1];
21612b342f0a76f3237e97f15dc2f4e8a0b72dd7c023Adam Powell        }
21622c095f367779ef32130c72849936a2e3013c8492Christopher Tate        final boolean isInView = child.pointInView(localX, localY);
21632c095f367779ef32130c72849936a2e3013c8492Christopher Tate        if (isInView && outLocalPoint != null) {
21642c095f367779ef32130c72849936a2e3013c8492Christopher Tate            outLocalPoint.set(localX, localY);
21652c095f367779ef32130c72849936a2e3013c8492Christopher Tate        }
21662c095f367779ef32130c72849936a2e3013c8492Christopher Tate        return isInView;
216720e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown    }
216820e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown
2169469b1dbeaf7d3267d1b43af4e7391b49eac10ee0Romain Guy    /**
2170469b1dbeaf7d3267d1b43af4e7391b49eac10ee0Romain Guy     * Transforms a motion event into the coordinate space of a particular child view,
217120e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown     * filters out irrelevant pointer ids, and overrides its action if necessary.
2172469b1dbeaf7d3267d1b43af4e7391b49eac10ee0Romain Guy     * If child is null, assumes the MotionEvent will be sent to this ViewGroup instead.
2173469b1dbeaf7d3267d1b43af4e7391b49eac10ee0Romain Guy     */
2174469b1dbeaf7d3267d1b43af4e7391b49eac10ee0Romain Guy    private boolean dispatchTransformedTouchEvent(MotionEvent event, boolean cancel,
217520e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown            View child, int desiredPointerIdBits) {
217620e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown        final boolean handled;
217720e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown
217820e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown        // Canceling motions is a special case.  We don't need to perform any transformations
217920e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown        // or filtering.  The important part is the action, not the contents.
218020e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown        final int oldAction = event.getAction();
218120e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown        if (cancel || oldAction == MotionEvent.ACTION_CANCEL) {
218220e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown            event.setAction(MotionEvent.ACTION_CANCEL);
218320e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown            if (child == null) {
218420e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown                handled = super.dispatchTouchEvent(event);
21859b073948cfb84c0dd04f8a94ee1f7f263f027c83Adam Cohen            } else {
218620e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown                handled = child.dispatchTouchEvent(event);
21879b073948cfb84c0dd04f8a94ee1f7f263f027c83Adam Cohen            }
218820e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown            event.setAction(oldAction);
218920e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown            return handled;
21902b342f0a76f3237e97f15dc2f4e8a0b72dd7c023Adam Powell        }
21912b342f0a76f3237e97f15dc2f4e8a0b72dd7c023Adam Powell
219220e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown        // Calculate the number of pointers to deliver.
2193fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown        final int oldPointerIdBits = event.getPointerIdBits();
2194fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown        final int newPointerIdBits = oldPointerIdBits & desiredPointerIdBits;
219520e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown
219620e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown        // If for some reason we ended up in an inconsistent state where it looks like we
219720e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown        // might produce a motion event with no pointers in it, then drop the event.
2198fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown        if (newPointerIdBits == 0) {
219920e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown            return false;
220020e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown        }
22012b342f0a76f3237e97f15dc2f4e8a0b72dd7c023Adam Powell
220220e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown        // If the number of pointers is the same and we don't need to perform any fancy
220320e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown        // irreversible transformations, then we can reuse the motion event for this
220420e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown        // dispatch as long as we are careful to revert any changes we make.
2205fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown        // Otherwise we need to make a copy.
2206fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown        final MotionEvent transformedEvent;
2207fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown        if (newPointerIdBits == oldPointerIdBits) {
2208fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown            if (child == null || child.hasIdentityMatrix()) {
2209fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown                if (child == null) {
2210fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown                    handled = super.dispatchTouchEvent(event);
221120e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown                } else {
2212fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown                    final float offsetX = mScrollX - child.mLeft;
2213fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown                    final float offsetY = mScrollY - child.mTop;
2214fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown                    event.offsetLocation(offsetX, offsetY);
22152b342f0a76f3237e97f15dc2f4e8a0b72dd7c023Adam Powell
2216fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown                    handled = child.dispatchTouchEvent(event);
22172b342f0a76f3237e97f15dc2f4e8a0b72dd7c023Adam Powell
2218fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown                    event.offsetLocation(-offsetX, -offsetY);
22192b342f0a76f3237e97f15dc2f4e8a0b72dd7c023Adam Powell                }
2220fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown                return handled;
22212b342f0a76f3237e97f15dc2f4e8a0b72dd7c023Adam Powell            }
2222fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown            transformedEvent = MotionEvent.obtain(event);
2223fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown        } else {
2224fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown            transformedEvent = event.split(newPointerIdBits);
22252b342f0a76f3237e97f15dc2f4e8a0b72dd7c023Adam Powell        }
22262b342f0a76f3237e97f15dc2f4e8a0b72dd7c023Adam Powell
222720e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown        // Perform any necessary transformations and dispatch.
222820e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown        if (child == null) {
222920e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown            handled = super.dispatchTouchEvent(transformedEvent);
223020e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown        } else {
223120e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown            final float offsetX = mScrollX - child.mLeft;
223220e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown            final float offsetY = mScrollY - child.mTop;
223320e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown            transformedEvent.offsetLocation(offsetX, offsetY);
223420e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown            if (! child.hasIdentityMatrix()) {
223520e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown                transformedEvent.transform(child.getInverseMatrix());
22362b342f0a76f3237e97f15dc2f4e8a0b72dd7c023Adam Powell            }
22372b342f0a76f3237e97f15dc2f4e8a0b72dd7c023Adam Powell
223820e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown            handled = child.dispatchTouchEvent(transformedEvent);
223920e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown        }
22402b342f0a76f3237e97f15dc2f4e8a0b72dd7c023Adam Powell
224120e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown        // Done.
224220e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown        transformedEvent.recycle();
224320e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown        return handled;
224420e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown    }
22452b342f0a76f3237e97f15dc2f4e8a0b72dd7c023Adam Powell
2246469b1dbeaf7d3267d1b43af4e7391b49eac10ee0Romain Guy    /**
22472b342f0a76f3237e97f15dc2f4e8a0b72dd7c023Adam Powell     * Enable or disable the splitting of MotionEvents to multiple children during touch event
2248995e77431982f9a320451dbe6132a62e69f73babJeff Brown     * dispatch. This behavior is enabled by default for applications that target an
2249995e77431982f9a320451dbe6132a62e69f73babJeff Brown     * SDK version of {@link Build.VERSION_CODES#HONEYCOMB} or newer.
22502b342f0a76f3237e97f15dc2f4e8a0b72dd7c023Adam Powell     *
22512b342f0a76f3237e97f15dc2f4e8a0b72dd7c023Adam Powell     * <p>When this option is enabled MotionEvents may be split and dispatched to different child
22522b342f0a76f3237e97f15dc2f4e8a0b72dd7c023Adam Powell     * views depending on where each pointer initially went down. This allows for user interactions
22532b342f0a76f3237e97f15dc2f4e8a0b72dd7c023Adam Powell     * such as scrolling two panes of content independently, chording of buttons, and performing
22542b342f0a76f3237e97f15dc2f4e8a0b72dd7c023Adam Powell     * independent gestures on different pieces of content.
22552b342f0a76f3237e97f15dc2f4e8a0b72dd7c023Adam Powell     *
22562b342f0a76f3237e97f15dc2f4e8a0b72dd7c023Adam Powell     * @param split <code>true</code> to allow MotionEvents to be split and dispatched to multiple
22572b342f0a76f3237e97f15dc2f4e8a0b72dd7c023Adam Powell     *              child views. <code>false</code> to only allow one child view to be the target of
22582b342f0a76f3237e97f15dc2f4e8a0b72dd7c023Adam Powell     *              any MotionEvent received by this ViewGroup.
225927a8508ee1236ded652cd452b93884a9193654fcScott Main     * @attr ref android.R.styleable#ViewGroup_splitMotionEvents
22602b342f0a76f3237e97f15dc2f4e8a0b72dd7c023Adam Powell     */
22612b342f0a76f3237e97f15dc2f4e8a0b72dd7c023Adam Powell    public void setMotionEventSplittingEnabled(boolean split) {
22622b342f0a76f3237e97f15dc2f4e8a0b72dd7c023Adam Powell        // TODO Applications really shouldn't change this setting mid-touch event,
22632b342f0a76f3237e97f15dc2f4e8a0b72dd7c023Adam Powell        // but perhaps this should handle that case and send ACTION_CANCELs to any child views
22642b342f0a76f3237e97f15dc2f4e8a0b72dd7c023Adam Powell        // with gestures in progress when this is changed.
22652b342f0a76f3237e97f15dc2f4e8a0b72dd7c023Adam Powell        if (split) {
22662b342f0a76f3237e97f15dc2f4e8a0b72dd7c023Adam Powell            mGroupFlags |= FLAG_SPLIT_MOTION_EVENTS;
22672b342f0a76f3237e97f15dc2f4e8a0b72dd7c023Adam Powell        } else {
22682b342f0a76f3237e97f15dc2f4e8a0b72dd7c023Adam Powell            mGroupFlags &= ~FLAG_SPLIT_MOTION_EVENTS;
22692b342f0a76f3237e97f15dc2f4e8a0b72dd7c023Adam Powell        }
22702b342f0a76f3237e97f15dc2f4e8a0b72dd7c023Adam Powell    }
22712b342f0a76f3237e97f15dc2f4e8a0b72dd7c023Adam Powell
22722b342f0a76f3237e97f15dc2f4e8a0b72dd7c023Adam Powell    /**
2273995e77431982f9a320451dbe6132a62e69f73babJeff Brown     * Returns true if MotionEvents dispatched to this ViewGroup can be split to multiple children.
22742b342f0a76f3237e97f15dc2f4e8a0b72dd7c023Adam Powell     * @return true if MotionEvents dispatched to this ViewGroup can be split to multiple children.
22752b342f0a76f3237e97f15dc2f4e8a0b72dd7c023Adam Powell     */
22762b342f0a76f3237e97f15dc2f4e8a0b72dd7c023Adam Powell    public boolean isMotionEventSplittingEnabled() {
22772b342f0a76f3237e97f15dc2f4e8a0b72dd7c023Adam Powell        return (mGroupFlags & FLAG_SPLIT_MOTION_EVENTS) == FLAG_SPLIT_MOTION_EVENTS;
22782b342f0a76f3237e97f15dc2f4e8a0b72dd7c023Adam Powell    }
22792b342f0a76f3237e97f15dc2f4e8a0b72dd7c023Adam Powell
22802b342f0a76f3237e97f15dc2f4e8a0b72dd7c023Adam Powell    /**
22819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@inheritDoc}
22829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
22839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void requestDisallowInterceptTouchEvent(boolean disallowIntercept) {
22848506ab4ac062d0e1ccde136e5e2f4081560e0c11Romain Guy
22859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (disallowIntercept == ((mGroupFlags & FLAG_DISALLOW_INTERCEPT) != 0)) {
22869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // We're already in this state, assume our ancestors are too
22879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return;
22889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
22898506ab4ac062d0e1ccde136e5e2f4081560e0c11Romain Guy
22909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (disallowIntercept) {
22919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mGroupFlags |= FLAG_DISALLOW_INTERCEPT;
22929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
22939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mGroupFlags &= ~FLAG_DISALLOW_INTERCEPT;
22949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
22958506ab4ac062d0e1ccde136e5e2f4081560e0c11Romain Guy
22969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Pass it up to our parent
22979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mParent != null) {
22989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mParent.requestDisallowInterceptTouchEvent(disallowIntercept);
22999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
23009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
23019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
23029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
23039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Implement this method to intercept all touch screen motion events.  This
23049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * allows you to watch events as they are dispatched to your children, and
23059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * take ownership of the current gesture at any point.
23069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
23079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Using this function takes some care, as it has a fairly complicated
23089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * interaction with {@link View#onTouchEvent(MotionEvent)
23099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * View.onTouchEvent(MotionEvent)}, and using it requires implementing
23109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * that method as well as this one in the correct way.  Events will be
23119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * received in the following order:
23129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
23139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <ol>
23149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <li> You will receive the down event here.
23159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <li> The down event will be handled either by a child of this view
23169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * group, or given to your own onTouchEvent() method to handle; this means
23179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * you should implement onTouchEvent() to return true, so you will
23189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * continue to see the rest of the gesture (instead of looking for
23199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * a parent view to handle it).  Also, by returning true from
23209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * onTouchEvent(), you will not receive any following
23219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * events in onInterceptTouchEvent() and all touch processing must
23229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * happen in onTouchEvent() like normal.
23239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <li> For as long as you return false from this function, each following
23249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * event (up to and including the final up) will be delivered first here
23259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * and then to the target's onTouchEvent().
23269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <li> If you return true from here, you will not receive any
23279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * following events: the target view will receive the same event but
23289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * with the action {@link MotionEvent#ACTION_CANCEL}, and all further
23299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * events will be delivered to your onTouchEvent() method and no longer
23309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * appear here.
23319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * </ol>
23329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
23339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param ev The motion event being dispatched down the hierarchy.
23349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return Return true to steal motion events from the children and have
23359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * them dispatched to this ViewGroup through onTouchEvent().
23369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * The current target will receive an ACTION_CANCEL event, and no further
23379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * messages will be delivered here.
23389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
23399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean onInterceptTouchEvent(MotionEvent ev) {
23409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return false;
23419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
23429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
23439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
23449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@inheritDoc}
23459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
23469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Looks for a view to give focus to respecting the setting specified by
23479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@link #getDescendantFocusability()}.
23489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
23499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Uses {@link #onRequestFocusInDescendants(int, android.graphics.Rect)} to
23509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * find focus within the children of this group when appropriate.
23519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
23529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #FOCUS_BEFORE_DESCENDANTS
23539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #FOCUS_AFTER_DESCENDANTS
23549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #FOCUS_BLOCK_DESCENDANTS
235502739a8eecce26783350041da332f8daf6691e25Romain Guy     * @see #onRequestFocusInDescendants(int, android.graphics.Rect)
23569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
23579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
23589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean requestFocus(int direction, Rect previouslyFocusedRect) {
23599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (DBG) {
23609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            System.out.println(this + " ViewGroup.requestFocus direction="
23619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    + direction);
23629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
23639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int descendantFocusability = getDescendantFocusability();
23649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
23659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        switch (descendantFocusability) {
23669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case FOCUS_BLOCK_DESCENDANTS:
23679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return super.requestFocus(direction, previouslyFocusedRect);
23689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case FOCUS_BEFORE_DESCENDANTS: {
23699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                final boolean took = super.requestFocus(direction, previouslyFocusedRect);
23709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return took ? took : onRequestFocusInDescendants(direction, previouslyFocusedRect);
23719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
23729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case FOCUS_AFTER_DESCENDANTS: {
23739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                final boolean took = onRequestFocusInDescendants(direction, previouslyFocusedRect);
23749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return took ? took : super.requestFocus(direction, previouslyFocusedRect);
23759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
23769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            default:
23779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                throw new IllegalStateException("descendant focusability must be "
23789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        + "one of FOCUS_BEFORE_DESCENDANTS, FOCUS_AFTER_DESCENDANTS, FOCUS_BLOCK_DESCENDANTS "
23799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        + "but is " + descendantFocusability);
23809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
23819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
23829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
23839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
23849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Look for a descendant to call {@link View#requestFocus} on.
23859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Called by {@link ViewGroup#requestFocus(int, android.graphics.Rect)}
23869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * when it wants to request focus within its children.  Override this to
23879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * customize how your {@link ViewGroup} requests focus within its children.
23889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param direction One of FOCUS_UP, FOCUS_DOWN, FOCUS_LEFT, and FOCUS_RIGHT
23899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param previouslyFocusedRect The rectangle (in this View's coordinate system)
23909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *        to give a finer grained hint about where focus is coming from.  May be null
23919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *        if there is no hint.
23929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return Whether focus was taken.
23939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
23949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @SuppressWarnings({"ConstantConditions"})
23959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected boolean onRequestFocusInDescendants(int direction,
23969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            Rect previouslyFocusedRect) {
23979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int index;
23989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int increment;
23999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int end;
24009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int count = mChildrenCount;
24019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if ((direction & FOCUS_FORWARD) != 0) {
24029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            index = 0;
24039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            increment = 1;
24049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            end = count;
24059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
24069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            index = count - 1;
24079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            increment = -1;
24089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            end = -1;
24099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
24109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final View[] children = mChildren;
24119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (int i = index; i != end; i += increment) {
24129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            View child = children[i];
24139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if ((child.mViewFlags & VISIBILITY_MASK) == VISIBLE) {
24149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (child.requestFocus(direction, previouslyFocusedRect)) {
24159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    return true;
24169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
24179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
24189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
24199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return false;
24209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
24215c13d89c1332fcc499379b9064b891187b75ca32Chet Haase
2422a440b002aa59e1455bdfa2c5a1ca51c74bbc19acRomain Guy    /**
2423a440b002aa59e1455bdfa2c5a1ca51c74bbc19acRomain Guy     * {@inheritDoc}
24245c13d89c1332fcc499379b9064b891187b75ca32Chet Haase     *
2425dcc490f20103a4bbd879ea040ce67779d211c2d7Romain Guy     * @hide
2426a440b002aa59e1455bdfa2c5a1ca51c74bbc19acRomain Guy     */
2427a440b002aa59e1455bdfa2c5a1ca51c74bbc19acRomain Guy    @Override
2428a440b002aa59e1455bdfa2c5a1ca51c74bbc19acRomain Guy    public void dispatchStartTemporaryDetach() {
2429a440b002aa59e1455bdfa2c5a1ca51c74bbc19acRomain Guy        super.dispatchStartTemporaryDetach();
2430a440b002aa59e1455bdfa2c5a1ca51c74bbc19acRomain Guy        final int count = mChildrenCount;
2431a440b002aa59e1455bdfa2c5a1ca51c74bbc19acRomain Guy        final View[] children = mChildren;
2432a440b002aa59e1455bdfa2c5a1ca51c74bbc19acRomain Guy        for (int i = 0; i < count; i++) {
2433a440b002aa59e1455bdfa2c5a1ca51c74bbc19acRomain Guy            children[i].dispatchStartTemporaryDetach();
2434a440b002aa59e1455bdfa2c5a1ca51c74bbc19acRomain Guy        }
2435a440b002aa59e1455bdfa2c5a1ca51c74bbc19acRomain Guy    }
24365c13d89c1332fcc499379b9064b891187b75ca32Chet Haase
2437a440b002aa59e1455bdfa2c5a1ca51c74bbc19acRomain Guy    /**
2438a440b002aa59e1455bdfa2c5a1ca51c74bbc19acRomain Guy     * {@inheritDoc}
24395c13d89c1332fcc499379b9064b891187b75ca32Chet Haase     *
2440dcc490f20103a4bbd879ea040ce67779d211c2d7Romain Guy     * @hide
2441a440b002aa59e1455bdfa2c5a1ca51c74bbc19acRomain Guy     */
2442a440b002aa59e1455bdfa2c5a1ca51c74bbc19acRomain Guy    @Override
2443a440b002aa59e1455bdfa2c5a1ca51c74bbc19acRomain Guy    public void dispatchFinishTemporaryDetach() {
2444a440b002aa59e1455bdfa2c5a1ca51c74bbc19acRomain Guy        super.dispatchFinishTemporaryDetach();
2445a440b002aa59e1455bdfa2c5a1ca51c74bbc19acRomain Guy        final int count = mChildrenCount;
2446a440b002aa59e1455bdfa2c5a1ca51c74bbc19acRomain Guy        final View[] children = mChildren;
2447a440b002aa59e1455bdfa2c5a1ca51c74bbc19acRomain Guy        for (int i = 0; i < count; i++) {
2448a440b002aa59e1455bdfa2c5a1ca51c74bbc19acRomain Guy            children[i].dispatchFinishTemporaryDetach();
2449a440b002aa59e1455bdfa2c5a1ca51c74bbc19acRomain Guy        }
2450a440b002aa59e1455bdfa2c5a1ca51c74bbc19acRomain Guy    }
24519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
24529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
24539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@inheritDoc}
24549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
24559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
24569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    void dispatchAttachedToWindow(AttachInfo info, int visibility) {
24574b86788003b3ddc968d0681d5ed4e5da07e4a65aAdam Powell        mGroupFlags |= FLAG_PREVENT_DISPATCH_ATTACHED_TO_WINDOW;
24589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        super.dispatchAttachedToWindow(info, visibility);
24594b86788003b3ddc968d0681d5ed4e5da07e4a65aAdam Powell        mGroupFlags &= ~FLAG_PREVENT_DISPATCH_ATTACHED_TO_WINDOW;
24604b86788003b3ddc968d0681d5ed4e5da07e4a65aAdam Powell
24619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final int count = mChildrenCount;
24629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final View[] children = mChildren;
24639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (int i = 0; i < count; i++) {
24643a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn            final View child = children[i];
24653a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn            child.dispatchAttachedToWindow(info,
24667b7578184567f4e4f0740ce935cc192765410ccaPhilip Milne                    visibility | (child.mViewFlags & VISIBILITY_MASK));
24679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
24689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
24699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
247075986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov    @Override
2471bb9908b828a8cfd5965553be66faa6af89973697Romain Guy    void dispatchScreenStateChanged(int screenState) {
2472bb9908b828a8cfd5965553be66faa6af89973697Romain Guy        super.dispatchScreenStateChanged(screenState);
2473bb9908b828a8cfd5965553be66faa6af89973697Romain Guy
2474bb9908b828a8cfd5965553be66faa6af89973697Romain Guy        final int count = mChildrenCount;
2475bb9908b828a8cfd5965553be66faa6af89973697Romain Guy        final View[] children = mChildren;
2476bb9908b828a8cfd5965553be66faa6af89973697Romain Guy        for (int i = 0; i < count; i++) {
2477bb9908b828a8cfd5965553be66faa6af89973697Romain Guy            children[i].dispatchScreenStateChanged(screenState);
2478bb9908b828a8cfd5965553be66faa6af89973697Romain Guy        }
2479bb9908b828a8cfd5965553be66faa6af89973697Romain Guy    }
2480bb9908b828a8cfd5965553be66faa6af89973697Romain Guy
2481bb9908b828a8cfd5965553be66faa6af89973697Romain Guy    @Override
2482031d9c1389de2b9dac7f175af0b962e24b21d5beSvetoslav Ganov    boolean dispatchPopulateAccessibilityEventInternal(AccessibilityEvent event) {
24834213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov        boolean handled = false;
24844213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov        if (includeForAccessibility()) {
24854213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov            handled = super.dispatchPopulateAccessibilityEventInternal(event);
24864213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov            if (handled) {
24874213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov                return handled;
24884213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov            }
2489b84b94e1a04cd1f396dd6fef98d65ca1a2729c92Svetoslav Ganov        }
2490736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov        // Let our children have a shot in populating the event.
24914213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov        ChildListForAccessibility children = ChildListForAccessibility.obtain(this, true);
249276f287e416ded85734b610f316e38d243d2ddb09Svetoslav Ganov        try {
249376f287e416ded85734b610f316e38d243d2ddb09Svetoslav Ganov            final int childCount = children.getChildCount();
249476f287e416ded85734b610f316e38d243d2ddb09Svetoslav Ganov            for (int i = 0; i < childCount; i++) {
249576f287e416ded85734b610f316e38d243d2ddb09Svetoslav Ganov                View child = children.getChildAt(i);
249676f287e416ded85734b610f316e38d243d2ddb09Svetoslav Ganov                if ((child.mViewFlags & VISIBILITY_MASK) == VISIBLE) {
249776f287e416ded85734b610f316e38d243d2ddb09Svetoslav Ganov                    handled = child.dispatchPopulateAccessibilityEvent(event);
249876f287e416ded85734b610f316e38d243d2ddb09Svetoslav Ganov                    if (handled) {
249976f287e416ded85734b610f316e38d243d2ddb09Svetoslav Ganov                        return handled;
250076f287e416ded85734b610f316e38d243d2ddb09Svetoslav Ganov                    }
25016179ea3196e9306d3f14361fe9ef14191b1edba6Svetoslav Ganov                }
2502736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov            }
250376f287e416ded85734b610f316e38d243d2ddb09Svetoslav Ganov        } finally {
250476f287e416ded85734b610f316e38d243d2ddb09Svetoslav Ganov            children.recycle();
250575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov        }
2506736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov        return false;
250775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov    }
250875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov
25098643aa0179e598e78d938c59035389054535a229Svetoslav Ganov    @Override
2510031d9c1389de2b9dac7f175af0b962e24b21d5beSvetoslav Ganov    void onInitializeAccessibilityNodeInfoInternal(AccessibilityNodeInfo info) {
2511031d9c1389de2b9dac7f175af0b962e24b21d5beSvetoslav Ganov        super.onInitializeAccessibilityNodeInfoInternal(info);
25124213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov        if (mAttachInfo != null) {
25134213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov            ArrayList<View> childrenForAccessibility = mAttachInfo.mTempArrayList;
25144213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov            childrenForAccessibility.clear();
25154213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov            addChildrenForAccessibility(childrenForAccessibility);
25164213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov            final int childrenForAccessibilityCount = childrenForAccessibility.size();
25174213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov            for (int i = 0; i < childrenForAccessibilityCount; i++) {
25184213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov                View child = childrenForAccessibility.get(i);
2519ea1da3d2e61625afcc7753ba2e03c5d2fb565daeSvetoslav Ganov                info.addChild(child);
2520ea1da3d2e61625afcc7753ba2e03c5d2fb565daeSvetoslav Ganov            }
25214213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov            childrenForAccessibility.clear();
25228643aa0179e598e78d938c59035389054535a229Svetoslav Ganov        }
25238643aa0179e598e78d938c59035389054535a229Svetoslav Ganov    }
25248643aa0179e598e78d938c59035389054535a229Svetoslav Ganov
25258a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganov    @Override
25268a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganov    void onInitializeAccessibilityEventInternal(AccessibilityEvent event) {
25278a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganov        super.onInitializeAccessibilityEventInternal(event);
25288a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganov        event.setClassName(ViewGroup.class.getName());
25298a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganov    }
25308a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganov
25314213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov    @Override
253277e9a28e2faa36f127231b842476d47f9823a83aAlan Viverette    public void notifySubtreeAccessibilityStateChanged(View child, View source, int changeType) {
253377e9a28e2faa36f127231b842476d47f9823a83aAlan Viverette        // If this is a live region, we should send a subtree change event
253477e9a28e2faa36f127231b842476d47f9823a83aAlan Viverette        // from this view. Otherwise, we can let it propagate up.
253577e9a28e2faa36f127231b842476d47f9823a83aAlan Viverette        if (getAccessibilityLiveRegion() != ACCESSIBILITY_LIVE_REGION_NONE) {
253677e9a28e2faa36f127231b842476d47f9823a83aAlan Viverette            notifyViewAccessibilityStateChangedIfNeeded(changeType);
253777e9a28e2faa36f127231b842476d47f9823a83aAlan Viverette        } else if (mParent != null) {
2538504a10f2f5c7343c863d31490700620109deb7aeAdam Powell            try {
253977e9a28e2faa36f127231b842476d47f9823a83aAlan Viverette                mParent.notifySubtreeAccessibilityStateChanged(this, source, changeType);
2540504a10f2f5c7343c863d31490700620109deb7aeAdam Powell            } catch (AbstractMethodError e) {
2541504a10f2f5c7343c863d31490700620109deb7aeAdam Powell                Log.e(VIEW_LOG_TAG, mParent.getClass().getSimpleName() +
2542504a10f2f5c7343c863d31490700620109deb7aeAdam Powell                        " does not fully implement ViewParent", e);
2543504a10f2f5c7343c863d31490700620109deb7aeAdam Powell            }
25446254f4806dd3db53b7380e77fbb183065685573eSvetoslav        }
25456254f4806dd3db53b7380e77fbb183065685573eSvetoslav    }
25466254f4806dd3db53b7380e77fbb183065685573eSvetoslav
25476254f4806dd3db53b7380e77fbb183065685573eSvetoslav    @Override
25486254f4806dd3db53b7380e77fbb183065685573eSvetoslav    void resetSubtreeAccessibilityStateChanged() {
25496254f4806dd3db53b7380e77fbb183065685573eSvetoslav        super.resetSubtreeAccessibilityStateChanged();
25504213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov        View[] children = mChildren;
25514213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov        final int childCount = mChildrenCount;
25524213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov        for (int i = 0; i < childCount; i++) {
25536254f4806dd3db53b7380e77fbb183065685573eSvetoslav            children[i].resetSubtreeAccessibilityStateChanged();
25544213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov        }
25554213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov    }
25564213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov
25574213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov    /**
25589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@inheritDoc}
25599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
25609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
25619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    void dispatchDetachedFromWindow() {
256220e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown        // If we still have a touch target, we are still in the process of
25639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // dispatching motion events to a child; we need to get rid of that
25649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // child to avoid dispatching events to it after the window is torn
25659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // down. To make sure we keep the child in a consistent state, we
25669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // first send it an ACTION_CANCEL motion event.
256720e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown        cancelAndClearTouchTargets(null);
25689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
256959a422e90035ce5df45c526607db2d3303e3112eJeff Brown        // Similarly, set ACTION_EXIT to all hover targets and clear them.
257059a422e90035ce5df45c526607db2d3303e3112eJeff Brown        exitHoverTargets();
257159a422e90035ce5df45c526607db2d3303e3112eJeff Brown
25729c0874408cfc6f6f4e4561973ca5ae52a5982db7Chet Haase        // In case view is detached while transition is running
2573b989502e5cf44d65c6dddc0179b6d9b6e61ef7fdChet Haase        mLayoutCalledWhileSuppressed = false;
25749c0874408cfc6f6f4e4561973ca5ae52a5982db7Chet Haase
257586cab1bd52197d6fa60786413fad9788d9236762Christopher Tate        // Tear down our drag tracking
257686cab1bd52197d6fa60786413fad9788d9236762Christopher Tate        mDragNotifiedChildren = null;
257786cab1bd52197d6fa60786413fad9788d9236762Christopher Tate        if (mCurrentDrag != null) {
257886cab1bd52197d6fa60786413fad9788d9236762Christopher Tate            mCurrentDrag.recycle();
257986cab1bd52197d6fa60786413fad9788d9236762Christopher Tate            mCurrentDrag = null;
258086cab1bd52197d6fa60786413fad9788d9236762Christopher Tate        }
258186cab1bd52197d6fa60786413fad9788d9236762Christopher Tate
25829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final int count = mChildrenCount;
25839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final View[] children = mChildren;
25849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (int i = 0; i < count; i++) {
25859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            children[i].dispatchDetachedFromWindow();
25869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
25879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        super.dispatchDetachedFromWindow();
25889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
25899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
259023c89fd1685a006957dc0f2aacf167b4449f3d80Fabrice Di Meglio    /**
259123c89fd1685a006957dc0f2aacf167b4449f3d80Fabrice Di Meglio     * @hide
259223c89fd1685a006957dc0f2aacf167b4449f3d80Fabrice Di Meglio     */
25939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
259423c89fd1685a006957dc0f2aacf167b4449f3d80Fabrice Di Meglio    protected void internalSetPadding(int left, int top, int right, int bottom) {
25952440e670de0294bdf64592849613db9b8f00ee11Romain Guy        super.internalSetPadding(left, top, right, bottom);
25969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
259713f35f3ce6a7d26c20d1c63485bfb5e2ffff31b9Romain Guy        if ((mPaddingLeft | mPaddingTop | mPaddingRight | mPaddingBottom) != 0) {
25989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mGroupFlags |= FLAG_PADDING_NOT_NULL;
25999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
26009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mGroupFlags &= ~FLAG_PADDING_NOT_NULL;
26019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
26029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
26039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
26049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
26059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@inheritDoc}
26069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
26079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
26089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected void dispatchSaveInstanceState(SparseArray<Parcelable> container) {
26099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        super.dispatchSaveInstanceState(container);
26109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final int count = mChildrenCount;
26119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final View[] children = mChildren;
26129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (int i = 0; i < count; i++) {
2613b4bc78b16a05554c57508b488e21dd8eca4e13e6Dianne Hackborn            View c = children[i];
2614b4bc78b16a05554c57508b488e21dd8eca4e13e6Dianne Hackborn            if ((c.mViewFlags & PARENT_SAVE_DISABLED_MASK) != PARENT_SAVE_DISABLED) {
2615b4bc78b16a05554c57508b488e21dd8eca4e13e6Dianne Hackborn                c.dispatchSaveInstanceState(container);
2616b4bc78b16a05554c57508b488e21dd8eca4e13e6Dianne Hackborn            }
26179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
26189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
26199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
26209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
26219fc27819d75e24ad63d7b383d80f5cb66a577a0dRomain Guy     * Perform dispatching of a {@link #saveHierarchyState(android.util.SparseArray)}  freeze()}
26229fc27819d75e24ad63d7b383d80f5cb66a577a0dRomain Guy     * to only this view, not to its children.  For use when overriding
26239fc27819d75e24ad63d7b383d80f5cb66a577a0dRomain Guy     * {@link #dispatchSaveInstanceState(android.util.SparseArray)}  dispatchFreeze()} to allow
26249fc27819d75e24ad63d7b383d80f5cb66a577a0dRomain Guy     * subclasses to freeze their own state but not the state of their children.
26259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
26269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param container the container
26279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
26289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected void dispatchFreezeSelfOnly(SparseArray<Parcelable> container) {
26299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        super.dispatchSaveInstanceState(container);
26309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
26319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
26329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
26339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@inheritDoc}
26349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
26359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
26369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected void dispatchRestoreInstanceState(SparseArray<Parcelable> container) {
26379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        super.dispatchRestoreInstanceState(container);
26389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final int count = mChildrenCount;
26399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final View[] children = mChildren;
26409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (int i = 0; i < count; i++) {
2641b4bc78b16a05554c57508b488e21dd8eca4e13e6Dianne Hackborn            View c = children[i];
2642b4bc78b16a05554c57508b488e21dd8eca4e13e6Dianne Hackborn            if ((c.mViewFlags & PARENT_SAVE_DISABLED_MASK) != PARENT_SAVE_DISABLED) {
2643b4bc78b16a05554c57508b488e21dd8eca4e13e6Dianne Hackborn                c.dispatchRestoreInstanceState(container);
2644b4bc78b16a05554c57508b488e21dd8eca4e13e6Dianne Hackborn            }
26459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
26469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
26479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
26489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
264902739a8eecce26783350041da332f8daf6691e25Romain Guy     * Perform dispatching of a {@link #restoreHierarchyState(android.util.SparseArray)}
265002739a8eecce26783350041da332f8daf6691e25Romain Guy     * to only this view, not to its children.  For use when overriding
265102739a8eecce26783350041da332f8daf6691e25Romain Guy     * {@link #dispatchRestoreInstanceState(android.util.SparseArray)} to allow
265202739a8eecce26783350041da332f8daf6691e25Romain Guy     * subclasses to thaw their own state but not the state of their children.
26539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
26549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param container the container
26559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
26569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected void dispatchThawSelfOnly(SparseArray<Parcelable> container) {
26579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        super.dispatchRestoreInstanceState(container);
26589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
26599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
26609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
26619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Enables or disables the drawing cache for each child of this view group.
26629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
26639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param enabled true to enable the cache, false to dispose of it
26649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
26659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected void setChildrenDrawingCacheEnabled(boolean enabled) {
26669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (enabled || (mPersistentDrawingCache & PERSISTENT_ALL_CACHES) != PERSISTENT_ALL_CACHES) {
26679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            final View[] children = mChildren;
26689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            final int count = mChildrenCount;
26699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            for (int i = 0; i < count; i++) {
26709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                children[i].setDrawingCacheEnabled(enabled);
26719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
26729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
26739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
26749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
26759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
26769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected void onAnimationStart() {
26779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        super.onAnimationStart();
26789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
26799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // When this ViewGroup's animation starts, build the cache for the children
26809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if ((mGroupFlags & FLAG_ANIMATION_CACHE) == FLAG_ANIMATION_CACHE) {
26819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            final int count = mChildrenCount;
26829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            final View[] children = mChildren;
26830d9275e565551eed57297627188aa39f3897a50bRomain Guy            final boolean buildCache = !isHardwareAccelerated();
26849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
26859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            for (int i = 0; i < count; i++) {
26869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                final View child = children[i];
26879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if ((child.mViewFlags & VISIBILITY_MASK) == VISIBLE) {
26889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    child.setDrawingCacheEnabled(true);
26890d9275e565551eed57297627188aa39f3897a50bRomain Guy                    if (buildCache) {
26900d9275e565551eed57297627188aa39f3897a50bRomain Guy                        child.buildDrawingCache(true);
26910d9275e565551eed57297627188aa39f3897a50bRomain Guy                    }
26929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
26939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
26949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
26959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mGroupFlags |= FLAG_CHILDREN_DRAWN_WITH_CACHE;
26969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
26979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
26989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
26999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
27009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected void onAnimationEnd() {
27019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        super.onAnimationEnd();
27029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
27039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // When this ViewGroup's animation ends, destroy the cache of the children
27049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if ((mGroupFlags & FLAG_ANIMATION_CACHE) == FLAG_ANIMATION_CACHE) {
27059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mGroupFlags &= ~FLAG_CHILDREN_DRAWN_WITH_CACHE;
27069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
27079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if ((mPersistentDrawingCache & PERSISTENT_ANIMATION_CACHE) == 0) {
27089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                setChildrenDrawingCacheEnabled(false);
27099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
27109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
27119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
27129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2713223ff5c0586adbbd1d6d57a3a4d176222e8b7434Romain Guy    @Override
2714223ff5c0586adbbd1d6d57a3a4d176222e8b7434Romain Guy    Bitmap createSnapshot(Bitmap.Config quality, int backgroundColor, boolean skipChildren) {
271565554f27855ce1764123604b061b10346f8b8404Romain Guy        int count = mChildrenCount;
271665554f27855ce1764123604b061b10346f8b8404Romain Guy        int[] visibilities = null;
271765554f27855ce1764123604b061b10346f8b8404Romain Guy
2718223ff5c0586adbbd1d6d57a3a4d176222e8b7434Romain Guy        if (skipChildren) {
271965554f27855ce1764123604b061b10346f8b8404Romain Guy            visibilities = new int[count];
272065554f27855ce1764123604b061b10346f8b8404Romain Guy            for (int i = 0; i < count; i++) {
272165554f27855ce1764123604b061b10346f8b8404Romain Guy                View child = getChildAt(i);
272265554f27855ce1764123604b061b10346f8b8404Romain Guy                visibilities[i] = child.getVisibility();
272365554f27855ce1764123604b061b10346f8b8404Romain Guy                if (visibilities[i] == View.VISIBLE) {
272465554f27855ce1764123604b061b10346f8b8404Romain Guy                    child.setVisibility(INVISIBLE);
272565554f27855ce1764123604b061b10346f8b8404Romain Guy                }
272665554f27855ce1764123604b061b10346f8b8404Romain Guy            }
2727223ff5c0586adbbd1d6d57a3a4d176222e8b7434Romain Guy        }
2728223ff5c0586adbbd1d6d57a3a4d176222e8b7434Romain Guy
2729223ff5c0586adbbd1d6d57a3a4d176222e8b7434Romain Guy        Bitmap b = super.createSnapshot(quality, backgroundColor, skipChildren);
273065554f27855ce1764123604b061b10346f8b8404Romain Guy
273165554f27855ce1764123604b061b10346f8b8404Romain Guy        if (skipChildren) {
273265554f27855ce1764123604b061b10346f8b8404Romain Guy            for (int i = 0; i < count; i++) {
273365554f27855ce1764123604b061b10346f8b8404Romain Guy                getChildAt(i).setVisibility(visibilities[i]);
27345c13d89c1332fcc499379b9064b891187b75ca32Chet Haase            }
273565554f27855ce1764123604b061b10346f8b8404Romain Guy        }
2736223ff5c0586adbbd1d6d57a3a4d176222e8b7434Romain Guy
2737223ff5c0586adbbd1d6d57a3a4d176222e8b7434Romain Guy        return b;
2738223ff5c0586adbbd1d6d57a3a4d176222e8b7434Romain Guy    }
2739223ff5c0586adbbd1d6d57a3a4d176222e8b7434Romain Guy
27407b7578184567f4e4f0740ce935cc192765410ccaPhilip Milne    /** Return true if this ViewGroup is laying out using optical bounds. */
27417b7578184567f4e4f0740ce935cc192765410ccaPhilip Milne    boolean isLayoutModeOptical() {
27427b7578184567f4e4f0740ce935cc192765410ccaPhilip Milne        return mLayoutMode == LAYOUT_MODE_OPTICAL_BOUNDS;
27437b7578184567f4e4f0740ce935cc192765410ccaPhilip Milne    }
27447b7578184567f4e4f0740ce935cc192765410ccaPhilip Milne
27457b7578184567f4e4f0740ce935cc192765410ccaPhilip Milne    Insets computeOpticalInsets() {
27467b7578184567f4e4f0740ce935cc192765410ccaPhilip Milne        if (isLayoutModeOptical()) {
27477b7578184567f4e4f0740ce935cc192765410ccaPhilip Milne            int left = 0;
27487b7578184567f4e4f0740ce935cc192765410ccaPhilip Milne            int top = 0;
27497b7578184567f4e4f0740ce935cc192765410ccaPhilip Milne            int right = 0;
27507b7578184567f4e4f0740ce935cc192765410ccaPhilip Milne            int bottom = 0;
27517b7578184567f4e4f0740ce935cc192765410ccaPhilip Milne            for (int i = 0; i < mChildrenCount; i++) {
27527b7578184567f4e4f0740ce935cc192765410ccaPhilip Milne                View child = getChildAt(i);
27537b7578184567f4e4f0740ce935cc192765410ccaPhilip Milne                if (child.getVisibility() == VISIBLE) {
27547b7578184567f4e4f0740ce935cc192765410ccaPhilip Milne                    Insets insets = child.getOpticalInsets();
27557b7578184567f4e4f0740ce935cc192765410ccaPhilip Milne                    left =   Math.max(left,   insets.left);
27567b7578184567f4e4f0740ce935cc192765410ccaPhilip Milne                    top =    Math.max(top,    insets.top);
27577b7578184567f4e4f0740ce935cc192765410ccaPhilip Milne                    right =  Math.max(right,  insets.right);
27587b7578184567f4e4f0740ce935cc192765410ccaPhilip Milne                    bottom = Math.max(bottom, insets.bottom);
27597b7578184567f4e4f0740ce935cc192765410ccaPhilip Milne                }
27607b7578184567f4e4f0740ce935cc192765410ccaPhilip Milne            }
27617b7578184567f4e4f0740ce935cc192765410ccaPhilip Milne            return Insets.of(left, top, right, bottom);
27627b7578184567f4e4f0740ce935cc192765410ccaPhilip Milne        } else {
27637b7578184567f4e4f0740ce935cc192765410ccaPhilip Milne            return Insets.NONE;
27647b7578184567f4e4f0740ce935cc192765410ccaPhilip Milne        }
27657b7578184567f4e4f0740ce935cc192765410ccaPhilip Milne    }
27667b7578184567f4e4f0740ce935cc192765410ccaPhilip Milne
27677b7578184567f4e4f0740ce935cc192765410ccaPhilip Milne    private static void fillRect(Canvas canvas, Paint paint, int x1, int y1, int x2, int y2) {
27687b7578184567f4e4f0740ce935cc192765410ccaPhilip Milne        if (x1 != x2 && y1 != y2) {
27697b7578184567f4e4f0740ce935cc192765410ccaPhilip Milne            if (x1 > x2) {
27707b7578184567f4e4f0740ce935cc192765410ccaPhilip Milne                int tmp = x1; x1 = x2; x2 = tmp;
27717b7578184567f4e4f0740ce935cc192765410ccaPhilip Milne            }
27727b7578184567f4e4f0740ce935cc192765410ccaPhilip Milne            if (y1 > y2) {
27737b7578184567f4e4f0740ce935cc192765410ccaPhilip Milne                int tmp = y1; y1 = y2; y2 = tmp;
27747b7578184567f4e4f0740ce935cc192765410ccaPhilip Milne            }
27757b7578184567f4e4f0740ce935cc192765410ccaPhilip Milne            canvas.drawRect(x1, y1, x2, y2, paint);
27767b7578184567f4e4f0740ce935cc192765410ccaPhilip Milne        }
27777b7578184567f4e4f0740ce935cc192765410ccaPhilip Milne    }
27787b7578184567f4e4f0740ce935cc192765410ccaPhilip Milne
27797b7578184567f4e4f0740ce935cc192765410ccaPhilip Milne    private static int sign(int x) {
27807b7578184567f4e4f0740ce935cc192765410ccaPhilip Milne        return (x >= 0) ? 1 : -1;
27817b7578184567f4e4f0740ce935cc192765410ccaPhilip Milne    }
2782cbc6774ef0285956da74193e5d217738e7411830Romain Guy
27837b7578184567f4e4f0740ce935cc192765410ccaPhilip Milne    private static void drawCorner(Canvas c, Paint paint, int x1, int y1, int dx, int dy, int lw) {
27847b7578184567f4e4f0740ce935cc192765410ccaPhilip Milne        fillRect(c, paint, x1, y1, x1 + dx, y1 + lw * sign(dy));
27857b7578184567f4e4f0740ce935cc192765410ccaPhilip Milne        fillRect(c, paint, x1, y1, x1 + lw * sign(dx), y1 + dy);
27867b7578184567f4e4f0740ce935cc192765410ccaPhilip Milne    }
27877b7578184567f4e4f0740ce935cc192765410ccaPhilip Milne
27887b7578184567f4e4f0740ce935cc192765410ccaPhilip Milne    private int dipsToPixels(int dips) {
27897b7578184567f4e4f0740ce935cc192765410ccaPhilip Milne        float scale = getContext().getResources().getDisplayMetrics().density;
27907b7578184567f4e4f0740ce935cc192765410ccaPhilip Milne        return (int) (dips * scale + 0.5f);
27917b7578184567f4e4f0740ce935cc192765410ccaPhilip Milne    }
27927b7578184567f4e4f0740ce935cc192765410ccaPhilip Milne
27936410c0aaf13c9aec606b90ee942f2ac2d98b1609Romain Guy    private static void drawRectCorners(Canvas canvas, int x1, int y1, int x2, int y2, Paint paint,
27946410c0aaf13c9aec606b90ee942f2ac2d98b1609Romain Guy            int lineLength, int lineWidth) {
27957b7578184567f4e4f0740ce935cc192765410ccaPhilip Milne        drawCorner(canvas, paint, x1, y1, lineLength, lineLength, lineWidth);
27967b7578184567f4e4f0740ce935cc192765410ccaPhilip Milne        drawCorner(canvas, paint, x1, y2, lineLength, -lineLength, lineWidth);
27977b7578184567f4e4f0740ce935cc192765410ccaPhilip Milne        drawCorner(canvas, paint, x2, y1, -lineLength, lineLength, lineWidth);
27987b7578184567f4e4f0740ce935cc192765410ccaPhilip Milne        drawCorner(canvas, paint, x2, y2, -lineLength, -lineLength, lineWidth);
27997b7578184567f4e4f0740ce935cc192765410ccaPhilip Milne    }
28007b7578184567f4e4f0740ce935cc192765410ccaPhilip Milne
28017b7578184567f4e4f0740ce935cc192765410ccaPhilip Milne    private static void fillDifference(Canvas canvas,
28027b7578184567f4e4f0740ce935cc192765410ccaPhilip Milne            int x2, int y2, int x3, int y3,
28037b7578184567f4e4f0740ce935cc192765410ccaPhilip Milne            int dx1, int dy1, int dx2, int dy2, Paint paint) {
28047b7578184567f4e4f0740ce935cc192765410ccaPhilip Milne        int x1 = x2 - dx1;
28057b7578184567f4e4f0740ce935cc192765410ccaPhilip Milne        int y1 = y2 - dy1;
28067b7578184567f4e4f0740ce935cc192765410ccaPhilip Milne
28077b7578184567f4e4f0740ce935cc192765410ccaPhilip Milne        int x4 = x3 + dx2;
28087b7578184567f4e4f0740ce935cc192765410ccaPhilip Milne        int y4 = y3 + dy2;
28097b7578184567f4e4f0740ce935cc192765410ccaPhilip Milne
28107b7578184567f4e4f0740ce935cc192765410ccaPhilip Milne        fillRect(canvas, paint, x1, y1, x4, y2);
28117b7578184567f4e4f0740ce935cc192765410ccaPhilip Milne        fillRect(canvas, paint, x1, y2, x2, y3);
28127b7578184567f4e4f0740ce935cc192765410ccaPhilip Milne        fillRect(canvas, paint, x3, y2, x4, y3);
28137b7578184567f4e4f0740ce935cc192765410ccaPhilip Milne        fillRect(canvas, paint, x1, y3, x4, y4);
281410ca24a97cefc14fca1b26f59e627f487b3b108bPhilip Milne    }
281510ca24a97cefc14fca1b26f59e627f487b3b108bPhilip Milne
281610ca24a97cefc14fca1b26f59e627f487b3b108bPhilip Milne    /**
281710ca24a97cefc14fca1b26f59e627f487b3b108bPhilip Milne     * @hide
281810ca24a97cefc14fca1b26f59e627f487b3b108bPhilip Milne     */
28197b7578184567f4e4f0740ce935cc192765410ccaPhilip Milne    protected void onDebugDrawMargins(Canvas canvas, Paint paint) {
282010ca24a97cefc14fca1b26f59e627f487b3b108bPhilip Milne        for (int i = 0; i < getChildCount(); i++) {
282110ca24a97cefc14fca1b26f59e627f487b3b108bPhilip Milne            View c = getChildAt(i);
28227b7578184567f4e4f0740ce935cc192765410ccaPhilip Milne            c.getLayoutParams().onDebugDraw(c, canvas, paint);
282310ca24a97cefc14fca1b26f59e627f487b3b108bPhilip Milne        }
282410ca24a97cefc14fca1b26f59e627f487b3b108bPhilip Milne    }
282510ca24a97cefc14fca1b26f59e627f487b3b108bPhilip Milne
282610ca24a97cefc14fca1b26f59e627f487b3b108bPhilip Milne    /**
282710ca24a97cefc14fca1b26f59e627f487b3b108bPhilip Milne     * @hide
282810ca24a97cefc14fca1b26f59e627f487b3b108bPhilip Milne     */
282910ca24a97cefc14fca1b26f59e627f487b3b108bPhilip Milne    protected void onDebugDraw(Canvas canvas) {
28307b7578184567f4e4f0740ce935cc192765410ccaPhilip Milne        Paint paint = getDebugPaint();
28317b7578184567f4e4f0740ce935cc192765410ccaPhilip Milne
283210ca24a97cefc14fca1b26f59e627f487b3b108bPhilip Milne        // Draw optical bounds
28337b7578184567f4e4f0740ce935cc192765410ccaPhilip Milne        {
28347b7578184567f4e4f0740ce935cc192765410ccaPhilip Milne            paint.setColor(Color.RED);
28357b7578184567f4e4f0740ce935cc192765410ccaPhilip Milne            paint.setStyle(Paint.Style.STROKE);
28367b7578184567f4e4f0740ce935cc192765410ccaPhilip Milne
283710ca24a97cefc14fca1b26f59e627f487b3b108bPhilip Milne            for (int i = 0; i < getChildCount(); i++) {
283810ca24a97cefc14fca1b26f59e627f487b3b108bPhilip Milne                View c = getChildAt(i);
28397a23b49a8ceb07d3fa12c45fd42cd16131fd746aPhilip Milne                Insets insets = c.getOpticalInsets();
28407b7578184567f4e4f0740ce935cc192765410ccaPhilip Milne
28417b7578184567f4e4f0740ce935cc192765410ccaPhilip Milne                drawRect(canvas, paint,
28427b7578184567f4e4f0740ce935cc192765410ccaPhilip Milne                        c.getLeft()   + insets.left,
28437b7578184567f4e4f0740ce935cc192765410ccaPhilip Milne                        c.getTop()    + insets.top,
28447b7578184567f4e4f0740ce935cc192765410ccaPhilip Milne                        c.getRight()  - insets.right  - 1,
28457b7578184567f4e4f0740ce935cc192765410ccaPhilip Milne                        c.getBottom() - insets.bottom - 1);
284610ca24a97cefc14fca1b26f59e627f487b3b108bPhilip Milne            }
284710ca24a97cefc14fca1b26f59e627f487b3b108bPhilip Milne        }
284810ca24a97cefc14fca1b26f59e627f487b3b108bPhilip Milne
2849604f440dfd6e5ee857f1e71d12c635d4ee1afcbcPhilip Milne        // Draw margins
28507b7578184567f4e4f0740ce935cc192765410ccaPhilip Milne        {
28517b7578184567f4e4f0740ce935cc192765410ccaPhilip Milne            paint.setColor(Color.argb(63, 255, 0, 255));
28527b7578184567f4e4f0740ce935cc192765410ccaPhilip Milne            paint.setStyle(Paint.Style.FILL);
2853604f440dfd6e5ee857f1e71d12c635d4ee1afcbcPhilip Milne
28547b7578184567f4e4f0740ce935cc192765410ccaPhilip Milne            onDebugDrawMargins(canvas, paint);
28557b7578184567f4e4f0740ce935cc192765410ccaPhilip Milne        }
28567b7578184567f4e4f0740ce935cc192765410ccaPhilip Milne
28577b7578184567f4e4f0740ce935cc192765410ccaPhilip Milne        // Draw clip bounds
28587b7578184567f4e4f0740ce935cc192765410ccaPhilip Milne        {
28597b7578184567f4e4f0740ce935cc192765410ccaPhilip Milne            paint.setColor(Color.rgb(63, 127, 255));
28607b7578184567f4e4f0740ce935cc192765410ccaPhilip Milne            paint.setStyle(Paint.Style.FILL);
28617b7578184567f4e4f0740ce935cc192765410ccaPhilip Milne
28627b7578184567f4e4f0740ce935cc192765410ccaPhilip Milne            int lineLength = dipsToPixels(8);
28637b7578184567f4e4f0740ce935cc192765410ccaPhilip Milne            int lineWidth = dipsToPixels(1);
28647b7578184567f4e4f0740ce935cc192765410ccaPhilip Milne            for (int i = 0; i < getChildCount(); i++) {
28657b7578184567f4e4f0740ce935cc192765410ccaPhilip Milne                View c = getChildAt(i);
28667b7578184567f4e4f0740ce935cc192765410ccaPhilip Milne                drawRectCorners(canvas, c.getLeft(), c.getTop(), c.getRight(), c.getBottom(),
28677b7578184567f4e4f0740ce935cc192765410ccaPhilip Milne                        paint, lineLength, lineWidth);
28687b7578184567f4e4f0740ce935cc192765410ccaPhilip Milne            }
286910ca24a97cefc14fca1b26f59e627f487b3b108bPhilip Milne        }
287010ca24a97cefc14fca1b26f59e627f487b3b108bPhilip Milne    }
287110ca24a97cefc14fca1b26f59e627f487b3b108bPhilip Milne
28729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
28739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@inheritDoc}
28749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
28759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
28769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected void dispatchDraw(Canvas canvas) {
28779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final int count = mChildrenCount;
28789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final View[] children = mChildren;
28799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int flags = mGroupFlags;
28809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
28819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if ((flags & FLAG_RUN_ANIMATION) != 0 && canAnimate()) {
28829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            final boolean cache = (mGroupFlags & FLAG_ANIMATION_CACHE) == FLAG_ANIMATION_CACHE;
28839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
28840d9275e565551eed57297627188aa39f3897a50bRomain Guy            final boolean buildCache = !isHardwareAccelerated();
28859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            for (int i = 0; i < count; i++) {
28869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                final View child = children[i];
28879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if ((child.mViewFlags & VISIBILITY_MASK) == VISIBLE) {
28889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    final LayoutParams params = child.getLayoutParams();
28899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    attachLayoutAnimationParameters(child, params, i, count);
28909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    bindLayoutAnimation(child);
28919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (cache) {
28929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        child.setDrawingCacheEnabled(true);
28930d9275e565551eed57297627188aa39f3897a50bRomain Guy                        if (buildCache) {
28940d9275e565551eed57297627188aa39f3897a50bRomain Guy                            child.buildDrawingCache(true);
28950d9275e565551eed57297627188aa39f3897a50bRomain Guy                        }
28969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
28979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
28989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
28999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
29009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            final LayoutAnimationController controller = mLayoutAnimationController;
29019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (controller.willOverlap()) {
29029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mGroupFlags |= FLAG_OPTIMIZE_INVALIDATE;
29039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
29049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
29059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            controller.start();
29069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
29079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mGroupFlags &= ~FLAG_RUN_ANIMATION;
29089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mGroupFlags &= ~FLAG_ANIMATION_DONE;
29099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
29109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (cache) {
29119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mGroupFlags |= FLAG_CHILDREN_DRAWN_WITH_CACHE;
29129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
29139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
29149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (mAnimationListener != null) {
29159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mAnimationListener.onAnimationStart(controller.getAnimation());
29169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
29179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
29189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
29199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int saveCount = 0;
29209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final boolean clipToPadding = (flags & CLIP_TO_PADDING_MASK) == CLIP_TO_PADDING_MASK;
29219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (clipToPadding) {
29229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            saveCount = canvas.save();
29238f2d94fd77836dac14319735e40f46b18b04216dRomain Guy            canvas.clipRect(mScrollX + mPaddingLeft, mScrollY + mPaddingTop,
29248f2d94fd77836dac14319735e40f46b18b04216dRomain Guy                    mScrollX + mRight - mLeft - mPaddingRight,
29258f2d94fd77836dac14319735e40f46b18b04216dRomain Guy                    mScrollY + mBottom - mTop - mPaddingBottom);
29269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
29279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
29289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
29299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // We will draw our child's animation, let's reset the flag
29304702a856973a553deb82f71b1d3b6c3db5dbf4baDianne Hackborn        mPrivateFlags &= ~PFLAG_DRAW_ANIMATION;
29319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mGroupFlags &= ~FLAG_INVALIDATE_REQUIRED;
29329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
29339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        boolean more = false;
29349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final long drawingTime = getDrawingTime();
29359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
29369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if ((flags & FLAG_USE_CHILD_DRAWING_ORDER) == 0) {
29379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            for (int i = 0; i < count; i++) {
29389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                final View child = children[i];
29399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if ((child.mViewFlags & VISIBILITY_MASK) == VISIBLE || child.getAnimation() != null) {
29409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    more |= drawChild(canvas, child, drawingTime);
29419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
29429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
29439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
29449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            for (int i = 0; i < count; i++) {
29459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                final View child = children[getChildDrawingOrder(count, i)];
29469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if ((child.mViewFlags & VISIBILITY_MASK) == VISIBLE || child.getAnimation() != null) {
29479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    more |= drawChild(canvas, child, drawingTime);
29489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
29499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
29509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
29519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
29529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Draw any disappearing views that have animations
29539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mDisappearingChildren != null) {
29549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            final ArrayList<View> disappearingChildren = mDisappearingChildren;
29559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            final int disappearingCount = disappearingChildren.size() - 1;
29569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // Go backwards -- we may delete as animations finish
29579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            for (int i = disappearingCount; i >= 0; i--) {
29589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                final View child = disappearingChildren.get(i);
29599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                more |= drawChild(canvas, child, drawingTime);
29609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
29619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
29629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
296310ca24a97cefc14fca1b26f59e627f487b3b108bPhilip Milne        if (debugDraw()) {
296410ca24a97cefc14fca1b26f59e627f487b3b108bPhilip Milne            onDebugDraw(canvas);
296510ca24a97cefc14fca1b26f59e627f487b3b108bPhilip Milne        }
296610ca24a97cefc14fca1b26f59e627f487b3b108bPhilip Milne
29679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (clipToPadding) {
29689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            canvas.restoreToCount(saveCount);
29699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
29709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
29719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // mGroupFlags might have been updated by drawChild()
29729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        flags = mGroupFlags;
29739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
29749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if ((flags & FLAG_INVALIDATE_REQUIRED) == FLAG_INVALIDATE_REQUIRED) {
2975849d0a37cf2ca6c6a6c2d4d4456495e32e363120Romain Guy            invalidate(true);
29769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
29779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
29789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if ((flags & FLAG_ANIMATION_DONE) == 0 && (flags & FLAG_NOTIFY_ANIMATION_LISTENER) == 0 &&
29799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mLayoutAnimationController.isDone() && !more) {
29809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // We want to erase the drawing cache and notify the listener after the
29819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // next frame is drawn because one extra invalidate() is caused by
29829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // drawChild() after the animation is over
29839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mGroupFlags |= FLAG_NOTIFY_ANIMATION_LISTENER;
29849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            final Runnable end = new Runnable() {
29859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project               public void run() {
29869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                   notifyAnimationListener();
29879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project               }
29889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            };
29899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            post(end);
29909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
29919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
29928506ab4ac062d0e1ccde136e5e2f4081560e0c11Romain Guy
29939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2994edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase     * Returns the ViewGroupOverlay for this view group, creating it if it does
2995edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase     * not yet exist. In addition to {@link ViewOverlay}'s support for drawables,
2996edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase     * {@link ViewGroupOverlay} allows views to be added to the overlay. These
2997edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase     * views, like overlay drawables, are visual-only; they do not receive input
2998edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase     * events and should not be used as anything other than a temporary
2999edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase     * representation of a view in a parent container, such as might be used
3000edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase     * by an animation effect.
3001edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase     *
300295399493c6070638946e5e6acd3b3872d3a90451Chet Haase     * <p>Note: Overlays do not currently work correctly with {@link
300395399493c6070638946e5e6acd3b3872d3a90451Chet Haase     * SurfaceView} or {@link TextureView}; contents in overlays for these
300495399493c6070638946e5e6acd3b3872d3a90451Chet Haase     * types of views may not display correctly.</p>
300595399493c6070638946e5e6acd3b3872d3a90451Chet Haase     *
3006edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase     * @return The ViewGroupOverlay object for this view.
3007edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase     * @see ViewGroupOverlay
3008edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase     */
3009edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase    @Override
3010edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase    public ViewGroupOverlay getOverlay() {
3011edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase        if (mOverlay == null) {
3012edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase            mOverlay = new ViewGroupOverlay(mContext, this);
3013edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase        }
3014edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase        return (ViewGroupOverlay) mOverlay;
3015edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase    }
3016edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase
3017edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase    /**
30189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Returns the index of the child to draw for this iteration. Override this
30199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * if you want to change the drawing order of children. By default, it
30209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * returns i.
30219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>
3022293451e4f005a26386db873f5192f86585cc79bcRomain Guy     * NOTE: In order for this method to be called, you must enable child ordering
3023293451e4f005a26386db873f5192f86585cc79bcRomain Guy     * first by calling {@link #setChildrenDrawingOrderEnabled(boolean)}.
30248506ab4ac062d0e1ccde136e5e2f4081560e0c11Romain Guy     *
30259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param i The current iteration.
30269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return The index of the child to draw this iteration.
30275c13d89c1332fcc499379b9064b891187b75ca32Chet Haase     *
3028293451e4f005a26386db873f5192f86585cc79bcRomain Guy     * @see #setChildrenDrawingOrderEnabled(boolean)
3029293451e4f005a26386db873f5192f86585cc79bcRomain Guy     * @see #isChildrenDrawingOrderEnabled()
30309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
30319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected int getChildDrawingOrder(int childCount, int i) {
30329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return i;
30339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
30348506ab4ac062d0e1ccde136e5e2f4081560e0c11Romain Guy
30359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private void notifyAnimationListener() {
30369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mGroupFlags &= ~FLAG_NOTIFY_ANIMATION_LISTENER;
30379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mGroupFlags |= FLAG_ANIMATION_DONE;
30389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
30399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mAnimationListener != null) {
30409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project           final Runnable end = new Runnable() {
30419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project               public void run() {
30429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                   mAnimationListener.onAnimationEnd(mLayoutAnimationController.getAnimation());
30439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project               }
30449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project           };
30459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project           post(end);
30469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
30479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
30489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if ((mGroupFlags & FLAG_ANIMATION_CACHE) == FLAG_ANIMATION_CACHE) {
30499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mGroupFlags &= ~FLAG_CHILDREN_DRAWN_WITH_CACHE;
30509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if ((mPersistentDrawingCache & PERSISTENT_ANIMATION_CACHE) == 0) {
30519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                setChildrenDrawingCacheEnabled(false);
30529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
30539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
30549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3055849d0a37cf2ca6c6a6c2d4d4456495e32e363120Romain Guy        invalidate(true);
30569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
30579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
30589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
3059daf98e941e140e8739458126640183b9f296a2abChet Haase     * This method is used to cause children of this ViewGroup to restore or recreate their
3060daf98e941e140e8739458126640183b9f296a2abChet Haase     * display lists. It is called by getDisplayList() when the parent ViewGroup does not need
3061daf98e941e140e8739458126640183b9f296a2abChet Haase     * to recreate its own display list, which would happen if it went through the normal
3062daf98e941e140e8739458126640183b9f296a2abChet Haase     * draw/dispatchDraw mechanisms.
3063daf98e941e140e8739458126640183b9f296a2abChet Haase     *
3064daf98e941e140e8739458126640183b9f296a2abChet Haase     * @hide
3065daf98e941e140e8739458126640183b9f296a2abChet Haase     */
3066daf98e941e140e8739458126640183b9f296a2abChet Haase    @Override
3067daf98e941e140e8739458126640183b9f296a2abChet Haase    protected void dispatchGetDisplayList() {
3068daf98e941e140e8739458126640183b9f296a2abChet Haase        final int count = mChildrenCount;
3069daf98e941e140e8739458126640183b9f296a2abChet Haase        final View[] children = mChildren;
3070daf98e941e140e8739458126640183b9f296a2abChet Haase        for (int i = 0; i < count; i++) {
3071daf98e941e140e8739458126640183b9f296a2abChet Haase            final View child = children[i];
307259c7f80dd20258cefa1fc4bdd3c9a709a8dd53b8Romain Guy            if (((child.mViewFlags & VISIBILITY_MASK) == VISIBLE || child.getAnimation() != null) &&
307359c7f80dd20258cefa1fc4bdd3c9a709a8dd53b8Romain Guy                    child.hasStaticLayer()) {
30744702a856973a553deb82f71b1d3b6c3db5dbf4baDianne Hackborn                child.mRecreateDisplayList = (child.mPrivateFlags & PFLAG_INVALIDATED)
30754702a856973a553deb82f71b1d3b6c3db5dbf4baDianne Hackborn                        == PFLAG_INVALIDATED;
30764702a856973a553deb82f71b1d3b6c3db5dbf4baDianne Hackborn                child.mPrivateFlags &= ~PFLAG_INVALIDATED;
30772f57ba56b3d4648476f0c00bd74fc4f6aa052810Romain Guy                child.getDisplayList();
30782f57ba56b3d4648476f0c00bd74fc4f6aa052810Romain Guy                child.mRecreateDisplayList = false;
30792f57ba56b3d4648476f0c00bd74fc4f6aa052810Romain Guy            }
3080daf98e941e140e8739458126640183b9f296a2abChet Haase        }
308191cedf1c3dbf7a52c2892294b2e5ba3e40ef3583Chet Haase        if (mOverlay != null) {
3082edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase            View overlayView = mOverlay.getOverlayView();
3083edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase            overlayView.mRecreateDisplayList = (overlayView.mPrivateFlags & PFLAG_INVALIDATED)
308491cedf1c3dbf7a52c2892294b2e5ba3e40ef3583Chet Haase                    == PFLAG_INVALIDATED;
3085edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase            overlayView.mPrivateFlags &= ~PFLAG_INVALIDATED;
3086edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase            overlayView.getDisplayList();
3087edf6f4b49f6e77c349f5055372ce381b74f12efbChet Haase            overlayView.mRecreateDisplayList = false;
308891cedf1c3dbf7a52c2892294b2e5ba3e40ef3583Chet Haase        }
3089daf98e941e140e8739458126640183b9f296a2abChet Haase    }
3090daf98e941e140e8739458126640183b9f296a2abChet Haase
3091daf98e941e140e8739458126640183b9f296a2abChet Haase    /**
30929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Draw one child of this View Group. This method is responsible for getting
30939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the canvas in the right state. This includes clipping, translating so
30949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * that the child's scrolled origin is at 0, 0, and applying any animation
30959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * transformations.
30969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
30979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param canvas The canvas on which to draw the child
30989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param child Who to draw
3099bcca79acb1ed31238a80079930bc69f8b9d8ccebChet Haase     * @param drawingTime The time at which draw is occurring
31009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return True if an invalidate() was issued
31019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
31029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected boolean drawChild(Canvas canvas, View child, long drawingTime) {
310364a48c1d3daca9e0565f2aa4d56f6e94ea073d9bChet Haase        return child.draw(canvas, this, drawingTime);
31049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
31059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
31069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
3107430742f09063574271e6c4091de13b9b9e762514Chet Haase     * Returns whether ths group's children are clipped to their bounds before drawing.
3108430742f09063574271e6c4091de13b9b9e762514Chet Haase     * The default value is true.
3109430742f09063574271e6c4091de13b9b9e762514Chet Haase     * @see #setClipChildren(boolean)
3110430742f09063574271e6c4091de13b9b9e762514Chet Haase     *
3111430742f09063574271e6c4091de13b9b9e762514Chet Haase     * @return True if the group's children will be clipped to their bounds,
3112430742f09063574271e6c4091de13b9b9e762514Chet Haase     * false otherwise.
3113430742f09063574271e6c4091de13b9b9e762514Chet Haase     */
3114430742f09063574271e6c4091de13b9b9e762514Chet Haase    public boolean getClipChildren() {
3115430742f09063574271e6c4091de13b9b9e762514Chet Haase        return ((mGroupFlags & FLAG_CLIP_CHILDREN) != 0);
3116430742f09063574271e6c4091de13b9b9e762514Chet Haase    }
3117430742f09063574271e6c4091de13b9b9e762514Chet Haase
3118430742f09063574271e6c4091de13b9b9e762514Chet Haase    /**
31199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * By default, children are clipped to their bounds before drawing. This
31209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * allows view groups to override this behavior for animations, etc.
31219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
31229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param clipChildren true to clip children to their bounds,
31239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *        false otherwise
31249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @attr ref android.R.styleable#ViewGroup_clipChildren
31259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
31269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setClipChildren(boolean clipChildren) {
3127a1cff5043d0fbd78fcf9c48e7658e56a5b0c2de3Chet Haase        boolean previousValue = (mGroupFlags & FLAG_CLIP_CHILDREN) == FLAG_CLIP_CHILDREN;
3128a1cff5043d0fbd78fcf9c48e7658e56a5b0c2de3Chet Haase        if (clipChildren != previousValue) {
3129a1cff5043d0fbd78fcf9c48e7658e56a5b0c2de3Chet Haase            setBooleanFlag(FLAG_CLIP_CHILDREN, clipChildren);
31301271e2cc80b01d577e9db339459ef0222bb9320dChet Haase            for (int i = 0; i < mChildrenCount; ++i) {
31311271e2cc80b01d577e9db339459ef0222bb9320dChet Haase                View child = getChildAt(i);
31321271e2cc80b01d577e9db339459ef0222bb9320dChet Haase                if (child.mDisplayList != null) {
3133dd671599bed9d3ca28e2c744e8c224e1e15bc914Chet Haase                    child.mDisplayList.setClipToBounds(clipChildren);
3134a1cff5043d0fbd78fcf9c48e7658e56a5b0c2de3Chet Haase                }
3135a1cff5043d0fbd78fcf9c48e7658e56a5b0c2de3Chet Haase            }
3136a1cff5043d0fbd78fcf9c48e7658e56a5b0c2de3Chet Haase        }
31379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
31389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
31399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
31409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * By default, children are clipped to the padding of the ViewGroup. This
31419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * allows view groups to override this behavior
31429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
31439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param clipToPadding true to clip children to the padding of the
31449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *        group, false otherwise
31459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @attr ref android.R.styleable#ViewGroup_clipToPadding
31469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
31479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setClipToPadding(boolean clipToPadding) {
31489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        setBooleanFlag(FLAG_CLIP_TO_PADDING, clipToPadding);
31499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
31509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
31519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
31529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@inheritDoc}
31539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
31549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
31559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void dispatchSetSelected(boolean selected) {
31569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final View[] children = mChildren;
31579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final int count = mChildrenCount;
31589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (int i = 0; i < count; i++) {
31599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            children[i].setSelected(selected);
31609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
31619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
31628506ab4ac062d0e1ccde136e5e2f4081560e0c11Romain Guy
3163d0fa371f276fde32d81c037006941bc93da0bb03Dianne Hackborn    /**
3164d0fa371f276fde32d81c037006941bc93da0bb03Dianne Hackborn     * {@inheritDoc}
3165d0fa371f276fde32d81c037006941bc93da0bb03Dianne Hackborn     */
3166d0fa371f276fde32d81c037006941bc93da0bb03Dianne Hackborn    @Override
3167d0fa371f276fde32d81c037006941bc93da0bb03Dianne Hackborn    public void dispatchSetActivated(boolean activated) {
3168d0fa371f276fde32d81c037006941bc93da0bb03Dianne Hackborn        final View[] children = mChildren;
3169d0fa371f276fde32d81c037006941bc93da0bb03Dianne Hackborn        final int count = mChildrenCount;
3170d0fa371f276fde32d81c037006941bc93da0bb03Dianne Hackborn        for (int i = 0; i < count; i++) {
3171d0fa371f276fde32d81c037006941bc93da0bb03Dianne Hackborn            children[i].setActivated(activated);
3172d0fa371f276fde32d81c037006941bc93da0bb03Dianne Hackborn        }
3173d0fa371f276fde32d81c037006941bc93da0bb03Dianne Hackborn    }
3174d0fa371f276fde32d81c037006941bc93da0bb03Dianne Hackborn
31759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
31769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected void dispatchSetPressed(boolean pressed) {
31779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final View[] children = mChildren;
31789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final int count = mChildrenCount;
31799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (int i = 0; i < count; i++) {
3180035a1fcd5ea3ac0080bb74101cf2793ccb9aa689Adam Powell            final View child = children[i];
3181035a1fcd5ea3ac0080bb74101cf2793ccb9aa689Adam Powell            // Children that are clickable on their own should not
3182035a1fcd5ea3ac0080bb74101cf2793ccb9aa689Adam Powell            // show a pressed state when their parent view does.
3183035a1fcd5ea3ac0080bb74101cf2793ccb9aa689Adam Powell            // Clearing a pressed state always propagates.
3184035a1fcd5ea3ac0080bb74101cf2793ccb9aa689Adam Powell            if (!pressed || (!child.isClickable() && !child.isLongClickable())) {
3185035a1fcd5ea3ac0080bb74101cf2793ccb9aa689Adam Powell                child.setPressed(pressed);
3186035a1fcd5ea3ac0080bb74101cf2793ccb9aa689Adam Powell            }
31879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
31889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
31899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
31901487466dc2ce14cccf0ff2bd2f824238aaa0044eAdam Powell    @Override
31911487466dc2ce14cccf0ff2bd2f824238aaa0044eAdam Powell    void dispatchCancelPendingInputEvents() {
31921487466dc2ce14cccf0ff2bd2f824238aaa0044eAdam Powell        super.dispatchCancelPendingInputEvents();
31931487466dc2ce14cccf0ff2bd2f824238aaa0044eAdam Powell
31941487466dc2ce14cccf0ff2bd2f824238aaa0044eAdam Powell        final View[] children = mChildren;
31951487466dc2ce14cccf0ff2bd2f824238aaa0044eAdam Powell        final int count = mChildrenCount;
31961487466dc2ce14cccf0ff2bd2f824238aaa0044eAdam Powell        for (int i = 0; i < count; i++) {
31971487466dc2ce14cccf0ff2bd2f824238aaa0044eAdam Powell            children[i].dispatchCancelPendingInputEvents();
31981487466dc2ce14cccf0ff2bd2f824238aaa0044eAdam Powell        }
31991487466dc2ce14cccf0ff2bd2f824238aaa0044eAdam Powell    }
32001487466dc2ce14cccf0ff2bd2f824238aaa0044eAdam Powell
32019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
32029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * When this property is set to true, this ViewGroup supports static transformations on
32039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * children; this causes
32049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@link #getChildStaticTransformation(View, android.view.animation.Transformation)} to be
32059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * invoked when a child is drawn.
32069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
32079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Any subclass overriding
32089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@link #getChildStaticTransformation(View, android.view.animation.Transformation)} should
32099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * set this property to true.
32109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
32119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param enabled True to enable static transformations on children, false otherwise.
32129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
3213599913d6e8e610665fad7edd7dfbd3cd48758b3aChet Haase     * @see #getChildStaticTransformation(View, android.view.animation.Transformation)
32149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
32159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected void setStaticTransformationsEnabled(boolean enabled) {
32169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        setBooleanFlag(FLAG_SUPPORT_STATIC_TRANSFORMATIONS, enabled);
32179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
32189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
32199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
32202d46fcc669ff5efe365e9be435ab9e5c5a304939Chet Haase     * Sets  <code>t</code> to be the static transformation of the child, if set, returning a
32212d46fcc669ff5efe365e9be435ab9e5c5a304939Chet Haase     * boolean to indicate whether a static transform was set. The default implementation
32222d46fcc669ff5efe365e9be435ab9e5c5a304939Chet Haase     * simply returns <code>false</code>; subclasses may override this method for different
3223599913d6e8e610665fad7edd7dfbd3cd48758b3aChet Haase     * behavior. {@link #setStaticTransformationsEnabled(boolean)} must be set to true
3224599913d6e8e610665fad7edd7dfbd3cd48758b3aChet Haase     * for this method to be called.
32259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
32262d46fcc669ff5efe365e9be435ab9e5c5a304939Chet Haase     * @param child The child view whose static transform is being requested
32272d46fcc669ff5efe365e9be435ab9e5c5a304939Chet Haase     * @param t The Transformation which will hold the result
32282d46fcc669ff5efe365e9be435ab9e5c5a304939Chet Haase     * @return true if the transformation was set, false otherwise
32298506ab4ac062d0e1ccde136e5e2f4081560e0c11Romain Guy     * @see #setStaticTransformationsEnabled(boolean)
32309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
32319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected boolean getChildStaticTransformation(View child, Transformation t) {
32329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return false;
32339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
32349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3235f69913056b8c6000ff0306573a97971702e8d35aRomain Guy    Transformation getChildTransformation() {
3236f69913056b8c6000ff0306573a97971702e8d35aRomain Guy        if (mChildTransformation == null) {
3237f69913056b8c6000ff0306573a97971702e8d35aRomain Guy            mChildTransformation = new Transformation();
3238f69913056b8c6000ff0306573a97971702e8d35aRomain Guy        }
3239f69913056b8c6000ff0306573a97971702e8d35aRomain Guy        return mChildTransformation;
3240f69913056b8c6000ff0306573a97971702e8d35aRomain Guy    }
3241f69913056b8c6000ff0306573a97971702e8d35aRomain Guy
32429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
32439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@hide}
32449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
32459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
32469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected View findViewTraversal(int id) {
32479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (id == mID) {
32489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return this;
32499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
32509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
32519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final View[] where = mChildren;
32529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final int len = mChildrenCount;
32539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
32549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (int i = 0; i < len; i++) {
32559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            View v = where[i];
32569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
32574702a856973a553deb82f71b1d3b6c3db5dbf4baDianne Hackborn            if ((v.mPrivateFlags & PFLAG_IS_ROOT_NAMESPACE) == 0) {
32589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                v = v.findViewById(id);
32599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
32609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (v != null) {
32619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    return v;
32629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
32639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
32649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
32659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
32669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return null;
32679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
32689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
32699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
32709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@hide}
32719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
32729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
32739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected View findViewWithTagTraversal(Object tag) {
32749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (tag != null && tag.equals(mTag)) {
32759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return this;
32769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
32779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
32789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final View[] where = mChildren;
32799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final int len = mChildrenCount;
32809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
32819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (int i = 0; i < len; i++) {
32829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            View v = where[i];
32839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
32844702a856973a553deb82f71b1d3b6c3db5dbf4baDianne Hackborn            if ((v.mPrivateFlags & PFLAG_IS_ROOT_NAMESPACE) == 0) {
32859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                v = v.findViewWithTag(tag);
32869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
32879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (v != null) {
32889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    return v;
32899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
32909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
32919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
32929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
32939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return null;
32949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
32959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
32969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
32974e6319b73c85082e18d1c532b86336ddd1f8cfaaJeff Brown     * {@hide}
32984e6319b73c85082e18d1c532b86336ddd1f8cfaaJeff Brown     */
32994e6319b73c85082e18d1c532b86336ddd1f8cfaaJeff Brown    @Override
33004dfbec2665bd5f567d7321f2e88a39e1ab45fdf8Jeff Brown    protected View findViewByPredicateTraversal(Predicate<View> predicate, View childToSkip) {
33014e6319b73c85082e18d1c532b86336ddd1f8cfaaJeff Brown        if (predicate.apply(this)) {
33024e6319b73c85082e18d1c532b86336ddd1f8cfaaJeff Brown            return this;
33034e6319b73c85082e18d1c532b86336ddd1f8cfaaJeff Brown        }
33044e6319b73c85082e18d1c532b86336ddd1f8cfaaJeff Brown
33054e6319b73c85082e18d1c532b86336ddd1f8cfaaJeff Brown        final View[] where = mChildren;
33064e6319b73c85082e18d1c532b86336ddd1f8cfaaJeff Brown        final int len = mChildrenCount;
33074e6319b73c85082e18d1c532b86336ddd1f8cfaaJeff Brown
33084e6319b73c85082e18d1c532b86336ddd1f8cfaaJeff Brown        for (int i = 0; i < len; i++) {
33094e6319b73c85082e18d1c532b86336ddd1f8cfaaJeff Brown            View v = where[i];
33104e6319b73c85082e18d1c532b86336ddd1f8cfaaJeff Brown
33114702a856973a553deb82f71b1d3b6c3db5dbf4baDianne Hackborn            if (v != childToSkip && (v.mPrivateFlags & PFLAG_IS_ROOT_NAMESPACE) == 0) {
33124e6319b73c85082e18d1c532b86336ddd1f8cfaaJeff Brown                v = v.findViewByPredicate(predicate);
33134e6319b73c85082e18d1c532b86336ddd1f8cfaaJeff Brown
33144e6319b73c85082e18d1c532b86336ddd1f8cfaaJeff Brown                if (v != null) {
33154e6319b73c85082e18d1c532b86336ddd1f8cfaaJeff Brown                    return v;
33164e6319b73c85082e18d1c532b86336ddd1f8cfaaJeff Brown                }
33174e6319b73c85082e18d1c532b86336ddd1f8cfaaJeff Brown            }
33184e6319b73c85082e18d1c532b86336ddd1f8cfaaJeff Brown        }
33194e6319b73c85082e18d1c532b86336ddd1f8cfaaJeff Brown
33204e6319b73c85082e18d1c532b86336ddd1f8cfaaJeff Brown        return null;
33214e6319b73c85082e18d1c532b86336ddd1f8cfaaJeff Brown    }
33224e6319b73c85082e18d1c532b86336ddd1f8cfaaJeff Brown
33234e6319b73c85082e18d1c532b86336ddd1f8cfaaJeff Brown    /**
3324393a52c9f628bbf2ab68508913177650f9183ee4Romain Guy     * <p>Adds a child view. If no layout parameters are already set on the child, the
3325393a52c9f628bbf2ab68508913177650f9183ee4Romain Guy     * default parameters for this ViewGroup are set on the child.</p>
3326393a52c9f628bbf2ab68508913177650f9183ee4Romain Guy     *
3327393a52c9f628bbf2ab68508913177650f9183ee4Romain Guy     * <p><strong>Note:</strong> do not invoke this method from
3328393a52c9f628bbf2ab68508913177650f9183ee4Romain Guy     * {@link #draw(android.graphics.Canvas)}, {@link #onDraw(android.graphics.Canvas)},
3329393a52c9f628bbf2ab68508913177650f9183ee4Romain Guy     * {@link #dispatchDraw(android.graphics.Canvas)} or any related method.</p>
33309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
33319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param child the child view to add
33329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
33339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #generateDefaultLayoutParams()
33349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
33359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void addView(View child) {
33369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        addView(child, -1);
33379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
33389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
33399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
33409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Adds a child view. If no layout parameters are already set on the child, the
33419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * default parameters for this ViewGroup are set on the child.
3342393a52c9f628bbf2ab68508913177650f9183ee4Romain Guy     *
3343393a52c9f628bbf2ab68508913177650f9183ee4Romain Guy     * <p><strong>Note:</strong> do not invoke this method from
3344393a52c9f628bbf2ab68508913177650f9183ee4Romain Guy     * {@link #draw(android.graphics.Canvas)}, {@link #onDraw(android.graphics.Canvas)},
3345393a52c9f628bbf2ab68508913177650f9183ee4Romain Guy     * {@link #dispatchDraw(android.graphics.Canvas)} or any related method.</p>
33469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
33479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param child the child view to add
33489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param index the position at which to add the child
33499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
33509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #generateDefaultLayoutParams()
33519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
33529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void addView(View child, int index) {
33539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        LayoutParams params = child.getLayoutParams();
33549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (params == null) {
33559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            params = generateDefaultLayoutParams();
33569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (params == null) {
33579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                throw new IllegalArgumentException("generateDefaultLayoutParams() cannot return null");
33589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
33599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
33609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        addView(child, index, params);
33619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
33629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
33639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
33649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Adds a child view with this ViewGroup's default layout parameters and the
33659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * specified width and height.
33669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
3367393a52c9f628bbf2ab68508913177650f9183ee4Romain Guy     * <p><strong>Note:</strong> do not invoke this method from
3368393a52c9f628bbf2ab68508913177650f9183ee4Romain Guy     * {@link #draw(android.graphics.Canvas)}, {@link #onDraw(android.graphics.Canvas)},
3369393a52c9f628bbf2ab68508913177650f9183ee4Romain Guy     * {@link #dispatchDraw(android.graphics.Canvas)} or any related method.</p>
3370393a52c9f628bbf2ab68508913177650f9183ee4Romain Guy     *
33719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param child the child view to add
33729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
33739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void addView(View child, int width, int height) {
33749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final LayoutParams params = generateDefaultLayoutParams();
33759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        params.width = width;
33769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        params.height = height;
33779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        addView(child, -1, params);
33789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
33799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
33809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
33819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Adds a child view with the specified layout parameters.
33829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
3383393a52c9f628bbf2ab68508913177650f9183ee4Romain Guy     * <p><strong>Note:</strong> do not invoke this method from
3384393a52c9f628bbf2ab68508913177650f9183ee4Romain Guy     * {@link #draw(android.graphics.Canvas)}, {@link #onDraw(android.graphics.Canvas)},
3385393a52c9f628bbf2ab68508913177650f9183ee4Romain Guy     * {@link #dispatchDraw(android.graphics.Canvas)} or any related method.</p>
3386393a52c9f628bbf2ab68508913177650f9183ee4Romain Guy     *
33879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param child the child view to add
33889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param params the layout parameters to set on the child
33899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
33909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void addView(View child, LayoutParams params) {
33919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        addView(child, -1, params);
33929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
33939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
33949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
33959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Adds a child view with the specified layout parameters.
33969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
3397393a52c9f628bbf2ab68508913177650f9183ee4Romain Guy     * <p><strong>Note:</strong> do not invoke this method from
3398393a52c9f628bbf2ab68508913177650f9183ee4Romain Guy     * {@link #draw(android.graphics.Canvas)}, {@link #onDraw(android.graphics.Canvas)},
3399393a52c9f628bbf2ab68508913177650f9183ee4Romain Guy     * {@link #dispatchDraw(android.graphics.Canvas)} or any related method.</p>
3400393a52c9f628bbf2ab68508913177650f9183ee4Romain Guy     *
34019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param child the child view to add
34029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param index the position at which to add the child
34039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param params the layout parameters to set on the child
34049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
34059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void addView(View child, int index, LayoutParams params) {
34069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (DBG) {
34079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            System.out.println(this + " addView");
34089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
34099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
34109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // addViewInner() will call child.requestLayout() when setting the new LayoutParams
34119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // therefore, we call requestLayout() on ourselves before, so that the child's request
34129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // will be blocked at our level
34139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        requestLayout();
3414849d0a37cf2ca6c6a6c2d4d4456495e32e363120Romain Guy        invalidate(true);
34159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        addViewInner(child, index, params, false);
34169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
34179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
34189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
34199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@inheritDoc}
34209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
34219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void updateViewLayout(View view, ViewGroup.LayoutParams params) {
34229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (!checkLayoutParams(params)) {
34239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new IllegalArgumentException("Invalid LayoutParams supplied to " + this);
34249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
34259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (view.mParent != this) {
34269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new IllegalArgumentException("Given view not a child of " + this);
34279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
34289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        view.setLayoutParams(params);
34299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
34309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
34319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
34329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@inheritDoc}
34339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
34349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected boolean checkLayoutParams(ViewGroup.LayoutParams p) {
34359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return  p != null;
34369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
34379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
34389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
34399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Interface definition for a callback to be invoked when the hierarchy
34409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * within this view changed. The hierarchy changes whenever a child is added
34419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * to or removed from this view.
34429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
34439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public interface OnHierarchyChangeListener {
34449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /**
34459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * Called when a new child is added to a parent view.
34469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         *
34479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * @param parent the view in which a child was added
34489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * @param child the new child view added in the hierarchy
34499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
34509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        void onChildViewAdded(View parent, View child);
34519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
34529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /**
34539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * Called when a child is removed from a parent view.
34549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         *
34559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * @param parent the view from which the child was removed
34569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * @param child the child removed from the hierarchy
34579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
34589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        void onChildViewRemoved(View parent, View child);
34599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
34609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
34619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
34629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Register a callback to be invoked when a child is added to or removed
34639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * from this view.
34649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
34659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param listener the callback to invoke on hierarchy change
34669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
34679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setOnHierarchyChangeListener(OnHierarchyChangeListener listener) {
34689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mOnHierarchyChangeListener = listener;
34699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
34709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
34719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
3472f51d91c3ab232154b6c00d7f71377ff2421f79bfPhilip Milne     * @hide
3473f51d91c3ab232154b6c00d7f71377ff2421f79bfPhilip Milne     */
3474f51d91c3ab232154b6c00d7f71377ff2421f79bfPhilip Milne    protected void onViewAdded(View child) {
3475f51d91c3ab232154b6c00d7f71377ff2421f79bfPhilip Milne        if (mOnHierarchyChangeListener != null) {
3476f51d91c3ab232154b6c00d7f71377ff2421f79bfPhilip Milne            mOnHierarchyChangeListener.onChildViewAdded(this, child);
3477f51d91c3ab232154b6c00d7f71377ff2421f79bfPhilip Milne        }
3478f51d91c3ab232154b6c00d7f71377ff2421f79bfPhilip Milne    }
3479f51d91c3ab232154b6c00d7f71377ff2421f79bfPhilip Milne
3480f51d91c3ab232154b6c00d7f71377ff2421f79bfPhilip Milne    /**
3481f51d91c3ab232154b6c00d7f71377ff2421f79bfPhilip Milne     * @hide
3482f51d91c3ab232154b6c00d7f71377ff2421f79bfPhilip Milne     */
3483f51d91c3ab232154b6c00d7f71377ff2421f79bfPhilip Milne    protected void onViewRemoved(View child) {
3484f51d91c3ab232154b6c00d7f71377ff2421f79bfPhilip Milne        if (mOnHierarchyChangeListener != null) {
3485f51d91c3ab232154b6c00d7f71377ff2421f79bfPhilip Milne            mOnHierarchyChangeListener.onChildViewRemoved(this, child);
3486f51d91c3ab232154b6c00d7f71377ff2421f79bfPhilip Milne        }
3487f51d91c3ab232154b6c00d7f71377ff2421f79bfPhilip Milne    }
3488f51d91c3ab232154b6c00d7f71377ff2421f79bfPhilip Milne
3489cfb631b0e56b7c6b9ca11e1a0553b7896b64b1c1Philip Milne    private void clearCachedLayoutMode() {
34906254f4806dd3db53b7380e77fbb183065685573eSvetoslav        if (!hasBooleanFlag(FLAG_LAYOUT_MODE_WAS_EXPLICITLY_SET)) {
3491cfb631b0e56b7c6b9ca11e1a0553b7896b64b1c1Philip Milne           mLayoutMode = LAYOUT_MODE_UNDEFINED;
3492cfb631b0e56b7c6b9ca11e1a0553b7896b64b1c1Philip Milne        }
3493cfb631b0e56b7c6b9ca11e1a0553b7896b64b1c1Philip Milne    }
3494cfb631b0e56b7c6b9ca11e1a0553b7896b64b1c1Philip Milne
3495cfb631b0e56b7c6b9ca11e1a0553b7896b64b1c1Philip Milne    @Override
3496cfb631b0e56b7c6b9ca11e1a0553b7896b64b1c1Philip Milne    protected void onAttachedToWindow() {
3497cfb631b0e56b7c6b9ca11e1a0553b7896b64b1c1Philip Milne        super.onAttachedToWindow();
3498cfb631b0e56b7c6b9ca11e1a0553b7896b64b1c1Philip Milne        clearCachedLayoutMode();
3499cfb631b0e56b7c6b9ca11e1a0553b7896b64b1c1Philip Milne    }
3500cfb631b0e56b7c6b9ca11e1a0553b7896b64b1c1Philip Milne
3501cfb631b0e56b7c6b9ca11e1a0553b7896b64b1c1Philip Milne    @Override
3502cfb631b0e56b7c6b9ca11e1a0553b7896b64b1c1Philip Milne    protected void onDetachedFromWindow() {
3503cfb631b0e56b7c6b9ca11e1a0553b7896b64b1c1Philip Milne        super.onDetachedFromWindow();
3504cfb631b0e56b7c6b9ca11e1a0553b7896b64b1c1Philip Milne        clearCachedLayoutMode();
3505cfb631b0e56b7c6b9ca11e1a0553b7896b64b1c1Philip Milne    }
3506cfb631b0e56b7c6b9ca11e1a0553b7896b64b1c1Philip Milne
3507f51d91c3ab232154b6c00d7f71377ff2421f79bfPhilip Milne    /**
35089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Adds a view during layout. This is useful if in your onLayout() method,
35099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * you need to add more views (as does the list view for example).
35109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
35119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * If index is negative, it means put it at the end of the list.
35129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
35139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param child the view to add to the group
35149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param index the index at which the child must be added
35159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param params the layout parameters to associate with the child
35169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return true if the child was added, false otherwise
35179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
35189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected boolean addViewInLayout(View child, int index, LayoutParams params) {
35199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return addViewInLayout(child, index, params, false);
35209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
35219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
35229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
35239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Adds a view during layout. This is useful if in your onLayout() method,
35249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * you need to add more views (as does the list view for example).
35259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
35269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * If index is negative, it means put it at the end of the list.
35279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
35289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param child the view to add to the group
35299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param index the index at which the child must be added
35309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param params the layout parameters to associate with the child
35319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param preventRequestLayout if true, calling this method will not trigger a
35329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *        layout request on child
35339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return true if the child was added, false otherwise
35349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
35359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected boolean addViewInLayout(View child, int index, LayoutParams params,
35369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            boolean preventRequestLayout) {
35379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        child.mParent = null;
35389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        addViewInner(child, index, params, preventRequestLayout);
35394702a856973a553deb82f71b1d3b6c3db5dbf4baDianne Hackborn        child.mPrivateFlags = (child.mPrivateFlags & ~PFLAG_DIRTY_MASK) | PFLAG_DRAWN;
35409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return true;
35419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
35429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
35439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
35449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Prevents the specified child to be laid out during the next layout pass.
35459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
35469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param child the child on which to perform the cleanup
35479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
35489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected void cleanupLayoutState(View child) {
35494702a856973a553deb82f71b1d3b6c3db5dbf4baDianne Hackborn        child.mPrivateFlags &= ~View.PFLAG_FORCE_LAYOUT;
35509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
35519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
35529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private void addViewInner(View child, int index, LayoutParams params,
35539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            boolean preventRequestLayout) {
35549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3555e8e45d32fd1f67fed1b70d0fc19d2f91a76f128eChet Haase        if (mTransition != null) {
3556e8e45d32fd1f67fed1b70d0fc19d2f91a76f128eChet Haase            // Don't prevent other add transitions from completing, but cancel remove
3557e8e45d32fd1f67fed1b70d0fc19d2f91a76f128eChet Haase            // transitions to let them complete the process before we add to the container
3558e8e45d32fd1f67fed1b70d0fc19d2f91a76f128eChet Haase            mTransition.cancel(LayoutTransition.DISAPPEARING);
3559add6577a0196258e5a48c5deefcdb12e05c935b3Chet Haase        }
3560add6577a0196258e5a48c5deefcdb12e05c935b3Chet Haase
35619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (child.getParent() != null) {
35629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new IllegalStateException("The specified child already has a parent. " +
35639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    "You must call removeView() on the child's parent first.");
35649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
35659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
356621cd1389d2ef218b20994b617c57af120841a57fChet Haase        if (mTransition != null) {
35675e25c2c14593caee5638603120553ae1ec530f85Chet Haase            mTransition.addChild(this, child);
356821cd1389d2ef218b20994b617c57af120841a57fChet Haase        }
356921cd1389d2ef218b20994b617c57af120841a57fChet Haase
35709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (!checkLayoutParams(params)) {
35719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            params = generateLayoutParams(params);
35729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
35739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
35749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (preventRequestLayout) {
35759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            child.mLayoutParams = params;
35769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
35779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            child.setLayoutParams(params);
35789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
35799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
35809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (index < 0) {
35819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            index = mChildrenCount;
35829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
35839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
35849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        addInArray(child, index);
35859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
35869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // tell our children
35879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (preventRequestLayout) {
35889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            child.assignParent(this);
35899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
35909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            child.mParent = this;
35919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
35929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
35939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (child.hasFocus()) {
35949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            requestChildFocus(child, child.findFocus());
35959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
35968506ab4ac062d0e1ccde136e5e2f4081560e0c11Romain Guy
35979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        AttachInfo ai = mAttachInfo;
35984b86788003b3ddc968d0681d5ed4e5da07e4a65aAdam Powell        if (ai != null && (mGroupFlags & FLAG_PREVENT_DISPATCH_ATTACHED_TO_WINDOW) == 0) {
35998506ab4ac062d0e1ccde136e5e2f4081560e0c11Romain Guy            boolean lastKeepOn = ai.mKeepScreenOn;
36009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            ai.mKeepScreenOn = false;
36019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            child.dispatchAttachedToWindow(mAttachInfo, (mViewFlags&VISIBILITY_MASK));
36029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (ai.mKeepScreenOn) {
36039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                needGlobalAttributesUpdate(true);
36049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
36059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            ai.mKeepScreenOn = lastKeepOn;
36069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
36079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
36089a04856d5ecb07dea564feae2942fd485b53f3ddFabrice Di Meglio        if (child.isLayoutDirectionInherited()) {
3609a7e0bcd87287ff2f11cdd872026f2eb9ee22bcd0Fabrice Di Meglio            child.resetRtlProperties();
36109a04856d5ecb07dea564feae2942fd485b53f3ddFabrice Di Meglio        }
36119a04856d5ecb07dea564feae2942fd485b53f3ddFabrice Di Meglio
3612f51d91c3ab232154b6c00d7f71377ff2421f79bfPhilip Milne        onViewAdded(child);
36139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
36149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if ((child.mViewFlags & DUPLICATE_PARENT_STATE) == DUPLICATE_PARENT_STATE) {
36159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mGroupFlags |= FLAG_NOTIFY_CHILDREN_ON_DRAWABLE_STATE_CHANGE;
36169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3617539ee8716b4f81260bab2e9f3dc5d88d81c99985Adam Powell
3618539ee8716b4f81260bab2e9f3dc5d88d81c99985Adam Powell        if (child.hasTransientState()) {
3619539ee8716b4f81260bab2e9f3dc5d88d81c99985Adam Powell            childHasTransientStateChanged(child, true);
3620539ee8716b4f81260bab2e9f3dc5d88d81c99985Adam Powell        }
36216254f4806dd3db53b7380e77fbb183065685573eSvetoslav
36226254f4806dd3db53b7380e77fbb183065685573eSvetoslav        if (child.isImportantForAccessibility() && child.getVisibility() != View.GONE) {
362300dbe81fea7be57ee2ff8a97844faf1bc15a427fSvetoslav            notifySubtreeAccessibilityStateChangedIfNeeded();
36246254f4806dd3db53b7380e77fbb183065685573eSvetoslav        }
36259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
36269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
36279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private void addInArray(View child, int index) {
36289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        View[] children = mChildren;
36299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final int count = mChildrenCount;
36309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final int size = children.length;
36319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (index == count) {
36329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (size == count) {
36339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mChildren = new View[size + ARRAY_CAPACITY_INCREMENT];
36349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                System.arraycopy(children, 0, mChildren, 0, size);
36359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                children = mChildren;
36369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
36379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            children[mChildrenCount++] = child;
36389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else if (index < count) {
36399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (size == count) {
36409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mChildren = new View[size + ARRAY_CAPACITY_INCREMENT];
36419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                System.arraycopy(children, 0, mChildren, 0, index);
36429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                System.arraycopy(children, index, mChildren, index + 1, count - index);
36439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                children = mChildren;
36449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else {
36459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                System.arraycopy(children, index, children, index + 1, count - index);
36469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
36479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            children[index] = child;
36489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mChildrenCount++;
364903ab0c7231a5c534b86eca28d875c6026ae09564Joe Onorato            if (mLastTouchDownIndex >= index) {
365003ab0c7231a5c534b86eca28d875c6026ae09564Joe Onorato                mLastTouchDownIndex++;
365103ab0c7231a5c534b86eca28d875c6026ae09564Joe Onorato            }
36529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
36539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new IndexOutOfBoundsException("index=" + index + " count=" + count);
36549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
36559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
36569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
36579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // This method also sets the child's mParent to null
36589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private void removeFromArray(int index) {
36599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final View[] children = mChildren;
366021cd1389d2ef218b20994b617c57af120841a57fChet Haase        if (!(mTransitioningViews != null && mTransitioningViews.contains(children[index]))) {
366121cd1389d2ef218b20994b617c57af120841a57fChet Haase            children[index].mParent = null;
366221cd1389d2ef218b20994b617c57af120841a57fChet Haase        }
36639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final int count = mChildrenCount;
36649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (index == count - 1) {
36659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            children[--mChildrenCount] = null;
36669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else if (index >= 0 && index < count) {
36679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            System.arraycopy(children, index + 1, children, index, count - index - 1);
36689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            children[--mChildrenCount] = null;
36699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
36709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new IndexOutOfBoundsException();
36719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
367203ab0c7231a5c534b86eca28d875c6026ae09564Joe Onorato        if (mLastTouchDownIndex == index) {
367303ab0c7231a5c534b86eca28d875c6026ae09564Joe Onorato            mLastTouchDownTime = 0;
367403ab0c7231a5c534b86eca28d875c6026ae09564Joe Onorato            mLastTouchDownIndex = -1;
367503ab0c7231a5c534b86eca28d875c6026ae09564Joe Onorato        } else if (mLastTouchDownIndex > index) {
367603ab0c7231a5c534b86eca28d875c6026ae09564Joe Onorato            mLastTouchDownIndex--;
367703ab0c7231a5c534b86eca28d875c6026ae09564Joe Onorato        }
36789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
36799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
36809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // This method also sets the children's mParent to null
36819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private void removeFromArray(int start, int count) {
36829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final View[] children = mChildren;
36839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final int childrenCount = mChildrenCount;
36849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
36859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        start = Math.max(0, start);
36869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final int end = Math.min(childrenCount, start + count);
36879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
36889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (start == end) {
36899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return;
36909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
36919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
36929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (end == childrenCount) {
36939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            for (int i = start; i < end; i++) {
36949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                children[i].mParent = null;
36959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                children[i] = null;
36969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
36979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
36989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            for (int i = start; i < end; i++) {
36999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                children[i].mParent = null;
37009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
37019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
37029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // Since we're looping above, we might as well do the copy, but is arraycopy()
37039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // faster than the extra 2 bounds checks we would do in the loop?
37049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            System.arraycopy(children, end, children, start, childrenCount - end);
37059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
37069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            for (int i = childrenCount - (end - start); i < childrenCount; i++) {
37079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                children[i] = null;
37089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
37099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
37109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
37119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mChildrenCount -= (end - start);
37129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
37139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
37149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private void bindLayoutAnimation(View child) {
37159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Animation a = mLayoutAnimationController.getAnimationForView(child);
37169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        child.setAnimation(a);
37179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
37189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
37199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
37209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Subclasses should override this method to set layout animation
37219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * parameters on the supplied child.
37229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
37239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param child the child to associate with animation parameters
37249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param params the child's layout parameters which hold the animation
37259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *        parameters
37269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param index the index of the child in the view group
37279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param count the number of children in the view group
37289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
37299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected void attachLayoutAnimationParameters(View child,
37309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            LayoutParams params, int index, int count) {
37319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        LayoutAnimationController.AnimationParameters animationParams =
37329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    params.layoutAnimationParameters;
37339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (animationParams == null) {
37349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            animationParams = new LayoutAnimationController.AnimationParameters();
37359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            params.layoutAnimationParameters = animationParams;
37369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
37379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
37389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        animationParams.count = count;
37399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        animationParams.index = index;
37409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
37419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
37429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
37439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@inheritDoc}
3744393a52c9f628bbf2ab68508913177650f9183ee4Romain Guy     *
3745393a52c9f628bbf2ab68508913177650f9183ee4Romain Guy     * <p><strong>Note:</strong> do not invoke this method from
3746393a52c9f628bbf2ab68508913177650f9183ee4Romain Guy     * {@link #draw(android.graphics.Canvas)}, {@link #onDraw(android.graphics.Canvas)},
3747393a52c9f628bbf2ab68508913177650f9183ee4Romain Guy     * {@link #dispatchDraw(android.graphics.Canvas)} or any related method.</p>
37489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
37499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void removeView(View view) {
37509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        removeViewInternal(view);
37519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        requestLayout();
3752849d0a37cf2ca6c6a6c2d4d4456495e32e363120Romain Guy        invalidate(true);
37539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
37549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
37559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
37569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Removes a view during layout. This is useful if in your onLayout() method,
37579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * you need to remove more views.
37589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
3759393a52c9f628bbf2ab68508913177650f9183ee4Romain Guy     * <p><strong>Note:</strong> do not invoke this method from
3760393a52c9f628bbf2ab68508913177650f9183ee4Romain Guy     * {@link #draw(android.graphics.Canvas)}, {@link #onDraw(android.graphics.Canvas)},
3761393a52c9f628bbf2ab68508913177650f9183ee4Romain Guy     * {@link #dispatchDraw(android.graphics.Canvas)} or any related method.</p>
3762393a52c9f628bbf2ab68508913177650f9183ee4Romain Guy     *
37639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param view the view to remove from the group
37649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
37659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void removeViewInLayout(View view) {
37669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        removeViewInternal(view);
37679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
37689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
37699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
37709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Removes a range of views during layout. This is useful if in your onLayout() method,
37719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * you need to remove more views.
37729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
3773393a52c9f628bbf2ab68508913177650f9183ee4Romain Guy     * <p><strong>Note:</strong> do not invoke this method from
3774393a52c9f628bbf2ab68508913177650f9183ee4Romain Guy     * {@link #draw(android.graphics.Canvas)}, {@link #onDraw(android.graphics.Canvas)},
3775393a52c9f628bbf2ab68508913177650f9183ee4Romain Guy     * {@link #dispatchDraw(android.graphics.Canvas)} or any related method.</p>
3776393a52c9f628bbf2ab68508913177650f9183ee4Romain Guy     *
37779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param start the index of the first view to remove from the group
37789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param count the number of views to remove from the group
37799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
37809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void removeViewsInLayout(int start, int count) {
37819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        removeViewsInternal(start, count);
37829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
37839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
37849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
37859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Removes the view at the specified position in the group.
37869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
3787393a52c9f628bbf2ab68508913177650f9183ee4Romain Guy     * <p><strong>Note:</strong> do not invoke this method from
3788393a52c9f628bbf2ab68508913177650f9183ee4Romain Guy     * {@link #draw(android.graphics.Canvas)}, {@link #onDraw(android.graphics.Canvas)},
3789393a52c9f628bbf2ab68508913177650f9183ee4Romain Guy     * {@link #dispatchDraw(android.graphics.Canvas)} or any related method.</p>
3790393a52c9f628bbf2ab68508913177650f9183ee4Romain Guy     *
37919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param index the position in the group of the view to remove
37929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
37939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void removeViewAt(int index) {
37949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        removeViewInternal(index, getChildAt(index));
37959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        requestLayout();
3796849d0a37cf2ca6c6a6c2d4d4456495e32e363120Romain Guy        invalidate(true);
37979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
37989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
37999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
38009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Removes the specified range of views from the group.
38019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
3802393a52c9f628bbf2ab68508913177650f9183ee4Romain Guy     * <p><strong>Note:</strong> do not invoke this method from
3803393a52c9f628bbf2ab68508913177650f9183ee4Romain Guy     * {@link #draw(android.graphics.Canvas)}, {@link #onDraw(android.graphics.Canvas)},
3804393a52c9f628bbf2ab68508913177650f9183ee4Romain Guy     * {@link #dispatchDraw(android.graphics.Canvas)} or any related method.</p>
3805393a52c9f628bbf2ab68508913177650f9183ee4Romain Guy     *
38069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param start the first position in the group of the range of views to remove
38079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param count the number of views to remove
38089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
38099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void removeViews(int start, int count) {
38109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        removeViewsInternal(start, count);
38119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        requestLayout();
3812849d0a37cf2ca6c6a6c2d4d4456495e32e363120Romain Guy        invalidate(true);
38139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
38149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
38159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private void removeViewInternal(View view) {
38169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final int index = indexOfChild(view);
38179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (index >= 0) {
38189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            removeViewInternal(index, view);
38199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
38209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
38219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
38229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private void removeViewInternal(int index, View view) {
382321cd1389d2ef218b20994b617c57af120841a57fChet Haase
382421cd1389d2ef218b20994b617c57af120841a57fChet Haase        if (mTransition != null) {
38255e25c2c14593caee5638603120553ae1ec530f85Chet Haase            mTransition.removeChild(this, view);
382621cd1389d2ef218b20994b617c57af120841a57fChet Haase        }
382721cd1389d2ef218b20994b617c57af120841a57fChet Haase
38289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        boolean clearChildFocus = false;
38299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (view == mFocused) {
383057cadf2a97a81e5bea49bac573249076ebd95a93Svetoslav Ganov            view.unFocus();
38319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            clearChildFocus = true;
38329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
38339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3834149567f9d59a07a9d7793ea455ff4c2586c3ae53Svetoslav Ganov        if (view.isAccessibilityFocused()) {
3835149567f9d59a07a9d7793ea455ff4c2586c3ae53Svetoslav Ganov            view.clearAccessibilityFocus();
3836149567f9d59a07a9d7793ea455ff4c2586c3ae53Svetoslav Ganov        }
3837961bf0e9b4ef94f52ae66856ac573995f1f34578Svetoslav Ganov
383859a422e90035ce5df45c526607db2d3303e3112eJeff Brown        cancelTouchTarget(view);
383959a422e90035ce5df45c526607db2d3303e3112eJeff Brown        cancelHoverTarget(view);
384059a422e90035ce5df45c526607db2d3303e3112eJeff Brown
384121cd1389d2ef218b20994b617c57af120841a57fChet Haase        if (view.getAnimation() != null ||
384221cd1389d2ef218b20994b617c57af120841a57fChet Haase                (mTransitioningViews != null && mTransitioningViews.contains(view))) {
38439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            addDisappearingView(view);
38449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else if (view.mAttachInfo != null) {
38459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project           view.dispatchDetachedFromWindow();
38469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
38479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3848539ee8716b4f81260bab2e9f3dc5d88d81c99985Adam Powell        if (view.hasTransientState()) {
3849539ee8716b4f81260bab2e9f3dc5d88d81c99985Adam Powell            childHasTransientStateChanged(view, false);
3850539ee8716b4f81260bab2e9f3dc5d88d81c99985Adam Powell        }
3851539ee8716b4f81260bab2e9f3dc5d88d81c99985Adam Powell
38529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        needGlobalAttributesUpdate(false);
38538506ab4ac062d0e1ccde136e5e2f4081560e0c11Romain Guy
38549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        removeFromArray(index);
38559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
38569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (clearChildFocus) {
38579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            clearChildFocus(view);
3858149567f9d59a07a9d7793ea455ff4c2586c3ae53Svetoslav Ganov            if (!rootViewRequestFocus()) {
3859149567f9d59a07a9d7793ea455ff4c2586c3ae53Svetoslav Ganov                notifyGlobalFocusCleared(this);
3860149567f9d59a07a9d7793ea455ff4c2586c3ae53Svetoslav Ganov            }
38614213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov        }
38626fb05630cf406f3844878d44c585754cd160567eRomain Guy
38636fb05630cf406f3844878d44c585754cd160567eRomain Guy        onViewRemoved(view);
38646254f4806dd3db53b7380e77fbb183065685573eSvetoslav
38656254f4806dd3db53b7380e77fbb183065685573eSvetoslav        if (view.isImportantForAccessibility() && view.getVisibility() != View.GONE) {
386600dbe81fea7be57ee2ff8a97844faf1bc15a427fSvetoslav            notifySubtreeAccessibilityStateChangedIfNeeded();
38676254f4806dd3db53b7380e77fbb183065685573eSvetoslav        }
38689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
38699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
387021cd1389d2ef218b20994b617c57af120841a57fChet Haase    /**
387121cd1389d2ef218b20994b617c57af120841a57fChet Haase     * Sets the LayoutTransition object for this ViewGroup. If the LayoutTransition object is
387221cd1389d2ef218b20994b617c57af120841a57fChet Haase     * not null, changes in layout which occur because of children being added to or removed from
387321cd1389d2ef218b20994b617c57af120841a57fChet Haase     * the ViewGroup will be animated according to the animations defined in that LayoutTransition
387421cd1389d2ef218b20994b617c57af120841a57fChet Haase     * object. By default, the transition object is null (so layout changes are not animated).
387521cd1389d2ef218b20994b617c57af120841a57fChet Haase     *
3876ef3cbfd4c42719d3e4feabb74c08f0311066c194Chet Haase     * <p>Replacing a non-null transition will cause that previous transition to be
3877ef3cbfd4c42719d3e4feabb74c08f0311066c194Chet Haase     * canceled, if it is currently running, to restore this container to
3878ef3cbfd4c42719d3e4feabb74c08f0311066c194Chet Haase     * its correct post-transition state.</p>
3879ef3cbfd4c42719d3e4feabb74c08f0311066c194Chet Haase     *
388021cd1389d2ef218b20994b617c57af120841a57fChet Haase     * @param transition The LayoutTransition object that will animated changes in layout. A value
388121cd1389d2ef218b20994b617c57af120841a57fChet Haase     * of <code>null</code> means no transition will run on layout changes.
388213cc1207fab68adc5c7da0bf3b365196e26a273eChet Haase     * @attr ref android.R.styleable#ViewGroup_animateLayoutChanges
388321cd1389d2ef218b20994b617c57af120841a57fChet Haase     */
388421cd1389d2ef218b20994b617c57af120841a57fChet Haase    public void setLayoutTransition(LayoutTransition transition) {
3885b20db3ec34e846010f389880b2cfab4d7bf79820Chet Haase        if (mTransition != null) {
3886fee6f2b3d30fe222486a70a773683e21d9dd12bfChet Haase            LayoutTransition previousTransition = mTransition;
3887fee6f2b3d30fe222486a70a773683e21d9dd12bfChet Haase            previousTransition.cancel();
3888fee6f2b3d30fe222486a70a773683e21d9dd12bfChet Haase            previousTransition.removeTransitionListener(mLayoutTransitionListener);
3889b20db3ec34e846010f389880b2cfab4d7bf79820Chet Haase        }
389021cd1389d2ef218b20994b617c57af120841a57fChet Haase        mTransition = transition;
389113cc1207fab68adc5c7da0bf3b365196e26a273eChet Haase        if (mTransition != null) {
389213cc1207fab68adc5c7da0bf3b365196e26a273eChet Haase            mTransition.addTransitionListener(mLayoutTransitionListener);
389313cc1207fab68adc5c7da0bf3b365196e26a273eChet Haase        }
389413cc1207fab68adc5c7da0bf3b365196e26a273eChet Haase    }
389513cc1207fab68adc5c7da0bf3b365196e26a273eChet Haase
389613cc1207fab68adc5c7da0bf3b365196e26a273eChet Haase    /**
389713cc1207fab68adc5c7da0bf3b365196e26a273eChet Haase     * Gets the LayoutTransition object for this ViewGroup. If the LayoutTransition object is
389813cc1207fab68adc5c7da0bf3b365196e26a273eChet Haase     * not null, changes in layout which occur because of children being added to or removed from
389913cc1207fab68adc5c7da0bf3b365196e26a273eChet Haase     * the ViewGroup will be animated according to the animations defined in that LayoutTransition
390013cc1207fab68adc5c7da0bf3b365196e26a273eChet Haase     * object. By default, the transition object is null (so layout changes are not animated).
390113cc1207fab68adc5c7da0bf3b365196e26a273eChet Haase     *
390213cc1207fab68adc5c7da0bf3b365196e26a273eChet Haase     * @return LayoutTranstion The LayoutTransition object that will animated changes in layout.
390313cc1207fab68adc5c7da0bf3b365196e26a273eChet Haase     * A value of <code>null</code> means no transition will run on layout changes.
390413cc1207fab68adc5c7da0bf3b365196e26a273eChet Haase     */
390513cc1207fab68adc5c7da0bf3b365196e26a273eChet Haase    public LayoutTransition getLayoutTransition() {
390613cc1207fab68adc5c7da0bf3b365196e26a273eChet Haase        return mTransition;
390721cd1389d2ef218b20994b617c57af120841a57fChet Haase    }
390821cd1389d2ef218b20994b617c57af120841a57fChet Haase
39099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private void removeViewsInternal(int start, int count) {
39109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final View focused = mFocused;
39119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final boolean detach = mAttachInfo != null;
3912149567f9d59a07a9d7793ea455ff4c2586c3ae53Svetoslav Ganov        boolean clearChildFocus = false;
39139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
39149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final View[] children = mChildren;
39159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final int end = start + count;
39169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
39179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (int i = start; i < end; i++) {
39189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            final View view = children[i];
39199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
392021cd1389d2ef218b20994b617c57af120841a57fChet Haase            if (mTransition != null) {
39215e25c2c14593caee5638603120553ae1ec530f85Chet Haase                mTransition.removeChild(this, view);
392221cd1389d2ef218b20994b617c57af120841a57fChet Haase            }
392321cd1389d2ef218b20994b617c57af120841a57fChet Haase
39249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (view == focused) {
392557cadf2a97a81e5bea49bac573249076ebd95a93Svetoslav Ganov                view.unFocus();
3926149567f9d59a07a9d7793ea455ff4c2586c3ae53Svetoslav Ganov                clearChildFocus = true;
39279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
39289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3929149567f9d59a07a9d7793ea455ff4c2586c3ae53Svetoslav Ganov            if (view.isAccessibilityFocused()) {
3930149567f9d59a07a9d7793ea455ff4c2586c3ae53Svetoslav Ganov                view.clearAccessibilityFocus();
3931149567f9d59a07a9d7793ea455ff4c2586c3ae53Svetoslav Ganov            }
3932961bf0e9b4ef94f52ae66856ac573995f1f34578Svetoslav Ganov
393359a422e90035ce5df45c526607db2d3303e3112eJeff Brown            cancelTouchTarget(view);
393459a422e90035ce5df45c526607db2d3303e3112eJeff Brown            cancelHoverTarget(view);
393559a422e90035ce5df45c526607db2d3303e3112eJeff Brown
393621cd1389d2ef218b20994b617c57af120841a57fChet Haase            if (view.getAnimation() != null ||
393721cd1389d2ef218b20994b617c57af120841a57fChet Haase                (mTransitioningViews != null && mTransitioningViews.contains(view))) {
39389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                addDisappearingView(view);
39399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else if (detach) {
39409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project               view.dispatchDetachedFromWindow();
39419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
39429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3943539ee8716b4f81260bab2e9f3dc5d88d81c99985Adam Powell            if (view.hasTransientState()) {
3944539ee8716b4f81260bab2e9f3dc5d88d81c99985Adam Powell                childHasTransientStateChanged(view, false);
3945539ee8716b4f81260bab2e9f3dc5d88d81c99985Adam Powell            }
3946539ee8716b4f81260bab2e9f3dc5d88d81c99985Adam Powell
39479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            needGlobalAttributesUpdate(false);
39488506ab4ac062d0e1ccde136e5e2f4081560e0c11Romain Guy
3949f51d91c3ab232154b6c00d7f71377ff2421f79bfPhilip Milne            onViewRemoved(view);
39509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
39519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
39529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        removeFromArray(start, count);
39539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3954149567f9d59a07a9d7793ea455ff4c2586c3ae53Svetoslav Ganov        if (clearChildFocus) {
3955149567f9d59a07a9d7793ea455ff4c2586c3ae53Svetoslav Ganov            clearChildFocus(focused);
3956149567f9d59a07a9d7793ea455ff4c2586c3ae53Svetoslav Ganov            if (!rootViewRequestFocus()) {
3957149567f9d59a07a9d7793ea455ff4c2586c3ae53Svetoslav Ganov                notifyGlobalFocusCleared(focused);
3958149567f9d59a07a9d7793ea455ff4c2586c3ae53Svetoslav Ganov            }
39599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
39609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
39619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
39629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
39639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Call this method to remove all child views from the
39649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * ViewGroup.
3965393a52c9f628bbf2ab68508913177650f9183ee4Romain Guy     *
3966393a52c9f628bbf2ab68508913177650f9183ee4Romain Guy     * <p><strong>Note:</strong> do not invoke this method from
3967393a52c9f628bbf2ab68508913177650f9183ee4Romain Guy     * {@link #draw(android.graphics.Canvas)}, {@link #onDraw(android.graphics.Canvas)},
3968393a52c9f628bbf2ab68508913177650f9183ee4Romain Guy     * {@link #dispatchDraw(android.graphics.Canvas)} or any related method.</p>
39699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
39709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void removeAllViews() {
39719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        removeAllViewsInLayout();
39729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        requestLayout();
3973849d0a37cf2ca6c6a6c2d4d4456495e32e363120Romain Guy        invalidate(true);
39749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
39759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
39769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
39779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Called by a ViewGroup subclass to remove child views from itself,
39789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * when it must first know its size on screen before it can calculate how many
39799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * child views it will render. An example is a Gallery or a ListView, which
39809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * may "have" 50 children, but actually only render the number of children
39819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * that can currently fit inside the object on screen. Do not call
39829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * this method unless you are extending ViewGroup and understand the
39839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * view measuring and layout pipeline.
3984393a52c9f628bbf2ab68508913177650f9183ee4Romain Guy     *
3985393a52c9f628bbf2ab68508913177650f9183ee4Romain Guy     * <p><strong>Note:</strong> do not invoke this method from
3986393a52c9f628bbf2ab68508913177650f9183ee4Romain Guy     * {@link #draw(android.graphics.Canvas)}, {@link #onDraw(android.graphics.Canvas)},
3987393a52c9f628bbf2ab68508913177650f9183ee4Romain Guy     * {@link #dispatchDraw(android.graphics.Canvas)} or any related method.</p>
39889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
39899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void removeAllViewsInLayout() {
39909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final int count = mChildrenCount;
39919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (count <= 0) {
39929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return;
39939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
39949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
39959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final View[] children = mChildren;
39969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mChildrenCount = 0;
39979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
39989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final View focused = mFocused;
39999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final boolean detach = mAttachInfo != null;
4000149567f9d59a07a9d7793ea455ff4c2586c3ae53Svetoslav Ganov        boolean clearChildFocus = false;
40019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
40029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        needGlobalAttributesUpdate(false);
40038506ab4ac062d0e1ccde136e5e2f4081560e0c11Romain Guy
40049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (int i = count - 1; i >= 0; i--) {
40059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            final View view = children[i];
40069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
400721cd1389d2ef218b20994b617c57af120841a57fChet Haase            if (mTransition != null) {
40085e25c2c14593caee5638603120553ae1ec530f85Chet Haase                mTransition.removeChild(this, view);
400921cd1389d2ef218b20994b617c57af120841a57fChet Haase            }
401021cd1389d2ef218b20994b617c57af120841a57fChet Haase
40119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (view == focused) {
401257cadf2a97a81e5bea49bac573249076ebd95a93Svetoslav Ganov                view.unFocus();
4013149567f9d59a07a9d7793ea455ff4c2586c3ae53Svetoslav Ganov                clearChildFocus = true;
40149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
40159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4016149567f9d59a07a9d7793ea455ff4c2586c3ae53Svetoslav Ganov            if (view.isAccessibilityFocused()) {
4017149567f9d59a07a9d7793ea455ff4c2586c3ae53Svetoslav Ganov                view.clearAccessibilityFocus();
4018149567f9d59a07a9d7793ea455ff4c2586c3ae53Svetoslav Ganov            }
4019961bf0e9b4ef94f52ae66856ac573995f1f34578Svetoslav Ganov
402059a422e90035ce5df45c526607db2d3303e3112eJeff Brown            cancelTouchTarget(view);
402159a422e90035ce5df45c526607db2d3303e3112eJeff Brown            cancelHoverTarget(view);
402259a422e90035ce5df45c526607db2d3303e3112eJeff Brown
402321cd1389d2ef218b20994b617c57af120841a57fChet Haase            if (view.getAnimation() != null ||
402421cd1389d2ef218b20994b617c57af120841a57fChet Haase                    (mTransitioningViews != null && mTransitioningViews.contains(view))) {
40259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                addDisappearingView(view);
40269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else if (detach) {
40279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project               view.dispatchDetachedFromWindow();
40289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
40299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4030539ee8716b4f81260bab2e9f3dc5d88d81c99985Adam Powell            if (view.hasTransientState()) {
4031539ee8716b4f81260bab2e9f3dc5d88d81c99985Adam Powell                childHasTransientStateChanged(view, false);
4032539ee8716b4f81260bab2e9f3dc5d88d81c99985Adam Powell            }
4033539ee8716b4f81260bab2e9f3dc5d88d81c99985Adam Powell
4034f51d91c3ab232154b6c00d7f71377ff2421f79bfPhilip Milne            onViewRemoved(view);
40359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
40369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            view.mParent = null;
40379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            children[i] = null;
40389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
40399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4040149567f9d59a07a9d7793ea455ff4c2586c3ae53Svetoslav Ganov        if (clearChildFocus) {
4041149567f9d59a07a9d7793ea455ff4c2586c3ae53Svetoslav Ganov            clearChildFocus(focused);
4042149567f9d59a07a9d7793ea455ff4c2586c3ae53Svetoslav Ganov            if (!rootViewRequestFocus()) {
4043149567f9d59a07a9d7793ea455ff4c2586c3ae53Svetoslav Ganov                notifyGlobalFocusCleared(focused);
4044149567f9d59a07a9d7793ea455ff4c2586c3ae53Svetoslav Ganov            }
40459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
40469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
40479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
40489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
40499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Finishes the removal of a detached view. This method will dispatch the detached from
40509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * window event and notify the hierarchy change listener.
4051ca479d468be963661fd82634f4b57f21c13f1fe6Chet Haase     * <p>
4052ca479d468be963661fd82634f4b57f21c13f1fe6Chet Haase     * This method is intended to be lightweight and makes no assumptions about whether the
4053ca479d468be963661fd82634f4b57f21c13f1fe6Chet Haase     * parent or child should be redrawn. Proper use of this method will include also making
4054ca479d468be963661fd82634f4b57f21c13f1fe6Chet Haase     * any appropriate {@link #requestLayout()} or {@link #invalidate()} calls.
4055ca479d468be963661fd82634f4b57f21c13f1fe6Chet Haase     * For example, callers can {@link #post(Runnable) post} a {@link Runnable}
4056ca479d468be963661fd82634f4b57f21c13f1fe6Chet Haase     * which performs a {@link #requestLayout()} on the next frame, after all detach/remove
4057ca479d468be963661fd82634f4b57f21c13f1fe6Chet Haase     * calls are finished, causing layout to be run prior to redrawing the view hierarchy.
40589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
40599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param child the child to be definitely removed from the view hierarchy
40609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param animate if true and the view has an animation, the view is placed in the
40619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *                disappearing views list, otherwise, it is detached from the window
40629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
40639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #attachViewToParent(View, int, android.view.ViewGroup.LayoutParams)
40649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #detachAllViewsFromParent()
40659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #detachViewFromParent(View)
40669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #detachViewFromParent(int)
40679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
40689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected void removeDetachedView(View child, boolean animate) {
406921cd1389d2ef218b20994b617c57af120841a57fChet Haase        if (mTransition != null) {
40705e25c2c14593caee5638603120553ae1ec530f85Chet Haase            mTransition.removeChild(this, child);
407121cd1389d2ef218b20994b617c57af120841a57fChet Haase        }
407221cd1389d2ef218b20994b617c57af120841a57fChet Haase
40739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (child == mFocused) {
40749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            child.clearFocus();
40759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
40768506ab4ac062d0e1ccde136e5e2f4081560e0c11Romain Guy
4077961bf0e9b4ef94f52ae66856ac573995f1f34578Svetoslav Ganov        child.clearAccessibilityFocus();
4078961bf0e9b4ef94f52ae66856ac573995f1f34578Svetoslav Ganov
407959a422e90035ce5df45c526607db2d3303e3112eJeff Brown        cancelTouchTarget(child);
408059a422e90035ce5df45c526607db2d3303e3112eJeff Brown        cancelHoverTarget(child);
408159a422e90035ce5df45c526607db2d3303e3112eJeff Brown
408221cd1389d2ef218b20994b617c57af120841a57fChet Haase        if ((animate && child.getAnimation() != null) ||
408321cd1389d2ef218b20994b617c57af120841a57fChet Haase                (mTransitioningViews != null && mTransitioningViews.contains(child))) {
40849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            addDisappearingView(child);
40859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else if (child.mAttachInfo != null) {
40869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            child.dispatchDetachedFromWindow();
40879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
40889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4089539ee8716b4f81260bab2e9f3dc5d88d81c99985Adam Powell        if (child.hasTransientState()) {
4090539ee8716b4f81260bab2e9f3dc5d88d81c99985Adam Powell            childHasTransientStateChanged(child, false);
4091539ee8716b4f81260bab2e9f3dc5d88d81c99985Adam Powell        }
4092539ee8716b4f81260bab2e9f3dc5d88d81c99985Adam Powell
4093f51d91c3ab232154b6c00d7f71377ff2421f79bfPhilip Milne        onViewRemoved(child);
40949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
40959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
40969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
40979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Attaches a view to this view group. Attaching a view assigns this group as the parent,
4098ca479d468be963661fd82634f4b57f21c13f1fe6Chet Haase     * sets the layout parameters and puts the view in the list of children so that
4099ca479d468be963661fd82634f4b57f21c13f1fe6Chet Haase     * it can be retrieved by calling {@link #getChildAt(int)}.
4100ca479d468be963661fd82634f4b57f21c13f1fe6Chet Haase     * <p>
4101ca479d468be963661fd82634f4b57f21c13f1fe6Chet Haase     * This method is intended to be lightweight and makes no assumptions about whether the
4102ca479d468be963661fd82634f4b57f21c13f1fe6Chet Haase     * parent or child should be redrawn. Proper use of this method will include also making
4103ca479d468be963661fd82634f4b57f21c13f1fe6Chet Haase     * any appropriate {@link #requestLayout()} or {@link #invalidate()} calls.
4104ca479d468be963661fd82634f4b57f21c13f1fe6Chet Haase     * For example, callers can {@link #post(Runnable) post} a {@link Runnable}
4105ca479d468be963661fd82634f4b57f21c13f1fe6Chet Haase     * which performs a {@link #requestLayout()} on the next frame, after all detach/attach
4106ca479d468be963661fd82634f4b57f21c13f1fe6Chet Haase     * calls are finished, causing layout to be run prior to redrawing the view hierarchy.
4107ca479d468be963661fd82634f4b57f21c13f1fe6Chet Haase     * <p>
4108ca479d468be963661fd82634f4b57f21c13f1fe6Chet Haase     * This method should be called only for views which were detached from their parent.
41099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
41109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param child the child to attach
41119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param index the index at which the child should be attached
41129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param params the layout parameters of the child
41139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
41149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #removeDetachedView(View, boolean)
41159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #detachAllViewsFromParent()
41169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #detachViewFromParent(View)
41179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #detachViewFromParent(int)
41189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
41199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected void attachViewToParent(View child, int index, LayoutParams params) {
41209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        child.mLayoutParams = params;
41219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
41229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (index < 0) {
41239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            index = mChildrenCount;
41249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
41259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
41269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        addInArray(child, index);
41279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
41289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        child.mParent = this;
41294702a856973a553deb82f71b1d3b6c3db5dbf4baDianne Hackborn        child.mPrivateFlags = (child.mPrivateFlags & ~PFLAG_DIRTY_MASK
41304702a856973a553deb82f71b1d3b6c3db5dbf4baDianne Hackborn                        & ~PFLAG_DRAWING_CACHE_VALID)
41314702a856973a553deb82f71b1d3b6c3db5dbf4baDianne Hackborn                | PFLAG_DRAWN | PFLAG_INVALIDATED;
41324702a856973a553deb82f71b1d3b6c3db5dbf4baDianne Hackborn        this.mPrivateFlags |= PFLAG_INVALIDATED;
41339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
41349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (child.hasFocus()) {
41359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            requestChildFocus(child, child.findFocus());
41369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
41379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
41389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
41399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
4140ca479d468be963661fd82634f4b57f21c13f1fe6Chet Haase     * Detaches a view from its parent. Detaching a view should be followed
4141ca479d468be963661fd82634f4b57f21c13f1fe6Chet Haase     * either by a call to
4142ca479d468be963661fd82634f4b57f21c13f1fe6Chet Haase     * {@link #attachViewToParent(View, int, android.view.ViewGroup.LayoutParams)}
4143ca479d468be963661fd82634f4b57f21c13f1fe6Chet Haase     * or a call to {@link #removeDetachedView(View, boolean)}. Detachment should only be
4144ca479d468be963661fd82634f4b57f21c13f1fe6Chet Haase     * temporary; reattachment or removal should happen within the same drawing cycle as
4145ca479d468be963661fd82634f4b57f21c13f1fe6Chet Haase     * detachment. When a view is detached, its parent is null and cannot be retrieved by a
4146ca479d468be963661fd82634f4b57f21c13f1fe6Chet Haase     * call to {@link #getChildAt(int)}.
41479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
41489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param child the child to detach
41499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
41509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #detachViewFromParent(int)
41519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #detachViewsFromParent(int, int)
41529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #detachAllViewsFromParent()
41539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #attachViewToParent(View, int, android.view.ViewGroup.LayoutParams)
41549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #removeDetachedView(View, boolean)
41559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
41569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected void detachViewFromParent(View child) {
41579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        removeFromArray(indexOfChild(child));
41589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
41599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
41609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
4161ca479d468be963661fd82634f4b57f21c13f1fe6Chet Haase     * Detaches a view from its parent. Detaching a view should be followed
4162ca479d468be963661fd82634f4b57f21c13f1fe6Chet Haase     * either by a call to
4163ca479d468be963661fd82634f4b57f21c13f1fe6Chet Haase     * {@link #attachViewToParent(View, int, android.view.ViewGroup.LayoutParams)}
4164ca479d468be963661fd82634f4b57f21c13f1fe6Chet Haase     * or a call to {@link #removeDetachedView(View, boolean)}. Detachment should only be
4165ca479d468be963661fd82634f4b57f21c13f1fe6Chet Haase     * temporary; reattachment or removal should happen within the same drawing cycle as
4166ca479d468be963661fd82634f4b57f21c13f1fe6Chet Haase     * detachment. When a view is detached, its parent is null and cannot be retrieved by a
4167ca479d468be963661fd82634f4b57f21c13f1fe6Chet Haase     * call to {@link #getChildAt(int)}.
41689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
41699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param index the index of the child to detach
41709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
41719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #detachViewFromParent(View)
41729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #detachAllViewsFromParent()
41739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #detachViewsFromParent(int, int)
41749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #attachViewToParent(View, int, android.view.ViewGroup.LayoutParams)
41759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #removeDetachedView(View, boolean)
41769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
41779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected void detachViewFromParent(int index) {
41789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        removeFromArray(index);
41799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
41809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
41819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
4182ca479d468be963661fd82634f4b57f21c13f1fe6Chet Haase     * Detaches a range of views from their parents. Detaching a view should be followed
4183ca479d468be963661fd82634f4b57f21c13f1fe6Chet Haase     * either by a call to
4184ca479d468be963661fd82634f4b57f21c13f1fe6Chet Haase     * {@link #attachViewToParent(View, int, android.view.ViewGroup.LayoutParams)}
4185ca479d468be963661fd82634f4b57f21c13f1fe6Chet Haase     * or a call to {@link #removeDetachedView(View, boolean)}. Detachment should only be
4186ca479d468be963661fd82634f4b57f21c13f1fe6Chet Haase     * temporary; reattachment or removal should happen within the same drawing cycle as
4187ca479d468be963661fd82634f4b57f21c13f1fe6Chet Haase     * detachment. When a view is detached, its parent is null and cannot be retrieved by a
4188ca479d468be963661fd82634f4b57f21c13f1fe6Chet Haase     * call to {@link #getChildAt(int)}.
41899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
41909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param start the first index of the childrend range to detach
41919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param count the number of children to detach
41929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
41939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #detachViewFromParent(View)
41949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #detachViewFromParent(int)
41959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #detachAllViewsFromParent()
41969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #attachViewToParent(View, int, android.view.ViewGroup.LayoutParams)
41979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #removeDetachedView(View, boolean)
41989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
41999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected void detachViewsFromParent(int start, int count) {
42009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        removeFromArray(start, count);
42019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
42029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
42039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
4204ca479d468be963661fd82634f4b57f21c13f1fe6Chet Haase     * Detaches all views from the parent. Detaching a view should be followed
4205ca479d468be963661fd82634f4b57f21c13f1fe6Chet Haase     * either by a call to
4206ca479d468be963661fd82634f4b57f21c13f1fe6Chet Haase     * {@link #attachViewToParent(View, int, android.view.ViewGroup.LayoutParams)}
4207ca479d468be963661fd82634f4b57f21c13f1fe6Chet Haase     * or a call to {@link #removeDetachedView(View, boolean)}. Detachment should only be
4208ca479d468be963661fd82634f4b57f21c13f1fe6Chet Haase     * temporary; reattachment or removal should happen within the same drawing cycle as
4209ca479d468be963661fd82634f4b57f21c13f1fe6Chet Haase     * detachment. When a view is detached, its parent is null and cannot be retrieved by a
4210ca479d468be963661fd82634f4b57f21c13f1fe6Chet Haase     * call to {@link #getChildAt(int)}.
42119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
42129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #detachViewFromParent(View)
42139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #detachViewFromParent(int)
42149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #detachViewsFromParent(int, int)
42159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #attachViewToParent(View, int, android.view.ViewGroup.LayoutParams)
42169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #removeDetachedView(View, boolean)
42179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
42189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected void detachAllViewsFromParent() {
42199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final int count = mChildrenCount;
42209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (count <= 0) {
42219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return;
42229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
42239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
42249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final View[] children = mChildren;
42259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mChildrenCount = 0;
42269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
42279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (int i = count - 1; i >= 0; i--) {
42289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            children[i].mParent = null;
42299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            children[i] = null;
42309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
42319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
42329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
42339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
42349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Don't call or override this method. It is used for the implementation of
42359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the view hierarchy.
42369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
42379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public final void invalidateChild(View child, final Rect dirty) {
42389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        ViewParent parent = this;
42399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
42409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final AttachInfo attachInfo = mAttachInfo;
42419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (attachInfo != null) {
42429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // If the child is drawing an animation, we want to copy this flag onto
42439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // ourselves and the parent to make sure the invalidate request goes
42449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // through
42454702a856973a553deb82f71b1d3b6c3db5dbf4baDianne Hackborn            final boolean drawAnimation = (child.mPrivateFlags & PFLAG_DRAW_ANIMATION)
42464702a856973a553deb82f71b1d3b6c3db5dbf4baDianne Hackborn                    == PFLAG_DRAW_ANIMATION;
424724443ea3992e372e47daa50266b0f2ec38cac388Romain Guy
4248fe455af277183f910eb74653a3ad172c717e7abfRomain Guy            // Check whether the child that requests the invalidate is fully opaque
4249fe455af277183f910eb74653a3ad172c717e7abfRomain Guy            // Views being animated or transformed are not considered opaque because we may
4250fe455af277183f910eb74653a3ad172c717e7abfRomain Guy            // be invalidating their old position and need the parent to paint behind them.
4251fe455af277183f910eb74653a3ad172c717e7abfRomain Guy            Matrix childMatrix = child.getMatrix();
4252fe455af277183f910eb74653a3ad172c717e7abfRomain Guy            final boolean isOpaque = child.isOpaque() && !drawAnimation &&
4253fe455af277183f910eb74653a3ad172c717e7abfRomain Guy                    child.getAnimation() == null && childMatrix.isIdentity();
4254fe455af277183f910eb74653a3ad172c717e7abfRomain Guy            // Mark the child as dirty, using the appropriate flag
4255fe455af277183f910eb74653a3ad172c717e7abfRomain Guy            // Make sure we do not set both flags at the same time
42564702a856973a553deb82f71b1d3b6c3db5dbf4baDianne Hackborn            int opaqueFlag = isOpaque ? PFLAG_DIRTY_OPAQUE : PFLAG_DIRTY;
425770d4ba15b1f0c1133c5aabc86de828b41e482fffChet Haase
4258fe455af277183f910eb74653a3ad172c717e7abfRomain Guy            if (child.mLayerType != LAYER_TYPE_NONE) {
42594702a856973a553deb82f71b1d3b6c3db5dbf4baDianne Hackborn                mPrivateFlags |= PFLAG_INVALIDATED;
42604702a856973a553deb82f71b1d3b6c3db5dbf4baDianne Hackborn                mPrivateFlags &= ~PFLAG_DRAWING_CACHE_VALID;
4261fe455af277183f910eb74653a3ad172c717e7abfRomain Guy                child.mLocalDirtyRect.union(dirty);
4262fe455af277183f910eb74653a3ad172c717e7abfRomain Guy            }
4263fe455af277183f910eb74653a3ad172c717e7abfRomain Guy
4264fe455af277183f910eb74653a3ad172c717e7abfRomain Guy            final int[] location = attachInfo.mInvalidateChildLocation;
4265fe455af277183f910eb74653a3ad172c717e7abfRomain Guy            location[CHILD_LEFT_INDEX] = child.mLeft;
4266fe455af277183f910eb74653a3ad172c717e7abfRomain Guy            location[CHILD_TOP_INDEX] = child.mTop;
4267599913d6e8e610665fad7edd7dfbd3cd48758b3aChet Haase            if (!childMatrix.isIdentity() ||
4268599913d6e8e610665fad7edd7dfbd3cd48758b3aChet Haase                    (mGroupFlags & ViewGroup.FLAG_SUPPORT_STATIC_TRANSFORMATIONS) != 0) {
4269fe455af277183f910eb74653a3ad172c717e7abfRomain Guy                RectF boundingRect = attachInfo.mTmpTransformRect;
4270fe455af277183f910eb74653a3ad172c717e7abfRomain Guy                boundingRect.set(dirty);
4271599913d6e8e610665fad7edd7dfbd3cd48758b3aChet Haase                Matrix transformMatrix;
4272599913d6e8e610665fad7edd7dfbd3cd48758b3aChet Haase                if ((mGroupFlags & ViewGroup.FLAG_SUPPORT_STATIC_TRANSFORMATIONS) != 0) {
4273599913d6e8e610665fad7edd7dfbd3cd48758b3aChet Haase                    Transformation t = attachInfo.mTmpTransformation;
4274599913d6e8e610665fad7edd7dfbd3cd48758b3aChet Haase                    boolean transformed = getChildStaticTransformation(child, t);
4275599913d6e8e610665fad7edd7dfbd3cd48758b3aChet Haase                    if (transformed) {
4276599913d6e8e610665fad7edd7dfbd3cd48758b3aChet Haase                        transformMatrix = attachInfo.mTmpMatrix;
4277599913d6e8e610665fad7edd7dfbd3cd48758b3aChet Haase                        transformMatrix.set(t.getMatrix());
4278599913d6e8e610665fad7edd7dfbd3cd48758b3aChet Haase                        if (!childMatrix.isIdentity()) {
4279599913d6e8e610665fad7edd7dfbd3cd48758b3aChet Haase                            transformMatrix.preConcat(childMatrix);
4280599913d6e8e610665fad7edd7dfbd3cd48758b3aChet Haase                        }
4281599913d6e8e610665fad7edd7dfbd3cd48758b3aChet Haase                    } else {
4282599913d6e8e610665fad7edd7dfbd3cd48758b3aChet Haase                        transformMatrix = childMatrix;
4283599913d6e8e610665fad7edd7dfbd3cd48758b3aChet Haase                    }
4284599913d6e8e610665fad7edd7dfbd3cd48758b3aChet Haase                } else {
4285599913d6e8e610665fad7edd7dfbd3cd48758b3aChet Haase                    transformMatrix = childMatrix;
4286599913d6e8e610665fad7edd7dfbd3cd48758b3aChet Haase                }
4287599913d6e8e610665fad7edd7dfbd3cd48758b3aChet Haase                transformMatrix.mapRect(boundingRect);
4288fe455af277183f910eb74653a3ad172c717e7abfRomain Guy                dirty.set((int) (boundingRect.left - 0.5f),
4289fe455af277183f910eb74653a3ad172c717e7abfRomain Guy                        (int) (boundingRect.top - 0.5f),
4290fe455af277183f910eb74653a3ad172c717e7abfRomain Guy                        (int) (boundingRect.right + 0.5f),
4291fe455af277183f910eb74653a3ad172c717e7abfRomain Guy                        (int) (boundingRect.bottom + 0.5f));
4292fe455af277183f910eb74653a3ad172c717e7abfRomain Guy            }
4293fe455af277183f910eb74653a3ad172c717e7abfRomain Guy
4294fe455af277183f910eb74653a3ad172c717e7abfRomain Guy            do {
4295fe455af277183f910eb74653a3ad172c717e7abfRomain Guy                View view = null;
4296fe455af277183f910eb74653a3ad172c717e7abfRomain Guy                if (parent instanceof View) {
4297fe455af277183f910eb74653a3ad172c717e7abfRomain Guy                    view = (View) parent;
4298fe455af277183f910eb74653a3ad172c717e7abfRomain Guy                }
429970d4ba15b1f0c1133c5aabc86de828b41e482fffChet Haase
4300fe455af277183f910eb74653a3ad172c717e7abfRomain Guy                if (drawAnimation) {
43017e68efb0a098149e1e6f86663e978e9fd26e0ea1Romain Guy                    if (view != null) {
43024702a856973a553deb82f71b1d3b6c3db5dbf4baDianne Hackborn                        view.mPrivateFlags |= PFLAG_DRAW_ANIMATION;
4303fe455af277183f910eb74653a3ad172c717e7abfRomain Guy                    } else if (parent instanceof ViewRootImpl) {
4304fe455af277183f910eb74653a3ad172c717e7abfRomain Guy                        ((ViewRootImpl) parent).mIsAnimating = true;
430570d4ba15b1f0c1133c5aabc86de828b41e482fffChet Haase                    }
4306fe455af277183f910eb74653a3ad172c717e7abfRomain Guy                }
430770d4ba15b1f0c1133c5aabc86de828b41e482fffChet Haase
4308fe455af277183f910eb74653a3ad172c717e7abfRomain Guy                // If the parent is dirty opaque or not dirty, mark it dirty with the opaque
4309fe455af277183f910eb74653a3ad172c717e7abfRomain Guy                // flag coming from the child that initiated the invalidate
4310fe455af277183f910eb74653a3ad172c717e7abfRomain Guy                if (view != null) {
4311fe455af277183f910eb74653a3ad172c717e7abfRomain Guy                    if ((view.mViewFlags & FADING_EDGE_MASK) != 0 &&
4312fe455af277183f910eb74653a3ad172c717e7abfRomain Guy                            view.getSolidColor() == 0) {
43134702a856973a553deb82f71b1d3b6c3db5dbf4baDianne Hackborn                        opaqueFlag = PFLAG_DIRTY;
431470d4ba15b1f0c1133c5aabc86de828b41e482fffChet Haase                    }
43154702a856973a553deb82f71b1d3b6c3db5dbf4baDianne Hackborn                    if ((view.mPrivateFlags & PFLAG_DIRTY_MASK) != PFLAG_DIRTY) {
43164702a856973a553deb82f71b1d3b6c3db5dbf4baDianne Hackborn                        view.mPrivateFlags = (view.mPrivateFlags & ~PFLAG_DIRTY_MASK) | opaqueFlag;
4317fe455af277183f910eb74653a3ad172c717e7abfRomain Guy                    }
4318fe455af277183f910eb74653a3ad172c717e7abfRomain Guy                }
4319fe455af277183f910eb74653a3ad172c717e7abfRomain Guy
4320fe455af277183f910eb74653a3ad172c717e7abfRomain Guy                parent = parent.invalidateChildInParent(location, dirty);
4321fe455af277183f910eb74653a3ad172c717e7abfRomain Guy                if (view != null) {
4322fe455af277183f910eb74653a3ad172c717e7abfRomain Guy                    // Account for transform on current parent
4323fe455af277183f910eb74653a3ad172c717e7abfRomain Guy                    Matrix m = view.getMatrix();
4324fe455af277183f910eb74653a3ad172c717e7abfRomain Guy                    if (!m.isIdentity()) {
4325fe455af277183f910eb74653a3ad172c717e7abfRomain Guy                        RectF boundingRect = attachInfo.mTmpTransformRect;
4326fe455af277183f910eb74653a3ad172c717e7abfRomain Guy                        boundingRect.set(dirty);
4327fe455af277183f910eb74653a3ad172c717e7abfRomain Guy                        m.mapRect(boundingRect);
4328e8585b1721b84798c4e7413939fd085f7a39bc0eRomain Guy                        dirty.set((int) (boundingRect.left - 0.5f),
4329e8585b1721b84798c4e7413939fd085f7a39bc0eRomain Guy                                (int) (boundingRect.top - 0.5f),
4330fe455af277183f910eb74653a3ad172c717e7abfRomain Guy                                (int) (boundingRect.right + 0.5f),
4331fe455af277183f910eb74653a3ad172c717e7abfRomain Guy                                (int) (boundingRect.bottom + 0.5f));
4332fe455af277183f910eb74653a3ad172c717e7abfRomain Guy                    }
4333fe455af277183f910eb74653a3ad172c717e7abfRomain Guy                }
4334fe455af277183f910eb74653a3ad172c717e7abfRomain Guy            } while (parent != null);
43359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
43369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
43379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
43389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
43399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Don't call or override this method. It is used for the implementation of
43409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the view hierarchy.
43419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
43429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * This implementation returns null if this ViewGroup does not have a parent,
43439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * if this ViewGroup is already fully invalidated or if the dirty rectangle
43449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * does not intersect with this ViewGroup's bounds.
43459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
43469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public ViewParent invalidateChildInParent(final int[] location, final Rect dirty) {
43474702a856973a553deb82f71b1d3b6c3db5dbf4baDianne Hackborn        if ((mPrivateFlags & PFLAG_DRAWN) == PFLAG_DRAWN ||
43484702a856973a553deb82f71b1d3b6c3db5dbf4baDianne Hackborn                (mPrivateFlags & PFLAG_DRAWING_CACHE_VALID) == PFLAG_DRAWING_CACHE_VALID) {
43499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if ((mGroupFlags & (FLAG_OPTIMIZE_INVALIDATE | FLAG_ANIMATION_DONE)) !=
43509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        FLAG_OPTIMIZE_INVALIDATE) {
43519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                dirty.offset(location[CHILD_LEFT_INDEX] - mScrollX,
43529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        location[CHILD_TOP_INDEX] - mScrollY);
4353a4f14ebe29b9c1286badeb47da19af4df88250ddChet Haase                if ((mGroupFlags & FLAG_CLIP_CHILDREN) == 0) {
4354a4f14ebe29b9c1286badeb47da19af4df88250ddChet Haase                    dirty.union(0, 0, mRight - mLeft, mBottom - mTop);
4355a4f14ebe29b9c1286badeb47da19af4df88250ddChet Haase                }
43569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
43579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                final int left = mLeft;
43589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                final int top = mTop;
43599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
436005e91ed5a7ea17f021e1811166942a7d758e1cceChet Haase                if ((mGroupFlags & FLAG_CLIP_CHILDREN) == FLAG_CLIP_CHILDREN) {
436105e91ed5a7ea17f021e1811166942a7d758e1cceChet Haase                    if (!dirty.intersect(0, 0, mRight - left, mBottom - top)) {
436205e91ed5a7ea17f021e1811166942a7d758e1cceChet Haase                        dirty.setEmpty();
43633a3133d876caf60ebff2176ad75c3dcf0259148dRomain Guy                    }
436405e91ed5a7ea17f021e1811166942a7d758e1cceChet Haase                }
43654702a856973a553deb82f71b1d3b6c3db5dbf4baDianne Hackborn                mPrivateFlags &= ~PFLAG_DRAWING_CACHE_VALID;
436605e91ed5a7ea17f021e1811166942a7d758e1cceChet Haase
436705e91ed5a7ea17f021e1811166942a7d758e1cceChet Haase                location[CHILD_LEFT_INDEX] = left;
436805e91ed5a7ea17f021e1811166942a7d758e1cceChet Haase                location[CHILD_TOP_INDEX] = top;
4369beff8d83ef062975459f149ad0c632a3797d78ceRomain Guy
437005e91ed5a7ea17f021e1811166942a7d758e1cceChet Haase                if (mLayerType != LAYER_TYPE_NONE) {
43714702a856973a553deb82f71b1d3b6c3db5dbf4baDianne Hackborn                    mPrivateFlags |= PFLAG_INVALIDATED;
437205e91ed5a7ea17f021e1811166942a7d758e1cceChet Haase                    mLocalDirtyRect.union(dirty);
43739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
437405e91ed5a7ea17f021e1811166942a7d758e1cceChet Haase
437505e91ed5a7ea17f021e1811166942a7d758e1cceChet Haase                return mParent;
437605e91ed5a7ea17f021e1811166942a7d758e1cceChet Haase
43779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else {
43784702a856973a553deb82f71b1d3b6c3db5dbf4baDianne Hackborn                mPrivateFlags &= ~PFLAG_DRAWN & ~PFLAG_DRAWING_CACHE_VALID;
43799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
43809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                location[CHILD_LEFT_INDEX] = mLeft;
43819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                location[CHILD_TOP_INDEX] = mTop;
4382a3db866056adb01820bbd6389d20fc550be87eb3Chet Haase                if ((mGroupFlags & FLAG_CLIP_CHILDREN) == FLAG_CLIP_CHILDREN) {
4383a3db866056adb01820bbd6389d20fc550be87eb3Chet Haase                    dirty.set(0, 0, mRight - mLeft, mBottom - mTop);
4384a3db866056adb01820bbd6389d20fc550be87eb3Chet Haase                } else {
4385a3db866056adb01820bbd6389d20fc550be87eb3Chet Haase                    // in case the dirty rect extends outside the bounds of this container
4386a3db866056adb01820bbd6389d20fc550be87eb3Chet Haase                    dirty.union(0, 0, mRight - mLeft, mBottom - mTop);
4387a3db866056adb01820bbd6389d20fc550be87eb3Chet Haase                }
43883a3133d876caf60ebff2176ad75c3dcf0259148dRomain Guy
43893a3133d876caf60ebff2176ad75c3dcf0259148dRomain Guy                if (mLayerType != LAYER_TYPE_NONE) {
43904702a856973a553deb82f71b1d3b6c3db5dbf4baDianne Hackborn                    mPrivateFlags |= PFLAG_INVALIDATED;
43913a3133d876caf60ebff2176ad75c3dcf0259148dRomain Guy                    mLocalDirtyRect.union(dirty);
43923a3133d876caf60ebff2176ad75c3dcf0259148dRomain Guy                }
43939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
43949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return mParent;
43959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
43969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
43979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
43989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return null;
43999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
44009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
44019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
44029d1992deaeb3d60d5928f05b649a2cc654ba98a3Chet Haase     * Quick invalidation method called by View.invalidateViewProperty. This doesn't set the
44039d1992deaeb3d60d5928f05b649a2cc654ba98a3Chet Haase     * DRAWN flags and doesn't handle the Animation logic that the default invalidation methods
44049d1992deaeb3d60d5928f05b649a2cc654ba98a3Chet Haase     * do; all we want to do here is schedule a traversal with the appropriate dirty rect.
44059d1992deaeb3d60d5928f05b649a2cc654ba98a3Chet Haase     *
44069d1992deaeb3d60d5928f05b649a2cc654ba98a3Chet Haase     * @hide
44079d1992deaeb3d60d5928f05b649a2cc654ba98a3Chet Haase     */
44089d1992deaeb3d60d5928f05b649a2cc654ba98a3Chet Haase    public void invalidateChildFast(View child, final Rect dirty) {
44099d1992deaeb3d60d5928f05b649a2cc654ba98a3Chet Haase        ViewParent parent = this;
44109d1992deaeb3d60d5928f05b649a2cc654ba98a3Chet Haase
44119d1992deaeb3d60d5928f05b649a2cc654ba98a3Chet Haase        final AttachInfo attachInfo = mAttachInfo;
44129d1992deaeb3d60d5928f05b649a2cc654ba98a3Chet Haase        if (attachInfo != null) {
44139d1992deaeb3d60d5928f05b649a2cc654ba98a3Chet Haase            if (child.mLayerType != LAYER_TYPE_NONE) {
44149d1992deaeb3d60d5928f05b649a2cc654ba98a3Chet Haase                child.mLocalDirtyRect.union(dirty);
44159d1992deaeb3d60d5928f05b649a2cc654ba98a3Chet Haase            }
44169d1992deaeb3d60d5928f05b649a2cc654ba98a3Chet Haase
44179d1992deaeb3d60d5928f05b649a2cc654ba98a3Chet Haase            int left = child.mLeft;
44189d1992deaeb3d60d5928f05b649a2cc654ba98a3Chet Haase            int top = child.mTop;
44199d1992deaeb3d60d5928f05b649a2cc654ba98a3Chet Haase            if (!child.getMatrix().isIdentity()) {
44209d1992deaeb3d60d5928f05b649a2cc654ba98a3Chet Haase                child.transformRect(dirty);
44219d1992deaeb3d60d5928f05b649a2cc654ba98a3Chet Haase            }
44229d1992deaeb3d60d5928f05b649a2cc654ba98a3Chet Haase
44239d1992deaeb3d60d5928f05b649a2cc654ba98a3Chet Haase            do {
44249d1992deaeb3d60d5928f05b649a2cc654ba98a3Chet Haase                if (parent instanceof ViewGroup) {
44259d1992deaeb3d60d5928f05b649a2cc654ba98a3Chet Haase                    ViewGroup parentVG = (ViewGroup) parent;
4426b85967b9af76e1e60f7a96603e2567a6449d2e04Chet Haase                    if (parentVG.mLayerType != LAYER_TYPE_NONE) {
4427b85967b9af76e1e60f7a96603e2567a6449d2e04Chet Haase                        // Layered parents should be recreated, not just re-issued
4428b85967b9af76e1e60f7a96603e2567a6449d2e04Chet Haase                        parentVG.invalidate();
4429b85967b9af76e1e60f7a96603e2567a6449d2e04Chet Haase                        parent = null;
4430b85967b9af76e1e60f7a96603e2567a6449d2e04Chet Haase                    } else {
4431b85967b9af76e1e60f7a96603e2567a6449d2e04Chet Haase                        parent = parentVG.invalidateChildInParentFast(left, top, dirty);
4432b85967b9af76e1e60f7a96603e2567a6449d2e04Chet Haase                        left = parentVG.mLeft;
4433b85967b9af76e1e60f7a96603e2567a6449d2e04Chet Haase                        top = parentVG.mTop;
4434b85967b9af76e1e60f7a96603e2567a6449d2e04Chet Haase                    }
44359d1992deaeb3d60d5928f05b649a2cc654ba98a3Chet Haase                } else {
44369d1992deaeb3d60d5928f05b649a2cc654ba98a3Chet Haase                    // Reached the top; this calls into the usual invalidate method in
44379d1992deaeb3d60d5928f05b649a2cc654ba98a3Chet Haase                    // ViewRootImpl, which schedules a traversal
44389d1992deaeb3d60d5928f05b649a2cc654ba98a3Chet Haase                    final int[] location = attachInfo.mInvalidateChildLocation;
44399d1992deaeb3d60d5928f05b649a2cc654ba98a3Chet Haase                    location[0] = left;
44409d1992deaeb3d60d5928f05b649a2cc654ba98a3Chet Haase                    location[1] = top;
44419d1992deaeb3d60d5928f05b649a2cc654ba98a3Chet Haase                    parent = parent.invalidateChildInParent(location, dirty);
44429d1992deaeb3d60d5928f05b649a2cc654ba98a3Chet Haase                }
44439d1992deaeb3d60d5928f05b649a2cc654ba98a3Chet Haase            } while (parent != null);
44449d1992deaeb3d60d5928f05b649a2cc654ba98a3Chet Haase        }
44459d1992deaeb3d60d5928f05b649a2cc654ba98a3Chet Haase    }
44469d1992deaeb3d60d5928f05b649a2cc654ba98a3Chet Haase
44479d1992deaeb3d60d5928f05b649a2cc654ba98a3Chet Haase    /**
44489d1992deaeb3d60d5928f05b649a2cc654ba98a3Chet Haase     * Quick invalidation method that simply transforms the dirty rect into the parent's
44499d1992deaeb3d60d5928f05b649a2cc654ba98a3Chet Haase     * coordinate system, pruning the invalidation if the parent has already been invalidated.
4450e4a2d7c48e17dd1c2f59dd18e91997029a6d0bdbChet Haase     *
4451e4a2d7c48e17dd1c2f59dd18e91997029a6d0bdbChet Haase     * @hide
44529d1992deaeb3d60d5928f05b649a2cc654ba98a3Chet Haase     */
4453e4a2d7c48e17dd1c2f59dd18e91997029a6d0bdbChet Haase    protected ViewParent invalidateChildInParentFast(int left, int top, final Rect dirty) {
44544702a856973a553deb82f71b1d3b6c3db5dbf4baDianne Hackborn        if ((mPrivateFlags & PFLAG_DRAWN) == PFLAG_DRAWN ||
44554702a856973a553deb82f71b1d3b6c3db5dbf4baDianne Hackborn                (mPrivateFlags & PFLAG_DRAWING_CACHE_VALID) == PFLAG_DRAWING_CACHE_VALID) {
44569d1992deaeb3d60d5928f05b649a2cc654ba98a3Chet Haase            dirty.offset(left - mScrollX, top - mScrollY);
4457a4f14ebe29b9c1286badeb47da19af4df88250ddChet Haase            if ((mGroupFlags & FLAG_CLIP_CHILDREN) == 0) {
4458a4f14ebe29b9c1286badeb47da19af4df88250ddChet Haase                dirty.union(0, 0, mRight - mLeft, mBottom - mTop);
4459a4f14ebe29b9c1286badeb47da19af4df88250ddChet Haase            }
44609d1992deaeb3d60d5928f05b649a2cc654ba98a3Chet Haase
44619d1992deaeb3d60d5928f05b649a2cc654ba98a3Chet Haase            if ((mGroupFlags & FLAG_CLIP_CHILDREN) == 0 ||
44629d1992deaeb3d60d5928f05b649a2cc654ba98a3Chet Haase                    dirty.intersect(0, 0, mRight - mLeft, mBottom - mTop)) {
44639d1992deaeb3d60d5928f05b649a2cc654ba98a3Chet Haase
44649d1992deaeb3d60d5928f05b649a2cc654ba98a3Chet Haase                if (mLayerType != LAYER_TYPE_NONE) {
44659d1992deaeb3d60d5928f05b649a2cc654ba98a3Chet Haase                    mLocalDirtyRect.union(dirty);
44669d1992deaeb3d60d5928f05b649a2cc654ba98a3Chet Haase                }
44679d1992deaeb3d60d5928f05b649a2cc654ba98a3Chet Haase                if (!getMatrix().isIdentity()) {
44689d1992deaeb3d60d5928f05b649a2cc654ba98a3Chet Haase                    transformRect(dirty);
44699d1992deaeb3d60d5928f05b649a2cc654ba98a3Chet Haase                }
44709d1992deaeb3d60d5928f05b649a2cc654ba98a3Chet Haase
44719d1992deaeb3d60d5928f05b649a2cc654ba98a3Chet Haase                return mParent;
44729d1992deaeb3d60d5928f05b649a2cc654ba98a3Chet Haase            }
44739d1992deaeb3d60d5928f05b649a2cc654ba98a3Chet Haase        }
44749d1992deaeb3d60d5928f05b649a2cc654ba98a3Chet Haase
44759d1992deaeb3d60d5928f05b649a2cc654ba98a3Chet Haase        return null;
44769d1992deaeb3d60d5928f05b649a2cc654ba98a3Chet Haase    }
44779d1992deaeb3d60d5928f05b649a2cc654ba98a3Chet Haase
44789d1992deaeb3d60d5928f05b649a2cc654ba98a3Chet Haase    /**
44799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Offset a rectangle that is in a descendant's coordinate
44809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * space into our coordinate space.
44819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param descendant A descendant of this view
44829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param rect A rectangle defined in descendant's coordinate space.
44839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
44849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public final void offsetDescendantRectToMyCoords(View descendant, Rect rect) {
44859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        offsetRectBetweenParentAndChild(descendant, rect, true, false);
44869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
44879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
44889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
44899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Offset a rectangle that is in our coordinate space into an ancestor's
44909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * coordinate space.
44919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param descendant A descendant of this view
44929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param rect A rectangle defined in descendant's coordinate space.
44939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
44949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public final void offsetRectIntoDescendantCoords(View descendant, Rect rect) {
44959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        offsetRectBetweenParentAndChild(descendant, rect, false, false);
44969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
44979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
44989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
44999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Helper method that offsets a rect either from parent to descendant or
45009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * descendant to parent.
45019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
45029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    void offsetRectBetweenParentAndChild(View descendant, Rect rect,
45039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            boolean offsetFromChildToParent, boolean clipToBounds) {
45049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
45059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // already in the same coord system :)
45069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (descendant == this) {
45079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return;
45089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
45099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
45109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        ViewParent theParent = descendant.mParent;
45119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
45129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // search and offset up to the parent
45139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        while ((theParent != null)
45149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                && (theParent instanceof View)
45159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                && (theParent != this)) {
45169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
45179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (offsetFromChildToParent) {
45189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                rect.offset(descendant.mLeft - descendant.mScrollX,
45199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        descendant.mTop - descendant.mScrollY);
45209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (clipToBounds) {
45219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    View p = (View) theParent;
45229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    rect.intersect(0, 0, p.mRight - p.mLeft, p.mBottom - p.mTop);
45239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
45249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else {
45259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (clipToBounds) {
45269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    View p = (View) theParent;
45279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    rect.intersect(0, 0, p.mRight - p.mLeft, p.mBottom - p.mTop);
45289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
45299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                rect.offset(descendant.mScrollX - descendant.mLeft,
45309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        descendant.mScrollY - descendant.mTop);
45319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
45329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
45339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            descendant = (View) theParent;
45349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            theParent = descendant.mParent;
45359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
45369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
45379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // now that we are up to this view, need to offset one more time
45389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // to get into our coordinate space
45399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (theParent == this) {
45409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (offsetFromChildToParent) {
45419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                rect.offset(descendant.mLeft - descendant.mScrollX,
45429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        descendant.mTop - descendant.mScrollY);
45439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else {
45449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                rect.offset(descendant.mScrollX - descendant.mLeft,
45459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        descendant.mScrollY - descendant.mTop);
45469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
45479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
45489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new IllegalArgumentException("parameter must be a descendant of this view");
45499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
45509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
45519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
45529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
45539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Offset the vertical location of all children of this view by the specified number of pixels.
45549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
45559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param offset the number of pixels to offset
45569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
45579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @hide
45589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
45599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void offsetChildrenTopAndBottom(int offset) {
45609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final int count = mChildrenCount;
45619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final View[] children = mChildren;
45625549cb590d0c63e4b7717664978e8512e67a9bfaRomain Guy        boolean invalidate = false;
45639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
45649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (int i = 0; i < count; i++) {
45659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            final View v = children[i];
45669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            v.mTop += offset;
45679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            v.mBottom += offset;
45681271e2cc80b01d577e9db339459ef0222bb9320dChet Haase            if (v.mDisplayList != null) {
45695549cb590d0c63e4b7717664978e8512e67a9bfaRomain Guy                invalidate = true;
457052036b19a5f82bc4d75cfcbff99c65df8d25a99bRomain Guy                v.mDisplayList.offsetTopAndBottom(offset);
4571a1cff5043d0fbd78fcf9c48e7658e56a5b0c2de3Chet Haase            }
45729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
45735549cb590d0c63e4b7717664978e8512e67a9bfaRomain Guy
45745549cb590d0c63e4b7717664978e8512e67a9bfaRomain Guy        if (invalidate) {
45755549cb590d0c63e4b7717664978e8512e67a9bfaRomain Guy            invalidateViewProperty(false, false);
45765549cb590d0c63e4b7717664978e8512e67a9bfaRomain Guy        }
45779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
45789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
45799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
45809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@inheritDoc}
45819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
45829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean getChildVisibleRect(View child, Rect r, android.graphics.Point offset) {
4583f93bb6d8fd81d8938b16cf40259f97c336e9ef3aAdam Powell        // It doesn't make a whole lot of sense to call this on a view that isn't attached,
4584f93bb6d8fd81d8938b16cf40259f97c336e9ef3aAdam Powell        // but for some simple tests it can be useful. If we don't have attach info this
4585f93bb6d8fd81d8938b16cf40259f97c336e9ef3aAdam Powell        // will allocate memory.
4586f93bb6d8fd81d8938b16cf40259f97c336e9ef3aAdam Powell        final RectF rect = mAttachInfo != null ? mAttachInfo.mTmpTransformRect : new RectF();
4587cea45132e3d5d32a6fc737abf10b8893a50f465bGilles Debunne        rect.set(r);
4588cea45132e3d5d32a6fc737abf10b8893a50f465bGilles Debunne
4589cea45132e3d5d32a6fc737abf10b8893a50f465bGilles Debunne        if (!child.hasIdentityMatrix()) {
4590cea45132e3d5d32a6fc737abf10b8893a50f465bGilles Debunne           child.getMatrix().mapRect(rect);
4591cea45132e3d5d32a6fc737abf10b8893a50f465bGilles Debunne        }
4592cea45132e3d5d32a6fc737abf10b8893a50f465bGilles Debunne
45939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int dx = child.mLeft - mScrollX;
45949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int dy = child.mTop - mScrollY;
4595cea45132e3d5d32a6fc737abf10b8893a50f465bGilles Debunne
4596cea45132e3d5d32a6fc737abf10b8893a50f465bGilles Debunne        rect.offset(dx, dy);
4597cea45132e3d5d32a6fc737abf10b8893a50f465bGilles Debunne
45989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (offset != null) {
4599cea45132e3d5d32a6fc737abf10b8893a50f465bGilles Debunne            if (!child.hasIdentityMatrix()) {
4600f93bb6d8fd81d8938b16cf40259f97c336e9ef3aAdam Powell                float[] position = mAttachInfo != null ? mAttachInfo.mTmpTransformLocation
4601f93bb6d8fd81d8938b16cf40259f97c336e9ef3aAdam Powell                        : new float[2];
4602cea45132e3d5d32a6fc737abf10b8893a50f465bGilles Debunne                position[0] = offset.x;
4603cea45132e3d5d32a6fc737abf10b8893a50f465bGilles Debunne                position[1] = offset.y;
4604cea45132e3d5d32a6fc737abf10b8893a50f465bGilles Debunne                child.getMatrix().mapPoints(position);
4605cea45132e3d5d32a6fc737abf10b8893a50f465bGilles Debunne                offset.x = (int) (position[0] + 0.5f);
4606cea45132e3d5d32a6fc737abf10b8893a50f465bGilles Debunne                offset.y = (int) (position[1] + 0.5f);
4607cea45132e3d5d32a6fc737abf10b8893a50f465bGilles Debunne            }
46089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            offset.x += dx;
46099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            offset.y += dy;
46109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4611cea45132e3d5d32a6fc737abf10b8893a50f465bGilles Debunne
4612cea45132e3d5d32a6fc737abf10b8893a50f465bGilles Debunne        if (rect.intersect(0, 0, mRight - mLeft, mBottom - mTop)) {
4613cea45132e3d5d32a6fc737abf10b8893a50f465bGilles Debunne            if (mParent == null) return true;
4614cea45132e3d5d32a6fc737abf10b8893a50f465bGilles Debunne            r.set((int) (rect.left + 0.5f), (int) (rect.top + 0.5f),
4615cea45132e3d5d32a6fc737abf10b8893a50f465bGilles Debunne                    (int) (rect.right + 0.5f), (int) (rect.bottom + 0.5f));
4616cea45132e3d5d32a6fc737abf10b8893a50f465bGilles Debunne            return mParent.getChildVisibleRect(this, r, offset);
4617cea45132e3d5d32a6fc737abf10b8893a50f465bGilles Debunne        }
4618cea45132e3d5d32a6fc737abf10b8893a50f465bGilles Debunne
4619cea45132e3d5d32a6fc737abf10b8893a50f465bGilles Debunne        return false;
46209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
46219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
46229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
46239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@inheritDoc}
46249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
46259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
46269c0874408cfc6f6f4e4561973ca5ae52a5982db7Chet Haase    public final void layout(int l, int t, int r, int b) {
4627430742f09063574271e6c4091de13b9b9e762514Chet Haase        if (!mSuppressLayout && (mTransition == null || !mTransition.isChangingLayout())) {
46287dd4a536a125d5e9573e82c39581bf9ee3922424Chet Haase            if (mTransition != null) {
46297dd4a536a125d5e9573e82c39581bf9ee3922424Chet Haase                mTransition.layoutChange(this);
46307dd4a536a125d5e9573e82c39581bf9ee3922424Chet Haase            }
46319c0874408cfc6f6f4e4561973ca5ae52a5982db7Chet Haase            super.layout(l, t, r, b);
46329c0874408cfc6f6f4e4561973ca5ae52a5982db7Chet Haase        } else {
46339c0874408cfc6f6f4e4561973ca5ae52a5982db7Chet Haase            // record the fact that we noop'd it; request layout when transition finishes
4634b989502e5cf44d65c6dddc0179b6d9b6e61ef7fdChet Haase            mLayoutCalledWhileSuppressed = true;
46359c0874408cfc6f6f4e4561973ca5ae52a5982db7Chet Haase        }
46369c0874408cfc6f6f4e4561973ca5ae52a5982db7Chet Haase    }
46379c0874408cfc6f6f4e4561973ca5ae52a5982db7Chet Haase
46389c0874408cfc6f6f4e4561973ca5ae52a5982db7Chet Haase    /**
46399c0874408cfc6f6f4e4561973ca5ae52a5982db7Chet Haase     * {@inheritDoc}
46409c0874408cfc6f6f4e4561973ca5ae52a5982db7Chet Haase     */
46419c0874408cfc6f6f4e4561973ca5ae52a5982db7Chet Haase    @Override
46429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected abstract void onLayout(boolean changed,
46439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            int l, int t, int r, int b);
46449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
46459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
46469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Indicates whether the view group has the ability to animate its children
46479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * after the first layout.
46489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
46499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return true if the children can be animated, false otherwise
46509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
46519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected boolean canAnimate() {
46529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mLayoutAnimationController != null;
46539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
46549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
46559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
46569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Runs the layout animation. Calling this method triggers a relayout of
46579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * this view group.
46589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
46599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void startLayoutAnimation() {
46609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mLayoutAnimationController != null) {
46619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mGroupFlags |= FLAG_RUN_ANIMATION;
46629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            requestLayout();
46639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
46649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
46659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
46669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
46679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Schedules the layout animation to be played after the next layout pass
46689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * of this view group. This can be used to restart the layout animation
46699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * when the content of the view group changes or when the activity is
46709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * paused and resumed.
46719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
46729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void scheduleLayoutAnimation() {
46739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mGroupFlags |= FLAG_RUN_ANIMATION;
46749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
46759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
46769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
46779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Sets the layout animation controller used to animate the group's
46789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * children after the first layout.
46799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
46809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param controller the animation controller
46819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
46829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setLayoutAnimation(LayoutAnimationController controller) {
46839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mLayoutAnimationController = controller;
46849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mLayoutAnimationController != null) {
46859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mGroupFlags |= FLAG_RUN_ANIMATION;
46869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
46879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
46889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
46899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
46909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Returns the layout animation controller used to animate the group's
46919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * children.
46929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
46939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return the current animation controller
46949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
46959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public LayoutAnimationController getLayoutAnimation() {
46969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mLayoutAnimationController;
46979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
46989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
46999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
47009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Indicates whether the children's drawing cache is used during a layout
47019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * animation. By default, the drawing cache is enabled but this will prevent
47029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * nested layout animations from working. To nest animations, you must disable
47039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the cache.
47049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
47059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return true if the animation cache is enabled, false otherwise
47069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
47079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #setAnimationCacheEnabled(boolean)
47089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see View#setDrawingCacheEnabled(boolean)
47099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
47109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @ViewDebug.ExportedProperty
47119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean isAnimationCacheEnabled() {
47129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return (mGroupFlags & FLAG_ANIMATION_CACHE) == FLAG_ANIMATION_CACHE;
47139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
47149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
47159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
47169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Enables or disables the children's drawing cache during a layout animation.
47179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * By default, the drawing cache is enabled but this will prevent nested
47189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * layout animations from working. To nest animations, you must disable the
47199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * cache.
47209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
47219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param enabled true to enable the animation cache, false otherwise
47229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
47239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #isAnimationCacheEnabled()
47249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see View#setDrawingCacheEnabled(boolean)
47259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
47269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setAnimationCacheEnabled(boolean enabled) {
47279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        setBooleanFlag(FLAG_ANIMATION_CACHE, enabled);
47289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
47299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
47309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
47319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Indicates whether this ViewGroup will always try to draw its children using their
47329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * drawing cache. By default this property is enabled.
47339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
47349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return true if the animation cache is enabled, false otherwise
47359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
47369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #setAlwaysDrawnWithCacheEnabled(boolean)
47379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #setChildrenDrawnWithCacheEnabled(boolean)
47389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see View#setDrawingCacheEnabled(boolean)
47399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
4740bea95162ca25bd00b0479d93739b6283795c3986Konstantin Lopyrev    @ViewDebug.ExportedProperty(category = "drawing")
47419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean isAlwaysDrawnWithCacheEnabled() {
47429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return (mGroupFlags & FLAG_ALWAYS_DRAWN_WITH_CACHE) == FLAG_ALWAYS_DRAWN_WITH_CACHE;
47439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
47449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
47459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
47469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Indicates whether this ViewGroup will always try to draw its children using their
47479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * drawing cache. This property can be set to true when the cache rendering is
47489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * slightly different from the children's normal rendering. Renderings can be different,
47499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * for instance, when the cache's quality is set to low.
47509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
47519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * When this property is disabled, the ViewGroup will use the drawing cache of its
47529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * children only when asked to. It's usually the task of subclasses to tell ViewGroup
47539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * when to start using the drawing cache and when to stop using it.
47549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
47559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param always true to always draw with the drawing cache, false otherwise
47569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
47579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #isAlwaysDrawnWithCacheEnabled()
47589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #setChildrenDrawnWithCacheEnabled(boolean)
47599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see View#setDrawingCacheEnabled(boolean)
47609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see View#setDrawingCacheQuality(int)
47619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
47629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setAlwaysDrawnWithCacheEnabled(boolean always) {
47639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        setBooleanFlag(FLAG_ALWAYS_DRAWN_WITH_CACHE, always);
47649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
47659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
47669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
47679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Indicates whether the ViewGroup is currently drawing its children using
47689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * their drawing cache.
47699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
47709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return true if children should be drawn with their cache, false otherwise
47719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
47729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #setAlwaysDrawnWithCacheEnabled(boolean)
47739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #setChildrenDrawnWithCacheEnabled(boolean)
47749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
4775bea95162ca25bd00b0479d93739b6283795c3986Konstantin Lopyrev    @ViewDebug.ExportedProperty(category = "drawing")
47769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected boolean isChildrenDrawnWithCacheEnabled() {
47779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return (mGroupFlags & FLAG_CHILDREN_DRAWN_WITH_CACHE) == FLAG_CHILDREN_DRAWN_WITH_CACHE;
47789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
47799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
47809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
47819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Tells the ViewGroup to draw its children using their drawing cache. This property
47829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * is ignored when {@link #isAlwaysDrawnWithCacheEnabled()} is true. A child's drawing cache
47839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * will be used only if it has been enabled.
47849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
47859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Subclasses should call this method to start and stop using the drawing cache when
47869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * they perform performance sensitive operations, like scrolling or animating.
47879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
47889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param enabled true if children should be drawn with their cache, false otherwise
47899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
47909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #setAlwaysDrawnWithCacheEnabled(boolean)
47919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #isChildrenDrawnWithCacheEnabled()
47929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
47939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected void setChildrenDrawnWithCacheEnabled(boolean enabled) {
47949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        setBooleanFlag(FLAG_CHILDREN_DRAWN_WITH_CACHE, enabled);
47959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
47969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4797293451e4f005a26386db873f5192f86585cc79bcRomain Guy    /**
4798293451e4f005a26386db873f5192f86585cc79bcRomain Guy     * Indicates whether the ViewGroup is drawing its children in the order defined by
4799293451e4f005a26386db873f5192f86585cc79bcRomain Guy     * {@link #getChildDrawingOrder(int, int)}.
4800293451e4f005a26386db873f5192f86585cc79bcRomain Guy     *
4801293451e4f005a26386db873f5192f86585cc79bcRomain Guy     * @return true if children drawing order is defined by {@link #getChildDrawingOrder(int, int)},
4802293451e4f005a26386db873f5192f86585cc79bcRomain Guy     *         false otherwise
4803293451e4f005a26386db873f5192f86585cc79bcRomain Guy     *
4804293451e4f005a26386db873f5192f86585cc79bcRomain Guy     * @see #setChildrenDrawingOrderEnabled(boolean)
4805293451e4f005a26386db873f5192f86585cc79bcRomain Guy     * @see #getChildDrawingOrder(int, int)
4806293451e4f005a26386db873f5192f86585cc79bcRomain Guy     */
4807bea95162ca25bd00b0479d93739b6283795c3986Konstantin Lopyrev    @ViewDebug.ExportedProperty(category = "drawing")
4808293451e4f005a26386db873f5192f86585cc79bcRomain Guy    protected boolean isChildrenDrawingOrderEnabled() {
4809293451e4f005a26386db873f5192f86585cc79bcRomain Guy        return (mGroupFlags & FLAG_USE_CHILD_DRAWING_ORDER) == FLAG_USE_CHILD_DRAWING_ORDER;
4810293451e4f005a26386db873f5192f86585cc79bcRomain Guy    }
4811293451e4f005a26386db873f5192f86585cc79bcRomain Guy
4812293451e4f005a26386db873f5192f86585cc79bcRomain Guy    /**
4813293451e4f005a26386db873f5192f86585cc79bcRomain Guy     * Tells the ViewGroup whether to draw its children in the order defined by the method
4814293451e4f005a26386db873f5192f86585cc79bcRomain Guy     * {@link #getChildDrawingOrder(int, int)}.
4815293451e4f005a26386db873f5192f86585cc79bcRomain Guy     *
4816293451e4f005a26386db873f5192f86585cc79bcRomain Guy     * @param enabled true if the order of the children when drawing is determined by
4817293451e4f005a26386db873f5192f86585cc79bcRomain Guy     *        {@link #getChildDrawingOrder(int, int)}, false otherwise
4818293451e4f005a26386db873f5192f86585cc79bcRomain Guy     *
4819293451e4f005a26386db873f5192f86585cc79bcRomain Guy     * @see #isChildrenDrawingOrderEnabled()
4820293451e4f005a26386db873f5192f86585cc79bcRomain Guy     * @see #getChildDrawingOrder(int, int)
4821293451e4f005a26386db873f5192f86585cc79bcRomain Guy     */
4822293451e4f005a26386db873f5192f86585cc79bcRomain Guy    protected void setChildrenDrawingOrderEnabled(boolean enabled) {
4823293451e4f005a26386db873f5192f86585cc79bcRomain Guy        setBooleanFlag(FLAG_USE_CHILD_DRAWING_ORDER, enabled);
4824293451e4f005a26386db873f5192f86585cc79bcRomain Guy    }
4825293451e4f005a26386db873f5192f86585cc79bcRomain Guy
48266254f4806dd3db53b7380e77fbb183065685573eSvetoslav    private boolean hasBooleanFlag(int flag) {
4827f091b662467eeca05ac0de9c8f3f120f4dde5bdcPhilip Milne        return (mGroupFlags & flag) == flag;
4828f091b662467eeca05ac0de9c8f3f120f4dde5bdcPhilip Milne    }
4829f091b662467eeca05ac0de9c8f3f120f4dde5bdcPhilip Milne
48309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private void setBooleanFlag(int flag, boolean value) {
48319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (value) {
48329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mGroupFlags |= flag;
48339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
48349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mGroupFlags &= ~flag;
48359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
48369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
48379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
48389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
48399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Returns an integer indicating what types of drawing caches are kept in memory.
48409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
48419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #setPersistentDrawingCache(int)
48429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #setAnimationCacheEnabled(boolean)
48439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
48449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return one or a combination of {@link #PERSISTENT_NO_CACHE},
48459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *         {@link #PERSISTENT_ANIMATION_CACHE}, {@link #PERSISTENT_SCROLLING_CACHE}
48469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *         and {@link #PERSISTENT_ALL_CACHES}
48479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
4848bea95162ca25bd00b0479d93739b6283795c3986Konstantin Lopyrev    @ViewDebug.ExportedProperty(category = "drawing", mapping = {
48499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        @ViewDebug.IntToString(from = PERSISTENT_NO_CACHE,        to = "NONE"),
4850203688c6579bc530288642972d1f872a12516dfeRomain Guy        @ViewDebug.IntToString(from = PERSISTENT_ANIMATION_CACHE, to = "ANIMATION"),
48519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        @ViewDebug.IntToString(from = PERSISTENT_SCROLLING_CACHE, to = "SCROLLING"),
48529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        @ViewDebug.IntToString(from = PERSISTENT_ALL_CACHES,      to = "ALL")
48539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    })
48549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public int getPersistentDrawingCache() {
48559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mPersistentDrawingCache;
48569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
48579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
48589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
48599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Indicates what types of drawing caches should be kept in memory after
48609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * they have been created.
48619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
48629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #getPersistentDrawingCache()
48639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #setAnimationCacheEnabled(boolean)
48649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
48659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param drawingCacheToKeep one or a combination of {@link #PERSISTENT_NO_CACHE},
48669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *        {@link #PERSISTENT_ANIMATION_CACHE}, {@link #PERSISTENT_SCROLLING_CACHE}
48679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *        and {@link #PERSISTENT_ALL_CACHES}
48689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
48699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setPersistentDrawingCache(int drawingCacheToKeep) {
48709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mPersistentDrawingCache = drawingCacheToKeep & PERSISTENT_ALL_CACHES;
48719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
48729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4873f091b662467eeca05ac0de9c8f3f120f4dde5bdcPhilip Milne    private void setLayoutMode(int layoutMode, boolean explicitly) {
4874f091b662467eeca05ac0de9c8f3f120f4dde5bdcPhilip Milne        mLayoutMode = layoutMode;
4875f091b662467eeca05ac0de9c8f3f120f4dde5bdcPhilip Milne        setBooleanFlag(FLAG_LAYOUT_MODE_WAS_EXPLICITLY_SET, explicitly);
4876f091b662467eeca05ac0de9c8f3f120f4dde5bdcPhilip Milne    }
4877f091b662467eeca05ac0de9c8f3f120f4dde5bdcPhilip Milne
4878f091b662467eeca05ac0de9c8f3f120f4dde5bdcPhilip Milne    /**
4879f091b662467eeca05ac0de9c8f3f120f4dde5bdcPhilip Milne     * Recursively traverse the view hierarchy, resetting the layoutMode of any
4880f091b662467eeca05ac0de9c8f3f120f4dde5bdcPhilip Milne     * descendants that had inherited a different layoutMode from a previous parent.
4881f091b662467eeca05ac0de9c8f3f120f4dde5bdcPhilip Milne     * Recursion terminates when a descendant's mode is:
4882f091b662467eeca05ac0de9c8f3f120f4dde5bdcPhilip Milne     * <ul>
4883f091b662467eeca05ac0de9c8f3f120f4dde5bdcPhilip Milne     *     <li>Undefined</li>
4884f091b662467eeca05ac0de9c8f3f120f4dde5bdcPhilip Milne     *     <li>The same as the root node's</li>
4885f091b662467eeca05ac0de9c8f3f120f4dde5bdcPhilip Milne     *     <li>A mode that had been explicitly set</li>
4886f091b662467eeca05ac0de9c8f3f120f4dde5bdcPhilip Milne     * <ul/>
4887f091b662467eeca05ac0de9c8f3f120f4dde5bdcPhilip Milne     * The first two clauses are optimizations.
4888f091b662467eeca05ac0de9c8f3f120f4dde5bdcPhilip Milne     * @param layoutModeOfRoot
4889f091b662467eeca05ac0de9c8f3f120f4dde5bdcPhilip Milne     */
4890f091b662467eeca05ac0de9c8f3f120f4dde5bdcPhilip Milne    @Override
4891f091b662467eeca05ac0de9c8f3f120f4dde5bdcPhilip Milne    void invalidateInheritedLayoutMode(int layoutModeOfRoot) {
4892f091b662467eeca05ac0de9c8f3f120f4dde5bdcPhilip Milne        if (mLayoutMode == LAYOUT_MODE_UNDEFINED ||
4893f091b662467eeca05ac0de9c8f3f120f4dde5bdcPhilip Milne            mLayoutMode == layoutModeOfRoot ||
48946254f4806dd3db53b7380e77fbb183065685573eSvetoslav            hasBooleanFlag(FLAG_LAYOUT_MODE_WAS_EXPLICITLY_SET)) {
4895f091b662467eeca05ac0de9c8f3f120f4dde5bdcPhilip Milne            return;
4896f091b662467eeca05ac0de9c8f3f120f4dde5bdcPhilip Milne        }
4897f091b662467eeca05ac0de9c8f3f120f4dde5bdcPhilip Milne        setLayoutMode(LAYOUT_MODE_UNDEFINED, false);
4898f091b662467eeca05ac0de9c8f3f120f4dde5bdcPhilip Milne
4899f091b662467eeca05ac0de9c8f3f120f4dde5bdcPhilip Milne        // apply recursively
4900f091b662467eeca05ac0de9c8f3f120f4dde5bdcPhilip Milne        for (int i = 0, N = getChildCount(); i < N; i++) {
4901f091b662467eeca05ac0de9c8f3f120f4dde5bdcPhilip Milne            getChildAt(i).invalidateInheritedLayoutMode(layoutModeOfRoot);
4902f091b662467eeca05ac0de9c8f3f120f4dde5bdcPhilip Milne        }
4903f091b662467eeca05ac0de9c8f3f120f4dde5bdcPhilip Milne    }
4904f091b662467eeca05ac0de9c8f3f120f4dde5bdcPhilip Milne
49059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
4906cfb631b0e56b7c6b9ca11e1a0553b7896b64b1c1Philip Milne     * Returns the basis of alignment during layout operations on this ViewGroup:
49077b7578184567f4e4f0740ce935cc192765410ccaPhilip Milne     * either {@link #LAYOUT_MODE_CLIP_BOUNDS} or {@link #LAYOUT_MODE_OPTICAL_BOUNDS}.
4908cfb631b0e56b7c6b9ca11e1a0553b7896b64b1c1Philip Milne     * <p>
4909cfb631b0e56b7c6b9ca11e1a0553b7896b64b1c1Philip Milne     * If no layoutMode was explicitly set, either programmatically or in an XML resource,
4910cfb631b0e56b7c6b9ca11e1a0553b7896b64b1c1Philip Milne     * the method returns the layoutMode of the view's parent ViewGroup if such a parent exists,
4911cfb631b0e56b7c6b9ca11e1a0553b7896b64b1c1Philip Milne     * otherwise the method returns a default value of {@link #LAYOUT_MODE_CLIP_BOUNDS}.
49121557fd7809078e421f751efc7d2539b3efdc54b2Philip Milne     *
4913fcc6a0f145fa721e3feee70bedf8e120fcc4c494Philip Milne     * @return the layout mode to use during layout operations
49141557fd7809078e421f751efc7d2539b3efdc54b2Philip Milne     *
49151557fd7809078e421f751efc7d2539b3efdc54b2Philip Milne     * @see #setLayoutMode(int)
49161557fd7809078e421f751efc7d2539b3efdc54b2Philip Milne     */
49171557fd7809078e421f751efc7d2539b3efdc54b2Philip Milne    public int getLayoutMode() {
4918cfb631b0e56b7c6b9ca11e1a0553b7896b64b1c1Philip Milne        if (mLayoutMode == LAYOUT_MODE_UNDEFINED) {
4919f091b662467eeca05ac0de9c8f3f120f4dde5bdcPhilip Milne            int inheritedLayoutMode = (mParent instanceof ViewGroup) ?
4920f091b662467eeca05ac0de9c8f3f120f4dde5bdcPhilip Milne                    ((ViewGroup) mParent).getLayoutMode() : LAYOUT_MODE_DEFAULT;
4921f091b662467eeca05ac0de9c8f3f120f4dde5bdcPhilip Milne            setLayoutMode(inheritedLayoutMode, false);
4922cfb631b0e56b7c6b9ca11e1a0553b7896b64b1c1Philip Milne        }
49231557fd7809078e421f751efc7d2539b3efdc54b2Philip Milne        return mLayoutMode;
49241557fd7809078e421f751efc7d2539b3efdc54b2Philip Milne    }
49251557fd7809078e421f751efc7d2539b3efdc54b2Philip Milne
49261557fd7809078e421f751efc7d2539b3efdc54b2Philip Milne    /**
4927cfb631b0e56b7c6b9ca11e1a0553b7896b64b1c1Philip Milne     * Sets the basis of alignment during the layout of this ViewGroup.
49287b7578184567f4e4f0740ce935cc192765410ccaPhilip Milne     * Valid values are either {@link #LAYOUT_MODE_CLIP_BOUNDS} or
49297b7578184567f4e4f0740ce935cc192765410ccaPhilip Milne     * {@link #LAYOUT_MODE_OPTICAL_BOUNDS}.
49301557fd7809078e421f751efc7d2539b3efdc54b2Philip Milne     *
4931fcc6a0f145fa721e3feee70bedf8e120fcc4c494Philip Milne     * @param layoutMode the layout mode to use during layout operations
49321557fd7809078e421f751efc7d2539b3efdc54b2Philip Milne     *
49331557fd7809078e421f751efc7d2539b3efdc54b2Philip Milne     * @see #getLayoutMode()
493427a8508ee1236ded652cd452b93884a9193654fcScott Main     * @attr ref android.R.styleable#ViewGroup_layoutMode
49351557fd7809078e421f751efc7d2539b3efdc54b2Philip Milne     */
49361557fd7809078e421f751efc7d2539b3efdc54b2Philip Milne    public void setLayoutMode(int layoutMode) {
49371557fd7809078e421f751efc7d2539b3efdc54b2Philip Milne        if (mLayoutMode != layoutMode) {
4938f091b662467eeca05ac0de9c8f3f120f4dde5bdcPhilip Milne            invalidateInheritedLayoutMode(layoutMode);
4939f091b662467eeca05ac0de9c8f3f120f4dde5bdcPhilip Milne            setLayoutMode(layoutMode, layoutMode != LAYOUT_MODE_UNDEFINED);
49401557fd7809078e421f751efc7d2539b3efdc54b2Philip Milne            requestLayout();
49411557fd7809078e421f751efc7d2539b3efdc54b2Philip Milne        }
49421557fd7809078e421f751efc7d2539b3efdc54b2Philip Milne    }
49431557fd7809078e421f751efc7d2539b3efdc54b2Philip Milne
49441557fd7809078e421f751efc7d2539b3efdc54b2Philip Milne    /**
49459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Returns a new set of layout parameters based on the supplied attributes set.
49469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
49479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param attrs the attributes to build the layout parameters from
49489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
49499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return an instance of {@link android.view.ViewGroup.LayoutParams} or one
49509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *         of its descendants
49519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
49529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public LayoutParams generateLayoutParams(AttributeSet attrs) {
49539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return new LayoutParams(getContext(), attrs);
49549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
49559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
49569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
49579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Returns a safe set of layout parameters based on the supplied layout params.
49589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * When a ViewGroup is passed a View whose layout params do not pass the test of
49599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@link #checkLayoutParams(android.view.ViewGroup.LayoutParams)}, this method
49609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * is invoked. This method should return a new set of layout params suitable for
49619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * this ViewGroup, possibly by copying the appropriate attributes from the
49629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * specified set of layout params.
49639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
49649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param p The layout parameters to convert into a suitable set of layout parameters
49659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *          for this ViewGroup.
49669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
49679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return an instance of {@link android.view.ViewGroup.LayoutParams} or one
49689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *         of its descendants
49699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
49709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected LayoutParams generateLayoutParams(ViewGroup.LayoutParams p) {
49719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return p;
49729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
49739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
49749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
49759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Returns a set of default layout parameters. These parameters are requested
49769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * when the View passed to {@link #addView(View)} has no layout parameters
49779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * already set. If null is returned, an exception is thrown from addView.
49789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
49799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return a set of default layout parameters or null
49809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
49819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected LayoutParams generateDefaultLayoutParams() {
49829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
49839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
49849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
49859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
49869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@inheritDoc}
49879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
49889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
49899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected void debug(int depth) {
49909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        super.debug(depth);
49919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        String output;
49929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
49939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mFocused != null) {
49949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            output = debugIndent(depth);
49959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            output += "mFocused";
49969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            Log.d(VIEW_LOG_TAG, output);
49979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
49989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mChildrenCount != 0) {
49999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            output = debugIndent(depth);
50009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            output += "{";
50019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            Log.d(VIEW_LOG_TAG, output);
50029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
50039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int count = mChildrenCount;
50049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (int i = 0; i < count; i++) {
50059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            View child = mChildren[i];
50069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            child.debug(depth + 1);
50079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
50089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
50099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mChildrenCount != 0) {
50109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            output = debugIndent(depth);
50119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            output += "}";
50129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            Log.d(VIEW_LOG_TAG, output);
50139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
50149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
50159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
50169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
50179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Returns the position in the group of the specified child view.
50189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
50199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param child the view for which to get the position
50209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return a positive integer representing the position of the view in the
50219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *         group, or -1 if the view does not exist in the group
50229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
50239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public int indexOfChild(View child) {
50249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final int count = mChildrenCount;
50259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final View[] children = mChildren;
50269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (int i = 0; i < count; i++) {
50279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (children[i] == child) {
50289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return i;
50299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
50309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
50319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return -1;
50329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
50339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
50349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
50359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Returns the number of children in the group.
50369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
50379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return a positive integer representing the number of children in
50389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *         the group
50399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
50409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public int getChildCount() {
50419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mChildrenCount;
50429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
50439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
50449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
50459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Returns the view at the specified position in the group.
50469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
50479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param index the position at which to get the view from
50489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return the view at the specified position or null if the position
50499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *         does not exist within the group
50509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
50519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public View getChildAt(int index) {
50523ba8f5d675831647e45d0ce11507c85dfb5f753bAdam Powell        if (index < 0 || index >= mChildrenCount) {
50539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return null;
50549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
50553ba8f5d675831647e45d0ce11507c85dfb5f753bAdam Powell        return mChildren[index];
50569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
50579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
50589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
50599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Ask all of the children of this view to measure themselves, taking into
50609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * account both the MeasureSpec requirements for this view and its padding.
50619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * We skip children that are in the GONE state The heavy lifting is done in
50629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * getChildMeasureSpec.
50639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
50649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param widthMeasureSpec The width requirements for this view
50659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param heightMeasureSpec The height requirements for this view
50669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
50679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected void measureChildren(int widthMeasureSpec, int heightMeasureSpec) {
50689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final int size = mChildrenCount;
50699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final View[] children = mChildren;
50709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (int i = 0; i < size; ++i) {
50719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            final View child = children[i];
50729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if ((child.mViewFlags & VISIBILITY_MASK) != GONE) {
50739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                measureChild(child, widthMeasureSpec, heightMeasureSpec);
50749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
50759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
50769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
50779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
50789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
50799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Ask one of the children of this view to measure itself, taking into
50809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * account both the MeasureSpec requirements for this view and its padding.
50819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * The heavy lifting is done in getChildMeasureSpec.
50829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
50839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param child The child to measure
50849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param parentWidthMeasureSpec The width requirements for this view
50859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param parentHeightMeasureSpec The height requirements for this view
50869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
50879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected void measureChild(View child, int parentWidthMeasureSpec,
50889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            int parentHeightMeasureSpec) {
50899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final LayoutParams lp = child.getLayoutParams();
50909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
50919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final int childWidthMeasureSpec = getChildMeasureSpec(parentWidthMeasureSpec,
50929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mPaddingLeft + mPaddingRight, lp.width);
50939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final int childHeightMeasureSpec = getChildMeasureSpec(parentHeightMeasureSpec,
50949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mPaddingTop + mPaddingBottom, lp.height);
50959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
50969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        child.measure(childWidthMeasureSpec, childHeightMeasureSpec);
50979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
50989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
50999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
51009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Ask one of the children of this view to measure itself, taking into
51019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * account both the MeasureSpec requirements for this view and its padding
51029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * and margins. The child must have MarginLayoutParams The heavy lifting is
51039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * done in getChildMeasureSpec.
51049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
51059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param child The child to measure
51069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param parentWidthMeasureSpec The width requirements for this view
51079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param widthUsed Extra space that has been used up by the parent
51089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *        horizontally (possibly by other children of the parent)
51099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param parentHeightMeasureSpec The height requirements for this view
51109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param heightUsed Extra space that has been used up by the parent
51119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *        vertically (possibly by other children of the parent)
51129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
51139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected void measureChildWithMargins(View child,
51149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            int parentWidthMeasureSpec, int widthUsed,
51159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            int parentHeightMeasureSpec, int heightUsed) {
51169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final MarginLayoutParams lp = (MarginLayoutParams) child.getLayoutParams();
51179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
51189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final int childWidthMeasureSpec = getChildMeasureSpec(parentWidthMeasureSpec,
51199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mPaddingLeft + mPaddingRight + lp.leftMargin + lp.rightMargin
51209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        + widthUsed, lp.width);
51219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final int childHeightMeasureSpec = getChildMeasureSpec(parentHeightMeasureSpec,
51229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mPaddingTop + mPaddingBottom + lp.topMargin + lp.bottomMargin
51239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        + heightUsed, lp.height);
51249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
51259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        child.measure(childWidthMeasureSpec, childHeightMeasureSpec);
51269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
51279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
51289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
51299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Does the hard part of measureChildren: figuring out the MeasureSpec to
51309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * pass to a particular child. This method figures out the right MeasureSpec
51319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * for one dimension (height or width) of one child view.
51329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
51339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * The goal is to combine information from our MeasureSpec with the
51349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * LayoutParams of the child to get the best possible results. For example,
51359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * if the this view knows its size (because its MeasureSpec has a mode of
51369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * EXACTLY), and the child has indicated in its LayoutParams that it wants
51379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * to be the same size as the parent, the parent should ask the child to
51389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * layout given an exact size.
51399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
51409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param spec The requirements for this view
51419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param padding The padding of this view for the current dimension and
51429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *        margins, if applicable
51439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param childDimension How big the child wants to be in the current
51449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *        dimension
51459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return a MeasureSpec integer for the child
51469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
51479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static int getChildMeasureSpec(int spec, int padding, int childDimension) {
51489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int specMode = MeasureSpec.getMode(spec);
51499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int specSize = MeasureSpec.getSize(spec);
51509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
51519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int size = Math.max(0, specSize - padding);
51529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
51539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int resultSize = 0;
51549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int resultMode = 0;
51559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
51569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        switch (specMode) {
51579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Parent has imposed an exact size on us
51589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        case MeasureSpec.EXACTLY:
51599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (childDimension >= 0) {
51609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                resultSize = childDimension;
51619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                resultMode = MeasureSpec.EXACTLY;
5162980a938c1c9a6a5791a8240e5a1e6638ab28dc77Romain Guy            } else if (childDimension == LayoutParams.MATCH_PARENT) {
51639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // Child wants to be our size. So be it.
51649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                resultSize = size;
51659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                resultMode = MeasureSpec.EXACTLY;
51669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else if (childDimension == LayoutParams.WRAP_CONTENT) {
51679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // Child wants to determine its own size. It can't be
51689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // bigger than us.
51699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                resultSize = size;
51709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                resultMode = MeasureSpec.AT_MOST;
51719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
51729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            break;
51739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
51749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Parent has imposed a maximum size on us
51759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        case MeasureSpec.AT_MOST:
51769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (childDimension >= 0) {
51779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // Child wants a specific size... so be it
51789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                resultSize = childDimension;
51799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                resultMode = MeasureSpec.EXACTLY;
5180980a938c1c9a6a5791a8240e5a1e6638ab28dc77Romain Guy            } else if (childDimension == LayoutParams.MATCH_PARENT) {
51819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // Child wants to be our size, but our size is not fixed.
51829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // Constrain child to not be bigger than us.
51839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                resultSize = size;
51849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                resultMode = MeasureSpec.AT_MOST;
51859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else if (childDimension == LayoutParams.WRAP_CONTENT) {
51869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // Child wants to determine its own size. It can't be
51879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // bigger than us.
51889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                resultSize = size;
51899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                resultMode = MeasureSpec.AT_MOST;
51909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
51919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            break;
51929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
51939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Parent asked to see how big we want to be
51949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        case MeasureSpec.UNSPECIFIED:
51959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (childDimension >= 0) {
51969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // Child wants a specific size... let him have it
51979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                resultSize = childDimension;
51989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                resultMode = MeasureSpec.EXACTLY;
5199980a938c1c9a6a5791a8240e5a1e6638ab28dc77Romain Guy            } else if (childDimension == LayoutParams.MATCH_PARENT) {
52009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // Child wants to be our size... find out how big it should
52019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // be
52029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                resultSize = 0;
52039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                resultMode = MeasureSpec.UNSPECIFIED;
52049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else if (childDimension == LayoutParams.WRAP_CONTENT) {
52059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // Child wants to determine its own size.... find out how
52069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // big it should be
52079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                resultSize = 0;
52089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                resultMode = MeasureSpec.UNSPECIFIED;
52099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
52109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            break;
52119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
52129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return MeasureSpec.makeMeasureSpec(resultSize, resultMode);
52139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
52149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
52159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
52169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
52179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Removes any pending animations for views that have been removed. Call
52189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * this if you don't want animations for exiting views to stack up.
52199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
52209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void clearDisappearingChildren() {
52219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mDisappearingChildren != null) {
52229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mDisappearingChildren.clear();
5223b85967b9af76e1e60f7a96603e2567a6449d2e04Chet Haase            invalidate();
52249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
52259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
52269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
52279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
52289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Add a view which is removed from mChildren but still needs animation
52299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
52309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param v View to add
52319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
52329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private void addDisappearingView(View v) {
52339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        ArrayList<View> disappearingChildren = mDisappearingChildren;
52349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
52359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (disappearingChildren == null) {
52369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            disappearingChildren = mDisappearingChildren = new ArrayList<View>();
52379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
52389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
52399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        disappearingChildren.add(v);
52409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
52419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
52429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
52439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Cleanup a view when its animation is done. This may mean removing it from
52449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the list of disappearing views.
52459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
52469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param view The view whose animation has finished
52479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param animation The animation, cannot be null
52489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
524964a48c1d3daca9e0565f2aa4d56f6e94ea073d9bChet Haase    void finishAnimatingView(final View view, Animation animation) {
52509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final ArrayList<View> disappearingChildren = mDisappearingChildren;
52519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (disappearingChildren != null) {
52529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (disappearingChildren.contains(view)) {
52539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                disappearingChildren.remove(view);
52549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
52559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (view.mAttachInfo != null) {
52569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    view.dispatchDetachedFromWindow();
52579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
52589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
52599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                view.clearAnimation();
52609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mGroupFlags |= FLAG_INVALIDATE_REQUIRED;
52619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
52629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
52639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
52649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (animation != null && !animation.getFillAfter()) {
52659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            view.clearAnimation();
52669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
52679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
52684702a856973a553deb82f71b1d3b6c3db5dbf4baDianne Hackborn        if ((view.mPrivateFlags & PFLAG_ANIMATION_STARTED) == PFLAG_ANIMATION_STARTED) {
52699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            view.onAnimationEnd();
52709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // Should be performed by onAnimationEnd() but this avoid an infinite loop,
52719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // so we'd rather be safe than sorry
52724702a856973a553deb82f71b1d3b6c3db5dbf4baDianne Hackborn            view.mPrivateFlags &= ~PFLAG_ANIMATION_STARTED;
52739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // Draw one more frame after the animation is done
52749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mGroupFlags |= FLAG_INVALIDATE_REQUIRED;
52759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
52769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
52779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5278b20db3ec34e846010f389880b2cfab4d7bf79820Chet Haase    /**
5279aceafe63eeb7d3bfc05ef5ab0b3957572d61ecf5Chet Haase     * Utility function called by View during invalidation to determine whether a view that
5280aceafe63eeb7d3bfc05ef5ab0b3957572d61ecf5Chet Haase     * is invisible or gone should still be invalidated because it is being transitioned (and
5281aceafe63eeb7d3bfc05ef5ab0b3957572d61ecf5Chet Haase     * therefore still needs to be drawn).
5282aceafe63eeb7d3bfc05ef5ab0b3957572d61ecf5Chet Haase     */
5283aceafe63eeb7d3bfc05ef5ab0b3957572d61ecf5Chet Haase    boolean isViewTransitioning(View view) {
5284aceafe63eeb7d3bfc05ef5ab0b3957572d61ecf5Chet Haase        return (mTransitioningViews != null && mTransitioningViews.contains(view));
5285aceafe63eeb7d3bfc05ef5ab0b3957572d61ecf5Chet Haase    }
5286aceafe63eeb7d3bfc05ef5ab0b3957572d61ecf5Chet Haase
5287aceafe63eeb7d3bfc05ef5ab0b3957572d61ecf5Chet Haase    /**
5288b20db3ec34e846010f389880b2cfab4d7bf79820Chet Haase     * This method tells the ViewGroup that the given View object, which should have this
5289b20db3ec34e846010f389880b2cfab4d7bf79820Chet Haase     * ViewGroup as its parent,
5290b20db3ec34e846010f389880b2cfab4d7bf79820Chet Haase     * should be kept around  (re-displayed when the ViewGroup draws its children) even if it
5291b20db3ec34e846010f389880b2cfab4d7bf79820Chet Haase     * is removed from its parent. This allows animations, such as those used by
5292b20db3ec34e846010f389880b2cfab4d7bf79820Chet Haase     * {@link android.app.Fragment} and {@link android.animation.LayoutTransition} to animate
5293b20db3ec34e846010f389880b2cfab4d7bf79820Chet Haase     * the removal of views. A call to this method should always be accompanied by a later call
5294b20db3ec34e846010f389880b2cfab4d7bf79820Chet Haase     * to {@link #endViewTransition(View)}, such as after an animation on the View has finished,
5295b20db3ec34e846010f389880b2cfab4d7bf79820Chet Haase     * so that the View finally gets removed.
5296b20db3ec34e846010f389880b2cfab4d7bf79820Chet Haase     *
5297b20db3ec34e846010f389880b2cfab4d7bf79820Chet Haase     * @param view The View object to be kept visible even if it gets removed from its parent.
5298b20db3ec34e846010f389880b2cfab4d7bf79820Chet Haase     */
5299b20db3ec34e846010f389880b2cfab4d7bf79820Chet Haase    public void startViewTransition(View view) {
5300b20db3ec34e846010f389880b2cfab4d7bf79820Chet Haase        if (view.mParent == this) {
5301b20db3ec34e846010f389880b2cfab4d7bf79820Chet Haase            if (mTransitioningViews == null) {
5302b20db3ec34e846010f389880b2cfab4d7bf79820Chet Haase                mTransitioningViews = new ArrayList<View>();
5303b20db3ec34e846010f389880b2cfab4d7bf79820Chet Haase            }
5304b20db3ec34e846010f389880b2cfab4d7bf79820Chet Haase            mTransitioningViews.add(view);
5305b20db3ec34e846010f389880b2cfab4d7bf79820Chet Haase        }
5306b20db3ec34e846010f389880b2cfab4d7bf79820Chet Haase    }
5307b20db3ec34e846010f389880b2cfab4d7bf79820Chet Haase
5308b20db3ec34e846010f389880b2cfab4d7bf79820Chet Haase    /**
5309b20db3ec34e846010f389880b2cfab4d7bf79820Chet Haase     * This method should always be called following an earlier call to
5310b20db3ec34e846010f389880b2cfab4d7bf79820Chet Haase     * {@link #startViewTransition(View)}. The given View is finally removed from its parent
5311b20db3ec34e846010f389880b2cfab4d7bf79820Chet Haase     * and will no longer be displayed. Note that this method does not perform the functionality
5312b20db3ec34e846010f389880b2cfab4d7bf79820Chet Haase     * of removing a view from its parent; it just discontinues the display of a View that
5313b20db3ec34e846010f389880b2cfab4d7bf79820Chet Haase     * has previously been removed.
5314b20db3ec34e846010f389880b2cfab4d7bf79820Chet Haase     *
5315b20db3ec34e846010f389880b2cfab4d7bf79820Chet Haase     * @return view The View object that has been removed but is being kept around in the visible
5316b20db3ec34e846010f389880b2cfab4d7bf79820Chet Haase     * hierarchy by an earlier call to {@link #startViewTransition(View)}.
5317b20db3ec34e846010f389880b2cfab4d7bf79820Chet Haase     */
5318b20db3ec34e846010f389880b2cfab4d7bf79820Chet Haase    public void endViewTransition(View view) {
5319b20db3ec34e846010f389880b2cfab4d7bf79820Chet Haase        if (mTransitioningViews != null) {
5320b20db3ec34e846010f389880b2cfab4d7bf79820Chet Haase            mTransitioningViews.remove(view);
5321b20db3ec34e846010f389880b2cfab4d7bf79820Chet Haase            final ArrayList<View> disappearingChildren = mDisappearingChildren;
5322b20db3ec34e846010f389880b2cfab4d7bf79820Chet Haase            if (disappearingChildren != null && disappearingChildren.contains(view)) {
5323b20db3ec34e846010f389880b2cfab4d7bf79820Chet Haase                disappearingChildren.remove(view);
53245e25c2c14593caee5638603120553ae1ec530f85Chet Haase                if (mVisibilityChangingChildren != null &&
53255e25c2c14593caee5638603120553ae1ec530f85Chet Haase                        mVisibilityChangingChildren.contains(view)) {
53265e25c2c14593caee5638603120553ae1ec530f85Chet Haase                    mVisibilityChangingChildren.remove(view);
53275e25c2c14593caee5638603120553ae1ec530f85Chet Haase                } else {
53285e25c2c14593caee5638603120553ae1ec530f85Chet Haase                    if (view.mAttachInfo != null) {
53295e25c2c14593caee5638603120553ae1ec530f85Chet Haase                        view.dispatchDetachedFromWindow();
53305e25c2c14593caee5638603120553ae1ec530f85Chet Haase                    }
53315e25c2c14593caee5638603120553ae1ec530f85Chet Haase                    if (view.mParent != null) {
53325e25c2c14593caee5638603120553ae1ec530f85Chet Haase                        view.mParent = null;
53335e25c2c14593caee5638603120553ae1ec530f85Chet Haase                    }
5334b20db3ec34e846010f389880b2cfab4d7bf79820Chet Haase                }
5335b85967b9af76e1e60f7a96603e2567a6449d2e04Chet Haase                invalidate();
5336b20db3ec34e846010f389880b2cfab4d7bf79820Chet Haase            }
5337b20db3ec34e846010f389880b2cfab4d7bf79820Chet Haase        }
5338b20db3ec34e846010f389880b2cfab4d7bf79820Chet Haase    }
5339b20db3ec34e846010f389880b2cfab4d7bf79820Chet Haase
534021cd1389d2ef218b20994b617c57af120841a57fChet Haase    private LayoutTransition.TransitionListener mLayoutTransitionListener =
534121cd1389d2ef218b20994b617c57af120841a57fChet Haase            new LayoutTransition.TransitionListener() {
534221cd1389d2ef218b20994b617c57af120841a57fChet Haase        @Override
534321cd1389d2ef218b20994b617c57af120841a57fChet Haase        public void startTransition(LayoutTransition transition, ViewGroup container,
534421cd1389d2ef218b20994b617c57af120841a57fChet Haase                View view, int transitionType) {
534521cd1389d2ef218b20994b617c57af120841a57fChet Haase            // We only care about disappearing items, since we need special logic to keep
534621cd1389d2ef218b20994b617c57af120841a57fChet Haase            // those items visible after they've been 'removed'
534721cd1389d2ef218b20994b617c57af120841a57fChet Haase            if (transitionType == LayoutTransition.DISAPPEARING) {
5348b20db3ec34e846010f389880b2cfab4d7bf79820Chet Haase                startViewTransition(view);
534921cd1389d2ef218b20994b617c57af120841a57fChet Haase            }
535021cd1389d2ef218b20994b617c57af120841a57fChet Haase        }
535121cd1389d2ef218b20994b617c57af120841a57fChet Haase
535221cd1389d2ef218b20994b617c57af120841a57fChet Haase        @Override
535321cd1389d2ef218b20994b617c57af120841a57fChet Haase        public void endTransition(LayoutTransition transition, ViewGroup container,
535421cd1389d2ef218b20994b617c57af120841a57fChet Haase                View view, int transitionType) {
5355b989502e5cf44d65c6dddc0179b6d9b6e61ef7fdChet Haase            if (mLayoutCalledWhileSuppressed && !transition.isChangingLayout()) {
53569c0874408cfc6f6f4e4561973ca5ae52a5982db7Chet Haase                requestLayout();
5357b989502e5cf44d65c6dddc0179b6d9b6e61ef7fdChet Haase                mLayoutCalledWhileSuppressed = false;
53589c0874408cfc6f6f4e4561973ca5ae52a5982db7Chet Haase            }
535921cd1389d2ef218b20994b617c57af120841a57fChet Haase            if (transitionType == LayoutTransition.DISAPPEARING && mTransitioningViews != null) {
5360b20db3ec34e846010f389880b2cfab4d7bf79820Chet Haase                endViewTransition(view);
536121cd1389d2ef218b20994b617c57af120841a57fChet Haase            }
536221cd1389d2ef218b20994b617c57af120841a57fChet Haase        }
536321cd1389d2ef218b20994b617c57af120841a57fChet Haase    };
536421cd1389d2ef218b20994b617c57af120841a57fChet Haase
53659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
5366b989502e5cf44d65c6dddc0179b6d9b6e61ef7fdChet Haase     * Tells this ViewGroup to suppress all layout() calls until layout
5367b989502e5cf44d65c6dddc0179b6d9b6e61ef7fdChet Haase     * suppression is disabled with a later call to suppressLayout(false).
5368b989502e5cf44d65c6dddc0179b6d9b6e61ef7fdChet Haase     * When layout suppression is disabled, a requestLayout() call is sent
5369b989502e5cf44d65c6dddc0179b6d9b6e61ef7fdChet Haase     * if layout() was attempted while layout was being suppressed.
5370b989502e5cf44d65c6dddc0179b6d9b6e61ef7fdChet Haase     *
5371b989502e5cf44d65c6dddc0179b6d9b6e61ef7fdChet Haase     * @hide
5372b989502e5cf44d65c6dddc0179b6d9b6e61ef7fdChet Haase     */
5373b989502e5cf44d65c6dddc0179b6d9b6e61ef7fdChet Haase    public void suppressLayout(boolean suppress) {
5374b989502e5cf44d65c6dddc0179b6d9b6e61ef7fdChet Haase        mSuppressLayout = suppress;
5375b989502e5cf44d65c6dddc0179b6d9b6e61ef7fdChet Haase        if (!suppress) {
5376b989502e5cf44d65c6dddc0179b6d9b6e61ef7fdChet Haase            if (mLayoutCalledWhileSuppressed) {
5377b989502e5cf44d65c6dddc0179b6d9b6e61ef7fdChet Haase                requestLayout();
5378b989502e5cf44d65c6dddc0179b6d9b6e61ef7fdChet Haase                mLayoutCalledWhileSuppressed = false;
5379b989502e5cf44d65c6dddc0179b6d9b6e61ef7fdChet Haase            }
5380b989502e5cf44d65c6dddc0179b6d9b6e61ef7fdChet Haase        }
5381b989502e5cf44d65c6dddc0179b6d9b6e61ef7fdChet Haase    }
5382b989502e5cf44d65c6dddc0179b6d9b6e61ef7fdChet Haase
5383b989502e5cf44d65c6dddc0179b6d9b6e61ef7fdChet Haase    /**
5384199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase     * Returns whether layout calls on this container are currently being
5385199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase     * suppressed, due to an earlier call to {@link #suppressLayout(boolean)}.
5386199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase     *
5387199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase     * @return true if layout calls are currently suppressed, false otherwise.
5388199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase     *
5389199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase     * @hide
5390199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase     */
5391199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase    public boolean isLayoutSuppressed() {
5392199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase        return mSuppressLayout;
5393199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase    }
5394199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase
5395199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase    /**
53969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@inheritDoc}
53979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
53989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
53999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean gatherTransparentRegion(Region region) {
54009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // If no transparent regions requested, we are always opaque.
54014702a856973a553deb82f71b1d3b6c3db5dbf4baDianne Hackborn        final boolean meOpaque = (mPrivateFlags & View.PFLAG_REQUEST_TRANSPARENT_REGIONS) == 0;
54029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (meOpaque && region == null) {
54039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // The caller doesn't care about the region, so stop now.
54049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return true;
54059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
54069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        super.gatherTransparentRegion(region);
54079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final View[] children = mChildren;
54089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final int count = mChildrenCount;
54099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        boolean noneOfTheChildrenAreTransparent = true;
54109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (int i = 0; i < count; i++) {
54119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            final View child = children[i];
5412e33811512eb061338792dbb0dbd37a1b8e4e1079Mathias Agopian            if ((child.mViewFlags & VISIBILITY_MASK) == VISIBLE || child.getAnimation() != null) {
54139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (!child.gatherTransparentRegion(region)) {
54149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    noneOfTheChildrenAreTransparent = false;
54159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
54169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
54179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
54189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return meOpaque || noneOfTheChildrenAreTransparent;
54199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
54209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
54219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
54229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@inheritDoc}
54239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
54249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void requestTransparentRegion(View child) {
54259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (child != null) {
54264702a856973a553deb82f71b1d3b6c3db5dbf4baDianne Hackborn            child.mPrivateFlags |= View.PFLAG_REQUEST_TRANSPARENT_REGIONS;
54279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (mParent != null) {
54289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mParent.requestTransparentRegion(this);
54299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
54309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
54319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
54328506ab4ac062d0e1ccde136e5e2f4081560e0c11Romain Guy
54339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
54349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
54359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected boolean fitSystemWindows(Rect insets) {
54369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        boolean done = super.fitSystemWindows(insets);
54379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (!done) {
54389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            final int count = mChildrenCount;
54399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            final View[] children = mChildren;
54409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            for (int i = 0; i < count; i++) {
54419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                done = children[i].fitSystemWindows(insets);
54429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (done) {
54439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    break;
54449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
54459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
54469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
54479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return done;
54489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
54499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
54509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
54519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Returns the animation listener to which layout animation events are
54529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * sent.
54539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
54549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return an {@link android.view.animation.Animation.AnimationListener}
54559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
54569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public Animation.AnimationListener getLayoutAnimationListener() {
54579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mAnimationListener;
54589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
54599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
54609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
54619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected void drawableStateChanged() {
54629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        super.drawableStateChanged();
54639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
54649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if ((mGroupFlags & FLAG_NOTIFY_CHILDREN_ON_DRAWABLE_STATE_CHANGE) != 0) {
54659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if ((mGroupFlags & FLAG_ADD_STATES_FROM_CHILDREN) != 0) {
54669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                throw new IllegalStateException("addStateFromChildren cannot be enabled if a"
54679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        + " child has duplicateParentState set to true");
54689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
54699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
54709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            final View[] children = mChildren;
54719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            final int count = mChildrenCount;
54729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
54739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            for (int i = 0; i < count; i++) {
54749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                final View child = children[i];
54759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if ((child.mViewFlags & DUPLICATE_PARENT_STATE) != 0) {
54769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    child.refreshDrawableState();
54779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
54789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
54799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
54809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
54819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
54829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
5483e213677037f836529efcc0ac201fc61dd95481c5Dianne Hackborn    public void jumpDrawablesToCurrentState() {
5484e213677037f836529efcc0ac201fc61dd95481c5Dianne Hackborn        super.jumpDrawablesToCurrentState();
5485e213677037f836529efcc0ac201fc61dd95481c5Dianne Hackborn        final View[] children = mChildren;
5486e213677037f836529efcc0ac201fc61dd95481c5Dianne Hackborn        final int count = mChildrenCount;
5487e213677037f836529efcc0ac201fc61dd95481c5Dianne Hackborn        for (int i = 0; i < count; i++) {
5488e213677037f836529efcc0ac201fc61dd95481c5Dianne Hackborn            children[i].jumpDrawablesToCurrentState();
5489e213677037f836529efcc0ac201fc61dd95481c5Dianne Hackborn        }
5490e213677037f836529efcc0ac201fc61dd95481c5Dianne Hackborn    }
5491e213677037f836529efcc0ac201fc61dd95481c5Dianne Hackborn
5492e213677037f836529efcc0ac201fc61dd95481c5Dianne Hackborn    @Override
54939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected int[] onCreateDrawableState(int extraSpace) {
54949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if ((mGroupFlags & FLAG_ADD_STATES_FROM_CHILDREN) == 0) {
54959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return super.onCreateDrawableState(extraSpace);
54969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
54979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
54989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int need = 0;
54999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int n = getChildCount();
55009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (int i = 0; i < n; i++) {
55019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            int[] childState = getChildAt(i).getDrawableState();
55029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
55039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (childState != null) {
55049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                need += childState.length;
55059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
55069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
55079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
55089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int[] state = super.onCreateDrawableState(extraSpace + need);
55099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
55109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (int i = 0; i < n; i++) {
55119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            int[] childState = getChildAt(i).getDrawableState();
55129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
55139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (childState != null) {
55149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                state = mergeDrawableStates(state, childState);
55159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
55169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
55179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
55189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return state;
55199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
55209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
55219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
55229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Sets whether this ViewGroup's drawable states also include
55239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * its children's drawable states.  This is used, for example, to
55249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * make a group appear to be focused when its child EditText or button
55259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * is focused.
55269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
55279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setAddStatesFromChildren(boolean addsStates) {
55289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (addsStates) {
55299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mGroupFlags |= FLAG_ADD_STATES_FROM_CHILDREN;
55309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
55319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mGroupFlags &= ~FLAG_ADD_STATES_FROM_CHILDREN;
55329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
55339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
55349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        refreshDrawableState();
55359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
55369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
55379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
55389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Returns whether this ViewGroup's drawable states also include
55399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * its children's drawable states.  This is used, for example, to
55409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * make a group appear to be focused when its child EditText or button
55419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * is focused.
55429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
55439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean addStatesFromChildren() {
55449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return (mGroupFlags & FLAG_ADD_STATES_FROM_CHILDREN) != 0;
55459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
55469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
55479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
5548a45746efadd11bb7dfab026fb3c81a25fae74ca4Jeff Smith     * If {@link #addStatesFromChildren} is true, refreshes this group's
55499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * drawable state (to include the states from its children).
55509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
55519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void childDrawableStateChanged(View child) {
55529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if ((mGroupFlags & FLAG_ADD_STATES_FROM_CHILDREN) != 0) {
55539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            refreshDrawableState();
55549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
55559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
55569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
55579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
55589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Specifies the animation listener to which layout animation events must
55599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * be sent. Only
55609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@link android.view.animation.Animation.AnimationListener#onAnimationStart(Animation)}
55619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * and
55629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@link android.view.animation.Animation.AnimationListener#onAnimationEnd(Animation)}
55639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * are invoked.
55649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
55659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param animationListener the layout animation listener
55669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
55679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setLayoutAnimationListener(Animation.AnimationListener animationListener) {
55689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mAnimationListener = animationListener;
55699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
55709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
55719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
5572cca2c9807206f320bd41bf8656a227e4f249e4baChet Haase     * This method is called by LayoutTransition when there are 'changing' animations that need
5573cca2c9807206f320bd41bf8656a227e4f249e4baChet Haase     * to start after the layout/setup phase. The request is forwarded to the ViewAncestor, who
5574cca2c9807206f320bd41bf8656a227e4f249e4baChet Haase     * starts all pending transitions prior to the drawing phase in the current traversal.
5575cca2c9807206f320bd41bf8656a227e4f249e4baChet Haase     *
5576cca2c9807206f320bd41bf8656a227e4f249e4baChet Haase     * @param transition The LayoutTransition to be started on the next traversal.
5577cca2c9807206f320bd41bf8656a227e4f249e4baChet Haase     *
5578cca2c9807206f320bd41bf8656a227e4f249e4baChet Haase     * @hide
5579cca2c9807206f320bd41bf8656a227e4f249e4baChet Haase     */
5580cca2c9807206f320bd41bf8656a227e4f249e4baChet Haase    public void requestTransitionStart(LayoutTransition transition) {
55816dd005b48138708762bfade0081d031a2a4a3822Dianne Hackborn        ViewRootImpl viewAncestor = getViewRootImpl();
55821abf7fa1d1930e24739cae9874970420101bc2f9Chet Haase        if (viewAncestor != null) {
55831abf7fa1d1930e24739cae9874970420101bc2f9Chet Haase            viewAncestor.requestTransitionStart(transition);
55841abf7fa1d1930e24739cae9874970420101bc2f9Chet Haase        }
5585cca2c9807206f320bd41bf8656a227e4f249e4baChet Haase    }
5586cca2c9807206f320bd41bf8656a227e4f249e4baChet Haase
55874457e85a7090ad51726d50a4daf981d917cceeddFabrice Di Meglio    /**
55884457e85a7090ad51726d50a4daf981d917cceeddFabrice Di Meglio     * @hide
55894457e85a7090ad51726d50a4daf981d917cceeddFabrice Di Meglio     */
559080dc53d652b060d4dea7d70e9a5aa3b8321bcf8dFabrice Di Meglio    @Override
559109ecb255a6d37567c8ce43dcd01bfb7ed7488a5dFabrice Di Meglio    public boolean resolveRtlPropertiesIfNeeded() {
559209ecb255a6d37567c8ce43dcd01bfb7ed7488a5dFabrice Di Meglio        final boolean result = super.resolveRtlPropertiesIfNeeded();
559309ecb255a6d37567c8ce43dcd01bfb7ed7488a5dFabrice Di Meglio        // We dont need to resolve the children RTL properties if nothing has changed for the parent
559409ecb255a6d37567c8ce43dcd01bfb7ed7488a5dFabrice Di Meglio        if (result) {
559509ecb255a6d37567c8ce43dcd01bfb7ed7488a5dFabrice Di Meglio            int count = getChildCount();
559609ecb255a6d37567c8ce43dcd01bfb7ed7488a5dFabrice Di Meglio            for (int i = 0; i < count; i++) {
559709ecb255a6d37567c8ce43dcd01bfb7ed7488a5dFabrice Di Meglio                final View child = getChildAt(i);
559809ecb255a6d37567c8ce43dcd01bfb7ed7488a5dFabrice Di Meglio                if (child.isLayoutDirectionInherited()) {
559909ecb255a6d37567c8ce43dcd01bfb7ed7488a5dFabrice Di Meglio                    child.resolveRtlPropertiesIfNeeded();
560009ecb255a6d37567c8ce43dcd01bfb7ed7488a5dFabrice Di Meglio                }
560184ebb35f392478600ddf8f08107fb345f13ef91cFabrice Di Meglio            }
560284ebb35f392478600ddf8f08107fb345f13ef91cFabrice Di Meglio        }
560309ecb255a6d37567c8ce43dcd01bfb7ed7488a5dFabrice Di Meglio        return result;
560484ebb35f392478600ddf8f08107fb345f13ef91cFabrice Di Meglio    }
560584ebb35f392478600ddf8f08107fb345f13ef91cFabrice Di Meglio
560684ebb35f392478600ddf8f08107fb345f13ef91cFabrice Di Meglio    /**
560784ebb35f392478600ddf8f08107fb345f13ef91cFabrice Di Meglio     * @hide
560884ebb35f392478600ddf8f08107fb345f13ef91cFabrice Di Meglio     */
560984ebb35f392478600ddf8f08107fb345f13ef91cFabrice Di Meglio    @Override
56109a04856d5ecb07dea564feae2942fd485b53f3ddFabrice Di Meglio    public boolean resolveLayoutDirection() {
56119a04856d5ecb07dea564feae2942fd485b53f3ddFabrice Di Meglio        final boolean result = super.resolveLayoutDirection();
56129a04856d5ecb07dea564feae2942fd485b53f3ddFabrice Di Meglio        if (result) {
56139a04856d5ecb07dea564feae2942fd485b53f3ddFabrice Di Meglio            int count = getChildCount();
56149a04856d5ecb07dea564feae2942fd485b53f3ddFabrice Di Meglio            for (int i = 0; i < count; i++) {
56159a04856d5ecb07dea564feae2942fd485b53f3ddFabrice Di Meglio                final View child = getChildAt(i);
56169a04856d5ecb07dea564feae2942fd485b53f3ddFabrice Di Meglio                if (child.isLayoutDirectionInherited()) {
56179a04856d5ecb07dea564feae2942fd485b53f3ddFabrice Di Meglio                    child.resolveLayoutDirection();
56189a04856d5ecb07dea564feae2942fd485b53f3ddFabrice Di Meglio                }
56191f88ba8bf67bb9264e39547ab1201aa3c5395d0eFabrice Di Meglio            }
56201f88ba8bf67bb9264e39547ab1201aa3c5395d0eFabrice Di Meglio        }
56219a04856d5ecb07dea564feae2942fd485b53f3ddFabrice Di Meglio        return result;
56221f88ba8bf67bb9264e39547ab1201aa3c5395d0eFabrice Di Meglio    }
56231f88ba8bf67bb9264e39547ab1201aa3c5395d0eFabrice Di Meglio
56241f88ba8bf67bb9264e39547ab1201aa3c5395d0eFabrice Di Meglio    /**
56251f88ba8bf67bb9264e39547ab1201aa3c5395d0eFabrice Di Meglio     * @hide
56261f88ba8bf67bb9264e39547ab1201aa3c5395d0eFabrice Di Meglio     */
56271f88ba8bf67bb9264e39547ab1201aa3c5395d0eFabrice Di Meglio    @Override
56289a04856d5ecb07dea564feae2942fd485b53f3ddFabrice Di Meglio    public boolean resolveTextDirection() {
56299a04856d5ecb07dea564feae2942fd485b53f3ddFabrice Di Meglio        final boolean result = super.resolveTextDirection();
56309a04856d5ecb07dea564feae2942fd485b53f3ddFabrice Di Meglio        if (result) {
56319a04856d5ecb07dea564feae2942fd485b53f3ddFabrice Di Meglio            int count = getChildCount();
56329a04856d5ecb07dea564feae2942fd485b53f3ddFabrice Di Meglio            for (int i = 0; i < count; i++) {
56339a04856d5ecb07dea564feae2942fd485b53f3ddFabrice Di Meglio                final View child = getChildAt(i);
56349a04856d5ecb07dea564feae2942fd485b53f3ddFabrice Di Meglio                if (child.isTextDirectionInherited()) {
56359a04856d5ecb07dea564feae2942fd485b53f3ddFabrice Di Meglio                    child.resolveTextDirection();
56369a04856d5ecb07dea564feae2942fd485b53f3ddFabrice Di Meglio                }
56371f88ba8bf67bb9264e39547ab1201aa3c5395d0eFabrice Di Meglio            }
56381f88ba8bf67bb9264e39547ab1201aa3c5395d0eFabrice Di Meglio        }
56399a04856d5ecb07dea564feae2942fd485b53f3ddFabrice Di Meglio        return result;
56401f88ba8bf67bb9264e39547ab1201aa3c5395d0eFabrice Di Meglio    }
56411f88ba8bf67bb9264e39547ab1201aa3c5395d0eFabrice Di Meglio
56421f88ba8bf67bb9264e39547ab1201aa3c5395d0eFabrice Di Meglio    /**
56431f88ba8bf67bb9264e39547ab1201aa3c5395d0eFabrice Di Meglio     * @hide
56441f88ba8bf67bb9264e39547ab1201aa3c5395d0eFabrice Di Meglio     */
56451f88ba8bf67bb9264e39547ab1201aa3c5395d0eFabrice Di Meglio    @Override
56469a04856d5ecb07dea564feae2942fd485b53f3ddFabrice Di Meglio    public boolean resolveTextAlignment() {
56479a04856d5ecb07dea564feae2942fd485b53f3ddFabrice Di Meglio        final boolean result = super.resolveTextAlignment();
56489a04856d5ecb07dea564feae2942fd485b53f3ddFabrice Di Meglio        if (result) {
56499a04856d5ecb07dea564feae2942fd485b53f3ddFabrice Di Meglio            int count = getChildCount();
56509a04856d5ecb07dea564feae2942fd485b53f3ddFabrice Di Meglio            for (int i = 0; i < count; i++) {
56519a04856d5ecb07dea564feae2942fd485b53f3ddFabrice Di Meglio                final View child = getChildAt(i);
56529a04856d5ecb07dea564feae2942fd485b53f3ddFabrice Di Meglio                if (child.isTextAlignmentInherited()) {
56539a04856d5ecb07dea564feae2942fd485b53f3ddFabrice Di Meglio                    child.resolveTextAlignment();
56549a04856d5ecb07dea564feae2942fd485b53f3ddFabrice Di Meglio                }
56551f88ba8bf67bb9264e39547ab1201aa3c5395d0eFabrice Di Meglio            }
56561f88ba8bf67bb9264e39547ab1201aa3c5395d0eFabrice Di Meglio        }
56579a04856d5ecb07dea564feae2942fd485b53f3ddFabrice Di Meglio        return result;
56581f88ba8bf67bb9264e39547ab1201aa3c5395d0eFabrice Di Meglio    }
56591f88ba8bf67bb9264e39547ab1201aa3c5395d0eFabrice Di Meglio
56601f88ba8bf67bb9264e39547ab1201aa3c5395d0eFabrice Di Meglio    /**
56611f88ba8bf67bb9264e39547ab1201aa3c5395d0eFabrice Di Meglio     * @hide
56621f88ba8bf67bb9264e39547ab1201aa3c5395d0eFabrice Di Meglio     */
56631f88ba8bf67bb9264e39547ab1201aa3c5395d0eFabrice Di Meglio    @Override
566484ebb35f392478600ddf8f08107fb345f13ef91cFabrice Di Meglio    public void resolvePadding() {
566584ebb35f392478600ddf8f08107fb345f13ef91cFabrice Di Meglio        super.resolvePadding();
566684ebb35f392478600ddf8f08107fb345f13ef91cFabrice Di Meglio        int count = getChildCount();
566784ebb35f392478600ddf8f08107fb345f13ef91cFabrice Di Meglio        for (int i = 0; i < count; i++) {
566884ebb35f392478600ddf8f08107fb345f13ef91cFabrice Di Meglio            final View child = getChildAt(i);
566984ebb35f392478600ddf8f08107fb345f13ef91cFabrice Di Meglio            if (child.isLayoutDirectionInherited()) {
567084ebb35f392478600ddf8f08107fb345f13ef91cFabrice Di Meglio                child.resolvePadding();
567184ebb35f392478600ddf8f08107fb345f13ef91cFabrice Di Meglio            }
567284ebb35f392478600ddf8f08107fb345f13ef91cFabrice Di Meglio        }
567384ebb35f392478600ddf8f08107fb345f13ef91cFabrice Di Meglio    }
567484ebb35f392478600ddf8f08107fb345f13ef91cFabrice Di Meglio
567584ebb35f392478600ddf8f08107fb345f13ef91cFabrice Di Meglio    /**
567684ebb35f392478600ddf8f08107fb345f13ef91cFabrice Di Meglio     * @hide
567784ebb35f392478600ddf8f08107fb345f13ef91cFabrice Di Meglio     */
567884ebb35f392478600ddf8f08107fb345f13ef91cFabrice Di Meglio    @Override
567984ebb35f392478600ddf8f08107fb345f13ef91cFabrice Di Meglio    protected void resolveDrawables() {
568084ebb35f392478600ddf8f08107fb345f13ef91cFabrice Di Meglio        super.resolveDrawables();
568184ebb35f392478600ddf8f08107fb345f13ef91cFabrice Di Meglio        int count = getChildCount();
568284ebb35f392478600ddf8f08107fb345f13ef91cFabrice Di Meglio        for (int i = 0; i < count; i++) {
568384ebb35f392478600ddf8f08107fb345f13ef91cFabrice Di Meglio            final View child = getChildAt(i);
568484ebb35f392478600ddf8f08107fb345f13ef91cFabrice Di Meglio            if (child.isLayoutDirectionInherited()) {
568584ebb35f392478600ddf8f08107fb345f13ef91cFabrice Di Meglio                child.resolveDrawables();
568684ebb35f392478600ddf8f08107fb345f13ef91cFabrice Di Meglio            }
568784ebb35f392478600ddf8f08107fb345f13ef91cFabrice Di Meglio        }
568884ebb35f392478600ddf8f08107fb345f13ef91cFabrice Di Meglio    }
568984ebb35f392478600ddf8f08107fb345f13ef91cFabrice Di Meglio
56901e0ed6b2320893efdecdf300a9adf1dce3700710Fabrice Di Meglio    /**
56911e0ed6b2320893efdecdf300a9adf1dce3700710Fabrice Di Meglio     * @hide
56921e0ed6b2320893efdecdf300a9adf1dce3700710Fabrice Di Meglio     */
5693fcc3348f61b2992f0b84e8e8dcb3535fc715298fFabrice Di Meglio    @Override
5694fcc3348f61b2992f0b84e8e8dcb3535fc715298fFabrice Di Meglio    public void resolveLayoutParams() {
5695fcc3348f61b2992f0b84e8e8dcb3535fc715298fFabrice Di Meglio        super.resolveLayoutParams();
5696fcc3348f61b2992f0b84e8e8dcb3535fc715298fFabrice Di Meglio        int count = getChildCount();
5697fcc3348f61b2992f0b84e8e8dcb3535fc715298fFabrice Di Meglio        for (int i = 0; i < count; i++) {
5698fcc3348f61b2992f0b84e8e8dcb3535fc715298fFabrice Di Meglio            final View child = getChildAt(i);
5699fcc3348f61b2992f0b84e8e8dcb3535fc715298fFabrice Di Meglio            child.resolveLayoutParams();
5700fcc3348f61b2992f0b84e8e8dcb3535fc715298fFabrice Di Meglio        }
5701fcc3348f61b2992f0b84e8e8dcb3535fc715298fFabrice Di Meglio    }
5702fcc3348f61b2992f0b84e8e8dcb3535fc715298fFabrice Di Meglio
570384ebb35f392478600ddf8f08107fb345f13ef91cFabrice Di Meglio    /**
570484ebb35f392478600ddf8f08107fb345f13ef91cFabrice Di Meglio     * @hide
570584ebb35f392478600ddf8f08107fb345f13ef91cFabrice Di Meglio     */
570684ebb35f392478600ddf8f08107fb345f13ef91cFabrice Di Meglio    @Override
57074457e85a7090ad51726d50a4daf981d917cceeddFabrice Di Meglio    public void resetResolvedLayoutDirection() {
57084457e85a7090ad51726d50a4daf981d917cceeddFabrice Di Meglio        super.resetResolvedLayoutDirection();
57094457e85a7090ad51726d50a4daf981d917cceeddFabrice Di Meglio
57104457e85a7090ad51726d50a4daf981d917cceeddFabrice Di Meglio        int count = getChildCount();
571180dc53d652b060d4dea7d70e9a5aa3b8321bcf8dFabrice Di Meglio        for (int i = 0; i < count; i++) {
571280dc53d652b060d4dea7d70e9a5aa3b8321bcf8dFabrice Di Meglio            final View child = getChildAt(i);
5713e56ffdc7b31b0937628609cc3bbaa15879023569Fabrice Di Meglio            if (child.isLayoutDirectionInherited()) {
57147f86c806ada21fc7a3feefd89d6fcb4282b0af40Fabrice Di Meglio                child.resetResolvedLayoutDirection();
571580dc53d652b060d4dea7d70e9a5aa3b8321bcf8dFabrice Di Meglio            }
57161f88ba8bf67bb9264e39547ab1201aa3c5395d0eFabrice Di Meglio        }
57171f88ba8bf67bb9264e39547ab1201aa3c5395d0eFabrice Di Meglio    }
57181f88ba8bf67bb9264e39547ab1201aa3c5395d0eFabrice Di Meglio
57191f88ba8bf67bb9264e39547ab1201aa3c5395d0eFabrice Di Meglio    /**
57201f88ba8bf67bb9264e39547ab1201aa3c5395d0eFabrice Di Meglio     * @hide
57211f88ba8bf67bb9264e39547ab1201aa3c5395d0eFabrice Di Meglio     */
57221f88ba8bf67bb9264e39547ab1201aa3c5395d0eFabrice Di Meglio    @Override
57231f88ba8bf67bb9264e39547ab1201aa3c5395d0eFabrice Di Meglio    public void resetResolvedTextDirection() {
57241f88ba8bf67bb9264e39547ab1201aa3c5395d0eFabrice Di Meglio        super.resetResolvedTextDirection();
57251f88ba8bf67bb9264e39547ab1201aa3c5395d0eFabrice Di Meglio
57261f88ba8bf67bb9264e39547ab1201aa3c5395d0eFabrice Di Meglio        int count = getChildCount();
57271f88ba8bf67bb9264e39547ab1201aa3c5395d0eFabrice Di Meglio        for (int i = 0; i < count; i++) {
57281f88ba8bf67bb9264e39547ab1201aa3c5395d0eFabrice Di Meglio            final View child = getChildAt(i);
572997e146cf02f87b91f81c37d53644e5415efddb72Fabrice Di Meglio            if (child.isTextDirectionInherited()) {
5730222688682e6e072076489d8203d01bdf2366101aFabrice Di Meglio                child.resetResolvedTextDirection();
5731222688682e6e072076489d8203d01bdf2366101aFabrice Di Meglio            }
57321f88ba8bf67bb9264e39547ab1201aa3c5395d0eFabrice Di Meglio        }
57331f88ba8bf67bb9264e39547ab1201aa3c5395d0eFabrice Di Meglio    }
57341f88ba8bf67bb9264e39547ab1201aa3c5395d0eFabrice Di Meglio
57351f88ba8bf67bb9264e39547ab1201aa3c5395d0eFabrice Di Meglio    /**
57361f88ba8bf67bb9264e39547ab1201aa3c5395d0eFabrice Di Meglio     * @hide
57371f88ba8bf67bb9264e39547ab1201aa3c5395d0eFabrice Di Meglio     */
57381f88ba8bf67bb9264e39547ab1201aa3c5395d0eFabrice Di Meglio    @Override
57391f88ba8bf67bb9264e39547ab1201aa3c5395d0eFabrice Di Meglio    public void resetResolvedTextAlignment() {
57401f88ba8bf67bb9264e39547ab1201aa3c5395d0eFabrice Di Meglio        super.resetResolvedTextAlignment();
57411f88ba8bf67bb9264e39547ab1201aa3c5395d0eFabrice Di Meglio
57421f88ba8bf67bb9264e39547ab1201aa3c5395d0eFabrice Di Meglio        int count = getChildCount();
57431f88ba8bf67bb9264e39547ab1201aa3c5395d0eFabrice Di Meglio        for (int i = 0; i < count; i++) {
57441f88ba8bf67bb9264e39547ab1201aa3c5395d0eFabrice Di Meglio            final View child = getChildAt(i);
57451a7d487380460b4aea37140baf6bf4bf7f92f8a5Fabrice Di Meglio            if (child.isTextAlignmentInherited()) {
57469da0f8a5c4bccf8e722ae2ebf43873457aec3271Fabrice Di Meglio                child.resetResolvedTextAlignment();
57479da0f8a5c4bccf8e722ae2ebf43873457aec3271Fabrice Di Meglio            }
57489da0f8a5c4bccf8e722ae2ebf43873457aec3271Fabrice Di Meglio        }
57499da0f8a5c4bccf8e722ae2ebf43873457aec3271Fabrice Di Meglio    }
57509da0f8a5c4bccf8e722ae2ebf43873457aec3271Fabrice Di Meglio
5751222688682e6e072076489d8203d01bdf2366101aFabrice Di Meglio    /**
575284ebb35f392478600ddf8f08107fb345f13ef91cFabrice Di Meglio     * @hide
575384ebb35f392478600ddf8f08107fb345f13ef91cFabrice Di Meglio     */
575484ebb35f392478600ddf8f08107fb345f13ef91cFabrice Di Meglio    @Override
575584ebb35f392478600ddf8f08107fb345f13ef91cFabrice Di Meglio    public void resetResolvedPadding() {
575684ebb35f392478600ddf8f08107fb345f13ef91cFabrice Di Meglio        super.resetResolvedPadding();
575784ebb35f392478600ddf8f08107fb345f13ef91cFabrice Di Meglio
575884ebb35f392478600ddf8f08107fb345f13ef91cFabrice Di Meglio        int count = getChildCount();
575984ebb35f392478600ddf8f08107fb345f13ef91cFabrice Di Meglio        for (int i = 0; i < count; i++) {
576084ebb35f392478600ddf8f08107fb345f13ef91cFabrice Di Meglio            final View child = getChildAt(i);
576184ebb35f392478600ddf8f08107fb345f13ef91cFabrice Di Meglio            if (child.isLayoutDirectionInherited()) {
576284ebb35f392478600ddf8f08107fb345f13ef91cFabrice Di Meglio                child.resetResolvedPadding();
576384ebb35f392478600ddf8f08107fb345f13ef91cFabrice Di Meglio            }
576484ebb35f392478600ddf8f08107fb345f13ef91cFabrice Di Meglio        }
576584ebb35f392478600ddf8f08107fb345f13ef91cFabrice Di Meglio    }
576684ebb35f392478600ddf8f08107fb345f13ef91cFabrice Di Meglio
576784ebb35f392478600ddf8f08107fb345f13ef91cFabrice Di Meglio    /**
576884ebb35f392478600ddf8f08107fb345f13ef91cFabrice Di Meglio     * @hide
576984ebb35f392478600ddf8f08107fb345f13ef91cFabrice Di Meglio     */
577084ebb35f392478600ddf8f08107fb345f13ef91cFabrice Di Meglio    @Override
577184ebb35f392478600ddf8f08107fb345f13ef91cFabrice Di Meglio    protected void resetResolvedDrawables() {
577284ebb35f392478600ddf8f08107fb345f13ef91cFabrice Di Meglio        super.resetResolvedDrawables();
577384ebb35f392478600ddf8f08107fb345f13ef91cFabrice Di Meglio
577484ebb35f392478600ddf8f08107fb345f13ef91cFabrice Di Meglio        int count = getChildCount();
577584ebb35f392478600ddf8f08107fb345f13ef91cFabrice Di Meglio        for (int i = 0; i < count; i++) {
577684ebb35f392478600ddf8f08107fb345f13ef91cFabrice Di Meglio            final View child = getChildAt(i);
577784ebb35f392478600ddf8f08107fb345f13ef91cFabrice Di Meglio            if (child.isLayoutDirectionInherited()) {
577884ebb35f392478600ddf8f08107fb345f13ef91cFabrice Di Meglio                child.resetResolvedDrawables();
577984ebb35f392478600ddf8f08107fb345f13ef91cFabrice Di Meglio            }
578084ebb35f392478600ddf8f08107fb345f13ef91cFabrice Di Meglio        }
578184ebb35f392478600ddf8f08107fb345f13ef91cFabrice Di Meglio    }
578284ebb35f392478600ddf8f08107fb345f13ef91cFabrice Di Meglio
578384ebb35f392478600ddf8f08107fb345f13ef91cFabrice Di Meglio    /**
5784e0a799a2ac1ca78e30fbac9e4e12a063425c08d3Patrick Dubroy     * Return true if the pressed state should be delayed for children or descendants of this
5785e0a799a2ac1ca78e30fbac9e4e12a063425c08d3Patrick Dubroy     * ViewGroup. Generally, this should be done for containers that can scroll, such as a List.
5786e0a799a2ac1ca78e30fbac9e4e12a063425c08d3Patrick Dubroy     * This prevents the pressed state from appearing when the user is actually trying to scroll
5787e0a799a2ac1ca78e30fbac9e4e12a063425c08d3Patrick Dubroy     * the content.
5788e0a799a2ac1ca78e30fbac9e4e12a063425c08d3Patrick Dubroy     *
5789e0a799a2ac1ca78e30fbac9e4e12a063425c08d3Patrick Dubroy     * The default implementation returns true for compatibility reasons. Subclasses that do
5790e0a799a2ac1ca78e30fbac9e4e12a063425c08d3Patrick Dubroy     * not scroll should generally override this method and return false.
5791e0a799a2ac1ca78e30fbac9e4e12a063425c08d3Patrick Dubroy     */
5792e0a799a2ac1ca78e30fbac9e4e12a063425c08d3Patrick Dubroy    public boolean shouldDelayChildPressedState() {
5793e0a799a2ac1ca78e30fbac9e4e12a063425c08d3Patrick Dubroy        return true;
5794e0a799a2ac1ca78e30fbac9e4e12a063425c08d3Patrick Dubroy    }
5795e0a799a2ac1ca78e30fbac9e4e12a063425c08d3Patrick Dubroy
5796d7dd89095ff2041f0793317c4ee8e8be49388148Philip Milne    /** @hide */
5797d7dd89095ff2041f0793317c4ee8e8be49388148Philip Milne    protected void onSetLayoutParams(View child, LayoutParams layoutParams) {
5798d7dd89095ff2041f0793317c4ee8e8be49388148Philip Milne    }
5799d7dd89095ff2041f0793317c4ee8e8be49388148Philip Milne
5800e0a799a2ac1ca78e30fbac9e4e12a063425c08d3Patrick Dubroy    /**
58019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * LayoutParams are used by views to tell their parents how they want to be
58029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * laid out. See
58039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@link android.R.styleable#ViewGroup_Layout ViewGroup Layout Attributes}
58049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * for a list of all child view attributes that this class supports.
58058506ab4ac062d0e1ccde136e5e2f4081560e0c11Romain Guy     *
58069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>
58079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * The base LayoutParams class just describes how big the view wants to be
58089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * for both width and height. For each dimension, it can specify one of:
58099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <ul>
581075c66da20927e7e854397c00ef1974140270c57fDirk Dougherty     * <li>FILL_PARENT (renamed MATCH_PARENT in API Level 8 and higher), which
581175c66da20927e7e854397c00ef1974140270c57fDirk Dougherty     * means that the view wants to be as big as its parent (minus padding)
58129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <li> WRAP_CONTENT, which means that the view wants to be just big enough
58139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * to enclose its content (plus padding)
581475c66da20927e7e854397c00ef1974140270c57fDirk Dougherty     * <li> an exact number
58159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * </ul>
58169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * There are subclasses of LayoutParams for different subclasses of
58179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * ViewGroup. For example, AbsoluteLayout has its own subclass of
5818558459fe85f56f29a6ed6a4d0adb4a0bd6665884Joe Fernandez     * LayoutParams which adds an X and Y value.</p>
5819558459fe85f56f29a6ed6a4d0adb4a0bd6665884Joe Fernandez     *
5820558459fe85f56f29a6ed6a4d0adb4a0bd6665884Joe Fernandez     * <div class="special reference">
5821558459fe85f56f29a6ed6a4d0adb4a0bd6665884Joe Fernandez     * <h3>Developer Guides</h3>
5822558459fe85f56f29a6ed6a4d0adb4a0bd6665884Joe Fernandez     * <p>For more information about creating user interface layouts, read the
5823558459fe85f56f29a6ed6a4d0adb4a0bd6665884Joe Fernandez     * <a href="{@docRoot}guide/topics/ui/declaring-layout.html">XML Layouts</a> developer
5824558459fe85f56f29a6ed6a4d0adb4a0bd6665884Joe Fernandez     * guide.</p></div>
58259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
58269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @attr ref android.R.styleable#ViewGroup_Layout_layout_height
58279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @attr ref android.R.styleable#ViewGroup_Layout_layout_width
58289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
58299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static class LayoutParams {
58309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /**
583175c66da20927e7e854397c00ef1974140270c57fDirk Dougherty         * Special value for the height or width requested by a View.
583275c66da20927e7e854397c00ef1974140270c57fDirk Dougherty         * FILL_PARENT means that the view wants to be as big as its parent,
583375c66da20927e7e854397c00ef1974140270c57fDirk Dougherty         * minus the parent's padding, if any. This value is deprecated
583475c66da20927e7e854397c00ef1974140270c57fDirk Dougherty         * starting in API Level 8 and replaced by {@link #MATCH_PARENT}.
58359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
5836980a938c1c9a6a5791a8240e5a1e6638ab28dc77Romain Guy        @SuppressWarnings({"UnusedDeclaration"})
5837980a938c1c9a6a5791a8240e5a1e6638ab28dc77Romain Guy        @Deprecated
58389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public static final int FILL_PARENT = -1;
58399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
58409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /**
58419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * Special value for the height or width requested by a View.
5842f5c6eff63d19a9f7a970a4f90619edac873c006dGilles Debunne         * MATCH_PARENT means that the view wants to be as big as its parent,
584375c66da20927e7e854397c00ef1974140270c57fDirk Dougherty         * minus the parent's padding, if any. Introduced in API Level 8.
5844980a938c1c9a6a5791a8240e5a1e6638ab28dc77Romain Guy         */
5845980a938c1c9a6a5791a8240e5a1e6638ab28dc77Romain Guy        public static final int MATCH_PARENT = -1;
5846980a938c1c9a6a5791a8240e5a1e6638ab28dc77Romain Guy
5847980a938c1c9a6a5791a8240e5a1e6638ab28dc77Romain Guy        /**
5848980a938c1c9a6a5791a8240e5a1e6638ab28dc77Romain Guy         * Special value for the height or width requested by a View.
58499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * WRAP_CONTENT means that the view wants to be just large enough to fit
58509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * its own internal content, taking its own padding into account.
58519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
58529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public static final int WRAP_CONTENT = -2;
58539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
58549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /**
585575c66da20927e7e854397c00ef1974140270c57fDirk Dougherty         * Information about how wide the view wants to be. Can be one of the
585675c66da20927e7e854397c00ef1974140270c57fDirk Dougherty         * constants FILL_PARENT (replaced by MATCH_PARENT ,
585775c66da20927e7e854397c00ef1974140270c57fDirk Dougherty         * in API Level 8) or WRAP_CONTENT. or an exact size.
58589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
5859bea95162ca25bd00b0479d93739b6283795c3986Konstantin Lopyrev        @ViewDebug.ExportedProperty(category = "layout", mapping = {
5860980a938c1c9a6a5791a8240e5a1e6638ab28dc77Romain Guy            @ViewDebug.IntToString(from = MATCH_PARENT, to = "MATCH_PARENT"),
58619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            @ViewDebug.IntToString(from = WRAP_CONTENT, to = "WRAP_CONTENT")
58629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        })
58639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public int width;
58649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
58659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /**
586675c66da20927e7e854397c00ef1974140270c57fDirk Dougherty         * Information about how tall the view wants to be. Can be one of the
586775c66da20927e7e854397c00ef1974140270c57fDirk Dougherty         * constants FILL_PARENT (replaced by MATCH_PARENT ,
586875c66da20927e7e854397c00ef1974140270c57fDirk Dougherty         * in API Level 8) or WRAP_CONTENT. or an exact size.
58699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
5870bea95162ca25bd00b0479d93739b6283795c3986Konstantin Lopyrev        @ViewDebug.ExportedProperty(category = "layout", mapping = {
5871980a938c1c9a6a5791a8240e5a1e6638ab28dc77Romain Guy            @ViewDebug.IntToString(from = MATCH_PARENT, to = "MATCH_PARENT"),
58729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            @ViewDebug.IntToString(from = WRAP_CONTENT, to = "WRAP_CONTENT")
58739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        })
58749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public int height;
58759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
58769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /**
58779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * Used to animate layouts.
58789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
58799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public LayoutAnimationController.AnimationParameters layoutAnimationParameters;
58809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
58819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /**
58829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * Creates a new set of layout parameters. The values are extracted from
58839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * the supplied attributes set and context. The XML attributes mapped
58849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * to this set of layout parameters are:
58859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         *
58869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * <ul>
58879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         *   <li><code>layout_width</code>: the width, either an exact value,
588875c66da20927e7e854397c00ef1974140270c57fDirk Dougherty         *   {@link #WRAP_CONTENT}, or {@link #FILL_PARENT} (replaced by
588975c66da20927e7e854397c00ef1974140270c57fDirk Dougherty         *   {@link #MATCH_PARENT} in API Level 8)</li>
58909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         *   <li><code>layout_height</code>: the height, either an exact value,
589175c66da20927e7e854397c00ef1974140270c57fDirk Dougherty         *   {@link #WRAP_CONTENT}, or {@link #FILL_PARENT} (replaced by
589275c66da20927e7e854397c00ef1974140270c57fDirk Dougherty         *   {@link #MATCH_PARENT} in API Level 8)</li>
58939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * </ul>
58949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         *
58959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * @param c the application environment
58969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * @param attrs the set of attributes from which to extract the layout
58979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         *              parameters' values
58989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
58999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public LayoutParams(Context c, AttributeSet attrs) {
59009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            TypedArray a = c.obtainStyledAttributes(attrs, R.styleable.ViewGroup_Layout);
59019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            setBaseAttributes(a,
59029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    R.styleable.ViewGroup_Layout_layout_width,
59039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    R.styleable.ViewGroup_Layout_layout_height);
59049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            a.recycle();
59059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
59069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
59079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /**
59089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * Creates a new set of layout parameters with the specified width
59099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * and height.
59109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         *
591175c66da20927e7e854397c00ef1974140270c57fDirk Dougherty         * @param width the width, either {@link #WRAP_CONTENT},
591275c66da20927e7e854397c00ef1974140270c57fDirk Dougherty         *        {@link #FILL_PARENT} (replaced by {@link #MATCH_PARENT} in
591375c66da20927e7e854397c00ef1974140270c57fDirk Dougherty         *        API Level 8), or a fixed size in pixels
591475c66da20927e7e854397c00ef1974140270c57fDirk Dougherty         * @param height the height, either {@link #WRAP_CONTENT},
591575c66da20927e7e854397c00ef1974140270c57fDirk Dougherty         *        {@link #FILL_PARENT} (replaced by {@link #MATCH_PARENT} in
591675c66da20927e7e854397c00ef1974140270c57fDirk Dougherty         *        API Level 8), or a fixed size in pixels
59179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
59189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public LayoutParams(int width, int height) {
59199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            this.width = width;
59209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            this.height = height;
59219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
59229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
59239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /**
59249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * Copy constructor. Clones the width and height values of the source.
59259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         *
59269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * @param source The layout params to copy from.
59279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
59289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public LayoutParams(LayoutParams source) {
59299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            this.width = source.width;
59309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            this.height = source.height;
59319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
59329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
59339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /**
59349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * Used internally by MarginLayoutParams.
59359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * @hide
59369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
59379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        LayoutParams() {
59389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
59399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
59409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /**
5941579e14016c4a972e70cd2bd0c6d89bbd7e9e941cDave Burke         * Extracts the layout parameters from the supplied attributes.
59429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         *
59439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * @param a the style attributes to extract the parameters from
59449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * @param widthAttr the identifier of the width attribute
59459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * @param heightAttr the identifier of the height attribute
59469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
59479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        protected void setBaseAttributes(TypedArray a, int widthAttr, int heightAttr) {
5948579e14016c4a972e70cd2bd0c6d89bbd7e9e941cDave Burke            width = a.getLayoutDimension(widthAttr, "layout_width");
5949579e14016c4a972e70cd2bd0c6d89bbd7e9e941cDave Burke            height = a.getLayoutDimension(heightAttr, "layout_height");
59509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
59519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
59529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /**
5953b76023afd192a1f5c81a8965cfd1b9dde2558726Fabrice Di Meglio         * Resolve layout parameters depending on the layout direction. Subclasses that care about
5954b76023afd192a1f5c81a8965cfd1b9dde2558726Fabrice Di Meglio         * layoutDirection changes should override this method. The default implementation does
5955b76023afd192a1f5c81a8965cfd1b9dde2558726Fabrice Di Meglio         * nothing.
5956b76023afd192a1f5c81a8965cfd1b9dde2558726Fabrice Di Meglio         *
5957b76023afd192a1f5c81a8965cfd1b9dde2558726Fabrice Di Meglio         * @param layoutDirection the direction of the layout
5958b76023afd192a1f5c81a8965cfd1b9dde2558726Fabrice Di Meglio         *
5959b76023afd192a1f5c81a8965cfd1b9dde2558726Fabrice Di Meglio         * {@link View#LAYOUT_DIRECTION_LTR}
5960b76023afd192a1f5c81a8965cfd1b9dde2558726Fabrice Di Meglio         * {@link View#LAYOUT_DIRECTION_RTL}
5961b76023afd192a1f5c81a8965cfd1b9dde2558726Fabrice Di Meglio         */
59622918ab6c3258639148b8a5c78a34483af195246eFabrice Di Meglio        public void resolveLayoutDirection(int layoutDirection) {
5963b76023afd192a1f5c81a8965cfd1b9dde2558726Fabrice Di Meglio        }
5964b76023afd192a1f5c81a8965cfd1b9dde2558726Fabrice Di Meglio
5965b76023afd192a1f5c81a8965cfd1b9dde2558726Fabrice Di Meglio        /**
59669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * Returns a String representation of this set of layout parameters.
59679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         *
59689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * @param output the String to prepend to the internal representation
59699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * @return a String with the following format: output +
59709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         *         "ViewGroup.LayoutParams={ width=WIDTH, height=HEIGHT }"
59718506ab4ac062d0e1ccde136e5e2f4081560e0c11Romain Guy         *
59729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * @hide
59739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
59749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public String debug(String output) {
59759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return output + "ViewGroup.LayoutParams={ width="
59769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    + sizeToString(width) + ", height=" + sizeToString(height) + " }";
59779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
59789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
59799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /**
598010ca24a97cefc14fca1b26f59e627f487b3b108bPhilip Milne         * Use {@code canvas} to draw suitable debugging annotations for these LayoutParameters.
598110ca24a97cefc14fca1b26f59e627f487b3b108bPhilip Milne         *
598210ca24a97cefc14fca1b26f59e627f487b3b108bPhilip Milne         * @param view the view that contains these layout parameters
598310ca24a97cefc14fca1b26f59e627f487b3b108bPhilip Milne         * @param canvas the canvas on which to draw
598410ca24a97cefc14fca1b26f59e627f487b3b108bPhilip Milne         *
598510ca24a97cefc14fca1b26f59e627f487b3b108bPhilip Milne         * @hide
598610ca24a97cefc14fca1b26f59e627f487b3b108bPhilip Milne         */
59877b7578184567f4e4f0740ce935cc192765410ccaPhilip Milne        public void onDebugDraw(View view, Canvas canvas, Paint paint) {
598810ca24a97cefc14fca1b26f59e627f487b3b108bPhilip Milne        }
598910ca24a97cefc14fca1b26f59e627f487b3b108bPhilip Milne
599010ca24a97cefc14fca1b26f59e627f487b3b108bPhilip Milne        /**
59919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * Converts the specified size to a readable String.
59929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         *
59939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * @param size the size to convert
59949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * @return a String instance representing the supplied size
59958506ab4ac062d0e1ccde136e5e2f4081560e0c11Romain Guy         *
59969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * @hide
59979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
59989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        protected static String sizeToString(int size) {
59999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (size == WRAP_CONTENT) {
60009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return "wrap-content";
60019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
6002980a938c1c9a6a5791a8240e5a1e6638ab28dc77Romain Guy            if (size == MATCH_PARENT) {
6003980a938c1c9a6a5791a8240e5a1e6638ab28dc77Romain Guy                return "match-parent";
60049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
60059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return String.valueOf(size);
60069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
60079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
60089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
60099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
60109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Per-child layout information for layouts that support margins.
60119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * See
60129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@link android.R.styleable#ViewGroup_MarginLayout ViewGroup Margin Layout Attributes}
60139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * for a list of all child view attributes that this class supports.
60149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
60159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static class MarginLayoutParams extends ViewGroup.LayoutParams {
60169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /**
6017d7dd89095ff2041f0793317c4ee8e8be49388148Philip Milne         * The left margin in pixels of the child.
6018d7dd89095ff2041f0793317c4ee8e8be49388148Philip Milne         * Call {@link ViewGroup#setLayoutParams(LayoutParams)} after reassigning a new value
6019d7dd89095ff2041f0793317c4ee8e8be49388148Philip Milne         * to this field.
60209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
6021bea95162ca25bd00b0479d93739b6283795c3986Konstantin Lopyrev        @ViewDebug.ExportedProperty(category = "layout")
60229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public int leftMargin;
60239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
60249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /**
6025d7dd89095ff2041f0793317c4ee8e8be49388148Philip Milne         * The top margin in pixels of the child.
6026d7dd89095ff2041f0793317c4ee8e8be49388148Philip Milne         * Call {@link ViewGroup#setLayoutParams(LayoutParams)} after reassigning a new value
6027d7dd89095ff2041f0793317c4ee8e8be49388148Philip Milne         * to this field.
60289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
6029bea95162ca25bd00b0479d93739b6283795c3986Konstantin Lopyrev        @ViewDebug.ExportedProperty(category = "layout")
60309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public int topMargin;
60319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
60329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /**
6033d7dd89095ff2041f0793317c4ee8e8be49388148Philip Milne         * The right margin in pixels of the child.
6034d7dd89095ff2041f0793317c4ee8e8be49388148Philip Milne         * Call {@link ViewGroup#setLayoutParams(LayoutParams)} after reassigning a new value
6035d7dd89095ff2041f0793317c4ee8e8be49388148Philip Milne         * to this field.
60369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
6037bea95162ca25bd00b0479d93739b6283795c3986Konstantin Lopyrev        @ViewDebug.ExportedProperty(category = "layout")
60389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public int rightMargin;
60399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
60409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /**
6041d7dd89095ff2041f0793317c4ee8e8be49388148Philip Milne         * The bottom margin in pixels of the child.
6042d7dd89095ff2041f0793317c4ee8e8be49388148Philip Milne         * Call {@link ViewGroup#setLayoutParams(LayoutParams)} after reassigning a new value
6043d7dd89095ff2041f0793317c4ee8e8be49388148Philip Milne         * to this field.
60449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
6045bea95162ca25bd00b0479d93739b6283795c3986Konstantin Lopyrev        @ViewDebug.ExportedProperty(category = "layout")
60469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public int bottomMargin;
60479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
60489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /**
6049b76023afd192a1f5c81a8965cfd1b9dde2558726Fabrice Di Meglio         * The start margin in pixels of the child.
605054546f22fbec63f8c12e56fa7109706a1bbc4e7bFabrice Di Meglio         * Call {@link ViewGroup#setLayoutParams(LayoutParams)} after reassigning a new value
605154546f22fbec63f8c12e56fa7109706a1bbc4e7bFabrice Di Meglio         * to this field.
6052b76023afd192a1f5c81a8965cfd1b9dde2558726Fabrice Di Meglio         */
6053b76023afd192a1f5c81a8965cfd1b9dde2558726Fabrice Di Meglio        @ViewDebug.ExportedProperty(category = "layout")
60540072f64939b37a4d84940656c2180ad2e0594ff4Fabrice Di Meglio        private int startMargin = DEFAULT_MARGIN_RELATIVE;
6055b76023afd192a1f5c81a8965cfd1b9dde2558726Fabrice Di Meglio
6056b76023afd192a1f5c81a8965cfd1b9dde2558726Fabrice Di Meglio        /**
6057b76023afd192a1f5c81a8965cfd1b9dde2558726Fabrice Di Meglio         * The end margin in pixels of the child.
605854546f22fbec63f8c12e56fa7109706a1bbc4e7bFabrice Di Meglio         * Call {@link ViewGroup#setLayoutParams(LayoutParams)} after reassigning a new value
605954546f22fbec63f8c12e56fa7109706a1bbc4e7bFabrice Di Meglio         * to this field.
6060b76023afd192a1f5c81a8965cfd1b9dde2558726Fabrice Di Meglio         */
6061b76023afd192a1f5c81a8965cfd1b9dde2558726Fabrice Di Meglio        @ViewDebug.ExportedProperty(category = "layout")
60620072f64939b37a4d84940656c2180ad2e0594ff4Fabrice Di Meglio        private int endMargin = DEFAULT_MARGIN_RELATIVE;
6063b76023afd192a1f5c81a8965cfd1b9dde2558726Fabrice Di Meglio
6064b76023afd192a1f5c81a8965cfd1b9dde2558726Fabrice Di Meglio        /**
6065b76023afd192a1f5c81a8965cfd1b9dde2558726Fabrice Di Meglio         * The default start and end margin.
6066f443f98e7f41badd8f5d6f7bf7d26432e79a88edFabrice Di Meglio         * @hide
6067b76023afd192a1f5c81a8965cfd1b9dde2558726Fabrice Di Meglio         */
60680072f64939b37a4d84940656c2180ad2e0594ff4Fabrice Di Meglio        public static final int DEFAULT_MARGIN_RELATIVE = Integer.MIN_VALUE;
6069b76023afd192a1f5c81a8965cfd1b9dde2558726Fabrice Di Meglio
6070b365f91688dc081b3bcea82377ce0e94c09124ffFabrice Di Meglio        /**
6071b365f91688dc081b3bcea82377ce0e94c09124ffFabrice Di Meglio         * Bit  0: layout direction
6072b365f91688dc081b3bcea82377ce0e94c09124ffFabrice Di Meglio         * Bit  1: layout direction
6073b365f91688dc081b3bcea82377ce0e94c09124ffFabrice Di Meglio         * Bit  2: left margin undefined
6074b365f91688dc081b3bcea82377ce0e94c09124ffFabrice Di Meglio         * Bit  3: right margin undefined
6075b365f91688dc081b3bcea82377ce0e94c09124ffFabrice Di Meglio         * Bit  4: is RTL compatibility mode
6076b365f91688dc081b3bcea82377ce0e94c09124ffFabrice Di Meglio         * Bit  5: need resolution
6077b365f91688dc081b3bcea82377ce0e94c09124ffFabrice Di Meglio         *
6078b365f91688dc081b3bcea82377ce0e94c09124ffFabrice Di Meglio         * Bit 6 to 7 not used
6079b365f91688dc081b3bcea82377ce0e94c09124ffFabrice Di Meglio         *
6080b365f91688dc081b3bcea82377ce0e94c09124ffFabrice Di Meglio         * @hide
6081b365f91688dc081b3bcea82377ce0e94c09124ffFabrice Di Meglio         */
6082b365f91688dc081b3bcea82377ce0e94c09124ffFabrice Di Meglio        @ViewDebug.ExportedProperty(category = "layout", flagMapping = {
6083b365f91688dc081b3bcea82377ce0e94c09124ffFabrice Di Meglio                @ViewDebug.FlagToString(mask = LAYOUT_DIRECTION_MASK,
6084b365f91688dc081b3bcea82377ce0e94c09124ffFabrice Di Meglio                        equals = LAYOUT_DIRECTION_MASK, name = "LAYOUT_DIRECTION"),
6085b365f91688dc081b3bcea82377ce0e94c09124ffFabrice Di Meglio                @ViewDebug.FlagToString(mask = LEFT_MARGIN_UNDEFINED_MASK,
6086b365f91688dc081b3bcea82377ce0e94c09124ffFabrice Di Meglio                        equals = LEFT_MARGIN_UNDEFINED_MASK, name = "LEFT_MARGIN_UNDEFINED_MASK"),
6087b365f91688dc081b3bcea82377ce0e94c09124ffFabrice Di Meglio                @ViewDebug.FlagToString(mask = RIGHT_MARGIN_UNDEFINED_MASK,
6088b365f91688dc081b3bcea82377ce0e94c09124ffFabrice Di Meglio                        equals = RIGHT_MARGIN_UNDEFINED_MASK, name = "RIGHT_MARGIN_UNDEFINED_MASK"),
6089b365f91688dc081b3bcea82377ce0e94c09124ffFabrice Di Meglio                @ViewDebug.FlagToString(mask = RTL_COMPATIBILITY_MODE_MASK,
6090b365f91688dc081b3bcea82377ce0e94c09124ffFabrice Di Meglio                        equals = RTL_COMPATIBILITY_MODE_MASK, name = "RTL_COMPATIBILITY_MODE_MASK"),
6091b365f91688dc081b3bcea82377ce0e94c09124ffFabrice Di Meglio                @ViewDebug.FlagToString(mask = NEED_RESOLUTION_MASK,
6092b365f91688dc081b3bcea82377ce0e94c09124ffFabrice Di Meglio                        equals = NEED_RESOLUTION_MASK, name = "NEED_RESOLUTION_MASK")
6093b365f91688dc081b3bcea82377ce0e94c09124ffFabrice Di Meglio        })
6094b365f91688dc081b3bcea82377ce0e94c09124ffFabrice Di Meglio        byte mMarginFlags;
609569bd55844b2b2b78a0ff43e5123954cab3693ea6Fabrice Di Meglio
6096b365f91688dc081b3bcea82377ce0e94c09124ffFabrice Di Meglio        private static final int LAYOUT_DIRECTION_MASK = 0x00000003;
6097b365f91688dc081b3bcea82377ce0e94c09124ffFabrice Di Meglio        private static final int LEFT_MARGIN_UNDEFINED_MASK = 0x00000004;
6098b365f91688dc081b3bcea82377ce0e94c09124ffFabrice Di Meglio        private static final int RIGHT_MARGIN_UNDEFINED_MASK = 0x00000008;
6099b365f91688dc081b3bcea82377ce0e94c09124ffFabrice Di Meglio        private static final int RTL_COMPATIBILITY_MODE_MASK = 0x00000010;
6100b365f91688dc081b3bcea82377ce0e94c09124ffFabrice Di Meglio        private static final int NEED_RESOLUTION_MASK = 0x00000020;
610102a7d5637c961632dc67cd0012addfdd6060885bFabrice Di Meglio
6102b365f91688dc081b3bcea82377ce0e94c09124ffFabrice Di Meglio        private static final int DEFAULT_MARGIN_RESOLVED = 0;
6103b365f91688dc081b3bcea82377ce0e94c09124ffFabrice Di Meglio        private static final int UNDEFINED_MARGIN = DEFAULT_MARGIN_RELATIVE;
610402a7d5637c961632dc67cd0012addfdd6060885bFabrice Di Meglio
6105b76023afd192a1f5c81a8965cfd1b9dde2558726Fabrice Di Meglio        /**
61069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * Creates a new set of layout parameters. The values are extracted from
61079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * the supplied attributes set and context.
61089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         *
61099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * @param c the application environment
61109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * @param attrs the set of attributes from which to extract the layout
61119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         *              parameters' values
61129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
61139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public MarginLayoutParams(Context c, AttributeSet attrs) {
61149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            super();
61159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
61169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            TypedArray a = c.obtainStyledAttributes(attrs, R.styleable.ViewGroup_MarginLayout);
61179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            setBaseAttributes(a,
61189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    R.styleable.ViewGroup_MarginLayout_layout_width,
61199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    R.styleable.ViewGroup_MarginLayout_layout_height);
61209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
61219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            int margin = a.getDimensionPixelSize(
61229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    com.android.internal.R.styleable.ViewGroup_MarginLayout_layout_margin, -1);
61239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (margin >= 0) {
61249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                leftMargin = margin;
61259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                topMargin = margin;
61269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                rightMargin= margin;
61279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                bottomMargin = margin;
61289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else {
61299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                leftMargin = a.getDimensionPixelSize(
61300072f64939b37a4d84940656c2180ad2e0594ff4Fabrice Di Meglio                        R.styleable.ViewGroup_MarginLayout_layout_marginLeft,
613102a7d5637c961632dc67cd0012addfdd6060885bFabrice Di Meglio                        UNDEFINED_MARGIN);
613202a7d5637c961632dc67cd0012addfdd6060885bFabrice Di Meglio                if (leftMargin == UNDEFINED_MARGIN) {
6133b365f91688dc081b3bcea82377ce0e94c09124ffFabrice Di Meglio                    mMarginFlags |= LEFT_MARGIN_UNDEFINED_MASK;
613402a7d5637c961632dc67cd0012addfdd6060885bFabrice Di Meglio                    leftMargin = DEFAULT_MARGIN_RESOLVED;
613502a7d5637c961632dc67cd0012addfdd6060885bFabrice Di Meglio                }
61369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                rightMargin = a.getDimensionPixelSize(
61370072f64939b37a4d84940656c2180ad2e0594ff4Fabrice Di Meglio                        R.styleable.ViewGroup_MarginLayout_layout_marginRight,
613802a7d5637c961632dc67cd0012addfdd6060885bFabrice Di Meglio                        UNDEFINED_MARGIN);
613902a7d5637c961632dc67cd0012addfdd6060885bFabrice Di Meglio                if (rightMargin == UNDEFINED_MARGIN) {
6140b365f91688dc081b3bcea82377ce0e94c09124ffFabrice Di Meglio                    mMarginFlags |= RIGHT_MARGIN_UNDEFINED_MASK;
614102a7d5637c961632dc67cd0012addfdd6060885bFabrice Di Meglio                    rightMargin = DEFAULT_MARGIN_RESOLVED;
614202a7d5637c961632dc67cd0012addfdd6060885bFabrice Di Meglio                }
614302a7d5637c961632dc67cd0012addfdd6060885bFabrice Di Meglio
614402a7d5637c961632dc67cd0012addfdd6060885bFabrice Di Meglio                topMargin = a.getDimensionPixelSize(
614502a7d5637c961632dc67cd0012addfdd6060885bFabrice Di Meglio                        R.styleable.ViewGroup_MarginLayout_layout_marginTop,
61460072f64939b37a4d84940656c2180ad2e0594ff4Fabrice Di Meglio                        DEFAULT_MARGIN_RESOLVED);
61479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                bottomMargin = a.getDimensionPixelSize(
61480072f64939b37a4d84940656c2180ad2e0594ff4Fabrice Di Meglio                        R.styleable.ViewGroup_MarginLayout_layout_marginBottom,
61490072f64939b37a4d84940656c2180ad2e0594ff4Fabrice Di Meglio                        DEFAULT_MARGIN_RESOLVED);
615002a7d5637c961632dc67cd0012addfdd6060885bFabrice Di Meglio
6151b76023afd192a1f5c81a8965cfd1b9dde2558726Fabrice Di Meglio                startMargin = a.getDimensionPixelSize(
61520072f64939b37a4d84940656c2180ad2e0594ff4Fabrice Di Meglio                        R.styleable.ViewGroup_MarginLayout_layout_marginStart,
61530072f64939b37a4d84940656c2180ad2e0594ff4Fabrice Di Meglio                        DEFAULT_MARGIN_RELATIVE);
6154b76023afd192a1f5c81a8965cfd1b9dde2558726Fabrice Di Meglio                endMargin = a.getDimensionPixelSize(
61550072f64939b37a4d84940656c2180ad2e0594ff4Fabrice Di Meglio                        R.styleable.ViewGroup_MarginLayout_layout_marginEnd,
61560072f64939b37a4d84940656c2180ad2e0594ff4Fabrice Di Meglio                        DEFAULT_MARGIN_RELATIVE);
61570072f64939b37a4d84940656c2180ad2e0594ff4Fabrice Di Meglio
6158b365f91688dc081b3bcea82377ce0e94c09124ffFabrice Di Meglio                if (isMarginRelative()) {
6159b365f91688dc081b3bcea82377ce0e94c09124ffFabrice Di Meglio                   mMarginFlags |= NEED_RESOLUTION_MASK;
6160b365f91688dc081b3bcea82377ce0e94c09124ffFabrice Di Meglio                }
61619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
61629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
61630072f64939b37a4d84940656c2180ad2e0594ff4Fabrice Di Meglio            final boolean hasRtlSupport = c.getApplicationInfo().hasRtlSupport();
61640072f64939b37a4d84940656c2180ad2e0594ff4Fabrice Di Meglio            final int targetSdkVersion = c.getApplicationInfo().targetSdkVersion;
6165b365f91688dc081b3bcea82377ce0e94c09124ffFabrice Di Meglio            if (targetSdkVersion < JELLY_BEAN_MR1 || !hasRtlSupport) {
6166b365f91688dc081b3bcea82377ce0e94c09124ffFabrice Di Meglio                mMarginFlags |= RTL_COMPATIBILITY_MODE_MASK;
6167b365f91688dc081b3bcea82377ce0e94c09124ffFabrice Di Meglio            }
6168b365f91688dc081b3bcea82377ce0e94c09124ffFabrice Di Meglio
6169b365f91688dc081b3bcea82377ce0e94c09124ffFabrice Di Meglio            // Layout direction is LTR by default
6170b365f91688dc081b3bcea82377ce0e94c09124ffFabrice Di Meglio            mMarginFlags |= LAYOUT_DIRECTION_LTR;
617169bd55844b2b2b78a0ff43e5123954cab3693ea6Fabrice Di Meglio
61729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            a.recycle();
61739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
61749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
61759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /**
61769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * {@inheritDoc}
61779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
61789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public MarginLayoutParams(int width, int height) {
61799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            super(width, height);
61800072f64939b37a4d84940656c2180ad2e0594ff4Fabrice Di Meglio
6181b365f91688dc081b3bcea82377ce0e94c09124ffFabrice Di Meglio            mMarginFlags |= LEFT_MARGIN_UNDEFINED_MASK;
6182b365f91688dc081b3bcea82377ce0e94c09124ffFabrice Di Meglio            mMarginFlags |= RIGHT_MARGIN_UNDEFINED_MASK;
618302a7d5637c961632dc67cd0012addfdd6060885bFabrice Di Meglio
6184b365f91688dc081b3bcea82377ce0e94c09124ffFabrice Di Meglio            mMarginFlags &= ~NEED_RESOLUTION_MASK;
6185b365f91688dc081b3bcea82377ce0e94c09124ffFabrice Di Meglio            mMarginFlags &= ~RTL_COMPATIBILITY_MODE_MASK;
61869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
61879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
61889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /**
61899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * Copy constructor. Clones the width, height and margin values of the source.
61909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         *
61919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * @param source The layout params to copy from.
61929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
61939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public MarginLayoutParams(MarginLayoutParams source) {
61949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            this.width = source.width;
61959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            this.height = source.height;
61969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
61979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            this.leftMargin = source.leftMargin;
61989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            this.topMargin = source.topMargin;
61999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            this.rightMargin = source.rightMargin;
62009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            this.bottomMargin = source.bottomMargin;
6201b76023afd192a1f5c81a8965cfd1b9dde2558726Fabrice Di Meglio            this.startMargin = source.startMargin;
6202b76023afd192a1f5c81a8965cfd1b9dde2558726Fabrice Di Meglio            this.endMargin = source.endMargin;
620369bd55844b2b2b78a0ff43e5123954cab3693ea6Fabrice Di Meglio
6204b365f91688dc081b3bcea82377ce0e94c09124ffFabrice Di Meglio            this.mMarginFlags = source.mMarginFlags;
62059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
62069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
62079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /**
62089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * {@inheritDoc}
62099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
62109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public MarginLayoutParams(LayoutParams source) {
62119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            super(source);
62120072f64939b37a4d84940656c2180ad2e0594ff4Fabrice Di Meglio
6213b365f91688dc081b3bcea82377ce0e94c09124ffFabrice Di Meglio            mMarginFlags |= LEFT_MARGIN_UNDEFINED_MASK;
6214b365f91688dc081b3bcea82377ce0e94c09124ffFabrice Di Meglio            mMarginFlags |= RIGHT_MARGIN_UNDEFINED_MASK;
621502a7d5637c961632dc67cd0012addfdd6060885bFabrice Di Meglio
6216b365f91688dc081b3bcea82377ce0e94c09124ffFabrice Di Meglio            mMarginFlags &= ~NEED_RESOLUTION_MASK;
6217b365f91688dc081b3bcea82377ce0e94c09124ffFabrice Di Meglio            mMarginFlags &= ~RTL_COMPATIBILITY_MODE_MASK;
62189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
62199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
62209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /**
6221b76023afd192a1f5c81a8965cfd1b9dde2558726Fabrice Di Meglio         * Sets the margins, in pixels. A call to {@link android.view.View#requestLayout()} needs
6222b76023afd192a1f5c81a8965cfd1b9dde2558726Fabrice Di Meglio         * to be done so that the new margins are taken into account. Left and right margins may be
6223b76023afd192a1f5c81a8965cfd1b9dde2558726Fabrice Di Meglio         * overriden by {@link android.view.View#requestLayout()} depending on layout direction.
62249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         *
62259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * @param left the left margin size
62269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * @param top the top margin size
62279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * @param right the right margin size
62289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * @param bottom the bottom margin size
62299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         *
62309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * @attr ref android.R.styleable#ViewGroup_MarginLayout_layout_marginLeft
62319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * @attr ref android.R.styleable#ViewGroup_MarginLayout_layout_marginTop
62329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * @attr ref android.R.styleable#ViewGroup_MarginLayout_layout_marginRight
62339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * @attr ref android.R.styleable#ViewGroup_MarginLayout_layout_marginBottom
62349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
62359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void setMargins(int left, int top, int right, int bottom) {
62369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            leftMargin = left;
62379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            topMargin = top;
62389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            rightMargin = right;
62399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            bottomMargin = bottom;
6240b365f91688dc081b3bcea82377ce0e94c09124ffFabrice Di Meglio            mMarginFlags &= ~LEFT_MARGIN_UNDEFINED_MASK;
6241b365f91688dc081b3bcea82377ce0e94c09124ffFabrice Di Meglio            mMarginFlags &= ~RIGHT_MARGIN_UNDEFINED_MASK;
6242b365f91688dc081b3bcea82377ce0e94c09124ffFabrice Di Meglio            if (isMarginRelative()) {
6243b365f91688dc081b3bcea82377ce0e94c09124ffFabrice Di Meglio                mMarginFlags |= NEED_RESOLUTION_MASK;
6244b365f91688dc081b3bcea82377ce0e94c09124ffFabrice Di Meglio            } else {
6245b365f91688dc081b3bcea82377ce0e94c09124ffFabrice Di Meglio                mMarginFlags &= ~NEED_RESOLUTION_MASK;
6246b365f91688dc081b3bcea82377ce0e94c09124ffFabrice Di Meglio            }
62479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6248b76023afd192a1f5c81a8965cfd1b9dde2558726Fabrice Di Meglio
6249b76023afd192a1f5c81a8965cfd1b9dde2558726Fabrice Di Meglio        /**
6250b76023afd192a1f5c81a8965cfd1b9dde2558726Fabrice Di Meglio         * Sets the relative margins, in pixels. A call to {@link android.view.View#requestLayout()}
6251b76023afd192a1f5c81a8965cfd1b9dde2558726Fabrice Di Meglio         * needs to be done so that the new relative margins are taken into account. Left and right
6252b76023afd192a1f5c81a8965cfd1b9dde2558726Fabrice Di Meglio         * margins may be overriden by {@link android.view.View#requestLayout()} depending on layout
6253b76023afd192a1f5c81a8965cfd1b9dde2558726Fabrice Di Meglio         * direction.
6254b76023afd192a1f5c81a8965cfd1b9dde2558726Fabrice Di Meglio         *
6255b76023afd192a1f5c81a8965cfd1b9dde2558726Fabrice Di Meglio         * @param start the start margin size
6256b76023afd192a1f5c81a8965cfd1b9dde2558726Fabrice Di Meglio         * @param top the top margin size
6257b76023afd192a1f5c81a8965cfd1b9dde2558726Fabrice Di Meglio         * @param end the right margin size
6258b76023afd192a1f5c81a8965cfd1b9dde2558726Fabrice Di Meglio         * @param bottom the bottom margin size
6259b76023afd192a1f5c81a8965cfd1b9dde2558726Fabrice Di Meglio         *
6260b76023afd192a1f5c81a8965cfd1b9dde2558726Fabrice Di Meglio         * @attr ref android.R.styleable#ViewGroup_MarginLayout_layout_marginStart
6261b76023afd192a1f5c81a8965cfd1b9dde2558726Fabrice Di Meglio         * @attr ref android.R.styleable#ViewGroup_MarginLayout_layout_marginTop
6262b76023afd192a1f5c81a8965cfd1b9dde2558726Fabrice Di Meglio         * @attr ref android.R.styleable#ViewGroup_MarginLayout_layout_marginEnd
6263b76023afd192a1f5c81a8965cfd1b9dde2558726Fabrice Di Meglio         * @attr ref android.R.styleable#ViewGroup_MarginLayout_layout_marginBottom
6264b76023afd192a1f5c81a8965cfd1b9dde2558726Fabrice Di Meglio         *
6265b76023afd192a1f5c81a8965cfd1b9dde2558726Fabrice Di Meglio         * @hide
6266b76023afd192a1f5c81a8965cfd1b9dde2558726Fabrice Di Meglio         */
6267b76023afd192a1f5c81a8965cfd1b9dde2558726Fabrice Di Meglio        public void setMarginsRelative(int start, int top, int end, int bottom) {
6268b76023afd192a1f5c81a8965cfd1b9dde2558726Fabrice Di Meglio            startMargin = start;
6269b76023afd192a1f5c81a8965cfd1b9dde2558726Fabrice Di Meglio            topMargin = top;
6270b76023afd192a1f5c81a8965cfd1b9dde2558726Fabrice Di Meglio            endMargin = end;
6271b76023afd192a1f5c81a8965cfd1b9dde2558726Fabrice Di Meglio            bottomMargin = bottom;
6272b365f91688dc081b3bcea82377ce0e94c09124ffFabrice Di Meglio            mMarginFlags |= NEED_RESOLUTION_MASK;
6273b76023afd192a1f5c81a8965cfd1b9dde2558726Fabrice Di Meglio        }
6274b76023afd192a1f5c81a8965cfd1b9dde2558726Fabrice Di Meglio
6275b76023afd192a1f5c81a8965cfd1b9dde2558726Fabrice Di Meglio        /**
6276a40627daee4891ab842fa509af254b349bff3a47Fabrice Di Meglio         * Sets the relative start margin.
6277a40627daee4891ab842fa509af254b349bff3a47Fabrice Di Meglio         *
627861a21770b789ad87b5ed5da3565d0d39939fdd5cFabrice Di Meglio         * @param start the start margin size
6279a40627daee4891ab842fa509af254b349bff3a47Fabrice Di Meglio         *
6280a40627daee4891ab842fa509af254b349bff3a47Fabrice Di Meglio         * @attr ref android.R.styleable#ViewGroup_MarginLayout_layout_marginStart
6281a40627daee4891ab842fa509af254b349bff3a47Fabrice Di Meglio         */
6282a40627daee4891ab842fa509af254b349bff3a47Fabrice Di Meglio        public void setMarginStart(int start) {
6283a40627daee4891ab842fa509af254b349bff3a47Fabrice Di Meglio            startMargin = start;
6284b365f91688dc081b3bcea82377ce0e94c09124ffFabrice Di Meglio            mMarginFlags |= NEED_RESOLUTION_MASK;
6285a40627daee4891ab842fa509af254b349bff3a47Fabrice Di Meglio        }
6286a40627daee4891ab842fa509af254b349bff3a47Fabrice Di Meglio
6287a40627daee4891ab842fa509af254b349bff3a47Fabrice Di Meglio        /**
6288b76023afd192a1f5c81a8965cfd1b9dde2558726Fabrice Di Meglio         * Returns the start margin in pixels.
6289b76023afd192a1f5c81a8965cfd1b9dde2558726Fabrice Di Meglio         *
6290b76023afd192a1f5c81a8965cfd1b9dde2558726Fabrice Di Meglio         * @attr ref android.R.styleable#ViewGroup_MarginLayout_layout_marginStart
6291b76023afd192a1f5c81a8965cfd1b9dde2558726Fabrice Di Meglio         *
6292b76023afd192a1f5c81a8965cfd1b9dde2558726Fabrice Di Meglio         * @return the start margin in pixels.
6293b76023afd192a1f5c81a8965cfd1b9dde2558726Fabrice Di Meglio         */
6294b76023afd192a1f5c81a8965cfd1b9dde2558726Fabrice Di Meglio        public int getMarginStart() {
62950072f64939b37a4d84940656c2180ad2e0594ff4Fabrice Di Meglio            if (startMargin != DEFAULT_MARGIN_RELATIVE) return startMargin;
6296b365f91688dc081b3bcea82377ce0e94c09124ffFabrice Di Meglio            if ((mMarginFlags & NEED_RESOLUTION_MASK) == NEED_RESOLUTION_MASK) {
62970072f64939b37a4d84940656c2180ad2e0594ff4Fabrice Di Meglio                doResolveMargins();
62980072f64939b37a4d84940656c2180ad2e0594ff4Fabrice Di Meglio            }
6299b365f91688dc081b3bcea82377ce0e94c09124ffFabrice Di Meglio            switch(mMarginFlags & LAYOUT_DIRECTION_MASK) {
630069bd55844b2b2b78a0ff43e5123954cab3693ea6Fabrice Di Meglio                case View.LAYOUT_DIRECTION_RTL:
630169bd55844b2b2b78a0ff43e5123954cab3693ea6Fabrice Di Meglio                    return rightMargin;
630269bd55844b2b2b78a0ff43e5123954cab3693ea6Fabrice Di Meglio                case View.LAYOUT_DIRECTION_LTR:
630369bd55844b2b2b78a0ff43e5123954cab3693ea6Fabrice Di Meglio                default:
630469bd55844b2b2b78a0ff43e5123954cab3693ea6Fabrice Di Meglio                    return leftMargin;
630569bd55844b2b2b78a0ff43e5123954cab3693ea6Fabrice Di Meglio            }
6306b76023afd192a1f5c81a8965cfd1b9dde2558726Fabrice Di Meglio        }
6307b76023afd192a1f5c81a8965cfd1b9dde2558726Fabrice Di Meglio
6308b76023afd192a1f5c81a8965cfd1b9dde2558726Fabrice Di Meglio        /**
6309a40627daee4891ab842fa509af254b349bff3a47Fabrice Di Meglio         * Sets the relative end margin.
6310a40627daee4891ab842fa509af254b349bff3a47Fabrice Di Meglio         *
631161a21770b789ad87b5ed5da3565d0d39939fdd5cFabrice Di Meglio         * @param end the end margin size
6312a40627daee4891ab842fa509af254b349bff3a47Fabrice Di Meglio         *
6313a40627daee4891ab842fa509af254b349bff3a47Fabrice Di Meglio         * @attr ref android.R.styleable#ViewGroup_MarginLayout_layout_marginEnd
6314a40627daee4891ab842fa509af254b349bff3a47Fabrice Di Meglio         */
6315a40627daee4891ab842fa509af254b349bff3a47Fabrice Di Meglio        public void setMarginEnd(int end) {
6316a40627daee4891ab842fa509af254b349bff3a47Fabrice Di Meglio            endMargin = end;
6317b365f91688dc081b3bcea82377ce0e94c09124ffFabrice Di Meglio            mMarginFlags |= NEED_RESOLUTION_MASK;
6318a40627daee4891ab842fa509af254b349bff3a47Fabrice Di Meglio        }
6319a40627daee4891ab842fa509af254b349bff3a47Fabrice Di Meglio
6320a40627daee4891ab842fa509af254b349bff3a47Fabrice Di Meglio        /**
6321b76023afd192a1f5c81a8965cfd1b9dde2558726Fabrice Di Meglio         * Returns the end margin in pixels.
6322b76023afd192a1f5c81a8965cfd1b9dde2558726Fabrice Di Meglio         *
6323b76023afd192a1f5c81a8965cfd1b9dde2558726Fabrice Di Meglio         * @attr ref android.R.styleable#ViewGroup_MarginLayout_layout_marginEnd
6324b76023afd192a1f5c81a8965cfd1b9dde2558726Fabrice Di Meglio         *
6325b76023afd192a1f5c81a8965cfd1b9dde2558726Fabrice Di Meglio         * @return the end margin in pixels.
6326b76023afd192a1f5c81a8965cfd1b9dde2558726Fabrice Di Meglio         */
6327b76023afd192a1f5c81a8965cfd1b9dde2558726Fabrice Di Meglio        public int getMarginEnd() {
63280072f64939b37a4d84940656c2180ad2e0594ff4Fabrice Di Meglio            if (endMargin != DEFAULT_MARGIN_RELATIVE) return endMargin;
6329b365f91688dc081b3bcea82377ce0e94c09124ffFabrice Di Meglio            if ((mMarginFlags & NEED_RESOLUTION_MASK) == NEED_RESOLUTION_MASK) {
63300072f64939b37a4d84940656c2180ad2e0594ff4Fabrice Di Meglio                doResolveMargins();
63310072f64939b37a4d84940656c2180ad2e0594ff4Fabrice Di Meglio            }
6332b365f91688dc081b3bcea82377ce0e94c09124ffFabrice Di Meglio            switch(mMarginFlags & LAYOUT_DIRECTION_MASK) {
633369bd55844b2b2b78a0ff43e5123954cab3693ea6Fabrice Di Meglio                case View.LAYOUT_DIRECTION_RTL:
633469bd55844b2b2b78a0ff43e5123954cab3693ea6Fabrice Di Meglio                    return leftMargin;
633569bd55844b2b2b78a0ff43e5123954cab3693ea6Fabrice Di Meglio                case View.LAYOUT_DIRECTION_LTR:
633669bd55844b2b2b78a0ff43e5123954cab3693ea6Fabrice Di Meglio                default:
633769bd55844b2b2b78a0ff43e5123954cab3693ea6Fabrice Di Meglio                    return rightMargin;
633869bd55844b2b2b78a0ff43e5123954cab3693ea6Fabrice Di Meglio            }
6339b76023afd192a1f5c81a8965cfd1b9dde2558726Fabrice Di Meglio        }
6340b76023afd192a1f5c81a8965cfd1b9dde2558726Fabrice Di Meglio
6341b76023afd192a1f5c81a8965cfd1b9dde2558726Fabrice Di Meglio        /**
6342b76023afd192a1f5c81a8965cfd1b9dde2558726Fabrice Di Meglio         * Check if margins are relative.
6343b76023afd192a1f5c81a8965cfd1b9dde2558726Fabrice Di Meglio         *
6344b76023afd192a1f5c81a8965cfd1b9dde2558726Fabrice Di Meglio         * @attr ref android.R.styleable#ViewGroup_MarginLayout_layout_marginStart
6345b76023afd192a1f5c81a8965cfd1b9dde2558726Fabrice Di Meglio         * @attr ref android.R.styleable#ViewGroup_MarginLayout_layout_marginEnd
6346b76023afd192a1f5c81a8965cfd1b9dde2558726Fabrice Di Meglio         *
6347f443f98e7f41badd8f5d6f7bf7d26432e79a88edFabrice Di Meglio         * @return true if either marginStart or marginEnd has been set.
6348b76023afd192a1f5c81a8965cfd1b9dde2558726Fabrice Di Meglio         */
6349b76023afd192a1f5c81a8965cfd1b9dde2558726Fabrice Di Meglio        public boolean isMarginRelative() {
63500072f64939b37a4d84940656c2180ad2e0594ff4Fabrice Di Meglio            return (startMargin != DEFAULT_MARGIN_RELATIVE || endMargin != DEFAULT_MARGIN_RELATIVE);
6351b76023afd192a1f5c81a8965cfd1b9dde2558726Fabrice Di Meglio        }
6352b76023afd192a1f5c81a8965cfd1b9dde2558726Fabrice Di Meglio
6353b76023afd192a1f5c81a8965cfd1b9dde2558726Fabrice Di Meglio        /**
6354f443f98e7f41badd8f5d6f7bf7d26432e79a88edFabrice Di Meglio         * Set the layout direction
6355f443f98e7f41badd8f5d6f7bf7d26432e79a88edFabrice Di Meglio         * @param layoutDirection the layout direction.
6356f443f98e7f41badd8f5d6f7bf7d26432e79a88edFabrice Di Meglio         *        Should be either {@link View#LAYOUT_DIRECTION_LTR}
6357f443f98e7f41badd8f5d6f7bf7d26432e79a88edFabrice Di Meglio         *                     or {@link View#LAYOUT_DIRECTION_RTL}.
6358f443f98e7f41badd8f5d6f7bf7d26432e79a88edFabrice Di Meglio         */
6359f443f98e7f41badd8f5d6f7bf7d26432e79a88edFabrice Di Meglio        public void setLayoutDirection(int layoutDirection) {
6360f443f98e7f41badd8f5d6f7bf7d26432e79a88edFabrice Di Meglio            if (layoutDirection != View.LAYOUT_DIRECTION_LTR &&
6361f443f98e7f41badd8f5d6f7bf7d26432e79a88edFabrice Di Meglio                    layoutDirection != View.LAYOUT_DIRECTION_RTL) return;
6362b365f91688dc081b3bcea82377ce0e94c09124ffFabrice Di Meglio            if (layoutDirection != (mMarginFlags & LAYOUT_DIRECTION_MASK)) {
6363b365f91688dc081b3bcea82377ce0e94c09124ffFabrice Di Meglio                mMarginFlags &= ~LAYOUT_DIRECTION_MASK;
6364b365f91688dc081b3bcea82377ce0e94c09124ffFabrice Di Meglio                mMarginFlags |= (layoutDirection & LAYOUT_DIRECTION_MASK);
6365b365f91688dc081b3bcea82377ce0e94c09124ffFabrice Di Meglio                if (isMarginRelative()) {
6366b365f91688dc081b3bcea82377ce0e94c09124ffFabrice Di Meglio                    mMarginFlags |= NEED_RESOLUTION_MASK;
6367b365f91688dc081b3bcea82377ce0e94c09124ffFabrice Di Meglio                } else {
6368b365f91688dc081b3bcea82377ce0e94c09124ffFabrice Di Meglio                    mMarginFlags &= ~NEED_RESOLUTION_MASK;
6369b365f91688dc081b3bcea82377ce0e94c09124ffFabrice Di Meglio                }
63700072f64939b37a4d84940656c2180ad2e0594ff4Fabrice Di Meglio            }
6371f443f98e7f41badd8f5d6f7bf7d26432e79a88edFabrice Di Meglio        }
6372f443f98e7f41badd8f5d6f7bf7d26432e79a88edFabrice Di Meglio
6373f443f98e7f41badd8f5d6f7bf7d26432e79a88edFabrice Di Meglio        /**
6374f443f98e7f41badd8f5d6f7bf7d26432e79a88edFabrice Di Meglio         * Retuns the layout direction. Can be either {@link View#LAYOUT_DIRECTION_LTR} or
6375f443f98e7f41badd8f5d6f7bf7d26432e79a88edFabrice Di Meglio         * {@link View#LAYOUT_DIRECTION_RTL}.
6376f443f98e7f41badd8f5d6f7bf7d26432e79a88edFabrice Di Meglio         *
6377f443f98e7f41badd8f5d6f7bf7d26432e79a88edFabrice Di Meglio         * @return the layout direction.
6378f443f98e7f41badd8f5d6f7bf7d26432e79a88edFabrice Di Meglio         */
6379f443f98e7f41badd8f5d6f7bf7d26432e79a88edFabrice Di Meglio        public int getLayoutDirection() {
6380b365f91688dc081b3bcea82377ce0e94c09124ffFabrice Di Meglio            return (mMarginFlags & LAYOUT_DIRECTION_MASK);
6381f443f98e7f41badd8f5d6f7bf7d26432e79a88edFabrice Di Meglio        }
6382f443f98e7f41badd8f5d6f7bf7d26432e79a88edFabrice Di Meglio
6383f443f98e7f41badd8f5d6f7bf7d26432e79a88edFabrice Di Meglio        /**
6384b76023afd192a1f5c81a8965cfd1b9dde2558726Fabrice Di Meglio         * This will be called by {@link android.view.View#requestLayout()}. Left and Right margins
638598aec1c7efa639ac902d1200a3ac5a4a7a140129Fabrice Di Meglio         * may be overridden depending on layout direction.
6386b76023afd192a1f5c81a8965cfd1b9dde2558726Fabrice Di Meglio         */
6387b76023afd192a1f5c81a8965cfd1b9dde2558726Fabrice Di Meglio        @Override
63882918ab6c3258639148b8a5c78a34483af195246eFabrice Di Meglio        public void resolveLayoutDirection(int layoutDirection) {
6389f443f98e7f41badd8f5d6f7bf7d26432e79a88edFabrice Di Meglio            setLayoutDirection(layoutDirection);
639069bd55844b2b2b78a0ff43e5123954cab3693ea6Fabrice Di Meglio
63910072f64939b37a4d84940656c2180ad2e0594ff4Fabrice Di Meglio            // No relative margin or pre JB-MR1 case or no need to resolve, just dont do anything
63920072f64939b37a4d84940656c2180ad2e0594ff4Fabrice Di Meglio            // Will use the left and right margins if no relative margin is defined.
6393b365f91688dc081b3bcea82377ce0e94c09124ffFabrice Di Meglio            if (!isMarginRelative() ||
6394b365f91688dc081b3bcea82377ce0e94c09124ffFabrice Di Meglio                    (mMarginFlags & NEED_RESOLUTION_MASK) != NEED_RESOLUTION_MASK) return;
63950072f64939b37a4d84940656c2180ad2e0594ff4Fabrice Di Meglio
63960072f64939b37a4d84940656c2180ad2e0594ff4Fabrice Di Meglio            // Proceed with resolution
63970072f64939b37a4d84940656c2180ad2e0594ff4Fabrice Di Meglio            doResolveMargins();
63980072f64939b37a4d84940656c2180ad2e0594ff4Fabrice Di Meglio        }
639969bd55844b2b2b78a0ff43e5123954cab3693ea6Fabrice Di Meglio
64000072f64939b37a4d84940656c2180ad2e0594ff4Fabrice Di Meglio        private void doResolveMargins() {
6401b365f91688dc081b3bcea82377ce0e94c09124ffFabrice Di Meglio            if ((mMarginFlags & RTL_COMPATIBILITY_MODE_MASK) == RTL_COMPATIBILITY_MODE_MASK) {
640202a7d5637c961632dc67cd0012addfdd6060885bFabrice Di Meglio                // if left or right margins are not defined and if we have some start or end margin
640302a7d5637c961632dc67cd0012addfdd6060885bFabrice Di Meglio                // defined then use those start and end margins.
6404b365f91688dc081b3bcea82377ce0e94c09124ffFabrice Di Meglio                if ((mMarginFlags & LEFT_MARGIN_UNDEFINED_MASK) == LEFT_MARGIN_UNDEFINED_MASK
6405b365f91688dc081b3bcea82377ce0e94c09124ffFabrice Di Meglio                        && startMargin > DEFAULT_MARGIN_RELATIVE) {
640602a7d5637c961632dc67cd0012addfdd6060885bFabrice Di Meglio                    leftMargin = startMargin;
640702a7d5637c961632dc67cd0012addfdd6060885bFabrice Di Meglio                }
6408b365f91688dc081b3bcea82377ce0e94c09124ffFabrice Di Meglio                if ((mMarginFlags & RIGHT_MARGIN_UNDEFINED_MASK) == RIGHT_MARGIN_UNDEFINED_MASK
6409b365f91688dc081b3bcea82377ce0e94c09124ffFabrice Di Meglio                        && endMargin > DEFAULT_MARGIN_RELATIVE) {
641002a7d5637c961632dc67cd0012addfdd6060885bFabrice Di Meglio                    rightMargin = endMargin;
641102a7d5637c961632dc67cd0012addfdd6060885bFabrice Di Meglio                }
641202a7d5637c961632dc67cd0012addfdd6060885bFabrice Di Meglio            } else {
641302a7d5637c961632dc67cd0012addfdd6060885bFabrice Di Meglio                // We have some relative margins (either the start one or the end one or both). So use
641402a7d5637c961632dc67cd0012addfdd6060885bFabrice Di Meglio                // them and override what has been defined for left and right margins. If either start
641502a7d5637c961632dc67cd0012addfdd6060885bFabrice Di Meglio                // or end margin is not defined, just set it to default "0".
6416b365f91688dc081b3bcea82377ce0e94c09124ffFabrice Di Meglio                switch(mMarginFlags & LAYOUT_DIRECTION_MASK) {
641702a7d5637c961632dc67cd0012addfdd6060885bFabrice Di Meglio                    case View.LAYOUT_DIRECTION_RTL:
641802a7d5637c961632dc67cd0012addfdd6060885bFabrice Di Meglio                        leftMargin = (endMargin > DEFAULT_MARGIN_RELATIVE) ?
641902a7d5637c961632dc67cd0012addfdd6060885bFabrice Di Meglio                                endMargin : DEFAULT_MARGIN_RESOLVED;
642002a7d5637c961632dc67cd0012addfdd6060885bFabrice Di Meglio                        rightMargin = (startMargin > DEFAULT_MARGIN_RELATIVE) ?
642102a7d5637c961632dc67cd0012addfdd6060885bFabrice Di Meglio                                startMargin : DEFAULT_MARGIN_RESOLVED;
642202a7d5637c961632dc67cd0012addfdd6060885bFabrice Di Meglio                        break;
642302a7d5637c961632dc67cd0012addfdd6060885bFabrice Di Meglio                    case View.LAYOUT_DIRECTION_LTR:
642402a7d5637c961632dc67cd0012addfdd6060885bFabrice Di Meglio                    default:
642502a7d5637c961632dc67cd0012addfdd6060885bFabrice Di Meglio                        leftMargin = (startMargin > DEFAULT_MARGIN_RELATIVE) ?
642602a7d5637c961632dc67cd0012addfdd6060885bFabrice Di Meglio                                startMargin : DEFAULT_MARGIN_RESOLVED;
642702a7d5637c961632dc67cd0012addfdd6060885bFabrice Di Meglio                        rightMargin = (endMargin > DEFAULT_MARGIN_RELATIVE) ?
642802a7d5637c961632dc67cd0012addfdd6060885bFabrice Di Meglio                                endMargin : DEFAULT_MARGIN_RESOLVED;
642902a7d5637c961632dc67cd0012addfdd6060885bFabrice Di Meglio                        break;
643002a7d5637c961632dc67cd0012addfdd6060885bFabrice Di Meglio                }
6431b76023afd192a1f5c81a8965cfd1b9dde2558726Fabrice Di Meglio            }
6432b365f91688dc081b3bcea82377ce0e94c09124ffFabrice Di Meglio            mMarginFlags &= ~NEED_RESOLUTION_MASK;
6433b76023afd192a1f5c81a8965cfd1b9dde2558726Fabrice Di Meglio        }
643410ca24a97cefc14fca1b26f59e627f487b3b108bPhilip Milne
643503b8d3a9a4d5c04953e2370fc44fe5e40a381910Fabrice Di Meglio        /**
643603b8d3a9a4d5c04953e2370fc44fe5e40a381910Fabrice Di Meglio         * @hide
643703b8d3a9a4d5c04953e2370fc44fe5e40a381910Fabrice Di Meglio         */
643803b8d3a9a4d5c04953e2370fc44fe5e40a381910Fabrice Di Meglio        public boolean isLayoutRtl() {
6439b365f91688dc081b3bcea82377ce0e94c09124ffFabrice Di Meglio            return ((mMarginFlags & LAYOUT_DIRECTION_MASK) == View.LAYOUT_DIRECTION_RTL);
6440f443f98e7f41badd8f5d6f7bf7d26432e79a88edFabrice Di Meglio        }
6441f443f98e7f41badd8f5d6f7bf7d26432e79a88edFabrice Di Meglio
644210ca24a97cefc14fca1b26f59e627f487b3b108bPhilip Milne        /**
644310ca24a97cefc14fca1b26f59e627f487b3b108bPhilip Milne         * @hide
644410ca24a97cefc14fca1b26f59e627f487b3b108bPhilip Milne         */
644510ca24a97cefc14fca1b26f59e627f487b3b108bPhilip Milne        @Override
64467b7578184567f4e4f0740ce935cc192765410ccaPhilip Milne        public void onDebugDraw(View view, Canvas canvas, Paint paint) {
64477b7578184567f4e4f0740ce935cc192765410ccaPhilip Milne            Insets oi = isLayoutModeOptical(view.mParent) ? view.getOpticalInsets() : Insets.NONE;
64487b7578184567f4e4f0740ce935cc192765410ccaPhilip Milne
64497b7578184567f4e4f0740ce935cc192765410ccaPhilip Milne            fillDifference(canvas,
64507b7578184567f4e4f0740ce935cc192765410ccaPhilip Milne                    view.getLeft()   + oi.left,
64517b7578184567f4e4f0740ce935cc192765410ccaPhilip Milne                    view.getTop()    + oi.top,
64527b7578184567f4e4f0740ce935cc192765410ccaPhilip Milne                    view.getRight()  - oi.right,
64537b7578184567f4e4f0740ce935cc192765410ccaPhilip Milne                    view.getBottom() - oi.bottom,
64547b7578184567f4e4f0740ce935cc192765410ccaPhilip Milne                    leftMargin,
64557b7578184567f4e4f0740ce935cc192765410ccaPhilip Milne                    topMargin,
64567b7578184567f4e4f0740ce935cc192765410ccaPhilip Milne                    rightMargin,
64577b7578184567f4e4f0740ce935cc192765410ccaPhilip Milne                    bottomMargin,
64587b7578184567f4e4f0740ce935cc192765410ccaPhilip Milne                    paint);
645910ca24a97cefc14fca1b26f59e627f487b3b108bPhilip Milne        }
64609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
64612b342f0a76f3237e97f15dc2f4e8a0b72dd7c023Adam Powell
646220e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown    /* Describes a touched view and the ids of the pointers that it has captured.
646320e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown     *
646420e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown     * This code assumes that pointer ids are always in the range 0..31 such that
646520e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown     * it can use a bitfield to track which pointer ids are present.
646620e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown     * As it happens, the lower layers of the input dispatch pipeline also use the
646720e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown     * same trick so the assumption should be safe here...
646820e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown     */
646920e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown    private static final class TouchTarget {
647020e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown        private static final int MAX_RECYCLED = 32;
64716410c0aaf13c9aec606b90ee942f2ac2d98b1609Romain Guy        private static final Object sRecycleLock = new Object[0];
647220e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown        private static TouchTarget sRecycleBin;
647320e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown        private static int sRecycledCount;
64742b342f0a76f3237e97f15dc2f4e8a0b72dd7c023Adam Powell
647520e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown        public static final int ALL_POINTER_IDS = -1; // all ones
64762b342f0a76f3237e97f15dc2f4e8a0b72dd7c023Adam Powell
647720e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown        // The touched child view.
647820e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown        public View child;
64792b342f0a76f3237e97f15dc2f4e8a0b72dd7c023Adam Powell
648020e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown        // The combined bit mask of pointer ids for all pointers captured by the target.
648120e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown        public int pointerIdBits;
64822b342f0a76f3237e97f15dc2f4e8a0b72dd7c023Adam Powell
648320e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown        // The next target in the target list.
648420e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown        public TouchTarget next;
64852b342f0a76f3237e97f15dc2f4e8a0b72dd7c023Adam Powell
648620e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown        private TouchTarget() {
64872b342f0a76f3237e97f15dc2f4e8a0b72dd7c023Adam Powell        }
6488816c3be1d7e27ee91ad4e87d39a208dbdc27c8f9Adam Powell
648920e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown        public static TouchTarget obtain(View child, int pointerIdBits) {
649020e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown            final TouchTarget target;
649120e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown            synchronized (sRecycleLock) {
6492816c3be1d7e27ee91ad4e87d39a208dbdc27c8f9Adam Powell                if (sRecycleBin == null) {
649320e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown                    target = new TouchTarget();
6494816c3be1d7e27ee91ad4e87d39a208dbdc27c8f9Adam Powell                } else {
649520e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown                    target = sRecycleBin;
649620e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown                    sRecycleBin = target.next;
649720e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown                     sRecycledCount--;
649820e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown                    target.next = null;
6499816c3be1d7e27ee91ad4e87d39a208dbdc27c8f9Adam Powell                }
6500816c3be1d7e27ee91ad4e87d39a208dbdc27c8f9Adam Powell            }
650120e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown            target.child = child;
650220e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown            target.pointerIdBits = pointerIdBits;
650320e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown            return target;
650420e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown        }
6505816c3be1d7e27ee91ad4e87d39a208dbdc27c8f9Adam Powell
650620e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown        public void recycle() {
650720e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown            synchronized (sRecycleLock) {
650820e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown                if (sRecycledCount < MAX_RECYCLED) {
650920e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown                    next = sRecycleBin;
651020e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown                    sRecycleBin = this;
651120e987bfc35d0ae6cb6344ead65ed44ee7cf8750Jeff Brown                    sRecycledCount += 1;
6512fb0547d2c0f84e8266dce1444d332433ada09249Patrick Dubroy                } else {
6513fb0547d2c0f84e8266dce1444d332433ada09249Patrick Dubroy                    next = null;
6514816c3be1d7e27ee91ad4e87d39a208dbdc27c8f9Adam Powell                }
6515fb0547d2c0f84e8266dce1444d332433ada09249Patrick Dubroy                child = null;
6516816c3be1d7e27ee91ad4e87d39a208dbdc27c8f9Adam Powell            }
6517816c3be1d7e27ee91ad4e87d39a208dbdc27c8f9Adam Powell        }
65182b342f0a76f3237e97f15dc2f4e8a0b72dd7c023Adam Powell    }
651987b7f805b94f5df53343264509f6d606d96dfb05Jeff Brown
652087b7f805b94f5df53343264509f6d606d96dfb05Jeff Brown    /* Describes a hovered view. */
652187b7f805b94f5df53343264509f6d606d96dfb05Jeff Brown    private static final class HoverTarget {
652287b7f805b94f5df53343264509f6d606d96dfb05Jeff Brown        private static final int MAX_RECYCLED = 32;
65236410c0aaf13c9aec606b90ee942f2ac2d98b1609Romain Guy        private static final Object sRecycleLock = new Object[0];
652487b7f805b94f5df53343264509f6d606d96dfb05Jeff Brown        private static HoverTarget sRecycleBin;
652587b7f805b94f5df53343264509f6d606d96dfb05Jeff Brown        private static int sRecycledCount;
652687b7f805b94f5df53343264509f6d606d96dfb05Jeff Brown
652787b7f805b94f5df53343264509f6d606d96dfb05Jeff Brown        // The hovered child view.
652887b7f805b94f5df53343264509f6d606d96dfb05Jeff Brown        public View child;
652987b7f805b94f5df53343264509f6d606d96dfb05Jeff Brown
653087b7f805b94f5df53343264509f6d606d96dfb05Jeff Brown        // The next target in the target list.
653187b7f805b94f5df53343264509f6d606d96dfb05Jeff Brown        public HoverTarget next;
653287b7f805b94f5df53343264509f6d606d96dfb05Jeff Brown
653387b7f805b94f5df53343264509f6d606d96dfb05Jeff Brown        private HoverTarget() {
653487b7f805b94f5df53343264509f6d606d96dfb05Jeff Brown        }
653587b7f805b94f5df53343264509f6d606d96dfb05Jeff Brown
653687b7f805b94f5df53343264509f6d606d96dfb05Jeff Brown        public static HoverTarget obtain(View child) {
653787b7f805b94f5df53343264509f6d606d96dfb05Jeff Brown            final HoverTarget target;
653887b7f805b94f5df53343264509f6d606d96dfb05Jeff Brown            synchronized (sRecycleLock) {
653987b7f805b94f5df53343264509f6d606d96dfb05Jeff Brown                if (sRecycleBin == null) {
654087b7f805b94f5df53343264509f6d606d96dfb05Jeff Brown                    target = new HoverTarget();
654187b7f805b94f5df53343264509f6d606d96dfb05Jeff Brown                } else {
654287b7f805b94f5df53343264509f6d606d96dfb05Jeff Brown                    target = sRecycleBin;
654387b7f805b94f5df53343264509f6d606d96dfb05Jeff Brown                    sRecycleBin = target.next;
654487b7f805b94f5df53343264509f6d606d96dfb05Jeff Brown                     sRecycledCount--;
654587b7f805b94f5df53343264509f6d606d96dfb05Jeff Brown                    target.next = null;
654687b7f805b94f5df53343264509f6d606d96dfb05Jeff Brown                }
654787b7f805b94f5df53343264509f6d606d96dfb05Jeff Brown            }
654887b7f805b94f5df53343264509f6d606d96dfb05Jeff Brown            target.child = child;
654987b7f805b94f5df53343264509f6d606d96dfb05Jeff Brown            return target;
655087b7f805b94f5df53343264509f6d606d96dfb05Jeff Brown        }
655187b7f805b94f5df53343264509f6d606d96dfb05Jeff Brown
655287b7f805b94f5df53343264509f6d606d96dfb05Jeff Brown        public void recycle() {
655387b7f805b94f5df53343264509f6d606d96dfb05Jeff Brown            synchronized (sRecycleLock) {
655487b7f805b94f5df53343264509f6d606d96dfb05Jeff Brown                if (sRecycledCount < MAX_RECYCLED) {
655587b7f805b94f5df53343264509f6d606d96dfb05Jeff Brown                    next = sRecycleBin;
655687b7f805b94f5df53343264509f6d606d96dfb05Jeff Brown                    sRecycleBin = this;
655787b7f805b94f5df53343264509f6d606d96dfb05Jeff Brown                    sRecycledCount += 1;
655887b7f805b94f5df53343264509f6d606d96dfb05Jeff Brown                } else {
655987b7f805b94f5df53343264509f6d606d96dfb05Jeff Brown                    next = null;
656087b7f805b94f5df53343264509f6d606d96dfb05Jeff Brown                }
656187b7f805b94f5df53343264509f6d606d96dfb05Jeff Brown                child = null;
656287b7f805b94f5df53343264509f6d606d96dfb05Jeff Brown            }
656387b7f805b94f5df53343264509f6d606d96dfb05Jeff Brown        }
656487b7f805b94f5df53343264509f6d606d96dfb05Jeff Brown    }
65654213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov
65664213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov    /**
65674213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov     * Pooled class that orderes the children of a ViewGroup from start
65684213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov     * to end based on how they are laid out and the layout direction.
65694213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov     */
65704213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov    static class ChildListForAccessibility {
65714213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov
65724213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov        private static final int MAX_POOL_SIZE = 32;
65734213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov
6574be922dc976b1ce1735dcc0cf49509a2149766c96Svetoslav Ganov        private static final SynchronizedPool<ChildListForAccessibility> sPool =
6575be922dc976b1ce1735dcc0cf49509a2149766c96Svetoslav Ganov                new SynchronizedPool<ChildListForAccessibility>(MAX_POOL_SIZE);
65764213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov
65774213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov        private final ArrayList<View> mChildren = new ArrayList<View>();
65784213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov
65794213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov        private final ArrayList<ViewLocationHolder> mHolders = new ArrayList<ViewLocationHolder>();
65804213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov
65814213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov        public static ChildListForAccessibility obtain(ViewGroup parent, boolean sort) {
6582be922dc976b1ce1735dcc0cf49509a2149766c96Svetoslav Ganov            ChildListForAccessibility list = sPool.acquire();
6583be922dc976b1ce1735dcc0cf49509a2149766c96Svetoslav Ganov            if (list == null) {
6584be922dc976b1ce1735dcc0cf49509a2149766c96Svetoslav Ganov                list = new ChildListForAccessibility();
65854213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov            }
6586be922dc976b1ce1735dcc0cf49509a2149766c96Svetoslav Ganov            list.init(parent, sort);
6587be922dc976b1ce1735dcc0cf49509a2149766c96Svetoslav Ganov            return list;
65884213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov        }
65894213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov
65904213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov        public void recycle() {
65914213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov            clear();
6592be922dc976b1ce1735dcc0cf49509a2149766c96Svetoslav Ganov            sPool.release(this);
65934213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov        }
65944213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov
65954213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov        public int getChildCount() {
65964213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov            return mChildren.size();
65974213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov        }
65984213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov
65994213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov        public View getChildAt(int index) {
66004213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov            return mChildren.get(index);
66014213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov        }
66024213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov
66034213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov        public int getChildIndex(View child) {
66044213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov            return mChildren.indexOf(child);
66054213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov        }
66064213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov
66074213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov        private void init(ViewGroup parent, boolean sort) {
66084213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov            ArrayList<View> children = mChildren;
66094213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov            final int childCount = parent.getChildCount();
66104213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov            for (int i = 0; i < childCount; i++) {
66114213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov                View child = parent.getChildAt(i);
66124213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov                children.add(child);
66134213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov            }
66144213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov            if (sort) {
66154213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov                ArrayList<ViewLocationHolder> holders = mHolders;
66164213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov                for (int i = 0; i < childCount; i++) {
66174213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov                    View child = children.get(i);
66184213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov                    ViewLocationHolder holder = ViewLocationHolder.obtain(parent, child);
66194213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov                    holders.add(holder);
66204213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov                }
66214213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov                Collections.sort(holders);
66224213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov                for (int i = 0; i < childCount; i++) {
66234213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov                    ViewLocationHolder holder = holders.get(i);
66244213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov                    children.set(i, holder.mView);
66254213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov                    holder.recycle();
66264213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov                }
66274213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov                holders.clear();
66284213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov            }
66294213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov        }
66304213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov
66314213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov        private void clear() {
66324213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov            mChildren.clear();
66334213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov        }
66344213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov    }
66354213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov
66364213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov    /**
66374213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov     * Pooled class that holds a View and its location with respect to
66384213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov     * a specified root. This enables sorting of views based on their
66394213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov     * coordinates without recomputing the position relative to the root
66404213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov     * on every comparison.
66414213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov     */
66424213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov    static class ViewLocationHolder implements Comparable<ViewLocationHolder> {
66434213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov
66444213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov        private static final int MAX_POOL_SIZE = 32;
66454213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov
6646be922dc976b1ce1735dcc0cf49509a2149766c96Svetoslav Ganov        private static final SynchronizedPool<ViewLocationHolder> sPool =
6647be922dc976b1ce1735dcc0cf49509a2149766c96Svetoslav Ganov                new SynchronizedPool<ViewLocationHolder>(MAX_POOL_SIZE);
66484213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov
66494213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov        private final Rect mLocation = new Rect();
66504213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov
66514213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov        public View mView;
66524213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov
66534213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov        private int mLayoutDirection;
66544213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov
66554213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov        public static ViewLocationHolder obtain(ViewGroup root, View view) {
6656be922dc976b1ce1735dcc0cf49509a2149766c96Svetoslav Ganov            ViewLocationHolder holder = sPool.acquire();
6657be922dc976b1ce1735dcc0cf49509a2149766c96Svetoslav Ganov            if (holder == null) {
6658be922dc976b1ce1735dcc0cf49509a2149766c96Svetoslav Ganov                holder = new ViewLocationHolder();
66594213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov            }
6660be922dc976b1ce1735dcc0cf49509a2149766c96Svetoslav Ganov            holder.init(root, view);
6661be922dc976b1ce1735dcc0cf49509a2149766c96Svetoslav Ganov            return holder;
66624213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov        }
66634213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov
66644213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov        public void recycle() {
66654213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov            clear();
6666be922dc976b1ce1735dcc0cf49509a2149766c96Svetoslav Ganov            sPool.release(this);
66674213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov        }
66684213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov
66694213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov        @Override
66704213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov        public int compareTo(ViewLocationHolder another) {
66714213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov            // This instance is greater than an invalid argument.
66724213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov            if (another == null) {
66734213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov                return 1;
66744213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov            }
66754213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov            if (getClass() != another.getClass()) {
66764213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov                return 1;
66774213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov            }
66784213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov            // First is above second.
66794213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov            if (mLocation.bottom - another.mLocation.top <= 0) {
66804213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov                return -1;
66814213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov            }
66824213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov            // First is below second.
66834213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov            if (mLocation.top - another.mLocation.bottom >= 0) {
66844213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov                return 1;
66854213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov            }
66864213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov            // LTR
66874213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov            if (mLayoutDirection == LAYOUT_DIRECTION_LTR) {
66884213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov                final int leftDifference = mLocation.left - another.mLocation.left;
66894213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov                // First more to the left than second.
66904213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov                if (leftDifference != 0) {
66914213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov                    return leftDifference;
66924213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov                }
66934213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov            } else { // RTL
66944213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov                final int rightDifference = mLocation.right - another.mLocation.right;
66954213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov                // First more to the right than second.
66964213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov                if (rightDifference != 0) {
66974213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov                    return -rightDifference;
66984213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov                }
66994213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov            }
67004213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov            // Break tie by top.
67014213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov            final int topDiference = mLocation.top - another.mLocation.top;
67024213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov            if (topDiference != 0) {
67034213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov                return topDiference;
67044213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov            }
67054213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov            // Break tie by height.
67064213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov            final int heightDiference = mLocation.height() - another.mLocation.height();
67074213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov            if (heightDiference != 0) {
67084213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov                return -heightDiference;
67094213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov            }
67104213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov            // Break tie by width.
67114213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov            final int widthDiference = mLocation.width() - another.mLocation.width();
67124213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov            if (widthDiference != 0) {
67134213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov                return -widthDiference;
67144213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov            }
6715005b83b0c62d3d0538f0d566b08bd457015ec661Svetoslav Ganov            // Just break the tie somehow. The accessibliity ids are unique
6716005b83b0c62d3d0538f0d566b08bd457015ec661Svetoslav Ganov            // and stable, hence this is deterministic tie breaking.
6717005b83b0c62d3d0538f0d566b08bd457015ec661Svetoslav Ganov            return mView.getAccessibilityViewId() - another.mView.getAccessibilityViewId();
67184213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov        }
67194213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov
67204213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov        private void init(ViewGroup root, View view) {
67214213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov            Rect viewLocation = mLocation;
67224213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov            view.getDrawingRect(viewLocation);
67234213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov            root.offsetDescendantRectToMyCoords(view, viewLocation);
67244213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov            mView = view;
6725e56ffdc7b31b0937628609cc3bbaa15879023569Fabrice Di Meglio            mLayoutDirection = root.getLayoutDirection();
67264213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov        }
67274213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov
67284213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov        private void clear() {
67294213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov            mView = null;
67304213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov            mLocation.set(0, 0, 0, 0);
67314213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov        }
67324213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov    }
6733cbc6774ef0285956da74193e5d217738e7411830Romain Guy
6734cbc6774ef0285956da74193e5d217738e7411830Romain Guy    private static Paint getDebugPaint() {
6735cbc6774ef0285956da74193e5d217738e7411830Romain Guy        if (sDebugPaint == null) {
6736cbc6774ef0285956da74193e5d217738e7411830Romain Guy            sDebugPaint = new Paint();
6737cbc6774ef0285956da74193e5d217738e7411830Romain Guy            sDebugPaint.setAntiAlias(false);
6738cbc6774ef0285956da74193e5d217738e7411830Romain Guy        }
6739cbc6774ef0285956da74193e5d217738e7411830Romain Guy        return sDebugPaint;
6740cbc6774ef0285956da74193e5d217738e7411830Romain Guy    }
6741cbc6774ef0285956da74193e5d217738e7411830Romain Guy
67426410c0aaf13c9aec606b90ee942f2ac2d98b1609Romain Guy    private static void drawRect(Canvas canvas, Paint paint, int x1, int y1, int x2, int y2) {
6743cbc6774ef0285956da74193e5d217738e7411830Romain Guy        if (sDebugLines== null) {
67446410c0aaf13c9aec606b90ee942f2ac2d98b1609Romain Guy            // TODO: This won't work with multiple UI threads in a single process
6745cbc6774ef0285956da74193e5d217738e7411830Romain Guy            sDebugLines = new float[16];
6746cbc6774ef0285956da74193e5d217738e7411830Romain Guy        }
6747cbc6774ef0285956da74193e5d217738e7411830Romain Guy
6748cbc6774ef0285956da74193e5d217738e7411830Romain Guy        sDebugLines[0] = x1;
6749cbc6774ef0285956da74193e5d217738e7411830Romain Guy        sDebugLines[1] = y1;
6750cbc6774ef0285956da74193e5d217738e7411830Romain Guy        sDebugLines[2] = x2;
6751cbc6774ef0285956da74193e5d217738e7411830Romain Guy        sDebugLines[3] = y1;
6752cbc6774ef0285956da74193e5d217738e7411830Romain Guy
6753cbc6774ef0285956da74193e5d217738e7411830Romain Guy        sDebugLines[4] = x2;
6754cbc6774ef0285956da74193e5d217738e7411830Romain Guy        sDebugLines[5] = y1;
6755cbc6774ef0285956da74193e5d217738e7411830Romain Guy        sDebugLines[6] = x2;
67567b7578184567f4e4f0740ce935cc192765410ccaPhilip Milne        sDebugLines[7] = y2;
6757cbc6774ef0285956da74193e5d217738e7411830Romain Guy
67587b7578184567f4e4f0740ce935cc192765410ccaPhilip Milne        sDebugLines[8] = x2;
6759cbc6774ef0285956da74193e5d217738e7411830Romain Guy        sDebugLines[9] = y2;
6760cbc6774ef0285956da74193e5d217738e7411830Romain Guy        sDebugLines[10] = x1;
6761cbc6774ef0285956da74193e5d217738e7411830Romain Guy        sDebugLines[11] = y2;
6762cbc6774ef0285956da74193e5d217738e7411830Romain Guy
67637b7578184567f4e4f0740ce935cc192765410ccaPhilip Milne        sDebugLines[12] = x1;
67647b7578184567f4e4f0740ce935cc192765410ccaPhilip Milne        sDebugLines[13] = y2;
6765cbc6774ef0285956da74193e5d217738e7411830Romain Guy        sDebugLines[14] = x1;
6766cbc6774ef0285956da74193e5d217738e7411830Romain Guy        sDebugLines[15] = y1;
6767cbc6774ef0285956da74193e5d217738e7411830Romain Guy
67687b7578184567f4e4f0740ce935cc192765410ccaPhilip Milne        canvas.drawLines(sDebugLines, paint);
6769cbc6774ef0285956da74193e5d217738e7411830Romain Guy    }
67709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
6771