197341bdc5bea1d7bf777de65228039142d249f38Adam Powell/*
297341bdc5bea1d7bf777de65228039142d249f38Adam Powell * Copyright (C) 2012 The Android Open Source Project
397341bdc5bea1d7bf777de65228039142d249f38Adam Powell *
497341bdc5bea1d7bf777de65228039142d249f38Adam Powell * Licensed under the Apache License, Version 2.0 (the "License");
597341bdc5bea1d7bf777de65228039142d249f38Adam Powell * you may not use this file except in compliance with the License.
697341bdc5bea1d7bf777de65228039142d249f38Adam Powell * You may obtain a copy of the License at
797341bdc5bea1d7bf777de65228039142d249f38Adam Powell *
897341bdc5bea1d7bf777de65228039142d249f38Adam Powell *      http://www.apache.org/licenses/LICENSE-2.0
997341bdc5bea1d7bf777de65228039142d249f38Adam Powell *
1097341bdc5bea1d7bf777de65228039142d249f38Adam Powell * Unless required by applicable law or agreed to in writing, software
1197341bdc5bea1d7bf777de65228039142d249f38Adam Powell * distributed under the License is distributed on an "AS IS" BASIS,
1297341bdc5bea1d7bf777de65228039142d249f38Adam Powell * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1397341bdc5bea1d7bf777de65228039142d249f38Adam Powell * See the License for the specific language governing permissions and
1497341bdc5bea1d7bf777de65228039142d249f38Adam Powell * limitations under the License.
1597341bdc5bea1d7bf777de65228039142d249f38Adam Powell */
1697341bdc5bea1d7bf777de65228039142d249f38Adam Powell
1797341bdc5bea1d7bf777de65228039142d249f38Adam Powellpackage android.support.v4.widget;
1897341bdc5bea1d7bf777de65228039142d249f38Adam Powell
1997341bdc5bea1d7bf777de65228039142d249f38Adam Powellimport android.content.Context;
2097341bdc5bea1d7bf777de65228039142d249f38Adam Powellimport android.content.res.TypedArray;
2197341bdc5bea1d7bf777de65228039142d249f38Adam Powellimport android.graphics.Bitmap;
2297341bdc5bea1d7bf777de65228039142d249f38Adam Powellimport android.graphics.Canvas;
2397341bdc5bea1d7bf777de65228039142d249f38Adam Powellimport android.graphics.Paint;
24c89f53833f1e272d32f7928837f0704fa33be309Adam Powellimport android.graphics.PixelFormat;
2597341bdc5bea1d7bf777de65228039142d249f38Adam Powellimport android.graphics.PorterDuff;
2697341bdc5bea1d7bf777de65228039142d249f38Adam Powellimport android.graphics.PorterDuffColorFilter;
271e43161e9e1f1dc10637a68d5c2304c1f95c9c46Adam Powellimport android.graphics.Rect;
28ee3f0ffb0199e295cbf48aa1a61c8ae7056526abAdam Powellimport android.graphics.drawable.Drawable;
2997341bdc5bea1d7bf777de65228039142d249f38Adam Powellimport android.os.Build;
3097341bdc5bea1d7bf777de65228039142d249f38Adam Powellimport android.os.Parcel;
3197341bdc5bea1d7bf777de65228039142d249f38Adam Powellimport android.os.Parcelable;
32a3ff3273e976adf19770651dcf473fa67b38eb22Tor Norbyeimport android.support.annotation.DrawableRes;
33c89f53833f1e272d32f7928837f0704fa33be309Adam Powellimport android.support.v4.view.AccessibilityDelegateCompat;
3497341bdc5bea1d7bf777de65228039142d249f38Adam Powellimport android.support.v4.view.MotionEventCompat;
3597341bdc5bea1d7bf777de65228039142d249f38Adam Powellimport android.support.v4.view.ViewCompat;
36c89f53833f1e272d32f7928837f0704fa33be309Adam Powellimport android.support.v4.view.accessibility.AccessibilityNodeInfoCompat;
3797341bdc5bea1d7bf777de65228039142d249f38Adam Powellimport android.util.AttributeSet;
3897341bdc5bea1d7bf777de65228039142d249f38Adam Powellimport android.util.Log;
3997341bdc5bea1d7bf777de65228039142d249f38Adam Powellimport android.view.MotionEvent;
4097341bdc5bea1d7bf777de65228039142d249f38Adam Powellimport android.view.View;
4197341bdc5bea1d7bf777de65228039142d249f38Adam Powellimport android.view.ViewConfiguration;
4297341bdc5bea1d7bf777de65228039142d249f38Adam Powellimport android.view.ViewGroup;
433cf6141d516a0a6170823b1bda5c0b6d7500e76cAdam Powellimport android.view.ViewParent;
44c89f53833f1e272d32f7928837f0704fa33be309Adam Powellimport android.view.accessibility.AccessibilityEvent;
4597341bdc5bea1d7bf777de65228039142d249f38Adam Powell
4697341bdc5bea1d7bf777de65228039142d249f38Adam Powellimport java.lang.reflect.Field;
4797341bdc5bea1d7bf777de65228039142d249f38Adam Powellimport java.lang.reflect.Method;
48f4445e06a8490b056cd892c4bc640dfd17905d6cAdam Powellimport java.util.ArrayList;
4997341bdc5bea1d7bf777de65228039142d249f38Adam Powell
5097341bdc5bea1d7bf777de65228039142d249f38Adam Powell/**
5197341bdc5bea1d7bf777de65228039142d249f38Adam Powell * SlidingPaneLayout provides a horizontal, multi-pane layout for use at the top level
52ee3f0ffb0199e295cbf48aa1a61c8ae7056526abAdam Powell * of a UI. A left (or first) pane is treated as a content list or browser, subordinate to a
5397341bdc5bea1d7bf777de65228039142d249f38Adam Powell * primary detail view for displaying content.
5497341bdc5bea1d7bf777de65228039142d249f38Adam Powell *
5597341bdc5bea1d7bf777de65228039142d249f38Adam Powell * <p>Child views may overlap if their combined width exceeds the available width
5697341bdc5bea1d7bf777de65228039142d249f38Adam Powell * in the SlidingPaneLayout. When this occurs the user may slide the topmost view out of the way
5797341bdc5bea1d7bf777de65228039142d249f38Adam Powell * by dragging it, or by navigating in the direction of the overlapped view using a keyboard.
5897341bdc5bea1d7bf777de65228039142d249f38Adam Powell * If the content of the dragged child view is itself horizontally scrollable, the user may
5997341bdc5bea1d7bf777de65228039142d249f38Adam Powell * grab it by the very edge.</p>
6097341bdc5bea1d7bf777de65228039142d249f38Adam Powell *
6197341bdc5bea1d7bf777de65228039142d249f38Adam Powell * <p>Thanks to this sliding behavior, SlidingPaneLayout may be suitable for creating layouts
6297341bdc5bea1d7bf777de65228039142d249f38Adam Powell * that can smoothly adapt across many different screen sizes, expanding out fully on larger
6397341bdc5bea1d7bf777de65228039142d249f38Adam Powell * screens and collapsing on smaller screens.</p>
6497341bdc5bea1d7bf777de65228039142d249f38Adam Powell *
65ee3f0ffb0199e295cbf48aa1a61c8ae7056526abAdam Powell * <p>SlidingPaneLayout is distinct from a navigation drawer as described in the design
66ee3f0ffb0199e295cbf48aa1a61c8ae7056526abAdam Powell * guide and should not be used in the same scenarios. SlidingPaneLayout should be thought
67ee3f0ffb0199e295cbf48aa1a61c8ae7056526abAdam Powell * of only as a way to allow a two-pane layout normally used on larger screens to adapt to smaller
68ee3f0ffb0199e295cbf48aa1a61c8ae7056526abAdam Powell * screens in a natural way. The interaction patterns expressed by SlidingPaneLayout imply
69ee3f0ffb0199e295cbf48aa1a61c8ae7056526abAdam Powell * a physicality and direct information hierarchy between panes that does not necessarily exist
70ee3f0ffb0199e295cbf48aa1a61c8ae7056526abAdam Powell * in a scenario where a navigation drawer should be used instead.</p>
71ee3f0ffb0199e295cbf48aa1a61c8ae7056526abAdam Powell *
72ee3f0ffb0199e295cbf48aa1a61c8ae7056526abAdam Powell * <p>Appropriate uses of SlidingPaneLayout include pairings of panes such as a contact list and
73ee3f0ffb0199e295cbf48aa1a61c8ae7056526abAdam Powell * subordinate interactions with those contacts, or an email thread list with the content pane
74ee3f0ffb0199e295cbf48aa1a61c8ae7056526abAdam Powell * displaying the contents of the selected thread. Inappropriate uses of SlidingPaneLayout include
75ee3f0ffb0199e295cbf48aa1a61c8ae7056526abAdam Powell * switching between disparate functions of your app, such as jumping from a social stream view
76ee3f0ffb0199e295cbf48aa1a61c8ae7056526abAdam Powell * to a view of your personal profile - cases such as this should use the navigation drawer
771d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * pattern instead. ({@link DrawerLayout DrawerLayout} implements this pattern.)</p>
78ee3f0ffb0199e295cbf48aa1a61c8ae7056526abAdam Powell *
7997341bdc5bea1d7bf777de65228039142d249f38Adam Powell * <p>Like {@link android.widget.LinearLayout LinearLayout}, SlidingPaneLayout supports
8097341bdc5bea1d7bf777de65228039142d249f38Adam Powell * the use of the layout parameter <code>layout_weight</code> on child views to determine
8197341bdc5bea1d7bf777de65228039142d249f38Adam Powell * how to divide leftover space after measurement is complete. It is only relevant for width.
8297341bdc5bea1d7bf777de65228039142d249f38Adam Powell * When views do not overlap weight behaves as it does in a LinearLayout.</p>
8397341bdc5bea1d7bf777de65228039142d249f38Adam Powell *
8497341bdc5bea1d7bf777de65228039142d249f38Adam Powell * <p>When views do overlap, weight on a slideable pane indicates that the pane should be
8597341bdc5bea1d7bf777de65228039142d249f38Adam Powell * sized to fill all available space in the closed state. Weight on a pane that becomes covered
8697341bdc5bea1d7bf777de65228039142d249f38Adam Powell * indicates that the pane should be sized to fill all available space except a small minimum strip
8797341bdc5bea1d7bf777de65228039142d249f38Adam Powell * that the user may use to grab the slideable view and pull it back over into a closed state.</p>
8897341bdc5bea1d7bf777de65228039142d249f38Adam Powell */
8997341bdc5bea1d7bf777de65228039142d249f38Adam Powellpublic class SlidingPaneLayout extends ViewGroup {
9097341bdc5bea1d7bf777de65228039142d249f38Adam Powell    private static final String TAG = "SlidingPaneLayout";
9197341bdc5bea1d7bf777de65228039142d249f38Adam Powell
9297341bdc5bea1d7bf777de65228039142d249f38Adam Powell    /**
9397341bdc5bea1d7bf777de65228039142d249f38Adam Powell     * Default size of the overhang for a pane in the open state.
9497341bdc5bea1d7bf777de65228039142d249f38Adam Powell     * At least this much of a sliding pane will remain visible.
9597341bdc5bea1d7bf777de65228039142d249f38Adam Powell     * This indicates that there is more content available and provides
9697341bdc5bea1d7bf777de65228039142d249f38Adam Powell     * a "physical" edge to grab to pull it closed.
9797341bdc5bea1d7bf777de65228039142d249f38Adam Powell     */
98ee3f0ffb0199e295cbf48aa1a61c8ae7056526abAdam Powell    private static final int DEFAULT_OVERHANG_SIZE = 32; // dp;
9997341bdc5bea1d7bf777de65228039142d249f38Adam Powell
10097341bdc5bea1d7bf777de65228039142d249f38Adam Powell    /**
101ee3f0ffb0199e295cbf48aa1a61c8ae7056526abAdam Powell     * If no fade color is given by default it will fade to 80% gray.
102ee3f0ffb0199e295cbf48aa1a61c8ae7056526abAdam Powell     */
103ee3f0ffb0199e295cbf48aa1a61c8ae7056526abAdam Powell    private static final int DEFAULT_FADE_COLOR = 0xcccccccc;
104ee3f0ffb0199e295cbf48aa1a61c8ae7056526abAdam Powell
105ee3f0ffb0199e295cbf48aa1a61c8ae7056526abAdam Powell    /**
10681e2f002d1b4ebf2d951eb9f239858b8a9481a24Adam Powell     * The fade color used for the sliding panel. 0 = no fading.
10781e2f002d1b4ebf2d951eb9f239858b8a9481a24Adam Powell     */
10881e2f002d1b4ebf2d951eb9f239858b8a9481a24Adam Powell    private int mSliderFadeColor = DEFAULT_FADE_COLOR;
10981e2f002d1b4ebf2d951eb9f239858b8a9481a24Adam Powell
11081e2f002d1b4ebf2d951eb9f239858b8a9481a24Adam Powell    /**
11179f95ce3e660d267831067e514ff455156c4381fAdam Powell     * Minimum velocity that will be detected as a fling
11279f95ce3e660d267831067e514ff455156c4381fAdam Powell     */
11379f95ce3e660d267831067e514ff455156c4381fAdam Powell    private static final int MIN_FLING_VELOCITY = 400; // dips per second
11479f95ce3e660d267831067e514ff455156c4381fAdam Powell
11579f95ce3e660d267831067e514ff455156c4381fAdam Powell    /**
11681e2f002d1b4ebf2d951eb9f239858b8a9481a24Adam Powell     * The fade color used for the panel covered by the slider. 0 = no fading.
11781e2f002d1b4ebf2d951eb9f239858b8a9481a24Adam Powell     */
11881e2f002d1b4ebf2d951eb9f239858b8a9481a24Adam Powell    private int mCoveredFadeColor;
11981e2f002d1b4ebf2d951eb9f239858b8a9481a24Adam Powell
12081e2f002d1b4ebf2d951eb9f239858b8a9481a24Adam Powell    /**
12119780f88506df4aeb57456fd6747af1b6848a11cfafaisland     * Drawable used to draw the shadow between panes by default.
122ee3f0ffb0199e295cbf48aa1a61c8ae7056526abAdam Powell     */
12319780f88506df4aeb57456fd6747af1b6848a11cfafaisland    private Drawable mShadowDrawableLeft;
12419780f88506df4aeb57456fd6747af1b6848a11cfafaisland
12519780f88506df4aeb57456fd6747af1b6848a11cfafaisland    /**
12619780f88506df4aeb57456fd6747af1b6848a11cfafaisland     * Drawable used to draw the shadow between panes to support RTL (right to left language).
12719780f88506df4aeb57456fd6747af1b6848a11cfafaisland     */
12819780f88506df4aeb57456fd6747af1b6848a11cfafaisland    private Drawable mShadowDrawableRight;
129ee3f0ffb0199e295cbf48aa1a61c8ae7056526abAdam Powell
130ee3f0ffb0199e295cbf48aa1a61c8ae7056526abAdam Powell    /**
13197341bdc5bea1d7bf777de65228039142d249f38Adam Powell     * The size of the overhang in pixels.
13297341bdc5bea1d7bf777de65228039142d249f38Adam Powell     * This is the minimum section of the sliding panel that will
13397341bdc5bea1d7bf777de65228039142d249f38Adam Powell     * be visible in the open state to allow for a closing drag.
13497341bdc5bea1d7bf777de65228039142d249f38Adam Powell     */
13597341bdc5bea1d7bf777de65228039142d249f38Adam Powell    private final int mOverhangSize;
13697341bdc5bea1d7bf777de65228039142d249f38Adam Powell
13797341bdc5bea1d7bf777de65228039142d249f38Adam Powell    /**
13897341bdc5bea1d7bf777de65228039142d249f38Adam Powell     * True if a panel can slide with the current measurements
13997341bdc5bea1d7bf777de65228039142d249f38Adam Powell     */
14097341bdc5bea1d7bf777de65228039142d249f38Adam Powell    private boolean mCanSlide;
14197341bdc5bea1d7bf777de65228039142d249f38Adam Powell
14297341bdc5bea1d7bf777de65228039142d249f38Adam Powell    /**
1430eefe9ad0819b223006533cbc79a35d66684af32Adam Powell     * The child view that can slide, if any.
14497341bdc5bea1d7bf777de65228039142d249f38Adam Powell     */
1450eefe9ad0819b223006533cbc79a35d66684af32Adam Powell    private View mSlideableView;
14697341bdc5bea1d7bf777de65228039142d249f38Adam Powell
1470eefe9ad0819b223006533cbc79a35d66684af32Adam Powell    /**
1480eefe9ad0819b223006533cbc79a35d66684af32Adam Powell     * How far the panel is offset from its closed position.
1490eefe9ad0819b223006533cbc79a35d66684af32Adam Powell     * range [0, 1] where 0 = closed, 1 = open.
1500eefe9ad0819b223006533cbc79a35d66684af32Adam Powell     */
1510eefe9ad0819b223006533cbc79a35d66684af32Adam Powell    private float mSlideOffset;
1520eefe9ad0819b223006533cbc79a35d66684af32Adam Powell
1530eefe9ad0819b223006533cbc79a35d66684af32Adam Powell    /**
1540eefe9ad0819b223006533cbc79a35d66684af32Adam Powell     * How far the non-sliding panel is parallaxed from its usual position when open.
1550eefe9ad0819b223006533cbc79a35d66684af32Adam Powell     * range [0, 1]
1560eefe9ad0819b223006533cbc79a35d66684af32Adam Powell     */
1570eefe9ad0819b223006533cbc79a35d66684af32Adam Powell    private float mParallaxOffset;
1580eefe9ad0819b223006533cbc79a35d66684af32Adam Powell
1590eefe9ad0819b223006533cbc79a35d66684af32Adam Powell    /**
1600eefe9ad0819b223006533cbc79a35d66684af32Adam Powell     * How far in pixels the slideable panel may move.
1610eefe9ad0819b223006533cbc79a35d66684af32Adam Powell     */
1620eefe9ad0819b223006533cbc79a35d66684af32Adam Powell    private int mSlideRange;
16397341bdc5bea1d7bf777de65228039142d249f38Adam Powell
16497341bdc5bea1d7bf777de65228039142d249f38Adam Powell    /**
16597341bdc5bea1d7bf777de65228039142d249f38Adam Powell     * A panel view is locked into internal scrolling or another condition that
16697341bdc5bea1d7bf777de65228039142d249f38Adam Powell     * is preventing a drag.
16797341bdc5bea1d7bf777de65228039142d249f38Adam Powell     */
16897341bdc5bea1d7bf777de65228039142d249f38Adam Powell    private boolean mIsUnableToDrag;
16997341bdc5bea1d7bf777de65228039142d249f38Adam Powell
1706debd2bbcae1cd285d2e21db633998b7801f9f40Adam Powell    /**
1716debd2bbcae1cd285d2e21db633998b7801f9f40Adam Powell     * Distance in pixels to parallax the fixed pane by when fully closed
1726debd2bbcae1cd285d2e21db633998b7801f9f40Adam Powell     */
1736debd2bbcae1cd285d2e21db633998b7801f9f40Adam Powell    private int mParallaxBy;
1746debd2bbcae1cd285d2e21db633998b7801f9f40Adam Powell
17597341bdc5bea1d7bf777de65228039142d249f38Adam Powell    private float mInitialMotionX;
176ee3f0ffb0199e295cbf48aa1a61c8ae7056526abAdam Powell    private float mInitialMotionY;
17797341bdc5bea1d7bf777de65228039142d249f38Adam Powell
17897341bdc5bea1d7bf777de65228039142d249f38Adam Powell    private PanelSlideListener mPanelSlideListener;
17997341bdc5bea1d7bf777de65228039142d249f38Adam Powell
180c56ba65d20be8742ff717907a3a2cd81dd0e5f3cAdam Powell    private final ViewDragHelper mDragHelper;
181c56ba65d20be8742ff717907a3a2cd81dd0e5f3cAdam Powell
18289e17886e6149bddfdb08a242c9e88889596419cAdam Powell    /**
18389e17886e6149bddfdb08a242c9e88889596419cAdam Powell     * Stores whether or not the pane was open the last time it was slideable.
18489e17886e6149bddfdb08a242c9e88889596419cAdam Powell     * If open/close operations are invoked this state is modified. Used by
18589e17886e6149bddfdb08a242c9e88889596419cAdam Powell     * instance state save/restore.
18689e17886e6149bddfdb08a242c9e88889596419cAdam Powell     */
18789e17886e6149bddfdb08a242c9e88889596419cAdam Powell    private boolean mPreservedOpenState;
18889e17886e6149bddfdb08a242c9e88889596419cAdam Powell    private boolean mFirstLayout = true;
18989e17886e6149bddfdb08a242c9e88889596419cAdam Powell
1901e43161e9e1f1dc10637a68d5c2304c1f95c9c46Adam Powell    private final Rect mTmpRect = new Rect();
1911e43161e9e1f1dc10637a68d5c2304c1f95c9c46Adam Powell
192f4445e06a8490b056cd892c4bc640dfd17905d6cAdam Powell    private final ArrayList<DisableLayerRunnable> mPostedRunnables =
193f4445e06a8490b056cd892c4bc640dfd17905d6cAdam Powell            new ArrayList<DisableLayerRunnable>();
194f4445e06a8490b056cd892c4bc640dfd17905d6cAdam Powell
19597341bdc5bea1d7bf777de65228039142d249f38Adam Powell    static final SlidingPanelLayoutImpl IMPL;
19697341bdc5bea1d7bf777de65228039142d249f38Adam Powell
19797341bdc5bea1d7bf777de65228039142d249f38Adam Powell    static {
1986debd2bbcae1cd285d2e21db633998b7801f9f40Adam Powell        final int deviceVersion = Build.VERSION.SDK_INT;
1996debd2bbcae1cd285d2e21db633998b7801f9f40Adam Powell        if (deviceVersion >= 17) {
2006debd2bbcae1cd285d2e21db633998b7801f9f40Adam Powell            IMPL = new SlidingPanelLayoutImplJBMR1();
2016debd2bbcae1cd285d2e21db633998b7801f9f40Adam Powell        } else if (deviceVersion >= 16) {
20297341bdc5bea1d7bf777de65228039142d249f38Adam Powell            IMPL = new SlidingPanelLayoutImplJB();
20397341bdc5bea1d7bf777de65228039142d249f38Adam Powell        } else {
20497341bdc5bea1d7bf777de65228039142d249f38Adam Powell            IMPL = new SlidingPanelLayoutImplBase();
20597341bdc5bea1d7bf777de65228039142d249f38Adam Powell        }
20697341bdc5bea1d7bf777de65228039142d249f38Adam Powell    }
20797341bdc5bea1d7bf777de65228039142d249f38Adam Powell
20897341bdc5bea1d7bf777de65228039142d249f38Adam Powell    /**
20997341bdc5bea1d7bf777de65228039142d249f38Adam Powell     * Listener for monitoring events about sliding panes.
21097341bdc5bea1d7bf777de65228039142d249f38Adam Powell     */
21197341bdc5bea1d7bf777de65228039142d249f38Adam Powell    public interface PanelSlideListener {
21297341bdc5bea1d7bf777de65228039142d249f38Adam Powell        /**
21397341bdc5bea1d7bf777de65228039142d249f38Adam Powell         * Called when a sliding pane's position changes.
21497341bdc5bea1d7bf777de65228039142d249f38Adam Powell         * @param panel The child view that was moved
21597341bdc5bea1d7bf777de65228039142d249f38Adam Powell         * @param slideOffset The new offset of this sliding pane within its range, from 0-1
21697341bdc5bea1d7bf777de65228039142d249f38Adam Powell         */
21797341bdc5bea1d7bf777de65228039142d249f38Adam Powell        public void onPanelSlide(View panel, float slideOffset);
21897341bdc5bea1d7bf777de65228039142d249f38Adam Powell        /**
21997341bdc5bea1d7bf777de65228039142d249f38Adam Powell         * Called when a sliding pane becomes slid completely open. The pane may or may not
22097341bdc5bea1d7bf777de65228039142d249f38Adam Powell         * be interactive at this point depending on how much of the pane is visible.
22197341bdc5bea1d7bf777de65228039142d249f38Adam Powell         * @param panel The child view that was slid to an open position, revealing other panes
22297341bdc5bea1d7bf777de65228039142d249f38Adam Powell         */
22397341bdc5bea1d7bf777de65228039142d249f38Adam Powell        public void onPanelOpened(View panel);
22497341bdc5bea1d7bf777de65228039142d249f38Adam Powell
22597341bdc5bea1d7bf777de65228039142d249f38Adam Powell        /**
22697341bdc5bea1d7bf777de65228039142d249f38Adam Powell         * Called when a sliding pane becomes slid completely closed. The pane is now guaranteed
22797341bdc5bea1d7bf777de65228039142d249f38Adam Powell         * to be interactive. It may now obscure other views in the layout.
22897341bdc5bea1d7bf777de65228039142d249f38Adam Powell         * @param panel The child view that was slid to a closed position
22997341bdc5bea1d7bf777de65228039142d249f38Adam Powell         */
23097341bdc5bea1d7bf777de65228039142d249f38Adam Powell        public void onPanelClosed(View panel);
23197341bdc5bea1d7bf777de65228039142d249f38Adam Powell    }
23297341bdc5bea1d7bf777de65228039142d249f38Adam Powell
23397341bdc5bea1d7bf777de65228039142d249f38Adam Powell    /**
23497341bdc5bea1d7bf777de65228039142d249f38Adam Powell     * No-op stubs for {@link PanelSlideListener}. If you only want to implement a subset
23597341bdc5bea1d7bf777de65228039142d249f38Adam Powell     * of the listener methods you can extend this instead of implement the full interface.
23697341bdc5bea1d7bf777de65228039142d249f38Adam Powell     */
23797341bdc5bea1d7bf777de65228039142d249f38Adam Powell    public static class SimplePanelSlideListener implements PanelSlideListener {
23897341bdc5bea1d7bf777de65228039142d249f38Adam Powell        @Override
23997341bdc5bea1d7bf777de65228039142d249f38Adam Powell        public void onPanelSlide(View panel, float slideOffset) {
24097341bdc5bea1d7bf777de65228039142d249f38Adam Powell        }
24197341bdc5bea1d7bf777de65228039142d249f38Adam Powell        @Override
24297341bdc5bea1d7bf777de65228039142d249f38Adam Powell        public void onPanelOpened(View panel) {
24397341bdc5bea1d7bf777de65228039142d249f38Adam Powell        }
24497341bdc5bea1d7bf777de65228039142d249f38Adam Powell        @Override
24597341bdc5bea1d7bf777de65228039142d249f38Adam Powell        public void onPanelClosed(View panel) {
24697341bdc5bea1d7bf777de65228039142d249f38Adam Powell        }
24797341bdc5bea1d7bf777de65228039142d249f38Adam Powell    }
24897341bdc5bea1d7bf777de65228039142d249f38Adam Powell
24997341bdc5bea1d7bf777de65228039142d249f38Adam Powell    public SlidingPaneLayout(Context context) {
25097341bdc5bea1d7bf777de65228039142d249f38Adam Powell        this(context, null);
25197341bdc5bea1d7bf777de65228039142d249f38Adam Powell    }
25297341bdc5bea1d7bf777de65228039142d249f38Adam Powell
25397341bdc5bea1d7bf777de65228039142d249f38Adam Powell    public SlidingPaneLayout(Context context, AttributeSet attrs) {
25497341bdc5bea1d7bf777de65228039142d249f38Adam Powell        this(context, attrs, 0);
25597341bdc5bea1d7bf777de65228039142d249f38Adam Powell    }
25697341bdc5bea1d7bf777de65228039142d249f38Adam Powell
25797341bdc5bea1d7bf777de65228039142d249f38Adam Powell    public SlidingPaneLayout(Context context, AttributeSet attrs, int defStyle) {
25897341bdc5bea1d7bf777de65228039142d249f38Adam Powell        super(context, attrs, defStyle);
25997341bdc5bea1d7bf777de65228039142d249f38Adam Powell
26097341bdc5bea1d7bf777de65228039142d249f38Adam Powell        final float density = context.getResources().getDisplayMetrics().density;
26197341bdc5bea1d7bf777de65228039142d249f38Adam Powell        mOverhangSize = (int) (DEFAULT_OVERHANG_SIZE * density + 0.5f);
26297341bdc5bea1d7bf777de65228039142d249f38Adam Powell
26397341bdc5bea1d7bf777de65228039142d249f38Adam Powell        final ViewConfiguration viewConfig = ViewConfiguration.get(context);
264ee3f0ffb0199e295cbf48aa1a61c8ae7056526abAdam Powell
265ee3f0ffb0199e295cbf48aa1a61c8ae7056526abAdam Powell        setWillNotDraw(false);
266c56ba65d20be8742ff717907a3a2cd81dd0e5f3cAdam Powell
267c89f53833f1e272d32f7928837f0704fa33be309Adam Powell        ViewCompat.setAccessibilityDelegate(this, new AccessibilityDelegate());
268d0cb2111677748ec19a72e5fe18c8c64a359a751Adam Powell        ViewCompat.setImportantForAccessibility(this, ViewCompat.IMPORTANT_FOR_ACCESSIBILITY_YES);
269c89f53833f1e272d32f7928837f0704fa33be309Adam Powell
2701d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell        mDragHelper = ViewDragHelper.create(this, 0.5f, new DragHelperCallback());
27179f95ce3e660d267831067e514ff455156c4381fAdam Powell        mDragHelper.setMinVelocity(MIN_FLING_VELOCITY * density);
27297341bdc5bea1d7bf777de65228039142d249f38Adam Powell    }
27397341bdc5bea1d7bf777de65228039142d249f38Adam Powell
2746debd2bbcae1cd285d2e21db633998b7801f9f40Adam Powell    /**
2756debd2bbcae1cd285d2e21db633998b7801f9f40Adam Powell     * Set a distance to parallax the lower pane by when the upper pane is in its
2766debd2bbcae1cd285d2e21db633998b7801f9f40Adam Powell     * fully closed state. The lower pane will scroll between this position and
2776debd2bbcae1cd285d2e21db633998b7801f9f40Adam Powell     * its fully open state.
2786debd2bbcae1cd285d2e21db633998b7801f9f40Adam Powell     *
2796debd2bbcae1cd285d2e21db633998b7801f9f40Adam Powell     * @param parallaxBy Distance to parallax by in pixels
2806debd2bbcae1cd285d2e21db633998b7801f9f40Adam Powell     */
2816debd2bbcae1cd285d2e21db633998b7801f9f40Adam Powell    public void setParallaxDistance(int parallaxBy) {
2826debd2bbcae1cd285d2e21db633998b7801f9f40Adam Powell        mParallaxBy = parallaxBy;
2836debd2bbcae1cd285d2e21db633998b7801f9f40Adam Powell        requestLayout();
2846debd2bbcae1cd285d2e21db633998b7801f9f40Adam Powell    }
2856debd2bbcae1cd285d2e21db633998b7801f9f40Adam Powell
2866debd2bbcae1cd285d2e21db633998b7801f9f40Adam Powell    /**
2876debd2bbcae1cd285d2e21db633998b7801f9f40Adam Powell     * @return The distance the lower pane will parallax by when the upper pane is fully closed.
2886debd2bbcae1cd285d2e21db633998b7801f9f40Adam Powell     *
2896debd2bbcae1cd285d2e21db633998b7801f9f40Adam Powell     * @see #setParallaxDistance(int)
2906debd2bbcae1cd285d2e21db633998b7801f9f40Adam Powell     */
2916debd2bbcae1cd285d2e21db633998b7801f9f40Adam Powell    public int getParallaxDistance() {
2926debd2bbcae1cd285d2e21db633998b7801f9f40Adam Powell        return mParallaxBy;
2936debd2bbcae1cd285d2e21db633998b7801f9f40Adam Powell    }
2946debd2bbcae1cd285d2e21db633998b7801f9f40Adam Powell
29581e2f002d1b4ebf2d951eb9f239858b8a9481a24Adam Powell    /**
29681e2f002d1b4ebf2d951eb9f239858b8a9481a24Adam Powell     * Set the color used to fade the sliding pane out when it is slid most of the way offscreen.
29781e2f002d1b4ebf2d951eb9f239858b8a9481a24Adam Powell     *
29881e2f002d1b4ebf2d951eb9f239858b8a9481a24Adam Powell     * @param color An ARGB-packed color value
29981e2f002d1b4ebf2d951eb9f239858b8a9481a24Adam Powell     */
30081e2f002d1b4ebf2d951eb9f239858b8a9481a24Adam Powell    public void setSliderFadeColor(int color) {
30181e2f002d1b4ebf2d951eb9f239858b8a9481a24Adam Powell        mSliderFadeColor = color;
30281e2f002d1b4ebf2d951eb9f239858b8a9481a24Adam Powell    }
30381e2f002d1b4ebf2d951eb9f239858b8a9481a24Adam Powell
30481e2f002d1b4ebf2d951eb9f239858b8a9481a24Adam Powell    /**
30581e2f002d1b4ebf2d951eb9f239858b8a9481a24Adam Powell     * @return The ARGB-packed color value used to fade the sliding pane
30681e2f002d1b4ebf2d951eb9f239858b8a9481a24Adam Powell     */
30781e2f002d1b4ebf2d951eb9f239858b8a9481a24Adam Powell    public int getSliderFadeColor() {
30881e2f002d1b4ebf2d951eb9f239858b8a9481a24Adam Powell        return mSliderFadeColor;
30981e2f002d1b4ebf2d951eb9f239858b8a9481a24Adam Powell    }
31081e2f002d1b4ebf2d951eb9f239858b8a9481a24Adam Powell
31181e2f002d1b4ebf2d951eb9f239858b8a9481a24Adam Powell    /**
31281e2f002d1b4ebf2d951eb9f239858b8a9481a24Adam Powell     * Set the color used to fade the pane covered by the sliding pane out when the pane
31381e2f002d1b4ebf2d951eb9f239858b8a9481a24Adam Powell     * will become fully covered in the closed state.
31481e2f002d1b4ebf2d951eb9f239858b8a9481a24Adam Powell     *
31581e2f002d1b4ebf2d951eb9f239858b8a9481a24Adam Powell     * @param color An ARGB-packed color value
31681e2f002d1b4ebf2d951eb9f239858b8a9481a24Adam Powell     */
31781e2f002d1b4ebf2d951eb9f239858b8a9481a24Adam Powell    public void setCoveredFadeColor(int color) {
31881e2f002d1b4ebf2d951eb9f239858b8a9481a24Adam Powell        mCoveredFadeColor = color;
31981e2f002d1b4ebf2d951eb9f239858b8a9481a24Adam Powell    }
32081e2f002d1b4ebf2d951eb9f239858b8a9481a24Adam Powell
32181e2f002d1b4ebf2d951eb9f239858b8a9481a24Adam Powell    /**
32281e2f002d1b4ebf2d951eb9f239858b8a9481a24Adam Powell     * @return The ARGB-packed color value used to fade the fixed pane
32381e2f002d1b4ebf2d951eb9f239858b8a9481a24Adam Powell     */
32481e2f002d1b4ebf2d951eb9f239858b8a9481a24Adam Powell    public int getCoveredFadeColor() {
32581e2f002d1b4ebf2d951eb9f239858b8a9481a24Adam Powell        return mCoveredFadeColor;
32681e2f002d1b4ebf2d951eb9f239858b8a9481a24Adam Powell    }
32781e2f002d1b4ebf2d951eb9f239858b8a9481a24Adam Powell
32897341bdc5bea1d7bf777de65228039142d249f38Adam Powell    public void setPanelSlideListener(PanelSlideListener listener) {
32997341bdc5bea1d7bf777de65228039142d249f38Adam Powell        mPanelSlideListener = listener;
33097341bdc5bea1d7bf777de65228039142d249f38Adam Powell    }
33197341bdc5bea1d7bf777de65228039142d249f38Adam Powell
33297341bdc5bea1d7bf777de65228039142d249f38Adam Powell    void dispatchOnPanelSlide(View panel) {
33397341bdc5bea1d7bf777de65228039142d249f38Adam Powell        if (mPanelSlideListener != null) {
3340eefe9ad0819b223006533cbc79a35d66684af32Adam Powell            mPanelSlideListener.onPanelSlide(panel, mSlideOffset);
33597341bdc5bea1d7bf777de65228039142d249f38Adam Powell        }
33697341bdc5bea1d7bf777de65228039142d249f38Adam Powell    }
33797341bdc5bea1d7bf777de65228039142d249f38Adam Powell
33897341bdc5bea1d7bf777de65228039142d249f38Adam Powell    void dispatchOnPanelOpened(View panel) {
33997341bdc5bea1d7bf777de65228039142d249f38Adam Powell        if (mPanelSlideListener != null) {
34097341bdc5bea1d7bf777de65228039142d249f38Adam Powell            mPanelSlideListener.onPanelOpened(panel);
34197341bdc5bea1d7bf777de65228039142d249f38Adam Powell        }
342c89f53833f1e272d32f7928837f0704fa33be309Adam Powell        sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);
34397341bdc5bea1d7bf777de65228039142d249f38Adam Powell    }
34497341bdc5bea1d7bf777de65228039142d249f38Adam Powell
34597341bdc5bea1d7bf777de65228039142d249f38Adam Powell    void dispatchOnPanelClosed(View panel) {
34697341bdc5bea1d7bf777de65228039142d249f38Adam Powell        if (mPanelSlideListener != null) {
34797341bdc5bea1d7bf777de65228039142d249f38Adam Powell            mPanelSlideListener.onPanelClosed(panel);
34897341bdc5bea1d7bf777de65228039142d249f38Adam Powell        }
349c89f53833f1e272d32f7928837f0704fa33be309Adam Powell        sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);
350c89f53833f1e272d32f7928837f0704fa33be309Adam Powell    }
351c89f53833f1e272d32f7928837f0704fa33be309Adam Powell
352c89f53833f1e272d32f7928837f0704fa33be309Adam Powell    void updateObscuredViewsVisibility(View panel) {
35319780f88506df4aeb57456fd6747af1b6848a11cfafaisland        final boolean isLayoutRtl = isLayoutRtlSupport();
35419780f88506df4aeb57456fd6747af1b6848a11cfafaisland        final int startBound = isLayoutRtl ? (getWidth() - getPaddingRight()) :
35519780f88506df4aeb57456fd6747af1b6848a11cfafaisland            getPaddingLeft();
35619780f88506df4aeb57456fd6747af1b6848a11cfafaisland        final int endBound = isLayoutRtl ? getPaddingLeft() :
35719780f88506df4aeb57456fd6747af1b6848a11cfafaisland            (getWidth() - getPaddingRight());
358f993018935168724fd4972edcf418fae09d81680Adam Powell        final int topBound = getPaddingTop();
359f993018935168724fd4972edcf418fae09d81680Adam Powell        final int bottomBound = getHeight() - getPaddingBottom();
360c89f53833f1e272d32f7928837f0704fa33be309Adam Powell        final int left;
361c89f53833f1e272d32f7928837f0704fa33be309Adam Powell        final int right;
362c89f53833f1e272d32f7928837f0704fa33be309Adam Powell        final int top;
363c89f53833f1e272d32f7928837f0704fa33be309Adam Powell        final int bottom;
364c029e15f5a4709214cb433a562256586824a0f33Adam Powell        if (panel != null && viewIsOpaque(panel)) {
365c89f53833f1e272d32f7928837f0704fa33be309Adam Powell            left = panel.getLeft();
366c89f53833f1e272d32f7928837f0704fa33be309Adam Powell            right = panel.getRight();
367c89f53833f1e272d32f7928837f0704fa33be309Adam Powell            top = panel.getTop();
368c89f53833f1e272d32f7928837f0704fa33be309Adam Powell            bottom = panel.getBottom();
369c89f53833f1e272d32f7928837f0704fa33be309Adam Powell        } else {
370c89f53833f1e272d32f7928837f0704fa33be309Adam Powell            left = right = top = bottom = 0;
371c89f53833f1e272d32f7928837f0704fa33be309Adam Powell        }
372c89f53833f1e272d32f7928837f0704fa33be309Adam Powell
373c89f53833f1e272d32f7928837f0704fa33be309Adam Powell        for (int i = 0, childCount = getChildCount(); i < childCount; i++) {
374c89f53833f1e272d32f7928837f0704fa33be309Adam Powell            final View child = getChildAt(i);
375c89f53833f1e272d32f7928837f0704fa33be309Adam Powell
376c89f53833f1e272d32f7928837f0704fa33be309Adam Powell            if (child == panel) {
377c89f53833f1e272d32f7928837f0704fa33be309Adam Powell                // There are still more children above the panel but they won't be affected.
378c89f53833f1e272d32f7928837f0704fa33be309Adam Powell                break;
379c89f53833f1e272d32f7928837f0704fa33be309Adam Powell            }
380c89f53833f1e272d32f7928837f0704fa33be309Adam Powell
38119780f88506df4aeb57456fd6747af1b6848a11cfafaisland            final int clampedChildLeft = Math.max((isLayoutRtl ? endBound :
38219780f88506df4aeb57456fd6747af1b6848a11cfafaisland                startBound), child.getLeft());
383f993018935168724fd4972edcf418fae09d81680Adam Powell            final int clampedChildTop = Math.max(topBound, child.getTop());
38419780f88506df4aeb57456fd6747af1b6848a11cfafaisland            final int clampedChildRight = Math.min((isLayoutRtl ? startBound :
38519780f88506df4aeb57456fd6747af1b6848a11cfafaisland                endBound), child.getRight());
386f993018935168724fd4972edcf418fae09d81680Adam Powell            final int clampedChildBottom = Math.min(bottomBound, child.getBottom());
387c89f53833f1e272d32f7928837f0704fa33be309Adam Powell            final int vis;
388f993018935168724fd4972edcf418fae09d81680Adam Powell            if (clampedChildLeft >= left && clampedChildTop >= top &&
389f993018935168724fd4972edcf418fae09d81680Adam Powell                    clampedChildRight <= right && clampedChildBottom <= bottom) {
390c89f53833f1e272d32f7928837f0704fa33be309Adam Powell                vis = INVISIBLE;
391c89f53833f1e272d32f7928837f0704fa33be309Adam Powell            } else {
392c89f53833f1e272d32f7928837f0704fa33be309Adam Powell                vis = VISIBLE;
393c89f53833f1e272d32f7928837f0704fa33be309Adam Powell            }
394c89f53833f1e272d32f7928837f0704fa33be309Adam Powell            child.setVisibility(vis);
395c89f53833f1e272d32f7928837f0704fa33be309Adam Powell        }
396c89f53833f1e272d32f7928837f0704fa33be309Adam Powell    }
397c89f53833f1e272d32f7928837f0704fa33be309Adam Powell
398c89f53833f1e272d32f7928837f0704fa33be309Adam Powell    void setAllChildrenVisible() {
399c89f53833f1e272d32f7928837f0704fa33be309Adam Powell        for (int i = 0, childCount = getChildCount(); i < childCount; i++) {
400c89f53833f1e272d32f7928837f0704fa33be309Adam Powell            final View child = getChildAt(i);
401c89f53833f1e272d32f7928837f0704fa33be309Adam Powell            if (child.getVisibility() == INVISIBLE) {
402c89f53833f1e272d32f7928837f0704fa33be309Adam Powell                child.setVisibility(VISIBLE);
403c89f53833f1e272d32f7928837f0704fa33be309Adam Powell            }
404c89f53833f1e272d32f7928837f0704fa33be309Adam Powell        }
405c89f53833f1e272d32f7928837f0704fa33be309Adam Powell    }
406c89f53833f1e272d32f7928837f0704fa33be309Adam Powell
407c029e15f5a4709214cb433a562256586824a0f33Adam Powell    private static boolean viewIsOpaque(View v) {
408c029e15f5a4709214cb433a562256586824a0f33Adam Powell        if (ViewCompat.isOpaque(v)) return true;
409c029e15f5a4709214cb433a562256586824a0f33Adam Powell
410c029e15f5a4709214cb433a562256586824a0f33Adam Powell        // View#isOpaque didn't take all valid opaque scrollbar modes into account
411c029e15f5a4709214cb433a562256586824a0f33Adam Powell        // before API 18 (JB-MR2). On newer devices rely solely on isOpaque above and return false
412c029e15f5a4709214cb433a562256586824a0f33Adam Powell        // here. On older devices, check the view's background drawable directly as a fallback.
413c029e15f5a4709214cb433a562256586824a0f33Adam Powell        if (Build.VERSION.SDK_INT >= 18) return false;
414c029e15f5a4709214cb433a562256586824a0f33Adam Powell
415c89f53833f1e272d32f7928837f0704fa33be309Adam Powell        final Drawable bg = v.getBackground();
416c89f53833f1e272d32f7928837f0704fa33be309Adam Powell        if (bg != null) {
417c89f53833f1e272d32f7928837f0704fa33be309Adam Powell            return bg.getOpacity() == PixelFormat.OPAQUE;
418c89f53833f1e272d32f7928837f0704fa33be309Adam Powell        }
419c89f53833f1e272d32f7928837f0704fa33be309Adam Powell        return false;
42097341bdc5bea1d7bf777de65228039142d249f38Adam Powell    }
42197341bdc5bea1d7bf777de65228039142d249f38Adam Powell
42297341bdc5bea1d7bf777de65228039142d249f38Adam Powell    @Override
42389e17886e6149bddfdb08a242c9e88889596419cAdam Powell    protected void onAttachedToWindow() {
42489e17886e6149bddfdb08a242c9e88889596419cAdam Powell        super.onAttachedToWindow();
42589e17886e6149bddfdb08a242c9e88889596419cAdam Powell        mFirstLayout = true;
42689e17886e6149bddfdb08a242c9e88889596419cAdam Powell    }
42789e17886e6149bddfdb08a242c9e88889596419cAdam Powell
42889e17886e6149bddfdb08a242c9e88889596419cAdam Powell    @Override
42989e17886e6149bddfdb08a242c9e88889596419cAdam Powell    protected void onDetachedFromWindow() {
43089e17886e6149bddfdb08a242c9e88889596419cAdam Powell        super.onDetachedFromWindow();
43189e17886e6149bddfdb08a242c9e88889596419cAdam Powell        mFirstLayout = true;
432f4445e06a8490b056cd892c4bc640dfd17905d6cAdam Powell
433f4445e06a8490b056cd892c4bc640dfd17905d6cAdam Powell        for (int i = 0, count = mPostedRunnables.size(); i < count; i++) {
434f4445e06a8490b056cd892c4bc640dfd17905d6cAdam Powell            final DisableLayerRunnable dlr = mPostedRunnables.get(i);
435f4445e06a8490b056cd892c4bc640dfd17905d6cAdam Powell            dlr.run();
436f4445e06a8490b056cd892c4bc640dfd17905d6cAdam Powell        }
437f4445e06a8490b056cd892c4bc640dfd17905d6cAdam Powell        mPostedRunnables.clear();
43889e17886e6149bddfdb08a242c9e88889596419cAdam Powell    }
43989e17886e6149bddfdb08a242c9e88889596419cAdam Powell
44089e17886e6149bddfdb08a242c9e88889596419cAdam Powell    @Override
44197341bdc5bea1d7bf777de65228039142d249f38Adam Powell    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
442c6f6c4511593aa49688d5425e2f6e36459076c25Adam Powell        int widthMode = MeasureSpec.getMode(widthMeasureSpec);
443c6f6c4511593aa49688d5425e2f6e36459076c25Adam Powell        int widthSize = MeasureSpec.getSize(widthMeasureSpec);
444c6f6c4511593aa49688d5425e2f6e36459076c25Adam Powell        int heightMode = MeasureSpec.getMode(heightMeasureSpec);
445c6f6c4511593aa49688d5425e2f6e36459076c25Adam Powell        int heightSize = MeasureSpec.getSize(heightMeasureSpec);
44697341bdc5bea1d7bf777de65228039142d249f38Adam Powell
44797341bdc5bea1d7bf777de65228039142d249f38Adam Powell        if (widthMode != MeasureSpec.EXACTLY) {
448c6f6c4511593aa49688d5425e2f6e36459076c25Adam Powell            if (isInEditMode()) {
449c6f6c4511593aa49688d5425e2f6e36459076c25Adam Powell                // Don't crash the layout editor. Consume all of the space if specified
450c6f6c4511593aa49688d5425e2f6e36459076c25Adam Powell                // or pick a magic number from thin air otherwise.
451c6f6c4511593aa49688d5425e2f6e36459076c25Adam Powell                // TODO Better communication with tools of this bogus state.
452c6f6c4511593aa49688d5425e2f6e36459076c25Adam Powell                // It will crash on a real device.
453c6f6c4511593aa49688d5425e2f6e36459076c25Adam Powell                if (widthMode == MeasureSpec.AT_MOST) {
454c6f6c4511593aa49688d5425e2f6e36459076c25Adam Powell                    widthMode = MeasureSpec.EXACTLY;
455c6f6c4511593aa49688d5425e2f6e36459076c25Adam Powell                } else if (widthMode == MeasureSpec.UNSPECIFIED) {
456c6f6c4511593aa49688d5425e2f6e36459076c25Adam Powell                    widthMode = MeasureSpec.EXACTLY;
457c6f6c4511593aa49688d5425e2f6e36459076c25Adam Powell                    widthSize = 300;
458c6f6c4511593aa49688d5425e2f6e36459076c25Adam Powell                }
459c6f6c4511593aa49688d5425e2f6e36459076c25Adam Powell            } else {
460c6f6c4511593aa49688d5425e2f6e36459076c25Adam Powell                throw new IllegalStateException("Width must have an exact value or MATCH_PARENT");
461c6f6c4511593aa49688d5425e2f6e36459076c25Adam Powell            }
46297341bdc5bea1d7bf777de65228039142d249f38Adam Powell        } else if (heightMode == MeasureSpec.UNSPECIFIED) {
463c6f6c4511593aa49688d5425e2f6e36459076c25Adam Powell            if (isInEditMode()) {
464c6f6c4511593aa49688d5425e2f6e36459076c25Adam Powell                // Don't crash the layout editor. Pick a magic number from thin air instead.
465c6f6c4511593aa49688d5425e2f6e36459076c25Adam Powell                // TODO Better communication with tools of this bogus state.
466c6f6c4511593aa49688d5425e2f6e36459076c25Adam Powell                // It will crash on a real device.
467c6f6c4511593aa49688d5425e2f6e36459076c25Adam Powell                if (heightMode == MeasureSpec.UNSPECIFIED) {
468c6f6c4511593aa49688d5425e2f6e36459076c25Adam Powell                    heightMode = MeasureSpec.AT_MOST;
469c6f6c4511593aa49688d5425e2f6e36459076c25Adam Powell                    heightSize = 300;
470c6f6c4511593aa49688d5425e2f6e36459076c25Adam Powell                }
471c6f6c4511593aa49688d5425e2f6e36459076c25Adam Powell            } else {
472c6f6c4511593aa49688d5425e2f6e36459076c25Adam Powell                throw new IllegalStateException("Height must not be UNSPECIFIED");
473c6f6c4511593aa49688d5425e2f6e36459076c25Adam Powell            }
47497341bdc5bea1d7bf777de65228039142d249f38Adam Powell        }
47597341bdc5bea1d7bf777de65228039142d249f38Adam Powell
47697341bdc5bea1d7bf777de65228039142d249f38Adam Powell        int layoutHeight = 0;
47797341bdc5bea1d7bf777de65228039142d249f38Adam Powell        int maxLayoutHeight = -1;
47897341bdc5bea1d7bf777de65228039142d249f38Adam Powell        switch (heightMode) {
47997341bdc5bea1d7bf777de65228039142d249f38Adam Powell            case MeasureSpec.EXACTLY:
48097341bdc5bea1d7bf777de65228039142d249f38Adam Powell                layoutHeight = maxLayoutHeight = heightSize - getPaddingTop() - getPaddingBottom();
48197341bdc5bea1d7bf777de65228039142d249f38Adam Powell                break;
48297341bdc5bea1d7bf777de65228039142d249f38Adam Powell            case MeasureSpec.AT_MOST:
48397341bdc5bea1d7bf777de65228039142d249f38Adam Powell                maxLayoutHeight = heightSize - getPaddingTop() - getPaddingBottom();
48497341bdc5bea1d7bf777de65228039142d249f38Adam Powell                break;
48597341bdc5bea1d7bf777de65228039142d249f38Adam Powell        }
48697341bdc5bea1d7bf777de65228039142d249f38Adam Powell
48797341bdc5bea1d7bf777de65228039142d249f38Adam Powell        float weightSum = 0;
4880eefe9ad0819b223006533cbc79a35d66684af32Adam Powell        boolean canSlide = false;
4896688e113ad2519dc07edf56acbd0f42ce209a585Sérgio Faria        final int widthAvailable = widthSize - getPaddingLeft() - getPaddingRight();
4906688e113ad2519dc07edf56acbd0f42ce209a585Sérgio Faria        int widthRemaining = widthAvailable;
49197341bdc5bea1d7bf777de65228039142d249f38Adam Powell        final int childCount = getChildCount();
49297341bdc5bea1d7bf777de65228039142d249f38Adam Powell
49397341bdc5bea1d7bf777de65228039142d249f38Adam Powell        if (childCount > 2) {
4940eefe9ad0819b223006533cbc79a35d66684af32Adam Powell            Log.e(TAG, "onMeasure: More than two child views are not supported.");
49597341bdc5bea1d7bf777de65228039142d249f38Adam Powell        }
49697341bdc5bea1d7bf777de65228039142d249f38Adam Powell
4971e43161e9e1f1dc10637a68d5c2304c1f95c9c46Adam Powell        // We'll find the current one below.
4981e43161e9e1f1dc10637a68d5c2304c1f95c9c46Adam Powell        mSlideableView = null;
4991e43161e9e1f1dc10637a68d5c2304c1f95c9c46Adam Powell
50097341bdc5bea1d7bf777de65228039142d249f38Adam Powell        // First pass. Measure based on child LayoutParams width/height.
50197341bdc5bea1d7bf777de65228039142d249f38Adam Powell        // Weight will incur a second pass.
50297341bdc5bea1d7bf777de65228039142d249f38Adam Powell        for (int i = 0; i < childCount; i++) {
50397341bdc5bea1d7bf777de65228039142d249f38Adam Powell            final View child = getChildAt(i);
50497341bdc5bea1d7bf777de65228039142d249f38Adam Powell            final LayoutParams lp = (LayoutParams) child.getLayoutParams();
50597341bdc5bea1d7bf777de65228039142d249f38Adam Powell
506dc56c78a7e2d06c9aabd3e90448c81671d8c05b1Adam Powell            if (child.getVisibility() == GONE) {
507dc56c78a7e2d06c9aabd3e90448c81671d8c05b1Adam Powell                lp.dimWhenOffset = false;
508dc56c78a7e2d06c9aabd3e90448c81671d8c05b1Adam Powell                continue;
509dc56c78a7e2d06c9aabd3e90448c81671d8c05b1Adam Powell            }
510dc56c78a7e2d06c9aabd3e90448c81671d8c05b1Adam Powell
51197341bdc5bea1d7bf777de65228039142d249f38Adam Powell            if (lp.weight > 0) {
51297341bdc5bea1d7bf777de65228039142d249f38Adam Powell                weightSum += lp.weight;
51397341bdc5bea1d7bf777de65228039142d249f38Adam Powell
51497341bdc5bea1d7bf777de65228039142d249f38Adam Powell                // If we have no width, weight is the only contributor to the final size.
51597341bdc5bea1d7bf777de65228039142d249f38Adam Powell                // Measure this view on the weight pass only.
51697341bdc5bea1d7bf777de65228039142d249f38Adam Powell                if (lp.width == 0) continue;
51797341bdc5bea1d7bf777de65228039142d249f38Adam Powell            }
51897341bdc5bea1d7bf777de65228039142d249f38Adam Powell
51997341bdc5bea1d7bf777de65228039142d249f38Adam Powell            int childWidthSpec;
52097341bdc5bea1d7bf777de65228039142d249f38Adam Powell            final int horizontalMargin = lp.leftMargin + lp.rightMargin;
52197341bdc5bea1d7bf777de65228039142d249f38Adam Powell            if (lp.width == LayoutParams.WRAP_CONTENT) {
5226688e113ad2519dc07edf56acbd0f42ce209a585Sérgio Faria                childWidthSpec = MeasureSpec.makeMeasureSpec(widthAvailable - horizontalMargin,
52397341bdc5bea1d7bf777de65228039142d249f38Adam Powell                        MeasureSpec.AT_MOST);
52497341bdc5bea1d7bf777de65228039142d249f38Adam Powell            } else if (lp.width == LayoutParams.FILL_PARENT) {
5256688e113ad2519dc07edf56acbd0f42ce209a585Sérgio Faria                childWidthSpec = MeasureSpec.makeMeasureSpec(widthAvailable - horizontalMargin,
52697341bdc5bea1d7bf777de65228039142d249f38Adam Powell                        MeasureSpec.EXACTLY);
52797341bdc5bea1d7bf777de65228039142d249f38Adam Powell            } else {
52897341bdc5bea1d7bf777de65228039142d249f38Adam Powell                childWidthSpec = MeasureSpec.makeMeasureSpec(lp.width, MeasureSpec.EXACTLY);
52997341bdc5bea1d7bf777de65228039142d249f38Adam Powell            }
53097341bdc5bea1d7bf777de65228039142d249f38Adam Powell
53197341bdc5bea1d7bf777de65228039142d249f38Adam Powell            int childHeightSpec;
53297341bdc5bea1d7bf777de65228039142d249f38Adam Powell            if (lp.height == LayoutParams.WRAP_CONTENT) {
53397341bdc5bea1d7bf777de65228039142d249f38Adam Powell                childHeightSpec = MeasureSpec.makeMeasureSpec(maxLayoutHeight, MeasureSpec.AT_MOST);
53497341bdc5bea1d7bf777de65228039142d249f38Adam Powell            } else if (lp.height == LayoutParams.FILL_PARENT) {
53597341bdc5bea1d7bf777de65228039142d249f38Adam Powell                childHeightSpec = MeasureSpec.makeMeasureSpec(maxLayoutHeight, MeasureSpec.EXACTLY);
53697341bdc5bea1d7bf777de65228039142d249f38Adam Powell            } else {
53797341bdc5bea1d7bf777de65228039142d249f38Adam Powell                childHeightSpec = MeasureSpec.makeMeasureSpec(lp.height, MeasureSpec.EXACTLY);
53897341bdc5bea1d7bf777de65228039142d249f38Adam Powell            }
53997341bdc5bea1d7bf777de65228039142d249f38Adam Powell
54097341bdc5bea1d7bf777de65228039142d249f38Adam Powell            child.measure(childWidthSpec, childHeightSpec);
54197341bdc5bea1d7bf777de65228039142d249f38Adam Powell            final int childWidth = child.getMeasuredWidth();
54297341bdc5bea1d7bf777de65228039142d249f38Adam Powell            final int childHeight = child.getMeasuredHeight();
54397341bdc5bea1d7bf777de65228039142d249f38Adam Powell
54497341bdc5bea1d7bf777de65228039142d249f38Adam Powell            if (heightMode == MeasureSpec.AT_MOST && childHeight > layoutHeight) {
54597341bdc5bea1d7bf777de65228039142d249f38Adam Powell                layoutHeight = Math.min(childHeight, maxLayoutHeight);
54697341bdc5bea1d7bf777de65228039142d249f38Adam Powell            }
54797341bdc5bea1d7bf777de65228039142d249f38Adam Powell
54897341bdc5bea1d7bf777de65228039142d249f38Adam Powell            widthRemaining -= childWidth;
5490eefe9ad0819b223006533cbc79a35d66684af32Adam Powell            canSlide |= lp.slideable = widthRemaining < 0;
5500eefe9ad0819b223006533cbc79a35d66684af32Adam Powell            if (lp.slideable) {
5510eefe9ad0819b223006533cbc79a35d66684af32Adam Powell                mSlideableView = child;
5520eefe9ad0819b223006533cbc79a35d66684af32Adam Powell            }
55397341bdc5bea1d7bf777de65228039142d249f38Adam Powell        }
55497341bdc5bea1d7bf777de65228039142d249f38Adam Powell
55597341bdc5bea1d7bf777de65228039142d249f38Adam Powell        // Resolve weight and make sure non-sliding panels are smaller than the full screen.
55697341bdc5bea1d7bf777de65228039142d249f38Adam Powell        if (canSlide || weightSum > 0) {
5576688e113ad2519dc07edf56acbd0f42ce209a585Sérgio Faria            final int fixedPanelWidthLimit = widthAvailable - mOverhangSize;
55897341bdc5bea1d7bf777de65228039142d249f38Adam Powell
55997341bdc5bea1d7bf777de65228039142d249f38Adam Powell            for (int i = 0; i < childCount; i++) {
56097341bdc5bea1d7bf777de65228039142d249f38Adam Powell                final View child = getChildAt(i);
5610eefe9ad0819b223006533cbc79a35d66684af32Adam Powell
5620eefe9ad0819b223006533cbc79a35d66684af32Adam Powell                if (child.getVisibility() == GONE) {
5630eefe9ad0819b223006533cbc79a35d66684af32Adam Powell                    continue;
5640eefe9ad0819b223006533cbc79a35d66684af32Adam Powell                }
5650eefe9ad0819b223006533cbc79a35d66684af32Adam Powell
56697341bdc5bea1d7bf777de65228039142d249f38Adam Powell                final LayoutParams lp = (LayoutParams) child.getLayoutParams();
56797341bdc5bea1d7bf777de65228039142d249f38Adam Powell
568dc56c78a7e2d06c9aabd3e90448c81671d8c05b1Adam Powell                if (child.getVisibility() == GONE) {
569dc56c78a7e2d06c9aabd3e90448c81671d8c05b1Adam Powell                    continue;
570dc56c78a7e2d06c9aabd3e90448c81671d8c05b1Adam Powell                }
571dc56c78a7e2d06c9aabd3e90448c81671d8c05b1Adam Powell
57297341bdc5bea1d7bf777de65228039142d249f38Adam Powell                final boolean skippedFirstPass = lp.width == 0 && lp.weight > 0;
57397341bdc5bea1d7bf777de65228039142d249f38Adam Powell                final int measuredWidth = skippedFirstPass ? 0 : child.getMeasuredWidth();
5740eefe9ad0819b223006533cbc79a35d66684af32Adam Powell                if (canSlide && child != mSlideableView) {
57597341bdc5bea1d7bf777de65228039142d249f38Adam Powell                    if (lp.width < 0 && (measuredWidth > fixedPanelWidthLimit || lp.weight > 0)) {
57697341bdc5bea1d7bf777de65228039142d249f38Adam Powell                        // Fixed panels in a sliding configuration should
57797341bdc5bea1d7bf777de65228039142d249f38Adam Powell                        // be clamped to the fixed panel limit.
57897341bdc5bea1d7bf777de65228039142d249f38Adam Powell                        final int childHeightSpec;
57997341bdc5bea1d7bf777de65228039142d249f38Adam Powell                        if (skippedFirstPass) {
58097341bdc5bea1d7bf777de65228039142d249f38Adam Powell                            // Do initial height measurement if we skipped measuring this view
58197341bdc5bea1d7bf777de65228039142d249f38Adam Powell                            // the first time around.
58297341bdc5bea1d7bf777de65228039142d249f38Adam Powell                            if (lp.height == LayoutParams.WRAP_CONTENT) {
58397341bdc5bea1d7bf777de65228039142d249f38Adam Powell                                childHeightSpec = MeasureSpec.makeMeasureSpec(maxLayoutHeight,
58497341bdc5bea1d7bf777de65228039142d249f38Adam Powell                                        MeasureSpec.AT_MOST);
58597341bdc5bea1d7bf777de65228039142d249f38Adam Powell                            } else if (lp.height == LayoutParams.FILL_PARENT) {
58697341bdc5bea1d7bf777de65228039142d249f38Adam Powell                                childHeightSpec = MeasureSpec.makeMeasureSpec(maxLayoutHeight,
58797341bdc5bea1d7bf777de65228039142d249f38Adam Powell                                        MeasureSpec.EXACTLY);
58897341bdc5bea1d7bf777de65228039142d249f38Adam Powell                            } else {
58997341bdc5bea1d7bf777de65228039142d249f38Adam Powell                                childHeightSpec = MeasureSpec.makeMeasureSpec(lp.height,
59097341bdc5bea1d7bf777de65228039142d249f38Adam Powell                                        MeasureSpec.EXACTLY);
59197341bdc5bea1d7bf777de65228039142d249f38Adam Powell                            }
59297341bdc5bea1d7bf777de65228039142d249f38Adam Powell                        } else {
59397341bdc5bea1d7bf777de65228039142d249f38Adam Powell                            childHeightSpec = MeasureSpec.makeMeasureSpec(
59497341bdc5bea1d7bf777de65228039142d249f38Adam Powell                                    child.getMeasuredHeight(), MeasureSpec.EXACTLY);
59597341bdc5bea1d7bf777de65228039142d249f38Adam Powell                        }
59697341bdc5bea1d7bf777de65228039142d249f38Adam Powell                        final int childWidthSpec = MeasureSpec.makeMeasureSpec(
59797341bdc5bea1d7bf777de65228039142d249f38Adam Powell                                fixedPanelWidthLimit, MeasureSpec.EXACTLY);
59897341bdc5bea1d7bf777de65228039142d249f38Adam Powell                        child.measure(childWidthSpec, childHeightSpec);
59997341bdc5bea1d7bf777de65228039142d249f38Adam Powell                    }
60097341bdc5bea1d7bf777de65228039142d249f38Adam Powell                } else if (lp.weight > 0) {
60197341bdc5bea1d7bf777de65228039142d249f38Adam Powell                    int childHeightSpec;
60297341bdc5bea1d7bf777de65228039142d249f38Adam Powell                    if (lp.width == 0) {
60397341bdc5bea1d7bf777de65228039142d249f38Adam Powell                        // This was skipped the first time; figure out a real height spec.
60497341bdc5bea1d7bf777de65228039142d249f38Adam Powell                        if (lp.height == LayoutParams.WRAP_CONTENT) {
60597341bdc5bea1d7bf777de65228039142d249f38Adam Powell                            childHeightSpec = MeasureSpec.makeMeasureSpec(maxLayoutHeight,
60697341bdc5bea1d7bf777de65228039142d249f38Adam Powell                                    MeasureSpec.AT_MOST);
60797341bdc5bea1d7bf777de65228039142d249f38Adam Powell                        } else if (lp.height == LayoutParams.FILL_PARENT) {
60897341bdc5bea1d7bf777de65228039142d249f38Adam Powell                            childHeightSpec = MeasureSpec.makeMeasureSpec(maxLayoutHeight,
60997341bdc5bea1d7bf777de65228039142d249f38Adam Powell                                    MeasureSpec.EXACTLY);
61097341bdc5bea1d7bf777de65228039142d249f38Adam Powell                        } else {
61197341bdc5bea1d7bf777de65228039142d249f38Adam Powell                            childHeightSpec = MeasureSpec.makeMeasureSpec(lp.height,
61297341bdc5bea1d7bf777de65228039142d249f38Adam Powell                                    MeasureSpec.EXACTLY);
61397341bdc5bea1d7bf777de65228039142d249f38Adam Powell                        }
61497341bdc5bea1d7bf777de65228039142d249f38Adam Powell                    } else {
61597341bdc5bea1d7bf777de65228039142d249f38Adam Powell                        childHeightSpec = MeasureSpec.makeMeasureSpec(
61697341bdc5bea1d7bf777de65228039142d249f38Adam Powell                                child.getMeasuredHeight(), MeasureSpec.EXACTLY);
61797341bdc5bea1d7bf777de65228039142d249f38Adam Powell                    }
61897341bdc5bea1d7bf777de65228039142d249f38Adam Powell
61997341bdc5bea1d7bf777de65228039142d249f38Adam Powell                    if (canSlide) {
62097341bdc5bea1d7bf777de65228039142d249f38Adam Powell                        // Consume available space
62197341bdc5bea1d7bf777de65228039142d249f38Adam Powell                        final int horizontalMargin = lp.leftMargin + lp.rightMargin;
6226688e113ad2519dc07edf56acbd0f42ce209a585Sérgio Faria                        final int newWidth = widthAvailable - horizontalMargin;
62397341bdc5bea1d7bf777de65228039142d249f38Adam Powell                        final int childWidthSpec = MeasureSpec.makeMeasureSpec(
62497341bdc5bea1d7bf777de65228039142d249f38Adam Powell                                newWidth, MeasureSpec.EXACTLY);
62597341bdc5bea1d7bf777de65228039142d249f38Adam Powell                        if (measuredWidth != newWidth) {
62697341bdc5bea1d7bf777de65228039142d249f38Adam Powell                            child.measure(childWidthSpec, childHeightSpec);
62797341bdc5bea1d7bf777de65228039142d249f38Adam Powell                        }
62897341bdc5bea1d7bf777de65228039142d249f38Adam Powell                    } else {
62997341bdc5bea1d7bf777de65228039142d249f38Adam Powell                        // Distribute the extra width proportionally similar to LinearLayout
63097341bdc5bea1d7bf777de65228039142d249f38Adam Powell                        final int widthToDistribute = Math.max(0, widthRemaining);
63197341bdc5bea1d7bf777de65228039142d249f38Adam Powell                        final int addedWidth = (int) (lp.weight * widthToDistribute / weightSum);
63297341bdc5bea1d7bf777de65228039142d249f38Adam Powell                        final int childWidthSpec = MeasureSpec.makeMeasureSpec(
63397341bdc5bea1d7bf777de65228039142d249f38Adam Powell                                measuredWidth + addedWidth, MeasureSpec.EXACTLY);
63497341bdc5bea1d7bf777de65228039142d249f38Adam Powell                        child.measure(childWidthSpec, childHeightSpec);
63597341bdc5bea1d7bf777de65228039142d249f38Adam Powell                    }
63697341bdc5bea1d7bf777de65228039142d249f38Adam Powell                }
63797341bdc5bea1d7bf777de65228039142d249f38Adam Powell            }
63897341bdc5bea1d7bf777de65228039142d249f38Adam Powell        }
63997341bdc5bea1d7bf777de65228039142d249f38Adam Powell
6406688e113ad2519dc07edf56acbd0f42ce209a585Sérgio Faria        final int measuredWidth = widthSize;
6416688e113ad2519dc07edf56acbd0f42ce209a585Sérgio Faria        final int measuredHeight = layoutHeight + getPaddingTop() + getPaddingBottom();
6426688e113ad2519dc07edf56acbd0f42ce209a585Sérgio Faria
6436688e113ad2519dc07edf56acbd0f42ce209a585Sérgio Faria        setMeasuredDimension(measuredWidth, measuredHeight);
64497341bdc5bea1d7bf777de65228039142d249f38Adam Powell        mCanSlide = canSlide;
6456688e113ad2519dc07edf56acbd0f42ce209a585Sérgio Faria
646471f0f4e84c7d1f96e48fb26713f246d69c3241fAdam Powell        if (mDragHelper.getViewDragState() != ViewDragHelper.STATE_IDLE && !canSlide) {
6470eefe9ad0819b223006533cbc79a35d66684af32Adam Powell            // Cancel scrolling in progress, it's no longer relevant.
648471f0f4e84c7d1f96e48fb26713f246d69c3241fAdam Powell            mDragHelper.abort();
64997341bdc5bea1d7bf777de65228039142d249f38Adam Powell        }
65097341bdc5bea1d7bf777de65228039142d249f38Adam Powell    }
65197341bdc5bea1d7bf777de65228039142d249f38Adam Powell
65297341bdc5bea1d7bf777de65228039142d249f38Adam Powell    @Override
65397341bdc5bea1d7bf777de65228039142d249f38Adam Powell    protected void onLayout(boolean changed, int l, int t, int r, int b) {
65419780f88506df4aeb57456fd6747af1b6848a11cfafaisland        final boolean isLayoutRtl = isLayoutRtlSupport();
65519780f88506df4aeb57456fd6747af1b6848a11cfafaisland        if (isLayoutRtl) {
65619780f88506df4aeb57456fd6747af1b6848a11cfafaisland            mDragHelper.setEdgeTrackingEnabled(ViewDragHelper.EDGE_RIGHT);
65719780f88506df4aeb57456fd6747af1b6848a11cfafaisland        } else {
65819780f88506df4aeb57456fd6747af1b6848a11cfafaisland            mDragHelper.setEdgeTrackingEnabled(ViewDragHelper.EDGE_LEFT);
65919780f88506df4aeb57456fd6747af1b6848a11cfafaisland        }
66097341bdc5bea1d7bf777de65228039142d249f38Adam Powell        final int width = r - l;
66119780f88506df4aeb57456fd6747af1b6848a11cfafaisland        final int paddingStart = isLayoutRtl ? getPaddingRight() : getPaddingLeft();
66219780f88506df4aeb57456fd6747af1b6848a11cfafaisland        final int paddingEnd = isLayoutRtl ? getPaddingLeft() : getPaddingRight();
66397341bdc5bea1d7bf777de65228039142d249f38Adam Powell        final int paddingTop = getPaddingTop();
66497341bdc5bea1d7bf777de65228039142d249f38Adam Powell
6656debd2bbcae1cd285d2e21db633998b7801f9f40Adam Powell        final int childCount = getChildCount();
66619780f88506df4aeb57456fd6747af1b6848a11cfafaisland        int xStart = paddingStart;
66797341bdc5bea1d7bf777de65228039142d249f38Adam Powell        int nextXStart = xStart;
66897341bdc5bea1d7bf777de65228039142d249f38Adam Powell
669d44315a54e002b20365189f03a09011f2bf6ba07Adam Powell        if (mFirstLayout) {
670d44315a54e002b20365189f03a09011f2bf6ba07Adam Powell            mSlideOffset = mCanSlide && mPreservedOpenState ? 1.f : 0.f;
671d44315a54e002b20365189f03a09011f2bf6ba07Adam Powell        }
672d44315a54e002b20365189f03a09011f2bf6ba07Adam Powell
67397341bdc5bea1d7bf777de65228039142d249f38Adam Powell        for (int i = 0; i < childCount; i++) {
67497341bdc5bea1d7bf777de65228039142d249f38Adam Powell            final View child = getChildAt(i);
6750eefe9ad0819b223006533cbc79a35d66684af32Adam Powell
6760eefe9ad0819b223006533cbc79a35d66684af32Adam Powell            if (child.getVisibility() == GONE) {
6770eefe9ad0819b223006533cbc79a35d66684af32Adam Powell                continue;
6780eefe9ad0819b223006533cbc79a35d66684af32Adam Powell            }
6790eefe9ad0819b223006533cbc79a35d66684af32Adam Powell
68097341bdc5bea1d7bf777de65228039142d249f38Adam Powell            final LayoutParams lp = (LayoutParams) child.getLayoutParams();
68197341bdc5bea1d7bf777de65228039142d249f38Adam Powell
68297341bdc5bea1d7bf777de65228039142d249f38Adam Powell            final int childWidth = child.getMeasuredWidth();
6836debd2bbcae1cd285d2e21db633998b7801f9f40Adam Powell            int offset = 0;
68497341bdc5bea1d7bf777de65228039142d249f38Adam Powell
6850eefe9ad0819b223006533cbc79a35d66684af32Adam Powell            if (lp.slideable) {
6866debd2bbcae1cd285d2e21db633998b7801f9f40Adam Powell                final int margin = lp.leftMargin + lp.rightMargin;
6876debd2bbcae1cd285d2e21db633998b7801f9f40Adam Powell                final int range = Math.min(nextXStart,
68819780f88506df4aeb57456fd6747af1b6848a11cfafaisland                        width - paddingEnd - mOverhangSize) - xStart - margin;
6890eefe9ad0819b223006533cbc79a35d66684af32Adam Powell                mSlideRange = range;
69019780f88506df4aeb57456fd6747af1b6848a11cfafaisland                final int lpMargin = isLayoutRtl ? lp.rightMargin : lp.leftMargin;
69119780f88506df4aeb57456fd6747af1b6848a11cfafaisland                lp.dimWhenOffset = xStart + lpMargin + range + childWidth / 2 >
69219780f88506df4aeb57456fd6747af1b6848a11cfafaisland                        width - paddingEnd;
693ed97d103ed92fece435d8bf24398ecd2c2a5d02aMark Wagner                final int pos = (int) (range * mSlideOffset);
69419780f88506df4aeb57456fd6747af1b6848a11cfafaisland                xStart += pos + lpMargin;
695ed97d103ed92fece435d8bf24398ecd2c2a5d02aMark Wagner                mSlideOffset = (float) pos / mSlideRange;
696dc56c78a7e2d06c9aabd3e90448c81671d8c05b1Adam Powell            } else if (mCanSlide && mParallaxBy != 0) {
6970eefe9ad0819b223006533cbc79a35d66684af32Adam Powell                offset = (int) ((1 - mSlideOffset) * mParallaxBy);
6986debd2bbcae1cd285d2e21db633998b7801f9f40Adam Powell                xStart = nextXStart;
69997341bdc5bea1d7bf777de65228039142d249f38Adam Powell            } else {
70097341bdc5bea1d7bf777de65228039142d249f38Adam Powell                xStart = nextXStart;
70197341bdc5bea1d7bf777de65228039142d249f38Adam Powell            }
70297341bdc5bea1d7bf777de65228039142d249f38Adam Powell
70319780f88506df4aeb57456fd6747af1b6848a11cfafaisland            final int childRight;
70419780f88506df4aeb57456fd6747af1b6848a11cfafaisland            final int childLeft;
70519780f88506df4aeb57456fd6747af1b6848a11cfafaisland            if (isLayoutRtl) {
70619780f88506df4aeb57456fd6747af1b6848a11cfafaisland                childRight = width - xStart + offset;
70719780f88506df4aeb57456fd6747af1b6848a11cfafaisland                childLeft = childRight - childWidth;
70819780f88506df4aeb57456fd6747af1b6848a11cfafaisland            } else {
70919780f88506df4aeb57456fd6747af1b6848a11cfafaisland                childLeft = xStart - offset;
71019780f88506df4aeb57456fd6747af1b6848a11cfafaisland                childRight = childLeft + childWidth;
71119780f88506df4aeb57456fd6747af1b6848a11cfafaisland            }
71219780f88506df4aeb57456fd6747af1b6848a11cfafaisland
71397341bdc5bea1d7bf777de65228039142d249f38Adam Powell            final int childTop = paddingTop;
71497341bdc5bea1d7bf777de65228039142d249f38Adam Powell            final int childBottom = childTop + child.getMeasuredHeight();
71597341bdc5bea1d7bf777de65228039142d249f38Adam Powell            child.layout(childLeft, paddingTop, childRight, childBottom);
71697341bdc5bea1d7bf777de65228039142d249f38Adam Powell
7176debd2bbcae1cd285d2e21db633998b7801f9f40Adam Powell            nextXStart += child.getWidth();
71897341bdc5bea1d7bf777de65228039142d249f38Adam Powell        }
71989e17886e6149bddfdb08a242c9e88889596419cAdam Powell
72058898b639b18392580694bc6c902479274331bf2Adam Powell        if (mFirstLayout) {
72158898b639b18392580694bc6c902479274331bf2Adam Powell            if (mCanSlide) {
72258898b639b18392580694bc6c902479274331bf2Adam Powell                if (mParallaxBy != 0) {
72358898b639b18392580694bc6c902479274331bf2Adam Powell                    parallaxOtherViews(mSlideOffset);
72458898b639b18392580694bc6c902479274331bf2Adam Powell                }
72558898b639b18392580694bc6c902479274331bf2Adam Powell                if (((LayoutParams) mSlideableView.getLayoutParams()).dimWhenOffset) {
72658898b639b18392580694bc6c902479274331bf2Adam Powell                    dimChildView(mSlideableView, mSlideOffset, mSliderFadeColor);
72758898b639b18392580694bc6c902479274331bf2Adam Powell                }
72858898b639b18392580694bc6c902479274331bf2Adam Powell            } else {
72958898b639b18392580694bc6c902479274331bf2Adam Powell                // Reset the dim level of all children; it's irrelevant when nothing moves.
73058898b639b18392580694bc6c902479274331bf2Adam Powell                for (int i = 0; i < childCount; i++) {
73158898b639b18392580694bc6c902479274331bf2Adam Powell                    dimChildView(getChildAt(i), 0, mSliderFadeColor);
73258898b639b18392580694bc6c902479274331bf2Adam Powell                }
73389e17886e6149bddfdb08a242c9e88889596419cAdam Powell            }
734c89f53833f1e272d32f7928837f0704fa33be309Adam Powell            updateObscuredViewsVisibility(mSlideableView);
73589e17886e6149bddfdb08a242c9e88889596419cAdam Powell        }
73689e17886e6149bddfdb08a242c9e88889596419cAdam Powell
73789e17886e6149bddfdb08a242c9e88889596419cAdam Powell        mFirstLayout = false;
73889e17886e6149bddfdb08a242c9e88889596419cAdam Powell    }
73989e17886e6149bddfdb08a242c9e88889596419cAdam Powell
74089e17886e6149bddfdb08a242c9e88889596419cAdam Powell    @Override
74189e17886e6149bddfdb08a242c9e88889596419cAdam Powell    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
74289e17886e6149bddfdb08a242c9e88889596419cAdam Powell        super.onSizeChanged(w, h, oldw, oldh);
74389e17886e6149bddfdb08a242c9e88889596419cAdam Powell        // Recalculate sliding panes and their details
74472c7316b081c3134f7b0566f703dfee7c970eadeAdam Powell        if (w != oldw) {
74572c7316b081c3134f7b0566f703dfee7c970eadeAdam Powell            mFirstLayout = true;
74672c7316b081c3134f7b0566f703dfee7c970eadeAdam Powell        }
74789e17886e6149bddfdb08a242c9e88889596419cAdam Powell    }
74889e17886e6149bddfdb08a242c9e88889596419cAdam Powell
74989e17886e6149bddfdb08a242c9e88889596419cAdam Powell    @Override
75089e17886e6149bddfdb08a242c9e88889596419cAdam Powell    public void requestChildFocus(View child, View focused) {
75189e17886e6149bddfdb08a242c9e88889596419cAdam Powell        super.requestChildFocus(child, focused);
75289e17886e6149bddfdb08a242c9e88889596419cAdam Powell        if (!isInTouchMode() && !mCanSlide) {
75389e17886e6149bddfdb08a242c9e88889596419cAdam Powell            mPreservedOpenState = child == mSlideableView;
75489e17886e6149bddfdb08a242c9e88889596419cAdam Powell        }
75597341bdc5bea1d7bf777de65228039142d249f38Adam Powell    }
75697341bdc5bea1d7bf777de65228039142d249f38Adam Powell
75797341bdc5bea1d7bf777de65228039142d249f38Adam Powell    @Override
75897341bdc5bea1d7bf777de65228039142d249f38Adam Powell    public boolean onInterceptTouchEvent(MotionEvent ev) {
75989e17886e6149bddfdb08a242c9e88889596419cAdam Powell        final int action = MotionEventCompat.getActionMasked(ev);
76089e17886e6149bddfdb08a242c9e88889596419cAdam Powell
76189e17886e6149bddfdb08a242c9e88889596419cAdam Powell        // Preserve the open state based on the last view that was touched.
76289e17886e6149bddfdb08a242c9e88889596419cAdam Powell        if (!mCanSlide && action == MotionEvent.ACTION_DOWN && getChildCount() > 1) {
76389e17886e6149bddfdb08a242c9e88889596419cAdam Powell            // After the first things will be slideable.
76489e17886e6149bddfdb08a242c9e88889596419cAdam Powell            final View secondChild = getChildAt(1);
76589e17886e6149bddfdb08a242c9e88889596419cAdam Powell            if (secondChild != null) {
76689e17886e6149bddfdb08a242c9e88889596419cAdam Powell                mPreservedOpenState = !mDragHelper.isViewUnder(secondChild,
76789e17886e6149bddfdb08a242c9e88889596419cAdam Powell                        (int) ev.getX(), (int) ev.getY());
76889e17886e6149bddfdb08a242c9e88889596419cAdam Powell            }
76989e17886e6149bddfdb08a242c9e88889596419cAdam Powell        }
7700eefe9ad0819b223006533cbc79a35d66684af32Adam Powell
7710eefe9ad0819b223006533cbc79a35d66684af32Adam Powell        if (!mCanSlide || (mIsUnableToDrag && action != MotionEvent.ACTION_DOWN)) {
7726580cf4b7e74a2a017ed95b0dc50155b9995edebAdam Powell            mDragHelper.cancel();
77397341bdc5bea1d7bf777de65228039142d249f38Adam Powell            return super.onInterceptTouchEvent(ev);
77497341bdc5bea1d7bf777de65228039142d249f38Adam Powell        }
77597341bdc5bea1d7bf777de65228039142d249f38Adam Powell
77697341bdc5bea1d7bf777de65228039142d249f38Adam Powell        if (action == MotionEvent.ACTION_CANCEL || action == MotionEvent.ACTION_UP) {
7776580cf4b7e74a2a017ed95b0dc50155b9995edebAdam Powell            mDragHelper.cancel();
77897341bdc5bea1d7bf777de65228039142d249f38Adam Powell            return false;
77997341bdc5bea1d7bf777de65228039142d249f38Adam Powell        }
78097341bdc5bea1d7bf777de65228039142d249f38Adam Powell
78197341bdc5bea1d7bf777de65228039142d249f38Adam Powell        boolean interceptTap = false;
78297341bdc5bea1d7bf777de65228039142d249f38Adam Powell
78397341bdc5bea1d7bf777de65228039142d249f38Adam Powell        switch (action) {
7846580cf4b7e74a2a017ed95b0dc50155b9995edebAdam Powell            case MotionEvent.ACTION_DOWN: {
78597341bdc5bea1d7bf777de65228039142d249f38Adam Powell                mIsUnableToDrag = false;
7866580cf4b7e74a2a017ed95b0dc50155b9995edebAdam Powell                final float x = ev.getX();
7876580cf4b7e74a2a017ed95b0dc50155b9995edebAdam Powell                final float y = ev.getY();
788ee3f0ffb0199e295cbf48aa1a61c8ae7056526abAdam Powell                mInitialMotionX = x;
789ee3f0ffb0199e295cbf48aa1a61c8ae7056526abAdam Powell                mInitialMotionY = y;
79089e17886e6149bddfdb08a242c9e88889596419cAdam Powell
7916580cf4b7e74a2a017ed95b0dc50155b9995edebAdam Powell                if (mDragHelper.isViewUnder(mSlideableView, (int) x, (int) y) &&
7921d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell                        isDimmed(mSlideableView)) {
793c56ba65d20be8742ff717907a3a2cd81dd0e5f3cAdam Powell                    interceptTap = true;
79497341bdc5bea1d7bf777de65228039142d249f38Adam Powell                }
79597341bdc5bea1d7bf777de65228039142d249f38Adam Powell                break;
79697341bdc5bea1d7bf777de65228039142d249f38Adam Powell            }
79729836199390f71d05b15eedb487c1f7465776f1dAdam Powell
79829836199390f71d05b15eedb487c1f7465776f1dAdam Powell            case MotionEvent.ACTION_MOVE: {
79929836199390f71d05b15eedb487c1f7465776f1dAdam Powell                final float x = ev.getX();
80029836199390f71d05b15eedb487c1f7465776f1dAdam Powell                final float y = ev.getY();
80129836199390f71d05b15eedb487c1f7465776f1dAdam Powell                final float adx = Math.abs(x - mInitialMotionX);
80229836199390f71d05b15eedb487c1f7465776f1dAdam Powell                final float ady = Math.abs(y - mInitialMotionY);
80329836199390f71d05b15eedb487c1f7465776f1dAdam Powell                final int slop = mDragHelper.getTouchSlop();
80429836199390f71d05b15eedb487c1f7465776f1dAdam Powell                if (adx > slop && ady > adx) {
80529836199390f71d05b15eedb487c1f7465776f1dAdam Powell                    mDragHelper.cancel();
80629836199390f71d05b15eedb487c1f7465776f1dAdam Powell                    mIsUnableToDrag = true;
80729836199390f71d05b15eedb487c1f7465776f1dAdam Powell                    return false;
80829836199390f71d05b15eedb487c1f7465776f1dAdam Powell                }
80929836199390f71d05b15eedb487c1f7465776f1dAdam Powell            }
81097341bdc5bea1d7bf777de65228039142d249f38Adam Powell        }
81197341bdc5bea1d7bf777de65228039142d249f38Adam Powell
81229836199390f71d05b15eedb487c1f7465776f1dAdam Powell        final boolean interceptForDrag = mDragHelper.shouldInterceptTouchEvent(ev);
81329836199390f71d05b15eedb487c1f7465776f1dAdam Powell
814c56ba65d20be8742ff717907a3a2cd81dd0e5f3cAdam Powell        return interceptForDrag || interceptTap;
81597341bdc5bea1d7bf777de65228039142d249f38Adam Powell    }
81697341bdc5bea1d7bf777de65228039142d249f38Adam Powell
81797341bdc5bea1d7bf777de65228039142d249f38Adam Powell    @Override
81897341bdc5bea1d7bf777de65228039142d249f38Adam Powell    public boolean onTouchEvent(MotionEvent ev) {
81997341bdc5bea1d7bf777de65228039142d249f38Adam Powell        if (!mCanSlide) {
82097341bdc5bea1d7bf777de65228039142d249f38Adam Powell            return super.onTouchEvent(ev);
82197341bdc5bea1d7bf777de65228039142d249f38Adam Powell        }
82297341bdc5bea1d7bf777de65228039142d249f38Adam Powell
823c56ba65d20be8742ff717907a3a2cd81dd0e5f3cAdam Powell        mDragHelper.processTouchEvent(ev);
82497341bdc5bea1d7bf777de65228039142d249f38Adam Powell
82597341bdc5bea1d7bf777de65228039142d249f38Adam Powell        final int action = ev.getAction();
8266debd2bbcae1cd285d2e21db633998b7801f9f40Adam Powell        boolean wantTouchEvents = true;
82797341bdc5bea1d7bf777de65228039142d249f38Adam Powell
82897341bdc5bea1d7bf777de65228039142d249f38Adam Powell        switch (action & MotionEventCompat.ACTION_MASK) {
82997341bdc5bea1d7bf777de65228039142d249f38Adam Powell            case MotionEvent.ACTION_DOWN: {
83097341bdc5bea1d7bf777de65228039142d249f38Adam Powell                final float x = ev.getX();
83197341bdc5bea1d7bf777de65228039142d249f38Adam Powell                final float y = ev.getY();
832ee3f0ffb0199e295cbf48aa1a61c8ae7056526abAdam Powell                mInitialMotionX = x;
833ee3f0ffb0199e295cbf48aa1a61c8ae7056526abAdam Powell                mInitialMotionY = y;
83497341bdc5bea1d7bf777de65228039142d249f38Adam Powell                break;
83597341bdc5bea1d7bf777de65228039142d249f38Adam Powell            }
83697341bdc5bea1d7bf777de65228039142d249f38Adam Powell
83797341bdc5bea1d7bf777de65228039142d249f38Adam Powell            case MotionEvent.ACTION_UP: {
838ee3f0ffb0199e295cbf48aa1a61c8ae7056526abAdam Powell                if (isDimmed(mSlideableView)) {
8396580cf4b7e74a2a017ed95b0dc50155b9995edebAdam Powell                    final float x = ev.getX();
8406580cf4b7e74a2a017ed95b0dc50155b9995edebAdam Powell                    final float y = ev.getY();
841ee3f0ffb0199e295cbf48aa1a61c8ae7056526abAdam Powell                    final float dx = x - mInitialMotionX;
842ee3f0ffb0199e295cbf48aa1a61c8ae7056526abAdam Powell                    final float dy = y - mInitialMotionY;
8431d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell                    final int slop = mDragHelper.getTouchSlop();
8441d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell                    if (dx * dx + dy * dy < slop * slop &&
8456580cf4b7e74a2a017ed95b0dc50155b9995edebAdam Powell                            mDragHelper.isViewUnder(mSlideableView, (int) x, (int) y)) {
846ee3f0ffb0199e295cbf48aa1a61c8ae7056526abAdam Powell                        // Taps close a dimmed open pane.
847ee3f0ffb0199e295cbf48aa1a61c8ae7056526abAdam Powell                        closePane(mSlideableView, 0);
848ee3f0ffb0199e295cbf48aa1a61c8ae7056526abAdam Powell                        break;
849ee3f0ffb0199e295cbf48aa1a61c8ae7056526abAdam Powell                    }
850ee3f0ffb0199e295cbf48aa1a61c8ae7056526abAdam Powell                }
85197341bdc5bea1d7bf777de65228039142d249f38Adam Powell                break;
85297341bdc5bea1d7bf777de65228039142d249f38Adam Powell            }
85397341bdc5bea1d7bf777de65228039142d249f38Adam Powell        }
85497341bdc5bea1d7bf777de65228039142d249f38Adam Powell
85597341bdc5bea1d7bf777de65228039142d249f38Adam Powell        return wantTouchEvents;
85697341bdc5bea1d7bf777de65228039142d249f38Adam Powell    }
85797341bdc5bea1d7bf777de65228039142d249f38Adam Powell
85889e17886e6149bddfdb08a242c9e88889596419cAdam Powell    private boolean closePane(View pane, int initialVelocity) {
85989e17886e6149bddfdb08a242c9e88889596419cAdam Powell        if (mFirstLayout || smoothSlideTo(0.f, initialVelocity)) {
86089e17886e6149bddfdb08a242c9e88889596419cAdam Powell            mPreservedOpenState = false;
86189e17886e6149bddfdb08a242c9e88889596419cAdam Powell            return true;
8620eefe9ad0819b223006533cbc79a35d66684af32Adam Powell        }
86389e17886e6149bddfdb08a242c9e88889596419cAdam Powell        return false;
86497341bdc5bea1d7bf777de65228039142d249f38Adam Powell    }
86597341bdc5bea1d7bf777de65228039142d249f38Adam Powell
86689e17886e6149bddfdb08a242c9e88889596419cAdam Powell    private boolean openPane(View pane, int initialVelocity) {
86789e17886e6149bddfdb08a242c9e88889596419cAdam Powell        if (mFirstLayout || smoothSlideTo(1.f, initialVelocity)) {
86889e17886e6149bddfdb08a242c9e88889596419cAdam Powell            mPreservedOpenState = true;
86989e17886e6149bddfdb08a242c9e88889596419cAdam Powell            return true;
8700eefe9ad0819b223006533cbc79a35d66684af32Adam Powell        }
87189e17886e6149bddfdb08a242c9e88889596419cAdam Powell        return false;
87297341bdc5bea1d7bf777de65228039142d249f38Adam Powell    }
87397341bdc5bea1d7bf777de65228039142d249f38Adam Powell
87497341bdc5bea1d7bf777de65228039142d249f38Adam Powell    /**
87589e17886e6149bddfdb08a242c9e88889596419cAdam Powell     * @deprecated Renamed to {@link #openPane()} - this method is going away soon!
87697341bdc5bea1d7bf777de65228039142d249f38Adam Powell     */
87789e17886e6149bddfdb08a242c9e88889596419cAdam Powell    @Deprecated
87897341bdc5bea1d7bf777de65228039142d249f38Adam Powell    public void smoothSlideOpen() {
87989e17886e6149bddfdb08a242c9e88889596419cAdam Powell        openPane();
88089e17886e6149bddfdb08a242c9e88889596419cAdam Powell    }
88189e17886e6149bddfdb08a242c9e88889596419cAdam Powell
88289e17886e6149bddfdb08a242c9e88889596419cAdam Powell    /**
88389e17886e6149bddfdb08a242c9e88889596419cAdam Powell     * Open the sliding pane if it is currently slideable. If first layout
88489e17886e6149bddfdb08a242c9e88889596419cAdam Powell     * has already completed this will animate.
88589e17886e6149bddfdb08a242c9e88889596419cAdam Powell     *
88689e17886e6149bddfdb08a242c9e88889596419cAdam Powell     * @return true if the pane was slideable and is now open/in the process of opening
88789e17886e6149bddfdb08a242c9e88889596419cAdam Powell     */
88889e17886e6149bddfdb08a242c9e88889596419cAdam Powell    public boolean openPane() {
88989e17886e6149bddfdb08a242c9e88889596419cAdam Powell        return openPane(mSlideableView, 0);
89097341bdc5bea1d7bf777de65228039142d249f38Adam Powell    }
89197341bdc5bea1d7bf777de65228039142d249f38Adam Powell
89297341bdc5bea1d7bf777de65228039142d249f38Adam Powell    /**
89389e17886e6149bddfdb08a242c9e88889596419cAdam Powell     * @deprecated Renamed to {@link #closePane()} - this method is going away soon!
89497341bdc5bea1d7bf777de65228039142d249f38Adam Powell     */
89589e17886e6149bddfdb08a242c9e88889596419cAdam Powell    @Deprecated
89697341bdc5bea1d7bf777de65228039142d249f38Adam Powell    public void smoothSlideClosed() {
89789e17886e6149bddfdb08a242c9e88889596419cAdam Powell        closePane();
89889e17886e6149bddfdb08a242c9e88889596419cAdam Powell    }
89989e17886e6149bddfdb08a242c9e88889596419cAdam Powell
90089e17886e6149bddfdb08a242c9e88889596419cAdam Powell    /**
90189e17886e6149bddfdb08a242c9e88889596419cAdam Powell     * Close the sliding pane if it is currently slideable. If first layout
90289e17886e6149bddfdb08a242c9e88889596419cAdam Powell     * has already completed this will animate.
90389e17886e6149bddfdb08a242c9e88889596419cAdam Powell     *
90489e17886e6149bddfdb08a242c9e88889596419cAdam Powell     * @return true if the pane was slideable and is now closed/in the process of closing
90589e17886e6149bddfdb08a242c9e88889596419cAdam Powell     */
90689e17886e6149bddfdb08a242c9e88889596419cAdam Powell    public boolean closePane() {
90789e17886e6149bddfdb08a242c9e88889596419cAdam Powell        return closePane(mSlideableView, 0);
90897341bdc5bea1d7bf777de65228039142d249f38Adam Powell    }
90997341bdc5bea1d7bf777de65228039142d249f38Adam Powell
91097341bdc5bea1d7bf777de65228039142d249f38Adam Powell    /**
91189e17886e6149bddfdb08a242c9e88889596419cAdam Powell     * Check if the layout is completely open. It can be open either because the slider
91289e17886e6149bddfdb08a242c9e88889596419cAdam Powell     * itself is open revealing the left pane, or if all content fits without sliding.
91389e17886e6149bddfdb08a242c9e88889596419cAdam Powell     *
91497341bdc5bea1d7bf777de65228039142d249f38Adam Powell     * @return true if sliding panels are completely open
91597341bdc5bea1d7bf777de65228039142d249f38Adam Powell     */
91697341bdc5bea1d7bf777de65228039142d249f38Adam Powell    public boolean isOpen() {
9170eefe9ad0819b223006533cbc79a35d66684af32Adam Powell        return !mCanSlide || mSlideOffset == 1;
91897341bdc5bea1d7bf777de65228039142d249f38Adam Powell    }
91997341bdc5bea1d7bf777de65228039142d249f38Adam Powell
92097341bdc5bea1d7bf777de65228039142d249f38Adam Powell    /**
92197341bdc5bea1d7bf777de65228039142d249f38Adam Powell     * @return true if content in this layout can be slid open and closed
92289e17886e6149bddfdb08a242c9e88889596419cAdam Powell     * @deprecated Renamed to {@link #isSlideable()} - this method is going away soon!
92397341bdc5bea1d7bf777de65228039142d249f38Adam Powell     */
92489e17886e6149bddfdb08a242c9e88889596419cAdam Powell    @Deprecated
92597341bdc5bea1d7bf777de65228039142d249f38Adam Powell    public boolean canSlide() {
92697341bdc5bea1d7bf777de65228039142d249f38Adam Powell        return mCanSlide;
92797341bdc5bea1d7bf777de65228039142d249f38Adam Powell    }
92897341bdc5bea1d7bf777de65228039142d249f38Adam Powell
92989e17886e6149bddfdb08a242c9e88889596419cAdam Powell    /**
93089e17886e6149bddfdb08a242c9e88889596419cAdam Powell     * Check if the content in this layout cannot fully fit side by side and therefore
93189e17886e6149bddfdb08a242c9e88889596419cAdam Powell     * the content pane can be slid back and forth.
93289e17886e6149bddfdb08a242c9e88889596419cAdam Powell     *
93389e17886e6149bddfdb08a242c9e88889596419cAdam Powell     * @return true if content in this layout can be slid open and closed
93489e17886e6149bddfdb08a242c9e88889596419cAdam Powell     */
93589e17886e6149bddfdb08a242c9e88889596419cAdam Powell    public boolean isSlideable() {
93689e17886e6149bddfdb08a242c9e88889596419cAdam Powell        return mCanSlide;
93789e17886e6149bddfdb08a242c9e88889596419cAdam Powell    }
93889e17886e6149bddfdb08a242c9e88889596419cAdam Powell
939d44315a54e002b20365189f03a09011f2bf6ba07Adam Powell    private void onPanelDragged(int newLeft) {
940a7f2dd4b8892a97edbe90470dcd20504d4131e5fAdam Powell        if (mSlideableView == null) {
941a7f2dd4b8892a97edbe90470dcd20504d4131e5fAdam Powell            // This can happen if we're aborting motion during layout because everything now fits.
942a7f2dd4b8892a97edbe90470dcd20504d4131e5fAdam Powell            mSlideOffset = 0;
943a7f2dd4b8892a97edbe90470dcd20504d4131e5fAdam Powell            return;
944a7f2dd4b8892a97edbe90470dcd20504d4131e5fAdam Powell        }
94519780f88506df4aeb57456fd6747af1b6848a11cfafaisland        final boolean isLayoutRtl = isLayoutRtlSupport();
9460eefe9ad0819b223006533cbc79a35d66684af32Adam Powell        final LayoutParams lp = (LayoutParams) mSlideableView.getLayoutParams();
94797341bdc5bea1d7bf777de65228039142d249f38Adam Powell
94819780f88506df4aeb57456fd6747af1b6848a11cfafaisland        int childWidth = mSlideableView.getWidth();
94919780f88506df4aeb57456fd6747af1b6848a11cfafaisland        final int newStart = isLayoutRtl ? getWidth() - newLeft - childWidth : newLeft;
95019780f88506df4aeb57456fd6747af1b6848a11cfafaisland
95119780f88506df4aeb57456fd6747af1b6848a11cfafaisland        final int paddingStart = isLayoutRtl ? getPaddingRight() : getPaddingLeft();
95219780f88506df4aeb57456fd6747af1b6848a11cfafaisland        final int lpMargin = isLayoutRtl ? lp.rightMargin : lp.leftMargin;
95319780f88506df4aeb57456fd6747af1b6848a11cfafaisland        final int startBound = paddingStart + lpMargin;
95419780f88506df4aeb57456fd6747af1b6848a11cfafaisland
95519780f88506df4aeb57456fd6747af1b6848a11cfafaisland        mSlideOffset = (float) (newStart - startBound) / mSlideRange;
95697341bdc5bea1d7bf777de65228039142d249f38Adam Powell
9576debd2bbcae1cd285d2e21db633998b7801f9f40Adam Powell        if (mParallaxBy != 0) {
9580eefe9ad0819b223006533cbc79a35d66684af32Adam Powell            parallaxOtherViews(mSlideOffset);
9596debd2bbcae1cd285d2e21db633998b7801f9f40Adam Powell        }
9606debd2bbcae1cd285d2e21db633998b7801f9f40Adam Powell
961ee3f0ffb0199e295cbf48aa1a61c8ae7056526abAdam Powell        if (lp.dimWhenOffset) {
96281e2f002d1b4ebf2d951eb9f239858b8a9481a24Adam Powell            dimChildView(mSlideableView, mSlideOffset, mSliderFadeColor);
963ee3f0ffb0199e295cbf48aa1a61c8ae7056526abAdam Powell        }
9640eefe9ad0819b223006533cbc79a35d66684af32Adam Powell        dispatchOnPanelSlide(mSlideableView);
96597341bdc5bea1d7bf777de65228039142d249f38Adam Powell    }
96697341bdc5bea1d7bf777de65228039142d249f38Adam Powell
96781e2f002d1b4ebf2d951eb9f239858b8a9481a24Adam Powell    private void dimChildView(View v, float mag, int fadeColor) {
96897341bdc5bea1d7bf777de65228039142d249f38Adam Powell        final LayoutParams lp = (LayoutParams) v.getLayoutParams();
96997341bdc5bea1d7bf777de65228039142d249f38Adam Powell
97081e2f002d1b4ebf2d951eb9f239858b8a9481a24Adam Powell        if (mag > 0 && fadeColor != 0) {
97181e2f002d1b4ebf2d951eb9f239858b8a9481a24Adam Powell            final int baseAlpha = (fadeColor & 0xff000000) >>> 24;
972ee3f0ffb0199e295cbf48aa1a61c8ae7056526abAdam Powell            int imag = (int) (baseAlpha * mag);
97381e2f002d1b4ebf2d951eb9f239858b8a9481a24Adam Powell            int color = imag << 24 | (fadeColor & 0xffffff);
97497341bdc5bea1d7bf777de65228039142d249f38Adam Powell            if (lp.dimPaint == null) {
97597341bdc5bea1d7bf777de65228039142d249f38Adam Powell                lp.dimPaint = new Paint();
97697341bdc5bea1d7bf777de65228039142d249f38Adam Powell            }
977ee3f0ffb0199e295cbf48aa1a61c8ae7056526abAdam Powell            lp.dimPaint.setColorFilter(new PorterDuffColorFilter(color, PorterDuff.Mode.SRC_OVER));
97897341bdc5bea1d7bf777de65228039142d249f38Adam Powell            if (ViewCompat.getLayerType(v) != ViewCompat.LAYER_TYPE_HARDWARE) {
97997341bdc5bea1d7bf777de65228039142d249f38Adam Powell                ViewCompat.setLayerType(v, ViewCompat.LAYER_TYPE_HARDWARE, lp.dimPaint);
98097341bdc5bea1d7bf777de65228039142d249f38Adam Powell            }
98197341bdc5bea1d7bf777de65228039142d249f38Adam Powell            invalidateChildRegion(v);
98297341bdc5bea1d7bf777de65228039142d249f38Adam Powell        } else if (ViewCompat.getLayerType(v) != ViewCompat.LAYER_TYPE_NONE) {
98358898b639b18392580694bc6c902479274331bf2Adam Powell            if (lp.dimPaint != null) {
98458898b639b18392580694bc6c902479274331bf2Adam Powell                lp.dimPaint.setColorFilter(null);
98558898b639b18392580694bc6c902479274331bf2Adam Powell            }
986f4445e06a8490b056cd892c4bc640dfd17905d6cAdam Powell            final DisableLayerRunnable dlr = new DisableLayerRunnable(v);
987f4445e06a8490b056cd892c4bc640dfd17905d6cAdam Powell            mPostedRunnables.add(dlr);
988f4445e06a8490b056cd892c4bc640dfd17905d6cAdam Powell            ViewCompat.postOnAnimation(this, dlr);
98997341bdc5bea1d7bf777de65228039142d249f38Adam Powell        }
99097341bdc5bea1d7bf777de65228039142d249f38Adam Powell    }
99197341bdc5bea1d7bf777de65228039142d249f38Adam Powell
99297341bdc5bea1d7bf777de65228039142d249f38Adam Powell    @Override
99397341bdc5bea1d7bf777de65228039142d249f38Adam Powell    protected boolean drawChild(Canvas canvas, View child, long drawingTime) {
9941e43161e9e1f1dc10637a68d5c2304c1f95c9c46Adam Powell        final LayoutParams lp = (LayoutParams) child.getLayoutParams();
9951e43161e9e1f1dc10637a68d5c2304c1f95c9c46Adam Powell        boolean result;
9961e43161e9e1f1dc10637a68d5c2304c1f95c9c46Adam Powell        final int save = canvas.save(Canvas.CLIP_SAVE_FLAG);
9971e43161e9e1f1dc10637a68d5c2304c1f95c9c46Adam Powell
9981e43161e9e1f1dc10637a68d5c2304c1f95c9c46Adam Powell        if (mCanSlide && !lp.slideable && mSlideableView != null) {
9991e43161e9e1f1dc10637a68d5c2304c1f95c9c46Adam Powell            // Clip against the slider; no sense drawing what will immediately be covered.
10001e43161e9e1f1dc10637a68d5c2304c1f95c9c46Adam Powell            canvas.getClipBounds(mTmpRect);
100119780f88506df4aeb57456fd6747af1b6848a11cfafaisland            if (isLayoutRtlSupport()) {
100219780f88506df4aeb57456fd6747af1b6848a11cfafaisland                mTmpRect.left = Math.max(mTmpRect.left, mSlideableView.getRight());
100319780f88506df4aeb57456fd6747af1b6848a11cfafaisland            } else {
100419780f88506df4aeb57456fd6747af1b6848a11cfafaisland                mTmpRect.right = Math.min(mTmpRect.right, mSlideableView.getLeft());
100519780f88506df4aeb57456fd6747af1b6848a11cfafaisland            }
10061e43161e9e1f1dc10637a68d5c2304c1f95c9c46Adam Powell            canvas.clipRect(mTmpRect);
100797341bdc5bea1d7bf777de65228039142d249f38Adam Powell        }
100897341bdc5bea1d7bf777de65228039142d249f38Adam Powell
10091e43161e9e1f1dc10637a68d5c2304c1f95c9c46Adam Powell        if (Build.VERSION.SDK_INT >= 11) { // HC
10101e43161e9e1f1dc10637a68d5c2304c1f95c9c46Adam Powell            result = super.drawChild(canvas, child, drawingTime);
101197341bdc5bea1d7bf777de65228039142d249f38Adam Powell        } else {
10121e43161e9e1f1dc10637a68d5c2304c1f95c9c46Adam Powell            if (lp.dimWhenOffset && mSlideOffset > 0) {
10131e43161e9e1f1dc10637a68d5c2304c1f95c9c46Adam Powell                if (!child.isDrawingCacheEnabled()) {
10141e43161e9e1f1dc10637a68d5c2304c1f95c9c46Adam Powell                    child.setDrawingCacheEnabled(true);
10151e43161e9e1f1dc10637a68d5c2304c1f95c9c46Adam Powell                }
10161e43161e9e1f1dc10637a68d5c2304c1f95c9c46Adam Powell                final Bitmap cache = child.getDrawingCache();
1017b5a259b30fd4646294ac4d7ea00bd041406b07eeAdam Powell                if (cache != null) {
1018b5a259b30fd4646294ac4d7ea00bd041406b07eeAdam Powell                    canvas.drawBitmap(cache, child.getLeft(), child.getTop(), lp.dimPaint);
1019b5a259b30fd4646294ac4d7ea00bd041406b07eeAdam Powell                    result = false;
1020b5a259b30fd4646294ac4d7ea00bd041406b07eeAdam Powell                } else {
1021b5a259b30fd4646294ac4d7ea00bd041406b07eeAdam Powell                    Log.e(TAG, "drawChild: child view " + child + " returned null drawing cache");
1022b5a259b30fd4646294ac4d7ea00bd041406b07eeAdam Powell                    result = super.drawChild(canvas, child, drawingTime);
1023b5a259b30fd4646294ac4d7ea00bd041406b07eeAdam Powell                }
10241e43161e9e1f1dc10637a68d5c2304c1f95c9c46Adam Powell            } else {
10251e43161e9e1f1dc10637a68d5c2304c1f95c9c46Adam Powell                if (child.isDrawingCacheEnabled()) {
10261e43161e9e1f1dc10637a68d5c2304c1f95c9c46Adam Powell                    child.setDrawingCacheEnabled(false);
10271e43161e9e1f1dc10637a68d5c2304c1f95c9c46Adam Powell                }
10281e43161e9e1f1dc10637a68d5c2304c1f95c9c46Adam Powell                result = super.drawChild(canvas, child, drawingTime);
102997341bdc5bea1d7bf777de65228039142d249f38Adam Powell            }
103097341bdc5bea1d7bf777de65228039142d249f38Adam Powell        }
10311e43161e9e1f1dc10637a68d5c2304c1f95c9c46Adam Powell
10321e43161e9e1f1dc10637a68d5c2304c1f95c9c46Adam Powell        canvas.restoreToCount(save);
10331e43161e9e1f1dc10637a68d5c2304c1f95c9c46Adam Powell
10341e43161e9e1f1dc10637a68d5c2304c1f95c9c46Adam Powell        return result;
103597341bdc5bea1d7bf777de65228039142d249f38Adam Powell    }
103697341bdc5bea1d7bf777de65228039142d249f38Adam Powell
103797341bdc5bea1d7bf777de65228039142d249f38Adam Powell    private void invalidateChildRegion(View v) {
103897341bdc5bea1d7bf777de65228039142d249f38Adam Powell        IMPL.invalidateChildRegion(this, v);
103997341bdc5bea1d7bf777de65228039142d249f38Adam Powell    }
104097341bdc5bea1d7bf777de65228039142d249f38Adam Powell
104197341bdc5bea1d7bf777de65228039142d249f38Adam Powell    /**
104297341bdc5bea1d7bf777de65228039142d249f38Adam Powell     * Smoothly animate mDraggingPane to the target X position within its range.
104397341bdc5bea1d7bf777de65228039142d249f38Adam Powell     *
104497341bdc5bea1d7bf777de65228039142d249f38Adam Powell     * @param slideOffset position to animate to
104597341bdc5bea1d7bf777de65228039142d249f38Adam Powell     * @param velocity initial velocity in case of fling, or 0.
104697341bdc5bea1d7bf777de65228039142d249f38Adam Powell     */
104789e17886e6149bddfdb08a242c9e88889596419cAdam Powell    boolean smoothSlideTo(float slideOffset, int velocity) {
10480eefe9ad0819b223006533cbc79a35d66684af32Adam Powell        if (!mCanSlide) {
104997341bdc5bea1d7bf777de65228039142d249f38Adam Powell            // Nothing to do.
105089e17886e6149bddfdb08a242c9e88889596419cAdam Powell            return false;
105197341bdc5bea1d7bf777de65228039142d249f38Adam Powell        }
105297341bdc5bea1d7bf777de65228039142d249f38Adam Powell
105319780f88506df4aeb57456fd6747af1b6848a11cfafaisland        final boolean isLayoutRtl = isLayoutRtlSupport();
10540eefe9ad0819b223006533cbc79a35d66684af32Adam Powell        final LayoutParams lp = (LayoutParams) mSlideableView.getLayoutParams();
105597341bdc5bea1d7bf777de65228039142d249f38Adam Powell
105619780f88506df4aeb57456fd6747af1b6848a11cfafaisland        int x;
105719780f88506df4aeb57456fd6747af1b6848a11cfafaisland        if (isLayoutRtl) {
105819780f88506df4aeb57456fd6747af1b6848a11cfafaisland            int startBound = getPaddingRight() + lp.rightMargin;
105919780f88506df4aeb57456fd6747af1b6848a11cfafaisland            int childWidth = mSlideableView.getWidth();
106019780f88506df4aeb57456fd6747af1b6848a11cfafaisland            x = (int) (getWidth() - (startBound + slideOffset * mSlideRange + childWidth));
106119780f88506df4aeb57456fd6747af1b6848a11cfafaisland        } else {
106219780f88506df4aeb57456fd6747af1b6848a11cfafaisland            int startBound = getPaddingLeft() + lp.leftMargin;
106319780f88506df4aeb57456fd6747af1b6848a11cfafaisland            x = (int) (startBound + slideOffset * mSlideRange);
106419780f88506df4aeb57456fd6747af1b6848a11cfafaisland        }
106597341bdc5bea1d7bf777de65228039142d249f38Adam Powell
1066c56ba65d20be8742ff717907a3a2cd81dd0e5f3cAdam Powell        if (mDragHelper.smoothSlideViewTo(mSlideableView, x, mSlideableView.getTop())) {
1067c89f53833f1e272d32f7928837f0704fa33be309Adam Powell            setAllChildrenVisible();
1068c56ba65d20be8742ff717907a3a2cd81dd0e5f3cAdam Powell            ViewCompat.postInvalidateOnAnimation(this);
106989e17886e6149bddfdb08a242c9e88889596419cAdam Powell            return true;
107097341bdc5bea1d7bf777de65228039142d249f38Adam Powell        }
107189e17886e6149bddfdb08a242c9e88889596419cAdam Powell        return false;
107297341bdc5bea1d7bf777de65228039142d249f38Adam Powell    }
107397341bdc5bea1d7bf777de65228039142d249f38Adam Powell
107497341bdc5bea1d7bf777de65228039142d249f38Adam Powell    @Override
107597341bdc5bea1d7bf777de65228039142d249f38Adam Powell    public void computeScroll() {
1076c56ba65d20be8742ff717907a3a2cd81dd0e5f3cAdam Powell        if (mDragHelper.continueSettling(true)) {
10770eefe9ad0819b223006533cbc79a35d66684af32Adam Powell            if (!mCanSlide) {
1078c56ba65d20be8742ff717907a3a2cd81dd0e5f3cAdam Powell                mDragHelper.abort();
107997341bdc5bea1d7bf777de65228039142d249f38Adam Powell                return;
108097341bdc5bea1d7bf777de65228039142d249f38Adam Powell            }
108197341bdc5bea1d7bf777de65228039142d249f38Adam Powell
108297341bdc5bea1d7bf777de65228039142d249f38Adam Powell            ViewCompat.postInvalidateOnAnimation(this);
108397341bdc5bea1d7bf777de65228039142d249f38Adam Powell        }
108497341bdc5bea1d7bf777de65228039142d249f38Adam Powell    }
108597341bdc5bea1d7bf777de65228039142d249f38Adam Powell
1086ee3f0ffb0199e295cbf48aa1a61c8ae7056526abAdam Powell    /**
108719780f88506df4aeb57456fd6747af1b6848a11cfafaisland     * @deprecated Renamed to {@link #setShadowDrawableLeft(Drawable d)} to support LTR (left to
108819780f88506df4aeb57456fd6747af1b6848a11cfafaisland     * right language) and {@link #setShadowDrawableRight(Drawable d)} to support RTL (right to left
108919780f88506df4aeb57456fd6747af1b6848a11cfafaisland     * language) during opening/closing.
109019780f88506df4aeb57456fd6747af1b6848a11cfafaisland     *
109119780f88506df4aeb57456fd6747af1b6848a11cfafaisland     * @param d drawable to use as a shadow
109219780f88506df4aeb57456fd6747af1b6848a11cfafaisland     */
109319780f88506df4aeb57456fd6747af1b6848a11cfafaisland    @Deprecated
109419780f88506df4aeb57456fd6747af1b6848a11cfafaisland    public void setShadowDrawable(Drawable d) {
109519780f88506df4aeb57456fd6747af1b6848a11cfafaisland        setShadowDrawableLeft(d);
109619780f88506df4aeb57456fd6747af1b6848a11cfafaisland    }
109719780f88506df4aeb57456fd6747af1b6848a11cfafaisland
109819780f88506df4aeb57456fd6747af1b6848a11cfafaisland    /**
1099ee3f0ffb0199e295cbf48aa1a61c8ae7056526abAdam Powell     * Set a drawable to use as a shadow cast by the right pane onto the left pane
1100ee3f0ffb0199e295cbf48aa1a61c8ae7056526abAdam Powell     * during opening/closing.
1101ee3f0ffb0199e295cbf48aa1a61c8ae7056526abAdam Powell     *
1102ee3f0ffb0199e295cbf48aa1a61c8ae7056526abAdam Powell     * @param d drawable to use as a shadow
1103ee3f0ffb0199e295cbf48aa1a61c8ae7056526abAdam Powell     */
110419780f88506df4aeb57456fd6747af1b6848a11cfafaisland    public void setShadowDrawableLeft(Drawable d) {
110519780f88506df4aeb57456fd6747af1b6848a11cfafaisland        mShadowDrawableLeft = d;
110619780f88506df4aeb57456fd6747af1b6848a11cfafaisland    }
110719780f88506df4aeb57456fd6747af1b6848a11cfafaisland
110819780f88506df4aeb57456fd6747af1b6848a11cfafaisland    /**
110919780f88506df4aeb57456fd6747af1b6848a11cfafaisland     * Set a drawable to use as a shadow cast by the left pane onto the right pane
111019780f88506df4aeb57456fd6747af1b6848a11cfafaisland     * during opening/closing to support right to left language.
111119780f88506df4aeb57456fd6747af1b6848a11cfafaisland     *
111219780f88506df4aeb57456fd6747af1b6848a11cfafaisland     * @param d drawable to use as a shadow
111319780f88506df4aeb57456fd6747af1b6848a11cfafaisland     */
111419780f88506df4aeb57456fd6747af1b6848a11cfafaisland    public void setShadowDrawableRight(Drawable d) {
111519780f88506df4aeb57456fd6747af1b6848a11cfafaisland        mShadowDrawableRight = d;
1116ee3f0ffb0199e295cbf48aa1a61c8ae7056526abAdam Powell    }
1117ee3f0ffb0199e295cbf48aa1a61c8ae7056526abAdam Powell
1118ee3f0ffb0199e295cbf48aa1a61c8ae7056526abAdam Powell    /**
1119ee3f0ffb0199e295cbf48aa1a61c8ae7056526abAdam Powell     * Set a drawable to use as a shadow cast by the right pane onto the left pane
1120ee3f0ffb0199e295cbf48aa1a61c8ae7056526abAdam Powell     * during opening/closing.
1121ee3f0ffb0199e295cbf48aa1a61c8ae7056526abAdam Powell     *
1122ee3f0ffb0199e295cbf48aa1a61c8ae7056526abAdam Powell     * @param resId Resource ID of a drawable to use
1123ee3f0ffb0199e295cbf48aa1a61c8ae7056526abAdam Powell     */
112419780f88506df4aeb57456fd6747af1b6848a11cfafaisland    @Deprecated
1125a3ff3273e976adf19770651dcf473fa67b38eb22Tor Norbye    public void setShadowResource(@DrawableRes int resId) {
1126ee3f0ffb0199e295cbf48aa1a61c8ae7056526abAdam Powell        setShadowDrawable(getResources().getDrawable(resId));
1127ee3f0ffb0199e295cbf48aa1a61c8ae7056526abAdam Powell    }
1128ee3f0ffb0199e295cbf48aa1a61c8ae7056526abAdam Powell
112919780f88506df4aeb57456fd6747af1b6848a11cfafaisland    /**
113019780f88506df4aeb57456fd6747af1b6848a11cfafaisland     * Set a drawable to use as a shadow cast by the right pane onto the left pane
113119780f88506df4aeb57456fd6747af1b6848a11cfafaisland     * during opening/closing.
113219780f88506df4aeb57456fd6747af1b6848a11cfafaisland     *
113319780f88506df4aeb57456fd6747af1b6848a11cfafaisland     * @param resId Resource ID of a drawable to use
113419780f88506df4aeb57456fd6747af1b6848a11cfafaisland     */
113519780f88506df4aeb57456fd6747af1b6848a11cfafaisland    public void setShadowResourceLeft(int resId) {
113619780f88506df4aeb57456fd6747af1b6848a11cfafaisland        setShadowDrawableLeft(getResources().getDrawable(resId));
113719780f88506df4aeb57456fd6747af1b6848a11cfafaisland    }
113819780f88506df4aeb57456fd6747af1b6848a11cfafaisland
113919780f88506df4aeb57456fd6747af1b6848a11cfafaisland    /**
114019780f88506df4aeb57456fd6747af1b6848a11cfafaisland     * Set a drawable to use as a shadow cast by the left pane onto the right pane
114119780f88506df4aeb57456fd6747af1b6848a11cfafaisland     * during opening/closing to support right to left language.
114219780f88506df4aeb57456fd6747af1b6848a11cfafaisland     *
114319780f88506df4aeb57456fd6747af1b6848a11cfafaisland     * @param resId Resource ID of a drawable to use
114419780f88506df4aeb57456fd6747af1b6848a11cfafaisland     */
114519780f88506df4aeb57456fd6747af1b6848a11cfafaisland    public void setShadowResourceRight(int resId) {
114619780f88506df4aeb57456fd6747af1b6848a11cfafaisland        setShadowDrawableRight(getResources().getDrawable(resId));
114719780f88506df4aeb57456fd6747af1b6848a11cfafaisland    }
114819780f88506df4aeb57456fd6747af1b6848a11cfafaisland
114919780f88506df4aeb57456fd6747af1b6848a11cfafaisland
1150ee3f0ffb0199e295cbf48aa1a61c8ae7056526abAdam Powell    @Override
1151ee3f0ffb0199e295cbf48aa1a61c8ae7056526abAdam Powell    public void draw(Canvas c) {
1152ee3f0ffb0199e295cbf48aa1a61c8ae7056526abAdam Powell        super.draw(c);
115319780f88506df4aeb57456fd6747af1b6848a11cfafaisland        final boolean isLayoutRtl = isLayoutRtlSupport();
115419780f88506df4aeb57456fd6747af1b6848a11cfafaisland        Drawable shadowDrawable;
115519780f88506df4aeb57456fd6747af1b6848a11cfafaisland        if (isLayoutRtl) {
115619780f88506df4aeb57456fd6747af1b6848a11cfafaisland            shadowDrawable = mShadowDrawableRight;
115719780f88506df4aeb57456fd6747af1b6848a11cfafaisland        } else {
115819780f88506df4aeb57456fd6747af1b6848a11cfafaisland            shadowDrawable = mShadowDrawableLeft;
115919780f88506df4aeb57456fd6747af1b6848a11cfafaisland        }
1160ee3f0ffb0199e295cbf48aa1a61c8ae7056526abAdam Powell
11611e43161e9e1f1dc10637a68d5c2304c1f95c9c46Adam Powell        final View shadowView = getChildCount() > 1 ? getChildAt(1) : null;
116219780f88506df4aeb57456fd6747af1b6848a11cfafaisland        if (shadowView == null || shadowDrawable == null) {
11633783c4b814bf70711fc4d674e9c7fbc34b1e5a83Adam Powell            // No need to draw a shadow if we don't have one.
1164ee3f0ffb0199e295cbf48aa1a61c8ae7056526abAdam Powell            return;
1165ee3f0ffb0199e295cbf48aa1a61c8ae7056526abAdam Powell        }
1166ee3f0ffb0199e295cbf48aa1a61c8ae7056526abAdam Powell
11671e43161e9e1f1dc10637a68d5c2304c1f95c9c46Adam Powell        final int top = shadowView.getTop();
11681e43161e9e1f1dc10637a68d5c2304c1f95c9c46Adam Powell        final int bottom = shadowView.getBottom();
116919780f88506df4aeb57456fd6747af1b6848a11cfafaisland
117019780f88506df4aeb57456fd6747af1b6848a11cfafaisland        final int shadowWidth = shadowDrawable.getIntrinsicWidth();
117119780f88506df4aeb57456fd6747af1b6848a11cfafaisland        final int left;
117219780f88506df4aeb57456fd6747af1b6848a11cfafaisland        final int right;
117319780f88506df4aeb57456fd6747af1b6848a11cfafaisland        if (isLayoutRtlSupport()) {
117419780f88506df4aeb57456fd6747af1b6848a11cfafaisland            left = shadowView.getRight();
117519780f88506df4aeb57456fd6747af1b6848a11cfafaisland            right = left + shadowWidth;
117619780f88506df4aeb57456fd6747af1b6848a11cfafaisland        } else {
117719780f88506df4aeb57456fd6747af1b6848a11cfafaisland            right = shadowView.getLeft();
117819780f88506df4aeb57456fd6747af1b6848a11cfafaisland            left = right - shadowWidth;
117919780f88506df4aeb57456fd6747af1b6848a11cfafaisland        }
118019780f88506df4aeb57456fd6747af1b6848a11cfafaisland
118119780f88506df4aeb57456fd6747af1b6848a11cfafaisland        shadowDrawable.setBounds(left, top, right, bottom);
118219780f88506df4aeb57456fd6747af1b6848a11cfafaisland        shadowDrawable.draw(c);
1183ee3f0ffb0199e295cbf48aa1a61c8ae7056526abAdam Powell    }
1184ee3f0ffb0199e295cbf48aa1a61c8ae7056526abAdam Powell
11856debd2bbcae1cd285d2e21db633998b7801f9f40Adam Powell    private void parallaxOtherViews(float slideOffset) {
118619780f88506df4aeb57456fd6747af1b6848a11cfafaisland        final boolean isLayoutRtl = isLayoutRtlSupport();
1187ee3f0ffb0199e295cbf48aa1a61c8ae7056526abAdam Powell        final LayoutParams slideLp = (LayoutParams) mSlideableView.getLayoutParams();
118819780f88506df4aeb57456fd6747af1b6848a11cfafaisland        final boolean dimViews = slideLp.dimWhenOffset &&
118919780f88506df4aeb57456fd6747af1b6848a11cfafaisland                (isLayoutRtl ? slideLp.rightMargin : slideLp.leftMargin) <= 0;
11906debd2bbcae1cd285d2e21db633998b7801f9f40Adam Powell        final int childCount = getChildCount();
11916debd2bbcae1cd285d2e21db633998b7801f9f40Adam Powell        for (int i = 0; i < childCount; i++) {
11926debd2bbcae1cd285d2e21db633998b7801f9f40Adam Powell            final View v = getChildAt(i);
11930eefe9ad0819b223006533cbc79a35d66684af32Adam Powell            if (v == mSlideableView) continue;
11946debd2bbcae1cd285d2e21db633998b7801f9f40Adam Powell
11950eefe9ad0819b223006533cbc79a35d66684af32Adam Powell            final int oldOffset = (int) ((1 - mParallaxOffset) * mParallaxBy);
11960eefe9ad0819b223006533cbc79a35d66684af32Adam Powell            mParallaxOffset = slideOffset;
11976debd2bbcae1cd285d2e21db633998b7801f9f40Adam Powell            final int newOffset = (int) ((1 - slideOffset) * mParallaxBy);
1198ad9696cf0da9b65c4a52f00fe5adaa17b99a05caAdam Powell            final int dx = oldOffset - newOffset;
1199ad9696cf0da9b65c4a52f00fe5adaa17b99a05caAdam Powell
120019780f88506df4aeb57456fd6747af1b6848a11cfafaisland            v.offsetLeftAndRight(isLayoutRtl ? -dx : dx);
1201ee3f0ffb0199e295cbf48aa1a61c8ae7056526abAdam Powell
1202ee3f0ffb0199e295cbf48aa1a61c8ae7056526abAdam Powell            if (dimViews) {
120319780f88506df4aeb57456fd6747af1b6848a11cfafaisland                dimChildView(v, isLayoutRtl ? mParallaxOffset - 1 :
120419780f88506df4aeb57456fd6747af1b6848a11cfafaisland                    1 - mParallaxOffset, mCoveredFadeColor);
1205ee3f0ffb0199e295cbf48aa1a61c8ae7056526abAdam Powell            }
12066debd2bbcae1cd285d2e21db633998b7801f9f40Adam Powell        }
12076debd2bbcae1cd285d2e21db633998b7801f9f40Adam Powell    }
12086debd2bbcae1cd285d2e21db633998b7801f9f40Adam Powell
120997341bdc5bea1d7bf777de65228039142d249f38Adam Powell    /**
121097341bdc5bea1d7bf777de65228039142d249f38Adam Powell     * Tests scrollability within child views of v given a delta of dx.
121197341bdc5bea1d7bf777de65228039142d249f38Adam Powell     *
121297341bdc5bea1d7bf777de65228039142d249f38Adam Powell     * @param v View to test for horizontal scrollability
121397341bdc5bea1d7bf777de65228039142d249f38Adam Powell     * @param checkV Whether the view v passed should itself be checked for scrollability (true),
121497341bdc5bea1d7bf777de65228039142d249f38Adam Powell     *               or just its children (false).
121597341bdc5bea1d7bf777de65228039142d249f38Adam Powell     * @param dx Delta scrolled in pixels
121697341bdc5bea1d7bf777de65228039142d249f38Adam Powell     * @param x X coordinate of the active touch point
121797341bdc5bea1d7bf777de65228039142d249f38Adam Powell     * @param y Y coordinate of the active touch point
121897341bdc5bea1d7bf777de65228039142d249f38Adam Powell     * @return true if child views of v can be scrolled by delta of dx.
121997341bdc5bea1d7bf777de65228039142d249f38Adam Powell     */
122097341bdc5bea1d7bf777de65228039142d249f38Adam Powell    protected boolean canScroll(View v, boolean checkV, int dx, int x, int y) {
122197341bdc5bea1d7bf777de65228039142d249f38Adam Powell        if (v instanceof ViewGroup) {
122297341bdc5bea1d7bf777de65228039142d249f38Adam Powell            final ViewGroup group = (ViewGroup) v;
122397341bdc5bea1d7bf777de65228039142d249f38Adam Powell            final int scrollX = v.getScrollX();
122497341bdc5bea1d7bf777de65228039142d249f38Adam Powell            final int scrollY = v.getScrollY();
122597341bdc5bea1d7bf777de65228039142d249f38Adam Powell            final int count = group.getChildCount();
122697341bdc5bea1d7bf777de65228039142d249f38Adam Powell            // Count backwards - let topmost views consume scroll distance first.
122797341bdc5bea1d7bf777de65228039142d249f38Adam Powell            for (int i = count - 1; i >= 0; i--) {
122897341bdc5bea1d7bf777de65228039142d249f38Adam Powell                // TODO: Add versioned support here for transformed views.
122997341bdc5bea1d7bf777de65228039142d249f38Adam Powell                // This will not work for transformed views in Honeycomb+
123097341bdc5bea1d7bf777de65228039142d249f38Adam Powell                final View child = group.getChildAt(i);
123197341bdc5bea1d7bf777de65228039142d249f38Adam Powell                if (x + scrollX >= child.getLeft() && x + scrollX < child.getRight() &&
123297341bdc5bea1d7bf777de65228039142d249f38Adam Powell                        y + scrollY >= child.getTop() && y + scrollY < child.getBottom() &&
123397341bdc5bea1d7bf777de65228039142d249f38Adam Powell                        canScroll(child, true, dx, x + scrollX - child.getLeft(),
123497341bdc5bea1d7bf777de65228039142d249f38Adam Powell                                y + scrollY - child.getTop())) {
123597341bdc5bea1d7bf777de65228039142d249f38Adam Powell                    return true;
123697341bdc5bea1d7bf777de65228039142d249f38Adam Powell                }
123797341bdc5bea1d7bf777de65228039142d249f38Adam Powell            }
123897341bdc5bea1d7bf777de65228039142d249f38Adam Powell        }
123997341bdc5bea1d7bf777de65228039142d249f38Adam Powell
124019780f88506df4aeb57456fd6747af1b6848a11cfafaisland        return checkV && ViewCompat.canScrollHorizontally(v, (isLayoutRtlSupport() ? dx : -dx));
124197341bdc5bea1d7bf777de65228039142d249f38Adam Powell    }
124297341bdc5bea1d7bf777de65228039142d249f38Adam Powell
12430eefe9ad0819b223006533cbc79a35d66684af32Adam Powell    boolean isDimmed(View child) {
12440eefe9ad0819b223006533cbc79a35d66684af32Adam Powell        if (child == null) {
12450eefe9ad0819b223006533cbc79a35d66684af32Adam Powell            return false;
12460eefe9ad0819b223006533cbc79a35d66684af32Adam Powell        }
124797341bdc5bea1d7bf777de65228039142d249f38Adam Powell        final LayoutParams lp = (LayoutParams) child.getLayoutParams();
12480eefe9ad0819b223006533cbc79a35d66684af32Adam Powell        return mCanSlide && lp.dimWhenOffset && mSlideOffset > 0;
124997341bdc5bea1d7bf777de65228039142d249f38Adam Powell    }
125097341bdc5bea1d7bf777de65228039142d249f38Adam Powell
125197341bdc5bea1d7bf777de65228039142d249f38Adam Powell    @Override
125297341bdc5bea1d7bf777de65228039142d249f38Adam Powell    protected ViewGroup.LayoutParams generateDefaultLayoutParams() {
125397341bdc5bea1d7bf777de65228039142d249f38Adam Powell        return new LayoutParams();
125497341bdc5bea1d7bf777de65228039142d249f38Adam Powell    }
125597341bdc5bea1d7bf777de65228039142d249f38Adam Powell
125697341bdc5bea1d7bf777de65228039142d249f38Adam Powell    @Override
125797341bdc5bea1d7bf777de65228039142d249f38Adam Powell    protected ViewGroup.LayoutParams generateLayoutParams(ViewGroup.LayoutParams p) {
125897341bdc5bea1d7bf777de65228039142d249f38Adam Powell        return p instanceof MarginLayoutParams
125997341bdc5bea1d7bf777de65228039142d249f38Adam Powell                ? new LayoutParams((MarginLayoutParams) p)
126097341bdc5bea1d7bf777de65228039142d249f38Adam Powell                : new LayoutParams(p);
126197341bdc5bea1d7bf777de65228039142d249f38Adam Powell    }
126297341bdc5bea1d7bf777de65228039142d249f38Adam Powell
126397341bdc5bea1d7bf777de65228039142d249f38Adam Powell    @Override
126497341bdc5bea1d7bf777de65228039142d249f38Adam Powell    protected boolean checkLayoutParams(ViewGroup.LayoutParams p) {
126597341bdc5bea1d7bf777de65228039142d249f38Adam Powell        return p instanceof LayoutParams && super.checkLayoutParams(p);
126697341bdc5bea1d7bf777de65228039142d249f38Adam Powell    }
126797341bdc5bea1d7bf777de65228039142d249f38Adam Powell
126897341bdc5bea1d7bf777de65228039142d249f38Adam Powell    @Override
126997341bdc5bea1d7bf777de65228039142d249f38Adam Powell    public ViewGroup.LayoutParams generateLayoutParams(AttributeSet attrs) {
127097341bdc5bea1d7bf777de65228039142d249f38Adam Powell        return new LayoutParams(getContext(), attrs);
127197341bdc5bea1d7bf777de65228039142d249f38Adam Powell    }
127297341bdc5bea1d7bf777de65228039142d249f38Adam Powell
12731d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell    @Override
12741d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell    protected Parcelable onSaveInstanceState() {
12751d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell        Parcelable superState = super.onSaveInstanceState();
12761d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell
12771d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell        SavedState ss = new SavedState(superState);
127889e17886e6149bddfdb08a242c9e88889596419cAdam Powell        ss.isOpen = isSlideable() ? isOpen() : mPreservedOpenState;
12791d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell
12801d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell        return ss;
12811d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell    }
12821d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell
12831d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell    @Override
12841d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell    protected void onRestoreInstanceState(Parcelable state) {
12851d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell        SavedState ss = (SavedState) state;
12861d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell        super.onRestoreInstanceState(ss.getSuperState());
12871d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell
128889e17886e6149bddfdb08a242c9e88889596419cAdam Powell        if (ss.isOpen) {
128989e17886e6149bddfdb08a242c9e88889596419cAdam Powell            openPane();
129089e17886e6149bddfdb08a242c9e88889596419cAdam Powell        } else {
129189e17886e6149bddfdb08a242c9e88889596419cAdam Powell            closePane();
129289e17886e6149bddfdb08a242c9e88889596419cAdam Powell        }
129389e17886e6149bddfdb08a242c9e88889596419cAdam Powell        mPreservedOpenState = ss.isOpen;
12941d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell    }
12951d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell
1296c56ba65d20be8742ff717907a3a2cd81dd0e5f3cAdam Powell    private class DragHelperCallback extends ViewDragHelper.Callback {
1297c56ba65d20be8742ff717907a3a2cd81dd0e5f3cAdam Powell
1298c56ba65d20be8742ff717907a3a2cd81dd0e5f3cAdam Powell        @Override
1299c56ba65d20be8742ff717907a3a2cd81dd0e5f3cAdam Powell        public boolean tryCaptureView(View child, int pointerId) {
1300c56ba65d20be8742ff717907a3a2cd81dd0e5f3cAdam Powell            if (mIsUnableToDrag) {
1301c56ba65d20be8742ff717907a3a2cd81dd0e5f3cAdam Powell                return false;
1302c56ba65d20be8742ff717907a3a2cd81dd0e5f3cAdam Powell            }
1303c56ba65d20be8742ff717907a3a2cd81dd0e5f3cAdam Powell
1304c56ba65d20be8742ff717907a3a2cd81dd0e5f3cAdam Powell            return ((LayoutParams) child.getLayoutParams()).slideable;
1305c56ba65d20be8742ff717907a3a2cd81dd0e5f3cAdam Powell        }
1306c56ba65d20be8742ff717907a3a2cd81dd0e5f3cAdam Powell
1307c56ba65d20be8742ff717907a3a2cd81dd0e5f3cAdam Powell        @Override
1308c56ba65d20be8742ff717907a3a2cd81dd0e5f3cAdam Powell        public void onViewDragStateChanged(int state) {
1309471f0f4e84c7d1f96e48fb26713f246d69c3241fAdam Powell            if (mDragHelper.getViewDragState() == ViewDragHelper.STATE_IDLE) {
13106580cf4b7e74a2a017ed95b0dc50155b9995edebAdam Powell                if (mSlideOffset == 0) {
1311c89f53833f1e272d32f7928837f0704fa33be309Adam Powell                    updateObscuredViewsVisibility(mSlideableView);
13126580cf4b7e74a2a017ed95b0dc50155b9995edebAdam Powell                    dispatchOnPanelClosed(mSlideableView);
131372c7316b081c3134f7b0566f703dfee7c970eadeAdam Powell                    mPreservedOpenState = false;
13146580cf4b7e74a2a017ed95b0dc50155b9995edebAdam Powell                } else {
13156580cf4b7e74a2a017ed95b0dc50155b9995edebAdam Powell                    dispatchOnPanelOpened(mSlideableView);
131672c7316b081c3134f7b0566f703dfee7c970eadeAdam Powell                    mPreservedOpenState = true;
13176580cf4b7e74a2a017ed95b0dc50155b9995edebAdam Powell                }
1318c56ba65d20be8742ff717907a3a2cd81dd0e5f3cAdam Powell            }
1319c56ba65d20be8742ff717907a3a2cd81dd0e5f3cAdam Powell        }
1320c56ba65d20be8742ff717907a3a2cd81dd0e5f3cAdam Powell
1321c56ba65d20be8742ff717907a3a2cd81dd0e5f3cAdam Powell        @Override
1322c89f53833f1e272d32f7928837f0704fa33be309Adam Powell        public void onViewCaptured(View capturedChild, int activePointerId) {
1323c89f53833f1e272d32f7928837f0704fa33be309Adam Powell            // Make all child views visible in preparation for sliding things around
1324c89f53833f1e272d32f7928837f0704fa33be309Adam Powell            setAllChildrenVisible();
1325c89f53833f1e272d32f7928837f0704fa33be309Adam Powell        }
1326c89f53833f1e272d32f7928837f0704fa33be309Adam Powell
1327c89f53833f1e272d32f7928837f0704fa33be309Adam Powell        @Override
13281d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell        public void onViewPositionChanged(View changedView, int left, int top, int dx, int dy) {
1329d44315a54e002b20365189f03a09011f2bf6ba07Adam Powell            onPanelDragged(left);
1330c56ba65d20be8742ff717907a3a2cd81dd0e5f3cAdam Powell            invalidate();
1331c56ba65d20be8742ff717907a3a2cd81dd0e5f3cAdam Powell        }
1332c56ba65d20be8742ff717907a3a2cd81dd0e5f3cAdam Powell
1333c56ba65d20be8742ff717907a3a2cd81dd0e5f3cAdam Powell        @Override
1334c56ba65d20be8742ff717907a3a2cd81dd0e5f3cAdam Powell        public void onViewReleased(View releasedChild, float xvel, float yvel) {
1335c56ba65d20be8742ff717907a3a2cd81dd0e5f3cAdam Powell            final LayoutParams lp = (LayoutParams) releasedChild.getLayoutParams();
133619780f88506df4aeb57456fd6747af1b6848a11cfafaisland
133719780f88506df4aeb57456fd6747af1b6848a11cfafaisland            int left;
133819780f88506df4aeb57456fd6747af1b6848a11cfafaisland            if (isLayoutRtlSupport()) {
133919780f88506df4aeb57456fd6747af1b6848a11cfafaisland                int startToRight =  getPaddingRight() + lp.rightMargin;
13407099553551ccfc346e22843e0541ed4393c9c4edfafaisland                if (xvel < 0 || (xvel == 0 && mSlideOffset > 0.5f)) {
134119780f88506df4aeb57456fd6747af1b6848a11cfafaisland                    startToRight += mSlideRange;
134219780f88506df4aeb57456fd6747af1b6848a11cfafaisland                }
134319780f88506df4aeb57456fd6747af1b6848a11cfafaisland                int childWidth = mSlideableView.getWidth();
134419780f88506df4aeb57456fd6747af1b6848a11cfafaisland                left = getWidth() - startToRight - childWidth;
134519780f88506df4aeb57456fd6747af1b6848a11cfafaisland            } else {
134619780f88506df4aeb57456fd6747af1b6848a11cfafaisland                left = getPaddingLeft() + lp.leftMargin;
134719780f88506df4aeb57456fd6747af1b6848a11cfafaisland                if (xvel > 0 || (xvel == 0 && mSlideOffset > 0.5f)) {
134819780f88506df4aeb57456fd6747af1b6848a11cfafaisland                    left += mSlideRange;
134919780f88506df4aeb57456fd6747af1b6848a11cfafaisland                }
1350c56ba65d20be8742ff717907a3a2cd81dd0e5f3cAdam Powell            }
1351c56ba65d20be8742ff717907a3a2cd81dd0e5f3cAdam Powell            mDragHelper.settleCapturedViewAt(left, releasedChild.getTop());
1352c56ba65d20be8742ff717907a3a2cd81dd0e5f3cAdam Powell            invalidate();
1353c56ba65d20be8742ff717907a3a2cd81dd0e5f3cAdam Powell        }
1354c56ba65d20be8742ff717907a3a2cd81dd0e5f3cAdam Powell
1355c56ba65d20be8742ff717907a3a2cd81dd0e5f3cAdam Powell        @Override
1356c56ba65d20be8742ff717907a3a2cd81dd0e5f3cAdam Powell        public int getViewHorizontalDragRange(View child) {
1357c56ba65d20be8742ff717907a3a2cd81dd0e5f3cAdam Powell            return mSlideRange;
1358c56ba65d20be8742ff717907a3a2cd81dd0e5f3cAdam Powell        }
1359c56ba65d20be8742ff717907a3a2cd81dd0e5f3cAdam Powell
1360c56ba65d20be8742ff717907a3a2cd81dd0e5f3cAdam Powell        @Override
13611d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell        public int clampViewPositionHorizontal(View child, int left, int dx) {
1362c56ba65d20be8742ff717907a3a2cd81dd0e5f3cAdam Powell            final LayoutParams lp = (LayoutParams) mSlideableView.getLayoutParams();
1363c56ba65d20be8742ff717907a3a2cd81dd0e5f3cAdam Powell
136419780f88506df4aeb57456fd6747af1b6848a11cfafaisland            final int newLeft;
136519780f88506df4aeb57456fd6747af1b6848a11cfafaisland            if (isLayoutRtlSupport()) {
136619780f88506df4aeb57456fd6747af1b6848a11cfafaisland                int startBound = getWidth() -
136719780f88506df4aeb57456fd6747af1b6848a11cfafaisland                        (getPaddingRight() + lp.rightMargin + mSlideableView.getWidth());
136819780f88506df4aeb57456fd6747af1b6848a11cfafaisland                int endBound =  startBound - mSlideRange;
136919780f88506df4aeb57456fd6747af1b6848a11cfafaisland                newLeft = Math.max(Math.min(left, startBound), endBound);
137019780f88506df4aeb57456fd6747af1b6848a11cfafaisland            } else {
137119780f88506df4aeb57456fd6747af1b6848a11cfafaisland                int startBound = getPaddingLeft() + lp.leftMargin;
137219780f88506df4aeb57456fd6747af1b6848a11cfafaisland                int endBound = startBound + mSlideRange;
137319780f88506df4aeb57456fd6747af1b6848a11cfafaisland                newLeft = Math.min(Math.max(left, startBound), endBound);
137419780f88506df4aeb57456fd6747af1b6848a11cfafaisland            }
13751d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell            return newLeft;
1376c56ba65d20be8742ff717907a3a2cd81dd0e5f3cAdam Powell        }
1377c56ba65d20be8742ff717907a3a2cd81dd0e5f3cAdam Powell
1378c56ba65d20be8742ff717907a3a2cd81dd0e5f3cAdam Powell        @Override
13796688e113ad2519dc07edf56acbd0f42ce209a585Sérgio Faria        public int clampViewPositionVertical(View child, int top, int dy) {
13806688e113ad2519dc07edf56acbd0f42ce209a585Sérgio Faria            // Make sure we never move views vertically.
13816688e113ad2519dc07edf56acbd0f42ce209a585Sérgio Faria            // This could happen if the child has less height than its parent.
13826688e113ad2519dc07edf56acbd0f42ce209a585Sérgio Faria            return child.getTop();
13836688e113ad2519dc07edf56acbd0f42ce209a585Sérgio Faria        }
13846688e113ad2519dc07edf56acbd0f42ce209a585Sérgio Faria
13856688e113ad2519dc07edf56acbd0f42ce209a585Sérgio Faria        @Override
1386c56ba65d20be8742ff717907a3a2cd81dd0e5f3cAdam Powell        public void onEdgeDragStarted(int edgeFlags, int pointerId) {
1387c56ba65d20be8742ff717907a3a2cd81dd0e5f3cAdam Powell            mDragHelper.captureChildView(mSlideableView, pointerId);
1388c56ba65d20be8742ff717907a3a2cd81dd0e5f3cAdam Powell        }
1389c56ba65d20be8742ff717907a3a2cd81dd0e5f3cAdam Powell    }
1390c56ba65d20be8742ff717907a3a2cd81dd0e5f3cAdam Powell
139197341bdc5bea1d7bf777de65228039142d249f38Adam Powell    public static class LayoutParams extends ViewGroup.MarginLayoutParams {
139297341bdc5bea1d7bf777de65228039142d249f38Adam Powell        private static final int[] ATTRS = new int[] {
139397341bdc5bea1d7bf777de65228039142d249f38Adam Powell            android.R.attr.layout_weight
139497341bdc5bea1d7bf777de65228039142d249f38Adam Powell        };
139597341bdc5bea1d7bf777de65228039142d249f38Adam Powell
13966debd2bbcae1cd285d2e21db633998b7801f9f40Adam Powell        /**
13976debd2bbcae1cd285d2e21db633998b7801f9f40Adam Powell         * The weighted proportion of how much of the leftover space
13986debd2bbcae1cd285d2e21db633998b7801f9f40Adam Powell         * this child should consume after measurement.
13996debd2bbcae1cd285d2e21db633998b7801f9f40Adam Powell         */
140097341bdc5bea1d7bf777de65228039142d249f38Adam Powell        public float weight = 0;
140197341bdc5bea1d7bf777de65228039142d249f38Adam Powell
140297341bdc5bea1d7bf777de65228039142d249f38Adam Powell        /**
14030eefe9ad0819b223006533cbc79a35d66684af32Adam Powell         * True if this pane is the slideable pane in the layout.
140497341bdc5bea1d7bf777de65228039142d249f38Adam Powell         */
14050eefe9ad0819b223006533cbc79a35d66684af32Adam Powell        boolean slideable;
140697341bdc5bea1d7bf777de65228039142d249f38Adam Powell
140797341bdc5bea1d7bf777de65228039142d249f38Adam Powell        /**
140897341bdc5bea1d7bf777de65228039142d249f38Adam Powell         * True if this view should be drawn dimmed
140997341bdc5bea1d7bf777de65228039142d249f38Adam Powell         * when it's been offset from its default position.
141097341bdc5bea1d7bf777de65228039142d249f38Adam Powell         */
141197341bdc5bea1d7bf777de65228039142d249f38Adam Powell        boolean dimWhenOffset;
141297341bdc5bea1d7bf777de65228039142d249f38Adam Powell
141397341bdc5bea1d7bf777de65228039142d249f38Adam Powell        Paint dimPaint;
141497341bdc5bea1d7bf777de65228039142d249f38Adam Powell
141597341bdc5bea1d7bf777de65228039142d249f38Adam Powell        public LayoutParams() {
141697341bdc5bea1d7bf777de65228039142d249f38Adam Powell            super(FILL_PARENT, FILL_PARENT);
141797341bdc5bea1d7bf777de65228039142d249f38Adam Powell        }
141897341bdc5bea1d7bf777de65228039142d249f38Adam Powell
141997341bdc5bea1d7bf777de65228039142d249f38Adam Powell        public LayoutParams(int width, int height) {
142097341bdc5bea1d7bf777de65228039142d249f38Adam Powell            super(width, height);
142197341bdc5bea1d7bf777de65228039142d249f38Adam Powell        }
142297341bdc5bea1d7bf777de65228039142d249f38Adam Powell
142397341bdc5bea1d7bf777de65228039142d249f38Adam Powell        public LayoutParams(android.view.ViewGroup.LayoutParams source) {
142497341bdc5bea1d7bf777de65228039142d249f38Adam Powell            super(source);
142597341bdc5bea1d7bf777de65228039142d249f38Adam Powell        }
142697341bdc5bea1d7bf777de65228039142d249f38Adam Powell
142797341bdc5bea1d7bf777de65228039142d249f38Adam Powell        public LayoutParams(MarginLayoutParams source) {
142897341bdc5bea1d7bf777de65228039142d249f38Adam Powell            super(source);
142997341bdc5bea1d7bf777de65228039142d249f38Adam Powell        }
143097341bdc5bea1d7bf777de65228039142d249f38Adam Powell
143197341bdc5bea1d7bf777de65228039142d249f38Adam Powell        public LayoutParams(LayoutParams source) {
143297341bdc5bea1d7bf777de65228039142d249f38Adam Powell            super(source);
143397341bdc5bea1d7bf777de65228039142d249f38Adam Powell            this.weight = source.weight;
143497341bdc5bea1d7bf777de65228039142d249f38Adam Powell        }
143597341bdc5bea1d7bf777de65228039142d249f38Adam Powell
143697341bdc5bea1d7bf777de65228039142d249f38Adam Powell        public LayoutParams(Context c, AttributeSet attrs) {
143797341bdc5bea1d7bf777de65228039142d249f38Adam Powell            super(c, attrs);
143897341bdc5bea1d7bf777de65228039142d249f38Adam Powell
143997341bdc5bea1d7bf777de65228039142d249f38Adam Powell            final TypedArray a = c.obtainStyledAttributes(attrs, ATTRS);
14400eefe9ad0819b223006533cbc79a35d66684af32Adam Powell            this.weight = a.getFloat(0, 0);
144197341bdc5bea1d7bf777de65228039142d249f38Adam Powell            a.recycle();
144297341bdc5bea1d7bf777de65228039142d249f38Adam Powell        }
144397341bdc5bea1d7bf777de65228039142d249f38Adam Powell
144497341bdc5bea1d7bf777de65228039142d249f38Adam Powell    }
144597341bdc5bea1d7bf777de65228039142d249f38Adam Powell
144697341bdc5bea1d7bf777de65228039142d249f38Adam Powell    static class SavedState extends BaseSavedState {
144797341bdc5bea1d7bf777de65228039142d249f38Adam Powell        boolean isOpen;
144897341bdc5bea1d7bf777de65228039142d249f38Adam Powell
144997341bdc5bea1d7bf777de65228039142d249f38Adam Powell        SavedState(Parcelable superState) {
145097341bdc5bea1d7bf777de65228039142d249f38Adam Powell            super(superState);
145197341bdc5bea1d7bf777de65228039142d249f38Adam Powell        }
145297341bdc5bea1d7bf777de65228039142d249f38Adam Powell
145397341bdc5bea1d7bf777de65228039142d249f38Adam Powell        private SavedState(Parcel in) {
145497341bdc5bea1d7bf777de65228039142d249f38Adam Powell            super(in);
145597341bdc5bea1d7bf777de65228039142d249f38Adam Powell            isOpen = in.readInt() != 0;
145697341bdc5bea1d7bf777de65228039142d249f38Adam Powell        }
145797341bdc5bea1d7bf777de65228039142d249f38Adam Powell
145897341bdc5bea1d7bf777de65228039142d249f38Adam Powell        @Override
145997341bdc5bea1d7bf777de65228039142d249f38Adam Powell        public void writeToParcel(Parcel out, int flags) {
146097341bdc5bea1d7bf777de65228039142d249f38Adam Powell            super.writeToParcel(out, flags);
146197341bdc5bea1d7bf777de65228039142d249f38Adam Powell            out.writeInt(isOpen ? 1 : 0);
146297341bdc5bea1d7bf777de65228039142d249f38Adam Powell        }
146397341bdc5bea1d7bf777de65228039142d249f38Adam Powell
146497341bdc5bea1d7bf777de65228039142d249f38Adam Powell        public static final Parcelable.Creator<SavedState> CREATOR =
146597341bdc5bea1d7bf777de65228039142d249f38Adam Powell                new Parcelable.Creator<SavedState>() {
146697341bdc5bea1d7bf777de65228039142d249f38Adam Powell            public SavedState createFromParcel(Parcel in) {
146797341bdc5bea1d7bf777de65228039142d249f38Adam Powell                return new SavedState(in);
146897341bdc5bea1d7bf777de65228039142d249f38Adam Powell            }
146997341bdc5bea1d7bf777de65228039142d249f38Adam Powell
147097341bdc5bea1d7bf777de65228039142d249f38Adam Powell            public SavedState[] newArray(int size) {
147197341bdc5bea1d7bf777de65228039142d249f38Adam Powell                return new SavedState[size];
147297341bdc5bea1d7bf777de65228039142d249f38Adam Powell            }
147397341bdc5bea1d7bf777de65228039142d249f38Adam Powell        };
147497341bdc5bea1d7bf777de65228039142d249f38Adam Powell    }
147597341bdc5bea1d7bf777de65228039142d249f38Adam Powell
147697341bdc5bea1d7bf777de65228039142d249f38Adam Powell    interface SlidingPanelLayoutImpl {
147797341bdc5bea1d7bf777de65228039142d249f38Adam Powell        void invalidateChildRegion(SlidingPaneLayout parent, View child);
147897341bdc5bea1d7bf777de65228039142d249f38Adam Powell    }
147997341bdc5bea1d7bf777de65228039142d249f38Adam Powell
148097341bdc5bea1d7bf777de65228039142d249f38Adam Powell    static class SlidingPanelLayoutImplBase implements SlidingPanelLayoutImpl {
148197341bdc5bea1d7bf777de65228039142d249f38Adam Powell        public void invalidateChildRegion(SlidingPaneLayout parent, View child) {
148297341bdc5bea1d7bf777de65228039142d249f38Adam Powell            ViewCompat.postInvalidateOnAnimation(parent, child.getLeft(), child.getTop(),
148397341bdc5bea1d7bf777de65228039142d249f38Adam Powell                    child.getRight(), child.getBottom());
148497341bdc5bea1d7bf777de65228039142d249f38Adam Powell        }
148597341bdc5bea1d7bf777de65228039142d249f38Adam Powell    }
148697341bdc5bea1d7bf777de65228039142d249f38Adam Powell
148797341bdc5bea1d7bf777de65228039142d249f38Adam Powell    static class SlidingPanelLayoutImplJB extends SlidingPanelLayoutImplBase {
148897341bdc5bea1d7bf777de65228039142d249f38Adam Powell        /*
148997341bdc5bea1d7bf777de65228039142d249f38Adam Powell         * Private API hacks! Nasty! Bad!
149097341bdc5bea1d7bf777de65228039142d249f38Adam Powell         *
149197341bdc5bea1d7bf777de65228039142d249f38Adam Powell         * In Jellybean, some optimizations in the hardware UI renderer
149297341bdc5bea1d7bf777de65228039142d249f38Adam Powell         * prevent a changed Paint on a View using a hardware layer from having
149397341bdc5bea1d7bf777de65228039142d249f38Adam Powell         * the intended effect. This twiddles some internal bits on the view to force
149497341bdc5bea1d7bf777de65228039142d249f38Adam Powell         * it to recreate the display list.
149597341bdc5bea1d7bf777de65228039142d249f38Adam Powell         */
149697341bdc5bea1d7bf777de65228039142d249f38Adam Powell        private Method mGetDisplayList;
149797341bdc5bea1d7bf777de65228039142d249f38Adam Powell        private Field mRecreateDisplayList;
149897341bdc5bea1d7bf777de65228039142d249f38Adam Powell
149997341bdc5bea1d7bf777de65228039142d249f38Adam Powell        SlidingPanelLayoutImplJB() {
150097341bdc5bea1d7bf777de65228039142d249f38Adam Powell            try {
150197341bdc5bea1d7bf777de65228039142d249f38Adam Powell                mGetDisplayList = View.class.getDeclaredMethod("getDisplayList", (Class[]) null);
150297341bdc5bea1d7bf777de65228039142d249f38Adam Powell            } catch (NoSuchMethodException e) {
150397341bdc5bea1d7bf777de65228039142d249f38Adam Powell                Log.e(TAG, "Couldn't fetch getDisplayList method; dimming won't work right.", e);
150497341bdc5bea1d7bf777de65228039142d249f38Adam Powell            }
150597341bdc5bea1d7bf777de65228039142d249f38Adam Powell            try {
150697341bdc5bea1d7bf777de65228039142d249f38Adam Powell                mRecreateDisplayList = View.class.getDeclaredField("mRecreateDisplayList");
150797341bdc5bea1d7bf777de65228039142d249f38Adam Powell                mRecreateDisplayList.setAccessible(true);
150897341bdc5bea1d7bf777de65228039142d249f38Adam Powell            } catch (NoSuchFieldException e) {
150997341bdc5bea1d7bf777de65228039142d249f38Adam Powell                Log.e(TAG, "Couldn't fetch mRecreateDisplayList field; dimming will be slow.", e);
151097341bdc5bea1d7bf777de65228039142d249f38Adam Powell            }
151197341bdc5bea1d7bf777de65228039142d249f38Adam Powell        }
151297341bdc5bea1d7bf777de65228039142d249f38Adam Powell
151397341bdc5bea1d7bf777de65228039142d249f38Adam Powell        @Override
151497341bdc5bea1d7bf777de65228039142d249f38Adam Powell        public void invalidateChildRegion(SlidingPaneLayout parent, View child) {
151597341bdc5bea1d7bf777de65228039142d249f38Adam Powell            if (mGetDisplayList != null && mRecreateDisplayList != null) {
151697341bdc5bea1d7bf777de65228039142d249f38Adam Powell                try {
151797341bdc5bea1d7bf777de65228039142d249f38Adam Powell                    mRecreateDisplayList.setBoolean(child, true);
151897341bdc5bea1d7bf777de65228039142d249f38Adam Powell                    mGetDisplayList.invoke(child, (Object[]) null);
151997341bdc5bea1d7bf777de65228039142d249f38Adam Powell                } catch (Exception e) {
152097341bdc5bea1d7bf777de65228039142d249f38Adam Powell                    Log.e(TAG, "Error refreshing display list state", e);
152197341bdc5bea1d7bf777de65228039142d249f38Adam Powell                }
152297341bdc5bea1d7bf777de65228039142d249f38Adam Powell            } else {
152397341bdc5bea1d7bf777de65228039142d249f38Adam Powell                // Slow path. REALLY slow path. Let's hope we don't get here.
152497341bdc5bea1d7bf777de65228039142d249f38Adam Powell                child.invalidate();
152597341bdc5bea1d7bf777de65228039142d249f38Adam Powell                return;
152697341bdc5bea1d7bf777de65228039142d249f38Adam Powell            }
152797341bdc5bea1d7bf777de65228039142d249f38Adam Powell            super.invalidateChildRegion(parent, child);
152897341bdc5bea1d7bf777de65228039142d249f38Adam Powell        }
152997341bdc5bea1d7bf777de65228039142d249f38Adam Powell    }
15306debd2bbcae1cd285d2e21db633998b7801f9f40Adam Powell
15316debd2bbcae1cd285d2e21db633998b7801f9f40Adam Powell    static class SlidingPanelLayoutImplJBMR1 extends SlidingPanelLayoutImplBase {
15326debd2bbcae1cd285d2e21db633998b7801f9f40Adam Powell        @Override
15336debd2bbcae1cd285d2e21db633998b7801f9f40Adam Powell        public void invalidateChildRegion(SlidingPaneLayout parent, View child) {
15346debd2bbcae1cd285d2e21db633998b7801f9f40Adam Powell            ViewCompat.setLayerPaint(child, ((LayoutParams) child.getLayoutParams()).dimPaint);
15356debd2bbcae1cd285d2e21db633998b7801f9f40Adam Powell        }
15366debd2bbcae1cd285d2e21db633998b7801f9f40Adam Powell    }
1537c89f53833f1e272d32f7928837f0704fa33be309Adam Powell
1538c89f53833f1e272d32f7928837f0704fa33be309Adam Powell    class AccessibilityDelegate extends AccessibilityDelegateCompat {
15393cf6141d516a0a6170823b1bda5c0b6d7500e76cAdam Powell        private final Rect mTmpRect = new Rect();
15403cf6141d516a0a6170823b1bda5c0b6d7500e76cAdam Powell
1541c89f53833f1e272d32f7928837f0704fa33be309Adam Powell        @Override
1542c89f53833f1e272d32f7928837f0704fa33be309Adam Powell        public void onInitializeAccessibilityNodeInfo(View host, AccessibilityNodeInfoCompat info) {
15433cf6141d516a0a6170823b1bda5c0b6d7500e76cAdam Powell            final AccessibilityNodeInfoCompat superNode = AccessibilityNodeInfoCompat.obtain(info);
15443cf6141d516a0a6170823b1bda5c0b6d7500e76cAdam Powell            super.onInitializeAccessibilityNodeInfo(host, superNode);
154551e43399398d051db26ecc85d6de34f310e77dbbAlan Viverette            copyNodeInfoNoChildren(info, superNode);
154651e43399398d051db26ecc85d6de34f310e77dbbAlan Viverette            superNode.recycle();
15473cf6141d516a0a6170823b1bda5c0b6d7500e76cAdam Powell
154851e43399398d051db26ecc85d6de34f310e77dbbAlan Viverette            info.setClassName(SlidingPaneLayout.class.getName());
15493cf6141d516a0a6170823b1bda5c0b6d7500e76cAdam Powell            info.setSource(host);
155051e43399398d051db26ecc85d6de34f310e77dbbAlan Viverette
15513cf6141d516a0a6170823b1bda5c0b6d7500e76cAdam Powell            final ViewParent parent = ViewCompat.getParentForAccessibility(host);
15523cf6141d516a0a6170823b1bda5c0b6d7500e76cAdam Powell            if (parent instanceof View) {
15533cf6141d516a0a6170823b1bda5c0b6d7500e76cAdam Powell                info.setParent((View) parent);
15543cf6141d516a0a6170823b1bda5c0b6d7500e76cAdam Powell            }
15553cf6141d516a0a6170823b1bda5c0b6d7500e76cAdam Powell
155651e43399398d051db26ecc85d6de34f310e77dbbAlan Viverette            // This is a best-approximation of addChildrenForAccessibility()
155751e43399398d051db26ecc85d6de34f310e77dbbAlan Viverette            // that accounts for filtering.
1558c89f53833f1e272d32f7928837f0704fa33be309Adam Powell            final int childCount = getChildCount();
1559c89f53833f1e272d32f7928837f0704fa33be309Adam Powell            for (int i = 0; i < childCount; i++) {
1560c89f53833f1e272d32f7928837f0704fa33be309Adam Powell                final View child = getChildAt(i);
156151e43399398d051db26ecc85d6de34f310e77dbbAlan Viverette                if (!filter(child) && (child.getVisibility() == View.VISIBLE)) {
1562f803407db4a369e3c176798d5318faaacb85e12bAlan Viverette                    // Force importance to "yes" since we can't read the value.
1563f803407db4a369e3c176798d5318faaacb85e12bAlan Viverette                    ViewCompat.setImportantForAccessibility(
1564f803407db4a369e3c176798d5318faaacb85e12bAlan Viverette                            child, ViewCompat.IMPORTANT_FOR_ACCESSIBILITY_YES);
1565c89f53833f1e272d32f7928837f0704fa33be309Adam Powell                    info.addChild(child);
1566c89f53833f1e272d32f7928837f0704fa33be309Adam Powell                }
1567c89f53833f1e272d32f7928837f0704fa33be309Adam Powell            }
1568c89f53833f1e272d32f7928837f0704fa33be309Adam Powell        }
1569c89f53833f1e272d32f7928837f0704fa33be309Adam Powell
1570c89f53833f1e272d32f7928837f0704fa33be309Adam Powell        @Override
157151e43399398d051db26ecc85d6de34f310e77dbbAlan Viverette        public void onInitializeAccessibilityEvent(View host, AccessibilityEvent event) {
157251e43399398d051db26ecc85d6de34f310e77dbbAlan Viverette            super.onInitializeAccessibilityEvent(host, event);
157351e43399398d051db26ecc85d6de34f310e77dbbAlan Viverette
157451e43399398d051db26ecc85d6de34f310e77dbbAlan Viverette            event.setClassName(SlidingPaneLayout.class.getName());
157551e43399398d051db26ecc85d6de34f310e77dbbAlan Viverette        }
157651e43399398d051db26ecc85d6de34f310e77dbbAlan Viverette
157751e43399398d051db26ecc85d6de34f310e77dbbAlan Viverette        @Override
1578c89f53833f1e272d32f7928837f0704fa33be309Adam Powell        public boolean onRequestSendAccessibilityEvent(ViewGroup host, View child,
1579c89f53833f1e272d32f7928837f0704fa33be309Adam Powell                AccessibilityEvent event) {
1580c89f53833f1e272d32f7928837f0704fa33be309Adam Powell            if (!filter(child)) {
1581c89f53833f1e272d32f7928837f0704fa33be309Adam Powell                return super.onRequestSendAccessibilityEvent(host, child, event);
1582c89f53833f1e272d32f7928837f0704fa33be309Adam Powell            }
1583c89f53833f1e272d32f7928837f0704fa33be309Adam Powell            return false;
1584c89f53833f1e272d32f7928837f0704fa33be309Adam Powell        }
1585c89f53833f1e272d32f7928837f0704fa33be309Adam Powell
1586c89f53833f1e272d32f7928837f0704fa33be309Adam Powell        public boolean filter(View child) {
1587c89f53833f1e272d32f7928837f0704fa33be309Adam Powell            return isDimmed(child);
1588c89f53833f1e272d32f7928837f0704fa33be309Adam Powell        }
15893cf6141d516a0a6170823b1bda5c0b6d7500e76cAdam Powell
15903cf6141d516a0a6170823b1bda5c0b6d7500e76cAdam Powell        /**
15913cf6141d516a0a6170823b1bda5c0b6d7500e76cAdam Powell         * This should really be in AccessibilityNodeInfoCompat, but there unfortunately
15923cf6141d516a0a6170823b1bda5c0b6d7500e76cAdam Powell         * seem to be a few elements that are not easily cloneable using the underlying API.
15933cf6141d516a0a6170823b1bda5c0b6d7500e76cAdam Powell         * Leave it private here as it's not general-purpose useful.
15943cf6141d516a0a6170823b1bda5c0b6d7500e76cAdam Powell         */
15953cf6141d516a0a6170823b1bda5c0b6d7500e76cAdam Powell        private void copyNodeInfoNoChildren(AccessibilityNodeInfoCompat dest,
15963cf6141d516a0a6170823b1bda5c0b6d7500e76cAdam Powell                AccessibilityNodeInfoCompat src) {
15973cf6141d516a0a6170823b1bda5c0b6d7500e76cAdam Powell            final Rect rect = mTmpRect;
15983cf6141d516a0a6170823b1bda5c0b6d7500e76cAdam Powell
15993cf6141d516a0a6170823b1bda5c0b6d7500e76cAdam Powell            src.getBoundsInParent(rect);
16003cf6141d516a0a6170823b1bda5c0b6d7500e76cAdam Powell            dest.setBoundsInParent(rect);
16013cf6141d516a0a6170823b1bda5c0b6d7500e76cAdam Powell
16023cf6141d516a0a6170823b1bda5c0b6d7500e76cAdam Powell            src.getBoundsInScreen(rect);
16033cf6141d516a0a6170823b1bda5c0b6d7500e76cAdam Powell            dest.setBoundsInScreen(rect);
16043cf6141d516a0a6170823b1bda5c0b6d7500e76cAdam Powell
16053cf6141d516a0a6170823b1bda5c0b6d7500e76cAdam Powell            dest.setVisibleToUser(src.isVisibleToUser());
16063cf6141d516a0a6170823b1bda5c0b6d7500e76cAdam Powell            dest.setPackageName(src.getPackageName());
16073cf6141d516a0a6170823b1bda5c0b6d7500e76cAdam Powell            dest.setClassName(src.getClassName());
16083cf6141d516a0a6170823b1bda5c0b6d7500e76cAdam Powell            dest.setContentDescription(src.getContentDescription());
16093cf6141d516a0a6170823b1bda5c0b6d7500e76cAdam Powell
16103cf6141d516a0a6170823b1bda5c0b6d7500e76cAdam Powell            dest.setEnabled(src.isEnabled());
16113cf6141d516a0a6170823b1bda5c0b6d7500e76cAdam Powell            dest.setClickable(src.isClickable());
16123cf6141d516a0a6170823b1bda5c0b6d7500e76cAdam Powell            dest.setFocusable(src.isFocusable());
16133cf6141d516a0a6170823b1bda5c0b6d7500e76cAdam Powell            dest.setFocused(src.isFocused());
16143cf6141d516a0a6170823b1bda5c0b6d7500e76cAdam Powell            dest.setAccessibilityFocused(src.isAccessibilityFocused());
16153cf6141d516a0a6170823b1bda5c0b6d7500e76cAdam Powell            dest.setSelected(src.isSelected());
16163cf6141d516a0a6170823b1bda5c0b6d7500e76cAdam Powell            dest.setLongClickable(src.isLongClickable());
16173cf6141d516a0a6170823b1bda5c0b6d7500e76cAdam Powell
16183cf6141d516a0a6170823b1bda5c0b6d7500e76cAdam Powell            dest.addAction(src.getActions());
161951e43399398d051db26ecc85d6de34f310e77dbbAlan Viverette
162051e43399398d051db26ecc85d6de34f310e77dbbAlan Viverette            dest.setMovementGranularities(src.getMovementGranularities());
16213cf6141d516a0a6170823b1bda5c0b6d7500e76cAdam Powell        }
1622c89f53833f1e272d32f7928837f0704fa33be309Adam Powell    }
1623f4445e06a8490b056cd892c4bc640dfd17905d6cAdam Powell
1624f4445e06a8490b056cd892c4bc640dfd17905d6cAdam Powell    private class DisableLayerRunnable implements Runnable {
1625f4445e06a8490b056cd892c4bc640dfd17905d6cAdam Powell        final View mChildView;
1626f4445e06a8490b056cd892c4bc640dfd17905d6cAdam Powell
1627f4445e06a8490b056cd892c4bc640dfd17905d6cAdam Powell        DisableLayerRunnable(View childView) {
1628f4445e06a8490b056cd892c4bc640dfd17905d6cAdam Powell            mChildView = childView;
1629f4445e06a8490b056cd892c4bc640dfd17905d6cAdam Powell        }
1630f4445e06a8490b056cd892c4bc640dfd17905d6cAdam Powell
1631f4445e06a8490b056cd892c4bc640dfd17905d6cAdam Powell        @Override
1632f4445e06a8490b056cd892c4bc640dfd17905d6cAdam Powell        public void run() {
1633f4445e06a8490b056cd892c4bc640dfd17905d6cAdam Powell            if (mChildView.getParent() == SlidingPaneLayout.this) {
1634f4445e06a8490b056cd892c4bc640dfd17905d6cAdam Powell                ViewCompat.setLayerType(mChildView, ViewCompat.LAYER_TYPE_NONE, null);
1635f4445e06a8490b056cd892c4bc640dfd17905d6cAdam Powell                invalidateChildRegion(mChildView);
1636f4445e06a8490b056cd892c4bc640dfd17905d6cAdam Powell            }
1637f4445e06a8490b056cd892c4bc640dfd17905d6cAdam Powell            mPostedRunnables.remove(this);
1638f4445e06a8490b056cd892c4bc640dfd17905d6cAdam Powell        }
1639f4445e06a8490b056cd892c4bc640dfd17905d6cAdam Powell    }
164019780f88506df4aeb57456fd6747af1b6848a11cfafaisland
164119780f88506df4aeb57456fd6747af1b6848a11cfafaisland    private boolean isLayoutRtlSupport() {
164219780f88506df4aeb57456fd6747af1b6848a11cfafaisland        return ViewCompat.getLayoutDirection(this) == ViewCompat.LAYOUT_DIRECTION_RTL;
164319780f88506df4aeb57456fd6747af1b6848a11cfafaisland    }
164497341bdc5bea1d7bf777de65228039142d249f38Adam Powell}
1645