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;
3270acb0c19be3831a2080e4f902324de16bfbf62eTor Norbyeimport android.support.annotation.ColorInt;
33a3ff3273e976adf19770651dcf473fa67b38eb22Tor Norbyeimport android.support.annotation.DrawableRes;
3405f5ba020fa6caa658c75b6d77436aa980ca0fccChris Banesimport android.support.v4.os.ParcelableCompat;
3505f5ba020fa6caa658c75b6d77436aa980ca0fccChris Banesimport android.support.v4.os.ParcelableCompatCreatorCallbacks;
3605f5ba020fa6caa658c75b6d77436aa980ca0fccChris Banesimport android.support.v4.view.AbsSavedState;
37c89f53833f1e272d32f7928837f0704fa33be309Adam Powellimport android.support.v4.view.AccessibilityDelegateCompat;
3897341bdc5bea1d7bf777de65228039142d249f38Adam Powellimport android.support.v4.view.MotionEventCompat;
3997341bdc5bea1d7bf777de65228039142d249f38Adam Powellimport android.support.v4.view.ViewCompat;
40c89f53833f1e272d32f7928837f0704fa33be309Adam Powellimport android.support.v4.view.accessibility.AccessibilityNodeInfoCompat;
4197341bdc5bea1d7bf777de65228039142d249f38Adam Powellimport android.util.AttributeSet;
4297341bdc5bea1d7bf777de65228039142d249f38Adam Powellimport android.util.Log;
4397341bdc5bea1d7bf777de65228039142d249f38Adam Powellimport android.view.MotionEvent;
4497341bdc5bea1d7bf777de65228039142d249f38Adam Powellimport android.view.View;
4597341bdc5bea1d7bf777de65228039142d249f38Adam Powellimport android.view.ViewConfiguration;
4697341bdc5bea1d7bf777de65228039142d249f38Adam Powellimport android.view.ViewGroup;
473cf6141d516a0a6170823b1bda5c0b6d7500e76cAdam Powellimport android.view.ViewParent;
48c89f53833f1e272d32f7928837f0704fa33be309Adam Powellimport android.view.accessibility.AccessibilityEvent;
4997341bdc5bea1d7bf777de65228039142d249f38Adam Powell
5097341bdc5bea1d7bf777de65228039142d249f38Adam Powellimport java.lang.reflect.Field;
5197341bdc5bea1d7bf777de65228039142d249f38Adam Powellimport java.lang.reflect.Method;
52f4445e06a8490b056cd892c4bc640dfd17905d6cAdam Powellimport java.util.ArrayList;
5397341bdc5bea1d7bf777de65228039142d249f38Adam Powell
5497341bdc5bea1d7bf777de65228039142d249f38Adam Powell/**
5597341bdc5bea1d7bf777de65228039142d249f38Adam Powell * SlidingPaneLayout provides a horizontal, multi-pane layout for use at the top level
56ee3f0ffb0199e295cbf48aa1a61c8ae7056526abAdam Powell * of a UI. A left (or first) pane is treated as a content list or browser, subordinate to a
5797341bdc5bea1d7bf777de65228039142d249f38Adam Powell * primary detail view for displaying content.
5897341bdc5bea1d7bf777de65228039142d249f38Adam Powell *
5997341bdc5bea1d7bf777de65228039142d249f38Adam Powell * <p>Child views may overlap if their combined width exceeds the available width
6097341bdc5bea1d7bf777de65228039142d249f38Adam Powell * in the SlidingPaneLayout. When this occurs the user may slide the topmost view out of the way
6197341bdc5bea1d7bf777de65228039142d249f38Adam Powell * by dragging it, or by navigating in the direction of the overlapped view using a keyboard.
6297341bdc5bea1d7bf777de65228039142d249f38Adam Powell * If the content of the dragged child view is itself horizontally scrollable, the user may
6397341bdc5bea1d7bf777de65228039142d249f38Adam Powell * grab it by the very edge.</p>
6497341bdc5bea1d7bf777de65228039142d249f38Adam Powell *
6597341bdc5bea1d7bf777de65228039142d249f38Adam Powell * <p>Thanks to this sliding behavior, SlidingPaneLayout may be suitable for creating layouts
6697341bdc5bea1d7bf777de65228039142d249f38Adam Powell * that can smoothly adapt across many different screen sizes, expanding out fully on larger
6797341bdc5bea1d7bf777de65228039142d249f38Adam Powell * screens and collapsing on smaller screens.</p>
6897341bdc5bea1d7bf777de65228039142d249f38Adam Powell *
69ee3f0ffb0199e295cbf48aa1a61c8ae7056526abAdam Powell * <p>SlidingPaneLayout is distinct from a navigation drawer as described in the design
70ee3f0ffb0199e295cbf48aa1a61c8ae7056526abAdam Powell * guide and should not be used in the same scenarios. SlidingPaneLayout should be thought
71ee3f0ffb0199e295cbf48aa1a61c8ae7056526abAdam Powell * of only as a way to allow a two-pane layout normally used on larger screens to adapt to smaller
72ee3f0ffb0199e295cbf48aa1a61c8ae7056526abAdam Powell * screens in a natural way. The interaction patterns expressed by SlidingPaneLayout imply
73ee3f0ffb0199e295cbf48aa1a61c8ae7056526abAdam Powell * a physicality and direct information hierarchy between panes that does not necessarily exist
74ee3f0ffb0199e295cbf48aa1a61c8ae7056526abAdam Powell * in a scenario where a navigation drawer should be used instead.</p>
75ee3f0ffb0199e295cbf48aa1a61c8ae7056526abAdam Powell *
76ee3f0ffb0199e295cbf48aa1a61c8ae7056526abAdam Powell * <p>Appropriate uses of SlidingPaneLayout include pairings of panes such as a contact list and
77ee3f0ffb0199e295cbf48aa1a61c8ae7056526abAdam Powell * subordinate interactions with those contacts, or an email thread list with the content pane
78ee3f0ffb0199e295cbf48aa1a61c8ae7056526abAdam Powell * displaying the contents of the selected thread. Inappropriate uses of SlidingPaneLayout include
79ee3f0ffb0199e295cbf48aa1a61c8ae7056526abAdam Powell * switching between disparate functions of your app, such as jumping from a social stream view
80ee3f0ffb0199e295cbf48aa1a61c8ae7056526abAdam Powell * to a view of your personal profile - cases such as this should use the navigation drawer
811d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * pattern instead. ({@link DrawerLayout DrawerLayout} implements this pattern.)</p>
82ee3f0ffb0199e295cbf48aa1a61c8ae7056526abAdam Powell *
8397341bdc5bea1d7bf777de65228039142d249f38Adam Powell * <p>Like {@link android.widget.LinearLayout LinearLayout}, SlidingPaneLayout supports
8497341bdc5bea1d7bf777de65228039142d249f38Adam Powell * the use of the layout parameter <code>layout_weight</code> on child views to determine
8597341bdc5bea1d7bf777de65228039142d249f38Adam Powell * how to divide leftover space after measurement is complete. It is only relevant for width.
8697341bdc5bea1d7bf777de65228039142d249f38Adam Powell * When views do not overlap weight behaves as it does in a LinearLayout.</p>
8797341bdc5bea1d7bf777de65228039142d249f38Adam Powell *
8897341bdc5bea1d7bf777de65228039142d249f38Adam Powell * <p>When views do overlap, weight on a slideable pane indicates that the pane should be
8997341bdc5bea1d7bf777de65228039142d249f38Adam Powell * sized to fill all available space in the closed state. Weight on a pane that becomes covered
9097341bdc5bea1d7bf777de65228039142d249f38Adam Powell * indicates that the pane should be sized to fill all available space except a small minimum strip
9197341bdc5bea1d7bf777de65228039142d249f38Adam Powell * that the user may use to grab the slideable view and pull it back over into a closed state.</p>
9297341bdc5bea1d7bf777de65228039142d249f38Adam Powell */
9397341bdc5bea1d7bf777de65228039142d249f38Adam Powellpublic class SlidingPaneLayout extends ViewGroup {
9497341bdc5bea1d7bf777de65228039142d249f38Adam Powell    private static final String TAG = "SlidingPaneLayout";
9597341bdc5bea1d7bf777de65228039142d249f38Adam Powell
9697341bdc5bea1d7bf777de65228039142d249f38Adam Powell    /**
9797341bdc5bea1d7bf777de65228039142d249f38Adam Powell     * Default size of the overhang for a pane in the open state.
9897341bdc5bea1d7bf777de65228039142d249f38Adam Powell     * At least this much of a sliding pane will remain visible.
9997341bdc5bea1d7bf777de65228039142d249f38Adam Powell     * This indicates that there is more content available and provides
10097341bdc5bea1d7bf777de65228039142d249f38Adam Powell     * a "physical" edge to grab to pull it closed.
10197341bdc5bea1d7bf777de65228039142d249f38Adam Powell     */
102ee3f0ffb0199e295cbf48aa1a61c8ae7056526abAdam Powell    private static final int DEFAULT_OVERHANG_SIZE = 32; // dp;
10397341bdc5bea1d7bf777de65228039142d249f38Adam Powell
10497341bdc5bea1d7bf777de65228039142d249f38Adam Powell    /**
105ee3f0ffb0199e295cbf48aa1a61c8ae7056526abAdam Powell     * If no fade color is given by default it will fade to 80% gray.
106ee3f0ffb0199e295cbf48aa1a61c8ae7056526abAdam Powell     */
107ee3f0ffb0199e295cbf48aa1a61c8ae7056526abAdam Powell    private static final int DEFAULT_FADE_COLOR = 0xcccccccc;
108ee3f0ffb0199e295cbf48aa1a61c8ae7056526abAdam Powell
109ee3f0ffb0199e295cbf48aa1a61c8ae7056526abAdam Powell    /**
11081e2f002d1b4ebf2d951eb9f239858b8a9481a24Adam Powell     * The fade color used for the sliding panel. 0 = no fading.
11181e2f002d1b4ebf2d951eb9f239858b8a9481a24Adam Powell     */
11281e2f002d1b4ebf2d951eb9f239858b8a9481a24Adam Powell    private int mSliderFadeColor = DEFAULT_FADE_COLOR;
11381e2f002d1b4ebf2d951eb9f239858b8a9481a24Adam Powell
11481e2f002d1b4ebf2d951eb9f239858b8a9481a24Adam Powell    /**
11579f95ce3e660d267831067e514ff455156c4381fAdam Powell     * Minimum velocity that will be detected as a fling
11679f95ce3e660d267831067e514ff455156c4381fAdam Powell     */
11779f95ce3e660d267831067e514ff455156c4381fAdam Powell    private static final int MIN_FLING_VELOCITY = 400; // dips per second
11879f95ce3e660d267831067e514ff455156c4381fAdam Powell
11979f95ce3e660d267831067e514ff455156c4381fAdam Powell    /**
12081e2f002d1b4ebf2d951eb9f239858b8a9481a24Adam Powell     * The fade color used for the panel covered by the slider. 0 = no fading.
12181e2f002d1b4ebf2d951eb9f239858b8a9481a24Adam Powell     */
12281e2f002d1b4ebf2d951eb9f239858b8a9481a24Adam Powell    private int mCoveredFadeColor;
12381e2f002d1b4ebf2d951eb9f239858b8a9481a24Adam Powell
12481e2f002d1b4ebf2d951eb9f239858b8a9481a24Adam Powell    /**
12519780f88506df4aeb57456fd6747af1b6848a11cfafaisland     * Drawable used to draw the shadow between panes by default.
126ee3f0ffb0199e295cbf48aa1a61c8ae7056526abAdam Powell     */
12719780f88506df4aeb57456fd6747af1b6848a11cfafaisland    private Drawable mShadowDrawableLeft;
12819780f88506df4aeb57456fd6747af1b6848a11cfafaisland
12919780f88506df4aeb57456fd6747af1b6848a11cfafaisland    /**
13019780f88506df4aeb57456fd6747af1b6848a11cfafaisland     * Drawable used to draw the shadow between panes to support RTL (right to left language).
13119780f88506df4aeb57456fd6747af1b6848a11cfafaisland     */
13219780f88506df4aeb57456fd6747af1b6848a11cfafaisland    private Drawable mShadowDrawableRight;
133ee3f0ffb0199e295cbf48aa1a61c8ae7056526abAdam Powell
134ee3f0ffb0199e295cbf48aa1a61c8ae7056526abAdam Powell    /**
13597341bdc5bea1d7bf777de65228039142d249f38Adam Powell     * The size of the overhang in pixels.
13697341bdc5bea1d7bf777de65228039142d249f38Adam Powell     * This is the minimum section of the sliding panel that will
13797341bdc5bea1d7bf777de65228039142d249f38Adam Powell     * be visible in the open state to allow for a closing drag.
13897341bdc5bea1d7bf777de65228039142d249f38Adam Powell     */
13997341bdc5bea1d7bf777de65228039142d249f38Adam Powell    private final int mOverhangSize;
14097341bdc5bea1d7bf777de65228039142d249f38Adam Powell
14197341bdc5bea1d7bf777de65228039142d249f38Adam Powell    /**
14297341bdc5bea1d7bf777de65228039142d249f38Adam Powell     * True if a panel can slide with the current measurements
14397341bdc5bea1d7bf777de65228039142d249f38Adam Powell     */
14497341bdc5bea1d7bf777de65228039142d249f38Adam Powell    private boolean mCanSlide;
14597341bdc5bea1d7bf777de65228039142d249f38Adam Powell
14697341bdc5bea1d7bf777de65228039142d249f38Adam Powell    /**
1470eefe9ad0819b223006533cbc79a35d66684af32Adam Powell     * The child view that can slide, if any.
14897341bdc5bea1d7bf777de65228039142d249f38Adam Powell     */
1490eefe9ad0819b223006533cbc79a35d66684af32Adam Powell    private View mSlideableView;
15097341bdc5bea1d7bf777de65228039142d249f38Adam Powell
1510eefe9ad0819b223006533cbc79a35d66684af32Adam Powell    /**
1520eefe9ad0819b223006533cbc79a35d66684af32Adam Powell     * How far the panel is offset from its closed position.
1530eefe9ad0819b223006533cbc79a35d66684af32Adam Powell     * range [0, 1] where 0 = closed, 1 = open.
1540eefe9ad0819b223006533cbc79a35d66684af32Adam Powell     */
1550eefe9ad0819b223006533cbc79a35d66684af32Adam Powell    private float mSlideOffset;
1560eefe9ad0819b223006533cbc79a35d66684af32Adam Powell
1570eefe9ad0819b223006533cbc79a35d66684af32Adam Powell    /**
1580eefe9ad0819b223006533cbc79a35d66684af32Adam Powell     * How far the non-sliding panel is parallaxed from its usual position when open.
1590eefe9ad0819b223006533cbc79a35d66684af32Adam Powell     * range [0, 1]
1600eefe9ad0819b223006533cbc79a35d66684af32Adam Powell     */
1610eefe9ad0819b223006533cbc79a35d66684af32Adam Powell    private float mParallaxOffset;
1620eefe9ad0819b223006533cbc79a35d66684af32Adam Powell
1630eefe9ad0819b223006533cbc79a35d66684af32Adam Powell    /**
1640eefe9ad0819b223006533cbc79a35d66684af32Adam Powell     * How far in pixels the slideable panel may move.
1650eefe9ad0819b223006533cbc79a35d66684af32Adam Powell     */
1660eefe9ad0819b223006533cbc79a35d66684af32Adam Powell    private int mSlideRange;
16797341bdc5bea1d7bf777de65228039142d249f38Adam Powell
16897341bdc5bea1d7bf777de65228039142d249f38Adam Powell    /**
16997341bdc5bea1d7bf777de65228039142d249f38Adam Powell     * A panel view is locked into internal scrolling or another condition that
17097341bdc5bea1d7bf777de65228039142d249f38Adam Powell     * is preventing a drag.
17197341bdc5bea1d7bf777de65228039142d249f38Adam Powell     */
17297341bdc5bea1d7bf777de65228039142d249f38Adam Powell    private boolean mIsUnableToDrag;
17397341bdc5bea1d7bf777de65228039142d249f38Adam Powell
1746debd2bbcae1cd285d2e21db633998b7801f9f40Adam Powell    /**
1756debd2bbcae1cd285d2e21db633998b7801f9f40Adam Powell     * Distance in pixels to parallax the fixed pane by when fully closed
1766debd2bbcae1cd285d2e21db633998b7801f9f40Adam Powell     */
1776debd2bbcae1cd285d2e21db633998b7801f9f40Adam Powell    private int mParallaxBy;
1786debd2bbcae1cd285d2e21db633998b7801f9f40Adam Powell
17997341bdc5bea1d7bf777de65228039142d249f38Adam Powell    private float mInitialMotionX;
180ee3f0ffb0199e295cbf48aa1a61c8ae7056526abAdam Powell    private float mInitialMotionY;
18197341bdc5bea1d7bf777de65228039142d249f38Adam Powell
18297341bdc5bea1d7bf777de65228039142d249f38Adam Powell    private PanelSlideListener mPanelSlideListener;
18397341bdc5bea1d7bf777de65228039142d249f38Adam Powell
184c56ba65d20be8742ff717907a3a2cd81dd0e5f3cAdam Powell    private final ViewDragHelper mDragHelper;
185c56ba65d20be8742ff717907a3a2cd81dd0e5f3cAdam Powell
18689e17886e6149bddfdb08a242c9e88889596419cAdam Powell    /**
18789e17886e6149bddfdb08a242c9e88889596419cAdam Powell     * Stores whether or not the pane was open the last time it was slideable.
18889e17886e6149bddfdb08a242c9e88889596419cAdam Powell     * If open/close operations are invoked this state is modified. Used by
18989e17886e6149bddfdb08a242c9e88889596419cAdam Powell     * instance state save/restore.
19089e17886e6149bddfdb08a242c9e88889596419cAdam Powell     */
19189e17886e6149bddfdb08a242c9e88889596419cAdam Powell    private boolean mPreservedOpenState;
19289e17886e6149bddfdb08a242c9e88889596419cAdam Powell    private boolean mFirstLayout = true;
19389e17886e6149bddfdb08a242c9e88889596419cAdam Powell
1941e43161e9e1f1dc10637a68d5c2304c1f95c9c46Adam Powell    private final Rect mTmpRect = new Rect();
1951e43161e9e1f1dc10637a68d5c2304c1f95c9c46Adam Powell
196f4445e06a8490b056cd892c4bc640dfd17905d6cAdam Powell    private final ArrayList<DisableLayerRunnable> mPostedRunnables =
197f4445e06a8490b056cd892c4bc640dfd17905d6cAdam Powell            new ArrayList<DisableLayerRunnable>();
198f4445e06a8490b056cd892c4bc640dfd17905d6cAdam Powell
19997341bdc5bea1d7bf777de65228039142d249f38Adam Powell    static final SlidingPanelLayoutImpl IMPL;
20097341bdc5bea1d7bf777de65228039142d249f38Adam Powell
20197341bdc5bea1d7bf777de65228039142d249f38Adam Powell    static {
2026debd2bbcae1cd285d2e21db633998b7801f9f40Adam Powell        final int deviceVersion = Build.VERSION.SDK_INT;
2036debd2bbcae1cd285d2e21db633998b7801f9f40Adam Powell        if (deviceVersion >= 17) {
2046debd2bbcae1cd285d2e21db633998b7801f9f40Adam Powell            IMPL = new SlidingPanelLayoutImplJBMR1();
2056debd2bbcae1cd285d2e21db633998b7801f9f40Adam Powell        } else if (deviceVersion >= 16) {
20697341bdc5bea1d7bf777de65228039142d249f38Adam Powell            IMPL = new SlidingPanelLayoutImplJB();
20797341bdc5bea1d7bf777de65228039142d249f38Adam Powell        } else {
20897341bdc5bea1d7bf777de65228039142d249f38Adam Powell            IMPL = new SlidingPanelLayoutImplBase();
20997341bdc5bea1d7bf777de65228039142d249f38Adam Powell        }
21097341bdc5bea1d7bf777de65228039142d249f38Adam Powell    }
21197341bdc5bea1d7bf777de65228039142d249f38Adam Powell
21297341bdc5bea1d7bf777de65228039142d249f38Adam Powell    /**
21397341bdc5bea1d7bf777de65228039142d249f38Adam Powell     * Listener for monitoring events about sliding panes.
21497341bdc5bea1d7bf777de65228039142d249f38Adam Powell     */
21597341bdc5bea1d7bf777de65228039142d249f38Adam Powell    public interface PanelSlideListener {
21697341bdc5bea1d7bf777de65228039142d249f38Adam Powell        /**
21797341bdc5bea1d7bf777de65228039142d249f38Adam Powell         * Called when a sliding pane's position changes.
21897341bdc5bea1d7bf777de65228039142d249f38Adam Powell         * @param panel The child view that was moved
21997341bdc5bea1d7bf777de65228039142d249f38Adam Powell         * @param slideOffset The new offset of this sliding pane within its range, from 0-1
22097341bdc5bea1d7bf777de65228039142d249f38Adam Powell         */
22197341bdc5bea1d7bf777de65228039142d249f38Adam Powell        public void onPanelSlide(View panel, float slideOffset);
22297341bdc5bea1d7bf777de65228039142d249f38Adam Powell        /**
22397341bdc5bea1d7bf777de65228039142d249f38Adam Powell         * Called when a sliding pane becomes slid completely open. The pane may or may not
22497341bdc5bea1d7bf777de65228039142d249f38Adam Powell         * be interactive at this point depending on how much of the pane is visible.
22597341bdc5bea1d7bf777de65228039142d249f38Adam Powell         * @param panel The child view that was slid to an open position, revealing other panes
22697341bdc5bea1d7bf777de65228039142d249f38Adam Powell         */
22797341bdc5bea1d7bf777de65228039142d249f38Adam Powell        public void onPanelOpened(View panel);
22897341bdc5bea1d7bf777de65228039142d249f38Adam Powell
22997341bdc5bea1d7bf777de65228039142d249f38Adam Powell        /**
23097341bdc5bea1d7bf777de65228039142d249f38Adam Powell         * Called when a sliding pane becomes slid completely closed. The pane is now guaranteed
23197341bdc5bea1d7bf777de65228039142d249f38Adam Powell         * to be interactive. It may now obscure other views in the layout.
23297341bdc5bea1d7bf777de65228039142d249f38Adam Powell         * @param panel The child view that was slid to a closed position
23397341bdc5bea1d7bf777de65228039142d249f38Adam Powell         */
23497341bdc5bea1d7bf777de65228039142d249f38Adam Powell        public void onPanelClosed(View panel);
23597341bdc5bea1d7bf777de65228039142d249f38Adam Powell    }
23697341bdc5bea1d7bf777de65228039142d249f38Adam Powell
23797341bdc5bea1d7bf777de65228039142d249f38Adam Powell    /**
23897341bdc5bea1d7bf777de65228039142d249f38Adam Powell     * No-op stubs for {@link PanelSlideListener}. If you only want to implement a subset
23997341bdc5bea1d7bf777de65228039142d249f38Adam Powell     * of the listener methods you can extend this instead of implement the full interface.
24097341bdc5bea1d7bf777de65228039142d249f38Adam Powell     */
24197341bdc5bea1d7bf777de65228039142d249f38Adam Powell    public static class SimplePanelSlideListener implements PanelSlideListener {
24297341bdc5bea1d7bf777de65228039142d249f38Adam Powell        @Override
24397341bdc5bea1d7bf777de65228039142d249f38Adam Powell        public void onPanelSlide(View panel, float slideOffset) {
24497341bdc5bea1d7bf777de65228039142d249f38Adam Powell        }
24597341bdc5bea1d7bf777de65228039142d249f38Adam Powell        @Override
24697341bdc5bea1d7bf777de65228039142d249f38Adam Powell        public void onPanelOpened(View panel) {
24797341bdc5bea1d7bf777de65228039142d249f38Adam Powell        }
24897341bdc5bea1d7bf777de65228039142d249f38Adam Powell        @Override
24997341bdc5bea1d7bf777de65228039142d249f38Adam Powell        public void onPanelClosed(View panel) {
25097341bdc5bea1d7bf777de65228039142d249f38Adam Powell        }
25197341bdc5bea1d7bf777de65228039142d249f38Adam Powell    }
25297341bdc5bea1d7bf777de65228039142d249f38Adam Powell
25397341bdc5bea1d7bf777de65228039142d249f38Adam Powell    public SlidingPaneLayout(Context context) {
25497341bdc5bea1d7bf777de65228039142d249f38Adam Powell        this(context, null);
25597341bdc5bea1d7bf777de65228039142d249f38Adam Powell    }
25697341bdc5bea1d7bf777de65228039142d249f38Adam Powell
25797341bdc5bea1d7bf777de65228039142d249f38Adam Powell    public SlidingPaneLayout(Context context, AttributeSet attrs) {
25897341bdc5bea1d7bf777de65228039142d249f38Adam Powell        this(context, attrs, 0);
25997341bdc5bea1d7bf777de65228039142d249f38Adam Powell    }
26097341bdc5bea1d7bf777de65228039142d249f38Adam Powell
26197341bdc5bea1d7bf777de65228039142d249f38Adam Powell    public SlidingPaneLayout(Context context, AttributeSet attrs, int defStyle) {
26297341bdc5bea1d7bf777de65228039142d249f38Adam Powell        super(context, attrs, defStyle);
26397341bdc5bea1d7bf777de65228039142d249f38Adam Powell
26497341bdc5bea1d7bf777de65228039142d249f38Adam Powell        final float density = context.getResources().getDisplayMetrics().density;
26597341bdc5bea1d7bf777de65228039142d249f38Adam Powell        mOverhangSize = (int) (DEFAULT_OVERHANG_SIZE * density + 0.5f);
26697341bdc5bea1d7bf777de65228039142d249f38Adam Powell
26797341bdc5bea1d7bf777de65228039142d249f38Adam Powell        final ViewConfiguration viewConfig = ViewConfiguration.get(context);
268ee3f0ffb0199e295cbf48aa1a61c8ae7056526abAdam Powell
269ee3f0ffb0199e295cbf48aa1a61c8ae7056526abAdam Powell        setWillNotDraw(false);
270c56ba65d20be8742ff717907a3a2cd81dd0e5f3cAdam Powell
271c89f53833f1e272d32f7928837f0704fa33be309Adam Powell        ViewCompat.setAccessibilityDelegate(this, new AccessibilityDelegate());
272d0cb2111677748ec19a72e5fe18c8c64a359a751Adam Powell        ViewCompat.setImportantForAccessibility(this, ViewCompat.IMPORTANT_FOR_ACCESSIBILITY_YES);
273c89f53833f1e272d32f7928837f0704fa33be309Adam Powell
2741d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell        mDragHelper = ViewDragHelper.create(this, 0.5f, new DragHelperCallback());
27579f95ce3e660d267831067e514ff455156c4381fAdam Powell        mDragHelper.setMinVelocity(MIN_FLING_VELOCITY * density);
27697341bdc5bea1d7bf777de65228039142d249f38Adam Powell    }
27797341bdc5bea1d7bf777de65228039142d249f38Adam Powell
2786debd2bbcae1cd285d2e21db633998b7801f9f40Adam Powell    /**
2796debd2bbcae1cd285d2e21db633998b7801f9f40Adam Powell     * Set a distance to parallax the lower pane by when the upper pane is in its
2806debd2bbcae1cd285d2e21db633998b7801f9f40Adam Powell     * fully closed state. The lower pane will scroll between this position and
2816debd2bbcae1cd285d2e21db633998b7801f9f40Adam Powell     * its fully open state.
2826debd2bbcae1cd285d2e21db633998b7801f9f40Adam Powell     *
2836debd2bbcae1cd285d2e21db633998b7801f9f40Adam Powell     * @param parallaxBy Distance to parallax by in pixels
2846debd2bbcae1cd285d2e21db633998b7801f9f40Adam Powell     */
2856debd2bbcae1cd285d2e21db633998b7801f9f40Adam Powell    public void setParallaxDistance(int parallaxBy) {
2866debd2bbcae1cd285d2e21db633998b7801f9f40Adam Powell        mParallaxBy = parallaxBy;
2876debd2bbcae1cd285d2e21db633998b7801f9f40Adam Powell        requestLayout();
2886debd2bbcae1cd285d2e21db633998b7801f9f40Adam Powell    }
2896debd2bbcae1cd285d2e21db633998b7801f9f40Adam Powell
2906debd2bbcae1cd285d2e21db633998b7801f9f40Adam Powell    /**
2916debd2bbcae1cd285d2e21db633998b7801f9f40Adam Powell     * @return The distance the lower pane will parallax by when the upper pane is fully closed.
2926debd2bbcae1cd285d2e21db633998b7801f9f40Adam Powell     *
2936debd2bbcae1cd285d2e21db633998b7801f9f40Adam Powell     * @see #setParallaxDistance(int)
2946debd2bbcae1cd285d2e21db633998b7801f9f40Adam Powell     */
2956debd2bbcae1cd285d2e21db633998b7801f9f40Adam Powell    public int getParallaxDistance() {
2966debd2bbcae1cd285d2e21db633998b7801f9f40Adam Powell        return mParallaxBy;
2976debd2bbcae1cd285d2e21db633998b7801f9f40Adam Powell    }
2986debd2bbcae1cd285d2e21db633998b7801f9f40Adam Powell
29981e2f002d1b4ebf2d951eb9f239858b8a9481a24Adam Powell    /**
30081e2f002d1b4ebf2d951eb9f239858b8a9481a24Adam Powell     * Set the color used to fade the sliding pane out when it is slid most of the way offscreen.
30181e2f002d1b4ebf2d951eb9f239858b8a9481a24Adam Powell     *
30281e2f002d1b4ebf2d951eb9f239858b8a9481a24Adam Powell     * @param color An ARGB-packed color value
30381e2f002d1b4ebf2d951eb9f239858b8a9481a24Adam Powell     */
30470acb0c19be3831a2080e4f902324de16bfbf62eTor Norbye    public void setSliderFadeColor(@ColorInt int color) {
30581e2f002d1b4ebf2d951eb9f239858b8a9481a24Adam Powell        mSliderFadeColor = color;
30681e2f002d1b4ebf2d951eb9f239858b8a9481a24Adam Powell    }
30781e2f002d1b4ebf2d951eb9f239858b8a9481a24Adam Powell
30881e2f002d1b4ebf2d951eb9f239858b8a9481a24Adam Powell    /**
30981e2f002d1b4ebf2d951eb9f239858b8a9481a24Adam Powell     * @return The ARGB-packed color value used to fade the sliding pane
31081e2f002d1b4ebf2d951eb9f239858b8a9481a24Adam Powell     */
31170acb0c19be3831a2080e4f902324de16bfbf62eTor Norbye    @ColorInt
31281e2f002d1b4ebf2d951eb9f239858b8a9481a24Adam Powell    public int getSliderFadeColor() {
31381e2f002d1b4ebf2d951eb9f239858b8a9481a24Adam Powell        return mSliderFadeColor;
31481e2f002d1b4ebf2d951eb9f239858b8a9481a24Adam Powell    }
31581e2f002d1b4ebf2d951eb9f239858b8a9481a24Adam Powell
31681e2f002d1b4ebf2d951eb9f239858b8a9481a24Adam Powell    /**
31781e2f002d1b4ebf2d951eb9f239858b8a9481a24Adam Powell     * Set the color used to fade the pane covered by the sliding pane out when the pane
31881e2f002d1b4ebf2d951eb9f239858b8a9481a24Adam Powell     * will become fully covered in the closed state.
31981e2f002d1b4ebf2d951eb9f239858b8a9481a24Adam Powell     *
32081e2f002d1b4ebf2d951eb9f239858b8a9481a24Adam Powell     * @param color An ARGB-packed color value
32181e2f002d1b4ebf2d951eb9f239858b8a9481a24Adam Powell     */
32270acb0c19be3831a2080e4f902324de16bfbf62eTor Norbye    public void setCoveredFadeColor(@ColorInt int color) {
32381e2f002d1b4ebf2d951eb9f239858b8a9481a24Adam Powell        mCoveredFadeColor = color;
32481e2f002d1b4ebf2d951eb9f239858b8a9481a24Adam Powell    }
32581e2f002d1b4ebf2d951eb9f239858b8a9481a24Adam Powell
32681e2f002d1b4ebf2d951eb9f239858b8a9481a24Adam Powell    /**
32781e2f002d1b4ebf2d951eb9f239858b8a9481a24Adam Powell     * @return The ARGB-packed color value used to fade the fixed pane
32881e2f002d1b4ebf2d951eb9f239858b8a9481a24Adam Powell     */
32970acb0c19be3831a2080e4f902324de16bfbf62eTor Norbye    @ColorInt
33081e2f002d1b4ebf2d951eb9f239858b8a9481a24Adam Powell    public int getCoveredFadeColor() {
33181e2f002d1b4ebf2d951eb9f239858b8a9481a24Adam Powell        return mCoveredFadeColor;
33281e2f002d1b4ebf2d951eb9f239858b8a9481a24Adam Powell    }
33381e2f002d1b4ebf2d951eb9f239858b8a9481a24Adam Powell
33497341bdc5bea1d7bf777de65228039142d249f38Adam Powell    public void setPanelSlideListener(PanelSlideListener listener) {
33597341bdc5bea1d7bf777de65228039142d249f38Adam Powell        mPanelSlideListener = listener;
33697341bdc5bea1d7bf777de65228039142d249f38Adam Powell    }
33797341bdc5bea1d7bf777de65228039142d249f38Adam Powell
33897341bdc5bea1d7bf777de65228039142d249f38Adam Powell    void dispatchOnPanelSlide(View panel) {
33997341bdc5bea1d7bf777de65228039142d249f38Adam Powell        if (mPanelSlideListener != null) {
3400eefe9ad0819b223006533cbc79a35d66684af32Adam Powell            mPanelSlideListener.onPanelSlide(panel, mSlideOffset);
34197341bdc5bea1d7bf777de65228039142d249f38Adam Powell        }
34297341bdc5bea1d7bf777de65228039142d249f38Adam Powell    }
34397341bdc5bea1d7bf777de65228039142d249f38Adam Powell
34497341bdc5bea1d7bf777de65228039142d249f38Adam Powell    void dispatchOnPanelOpened(View panel) {
34597341bdc5bea1d7bf777de65228039142d249f38Adam Powell        if (mPanelSlideListener != null) {
34697341bdc5bea1d7bf777de65228039142d249f38Adam Powell            mPanelSlideListener.onPanelOpened(panel);
34797341bdc5bea1d7bf777de65228039142d249f38Adam Powell        }
348c89f53833f1e272d32f7928837f0704fa33be309Adam Powell        sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);
34997341bdc5bea1d7bf777de65228039142d249f38Adam Powell    }
35097341bdc5bea1d7bf777de65228039142d249f38Adam Powell
35197341bdc5bea1d7bf777de65228039142d249f38Adam Powell    void dispatchOnPanelClosed(View panel) {
35297341bdc5bea1d7bf777de65228039142d249f38Adam Powell        if (mPanelSlideListener != null) {
35397341bdc5bea1d7bf777de65228039142d249f38Adam Powell            mPanelSlideListener.onPanelClosed(panel);
35497341bdc5bea1d7bf777de65228039142d249f38Adam Powell        }
355c89f53833f1e272d32f7928837f0704fa33be309Adam Powell        sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);
356c89f53833f1e272d32f7928837f0704fa33be309Adam Powell    }
357c89f53833f1e272d32f7928837f0704fa33be309Adam Powell
358c89f53833f1e272d32f7928837f0704fa33be309Adam Powell    void updateObscuredViewsVisibility(View panel) {
35919780f88506df4aeb57456fd6747af1b6848a11cfafaisland        final boolean isLayoutRtl = isLayoutRtlSupport();
36019780f88506df4aeb57456fd6747af1b6848a11cfafaisland        final int startBound = isLayoutRtl ? (getWidth() - getPaddingRight()) :
36119780f88506df4aeb57456fd6747af1b6848a11cfafaisland            getPaddingLeft();
36219780f88506df4aeb57456fd6747af1b6848a11cfafaisland        final int endBound = isLayoutRtl ? getPaddingLeft() :
36319780f88506df4aeb57456fd6747af1b6848a11cfafaisland            (getWidth() - getPaddingRight());
364f993018935168724fd4972edcf418fae09d81680Adam Powell        final int topBound = getPaddingTop();
365f993018935168724fd4972edcf418fae09d81680Adam Powell        final int bottomBound = getHeight() - getPaddingBottom();
366c89f53833f1e272d32f7928837f0704fa33be309Adam Powell        final int left;
367c89f53833f1e272d32f7928837f0704fa33be309Adam Powell        final int right;
368c89f53833f1e272d32f7928837f0704fa33be309Adam Powell        final int top;
369c89f53833f1e272d32f7928837f0704fa33be309Adam Powell        final int bottom;
370c029e15f5a4709214cb433a562256586824a0f33Adam Powell        if (panel != null && viewIsOpaque(panel)) {
371c89f53833f1e272d32f7928837f0704fa33be309Adam Powell            left = panel.getLeft();
372c89f53833f1e272d32f7928837f0704fa33be309Adam Powell            right = panel.getRight();
373c89f53833f1e272d32f7928837f0704fa33be309Adam Powell            top = panel.getTop();
374c89f53833f1e272d32f7928837f0704fa33be309Adam Powell            bottom = panel.getBottom();
375c89f53833f1e272d32f7928837f0704fa33be309Adam Powell        } else {
376c89f53833f1e272d32f7928837f0704fa33be309Adam Powell            left = right = top = bottom = 0;
377c89f53833f1e272d32f7928837f0704fa33be309Adam Powell        }
378c89f53833f1e272d32f7928837f0704fa33be309Adam Powell
379c89f53833f1e272d32f7928837f0704fa33be309Adam Powell        for (int i = 0, childCount = getChildCount(); i < childCount; i++) {
380c89f53833f1e272d32f7928837f0704fa33be309Adam Powell            final View child = getChildAt(i);
381c89f53833f1e272d32f7928837f0704fa33be309Adam Powell
382c89f53833f1e272d32f7928837f0704fa33be309Adam Powell            if (child == panel) {
383c89f53833f1e272d32f7928837f0704fa33be309Adam Powell                // There are still more children above the panel but they won't be affected.
384c89f53833f1e272d32f7928837f0704fa33be309Adam Powell                break;
385c89f53833f1e272d32f7928837f0704fa33be309Adam Powell            }
386c89f53833f1e272d32f7928837f0704fa33be309Adam Powell
38719780f88506df4aeb57456fd6747af1b6848a11cfafaisland            final int clampedChildLeft = Math.max((isLayoutRtl ? endBound :
38819780f88506df4aeb57456fd6747af1b6848a11cfafaisland                startBound), child.getLeft());
389f993018935168724fd4972edcf418fae09d81680Adam Powell            final int clampedChildTop = Math.max(topBound, child.getTop());
39019780f88506df4aeb57456fd6747af1b6848a11cfafaisland            final int clampedChildRight = Math.min((isLayoutRtl ? startBound :
39119780f88506df4aeb57456fd6747af1b6848a11cfafaisland                endBound), child.getRight());
392f993018935168724fd4972edcf418fae09d81680Adam Powell            final int clampedChildBottom = Math.min(bottomBound, child.getBottom());
393c89f53833f1e272d32f7928837f0704fa33be309Adam Powell            final int vis;
394f993018935168724fd4972edcf418fae09d81680Adam Powell            if (clampedChildLeft >= left && clampedChildTop >= top &&
395f993018935168724fd4972edcf418fae09d81680Adam Powell                    clampedChildRight <= right && clampedChildBottom <= bottom) {
396c89f53833f1e272d32f7928837f0704fa33be309Adam Powell                vis = INVISIBLE;
397c89f53833f1e272d32f7928837f0704fa33be309Adam Powell            } else {
398c89f53833f1e272d32f7928837f0704fa33be309Adam Powell                vis = VISIBLE;
399c89f53833f1e272d32f7928837f0704fa33be309Adam Powell            }
400c89f53833f1e272d32f7928837f0704fa33be309Adam Powell            child.setVisibility(vis);
401c89f53833f1e272d32f7928837f0704fa33be309Adam Powell        }
402c89f53833f1e272d32f7928837f0704fa33be309Adam Powell    }
403c89f53833f1e272d32f7928837f0704fa33be309Adam Powell
404c89f53833f1e272d32f7928837f0704fa33be309Adam Powell    void setAllChildrenVisible() {
405c89f53833f1e272d32f7928837f0704fa33be309Adam Powell        for (int i = 0, childCount = getChildCount(); i < childCount; i++) {
406c89f53833f1e272d32f7928837f0704fa33be309Adam Powell            final View child = getChildAt(i);
407c89f53833f1e272d32f7928837f0704fa33be309Adam Powell            if (child.getVisibility() == INVISIBLE) {
408c89f53833f1e272d32f7928837f0704fa33be309Adam Powell                child.setVisibility(VISIBLE);
409c89f53833f1e272d32f7928837f0704fa33be309Adam Powell            }
410c89f53833f1e272d32f7928837f0704fa33be309Adam Powell        }
411c89f53833f1e272d32f7928837f0704fa33be309Adam Powell    }
412c89f53833f1e272d32f7928837f0704fa33be309Adam Powell
413c029e15f5a4709214cb433a562256586824a0f33Adam Powell    private static boolean viewIsOpaque(View v) {
414c029e15f5a4709214cb433a562256586824a0f33Adam Powell        if (ViewCompat.isOpaque(v)) return true;
415c029e15f5a4709214cb433a562256586824a0f33Adam Powell
416c029e15f5a4709214cb433a562256586824a0f33Adam Powell        // View#isOpaque didn't take all valid opaque scrollbar modes into account
417c029e15f5a4709214cb433a562256586824a0f33Adam Powell        // before API 18 (JB-MR2). On newer devices rely solely on isOpaque above and return false
418c029e15f5a4709214cb433a562256586824a0f33Adam Powell        // here. On older devices, check the view's background drawable directly as a fallback.
419c029e15f5a4709214cb433a562256586824a0f33Adam Powell        if (Build.VERSION.SDK_INT >= 18) return false;
420c029e15f5a4709214cb433a562256586824a0f33Adam Powell
421c89f53833f1e272d32f7928837f0704fa33be309Adam Powell        final Drawable bg = v.getBackground();
422c89f53833f1e272d32f7928837f0704fa33be309Adam Powell        if (bg != null) {
423c89f53833f1e272d32f7928837f0704fa33be309Adam Powell            return bg.getOpacity() == PixelFormat.OPAQUE;
424c89f53833f1e272d32f7928837f0704fa33be309Adam Powell        }
425c89f53833f1e272d32f7928837f0704fa33be309Adam Powell        return false;
42697341bdc5bea1d7bf777de65228039142d249f38Adam Powell    }
42797341bdc5bea1d7bf777de65228039142d249f38Adam Powell
42897341bdc5bea1d7bf777de65228039142d249f38Adam Powell    @Override
42989e17886e6149bddfdb08a242c9e88889596419cAdam Powell    protected void onAttachedToWindow() {
43089e17886e6149bddfdb08a242c9e88889596419cAdam Powell        super.onAttachedToWindow();
43189e17886e6149bddfdb08a242c9e88889596419cAdam Powell        mFirstLayout = true;
43289e17886e6149bddfdb08a242c9e88889596419cAdam Powell    }
43389e17886e6149bddfdb08a242c9e88889596419cAdam Powell
43489e17886e6149bddfdb08a242c9e88889596419cAdam Powell    @Override
43589e17886e6149bddfdb08a242c9e88889596419cAdam Powell    protected void onDetachedFromWindow() {
43689e17886e6149bddfdb08a242c9e88889596419cAdam Powell        super.onDetachedFromWindow();
43789e17886e6149bddfdb08a242c9e88889596419cAdam Powell        mFirstLayout = true;
438f4445e06a8490b056cd892c4bc640dfd17905d6cAdam Powell
439f4445e06a8490b056cd892c4bc640dfd17905d6cAdam Powell        for (int i = 0, count = mPostedRunnables.size(); i < count; i++) {
440f4445e06a8490b056cd892c4bc640dfd17905d6cAdam Powell            final DisableLayerRunnable dlr = mPostedRunnables.get(i);
441f4445e06a8490b056cd892c4bc640dfd17905d6cAdam Powell            dlr.run();
442f4445e06a8490b056cd892c4bc640dfd17905d6cAdam Powell        }
443f4445e06a8490b056cd892c4bc640dfd17905d6cAdam Powell        mPostedRunnables.clear();
44489e17886e6149bddfdb08a242c9e88889596419cAdam Powell    }
44589e17886e6149bddfdb08a242c9e88889596419cAdam Powell
44689e17886e6149bddfdb08a242c9e88889596419cAdam Powell    @Override
44797341bdc5bea1d7bf777de65228039142d249f38Adam Powell    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
448c6f6c4511593aa49688d5425e2f6e36459076c25Adam Powell        int widthMode = MeasureSpec.getMode(widthMeasureSpec);
449c6f6c4511593aa49688d5425e2f6e36459076c25Adam Powell        int widthSize = MeasureSpec.getSize(widthMeasureSpec);
450c6f6c4511593aa49688d5425e2f6e36459076c25Adam Powell        int heightMode = MeasureSpec.getMode(heightMeasureSpec);
451c6f6c4511593aa49688d5425e2f6e36459076c25Adam Powell        int heightSize = MeasureSpec.getSize(heightMeasureSpec);
45297341bdc5bea1d7bf777de65228039142d249f38Adam Powell
45397341bdc5bea1d7bf777de65228039142d249f38Adam Powell        if (widthMode != MeasureSpec.EXACTLY) {
454c6f6c4511593aa49688d5425e2f6e36459076c25Adam Powell            if (isInEditMode()) {
455c6f6c4511593aa49688d5425e2f6e36459076c25Adam Powell                // Don't crash the layout editor. Consume all of the space if specified
456c6f6c4511593aa49688d5425e2f6e36459076c25Adam Powell                // or pick a magic number from thin air otherwise.
457c6f6c4511593aa49688d5425e2f6e36459076c25Adam Powell                // TODO Better communication with tools of this bogus state.
458c6f6c4511593aa49688d5425e2f6e36459076c25Adam Powell                // It will crash on a real device.
459c6f6c4511593aa49688d5425e2f6e36459076c25Adam Powell                if (widthMode == MeasureSpec.AT_MOST) {
460c6f6c4511593aa49688d5425e2f6e36459076c25Adam Powell                    widthMode = MeasureSpec.EXACTLY;
461c6f6c4511593aa49688d5425e2f6e36459076c25Adam Powell                } else if (widthMode == MeasureSpec.UNSPECIFIED) {
462c6f6c4511593aa49688d5425e2f6e36459076c25Adam Powell                    widthMode = MeasureSpec.EXACTLY;
463c6f6c4511593aa49688d5425e2f6e36459076c25Adam Powell                    widthSize = 300;
464c6f6c4511593aa49688d5425e2f6e36459076c25Adam Powell                }
465c6f6c4511593aa49688d5425e2f6e36459076c25Adam Powell            } else {
466c6f6c4511593aa49688d5425e2f6e36459076c25Adam Powell                throw new IllegalStateException("Width must have an exact value or MATCH_PARENT");
467c6f6c4511593aa49688d5425e2f6e36459076c25Adam Powell            }
46897341bdc5bea1d7bf777de65228039142d249f38Adam Powell        } else if (heightMode == MeasureSpec.UNSPECIFIED) {
469c6f6c4511593aa49688d5425e2f6e36459076c25Adam Powell            if (isInEditMode()) {
470c6f6c4511593aa49688d5425e2f6e36459076c25Adam Powell                // Don't crash the layout editor. Pick a magic number from thin air instead.
471c6f6c4511593aa49688d5425e2f6e36459076c25Adam Powell                // TODO Better communication with tools of this bogus state.
472c6f6c4511593aa49688d5425e2f6e36459076c25Adam Powell                // It will crash on a real device.
473c6f6c4511593aa49688d5425e2f6e36459076c25Adam Powell                if (heightMode == MeasureSpec.UNSPECIFIED) {
474c6f6c4511593aa49688d5425e2f6e36459076c25Adam Powell                    heightMode = MeasureSpec.AT_MOST;
475c6f6c4511593aa49688d5425e2f6e36459076c25Adam Powell                    heightSize = 300;
476c6f6c4511593aa49688d5425e2f6e36459076c25Adam Powell                }
477c6f6c4511593aa49688d5425e2f6e36459076c25Adam Powell            } else {
478c6f6c4511593aa49688d5425e2f6e36459076c25Adam Powell                throw new IllegalStateException("Height must not be UNSPECIFIED");
479c6f6c4511593aa49688d5425e2f6e36459076c25Adam Powell            }
48097341bdc5bea1d7bf777de65228039142d249f38Adam Powell        }
48197341bdc5bea1d7bf777de65228039142d249f38Adam Powell
48297341bdc5bea1d7bf777de65228039142d249f38Adam Powell        int layoutHeight = 0;
48397341bdc5bea1d7bf777de65228039142d249f38Adam Powell        int maxLayoutHeight = -1;
48497341bdc5bea1d7bf777de65228039142d249f38Adam Powell        switch (heightMode) {
48597341bdc5bea1d7bf777de65228039142d249f38Adam Powell            case MeasureSpec.EXACTLY:
48697341bdc5bea1d7bf777de65228039142d249f38Adam Powell                layoutHeight = maxLayoutHeight = heightSize - getPaddingTop() - getPaddingBottom();
48797341bdc5bea1d7bf777de65228039142d249f38Adam Powell                break;
48897341bdc5bea1d7bf777de65228039142d249f38Adam Powell            case MeasureSpec.AT_MOST:
48997341bdc5bea1d7bf777de65228039142d249f38Adam Powell                maxLayoutHeight = heightSize - getPaddingTop() - getPaddingBottom();
49097341bdc5bea1d7bf777de65228039142d249f38Adam Powell                break;
49197341bdc5bea1d7bf777de65228039142d249f38Adam Powell        }
49297341bdc5bea1d7bf777de65228039142d249f38Adam Powell
49397341bdc5bea1d7bf777de65228039142d249f38Adam Powell        float weightSum = 0;
4940eefe9ad0819b223006533cbc79a35d66684af32Adam Powell        boolean canSlide = false;
4956688e113ad2519dc07edf56acbd0f42ce209a585Sérgio Faria        final int widthAvailable = widthSize - getPaddingLeft() - getPaddingRight();
4966688e113ad2519dc07edf56acbd0f42ce209a585Sérgio Faria        int widthRemaining = widthAvailable;
49797341bdc5bea1d7bf777de65228039142d249f38Adam Powell        final int childCount = getChildCount();
49897341bdc5bea1d7bf777de65228039142d249f38Adam Powell
49997341bdc5bea1d7bf777de65228039142d249f38Adam Powell        if (childCount > 2) {
5000eefe9ad0819b223006533cbc79a35d66684af32Adam Powell            Log.e(TAG, "onMeasure: More than two child views are not supported.");
50197341bdc5bea1d7bf777de65228039142d249f38Adam Powell        }
50297341bdc5bea1d7bf777de65228039142d249f38Adam Powell
5031e43161e9e1f1dc10637a68d5c2304c1f95c9c46Adam Powell        // We'll find the current one below.
5041e43161e9e1f1dc10637a68d5c2304c1f95c9c46Adam Powell        mSlideableView = null;
5051e43161e9e1f1dc10637a68d5c2304c1f95c9c46Adam Powell
50697341bdc5bea1d7bf777de65228039142d249f38Adam Powell        // First pass. Measure based on child LayoutParams width/height.
50797341bdc5bea1d7bf777de65228039142d249f38Adam Powell        // Weight will incur a second pass.
50897341bdc5bea1d7bf777de65228039142d249f38Adam Powell        for (int i = 0; i < childCount; i++) {
50997341bdc5bea1d7bf777de65228039142d249f38Adam Powell            final View child = getChildAt(i);
51097341bdc5bea1d7bf777de65228039142d249f38Adam Powell            final LayoutParams lp = (LayoutParams) child.getLayoutParams();
51197341bdc5bea1d7bf777de65228039142d249f38Adam Powell
512dc56c78a7e2d06c9aabd3e90448c81671d8c05b1Adam Powell            if (child.getVisibility() == GONE) {
513dc56c78a7e2d06c9aabd3e90448c81671d8c05b1Adam Powell                lp.dimWhenOffset = false;
514dc56c78a7e2d06c9aabd3e90448c81671d8c05b1Adam Powell                continue;
515dc56c78a7e2d06c9aabd3e90448c81671d8c05b1Adam Powell            }
516dc56c78a7e2d06c9aabd3e90448c81671d8c05b1Adam Powell
51797341bdc5bea1d7bf777de65228039142d249f38Adam Powell            if (lp.weight > 0) {
51897341bdc5bea1d7bf777de65228039142d249f38Adam Powell                weightSum += lp.weight;
51997341bdc5bea1d7bf777de65228039142d249f38Adam Powell
52097341bdc5bea1d7bf777de65228039142d249f38Adam Powell                // If we have no width, weight is the only contributor to the final size.
52197341bdc5bea1d7bf777de65228039142d249f38Adam Powell                // Measure this view on the weight pass only.
52297341bdc5bea1d7bf777de65228039142d249f38Adam Powell                if (lp.width == 0) continue;
52397341bdc5bea1d7bf777de65228039142d249f38Adam Powell            }
52497341bdc5bea1d7bf777de65228039142d249f38Adam Powell
52597341bdc5bea1d7bf777de65228039142d249f38Adam Powell            int childWidthSpec;
52697341bdc5bea1d7bf777de65228039142d249f38Adam Powell            final int horizontalMargin = lp.leftMargin + lp.rightMargin;
52797341bdc5bea1d7bf777de65228039142d249f38Adam Powell            if (lp.width == LayoutParams.WRAP_CONTENT) {
5286688e113ad2519dc07edf56acbd0f42ce209a585Sérgio Faria                childWidthSpec = MeasureSpec.makeMeasureSpec(widthAvailable - horizontalMargin,
52997341bdc5bea1d7bf777de65228039142d249f38Adam Powell                        MeasureSpec.AT_MOST);
53097341bdc5bea1d7bf777de65228039142d249f38Adam Powell            } else if (lp.width == LayoutParams.FILL_PARENT) {
5316688e113ad2519dc07edf56acbd0f42ce209a585Sérgio Faria                childWidthSpec = MeasureSpec.makeMeasureSpec(widthAvailable - horizontalMargin,
53297341bdc5bea1d7bf777de65228039142d249f38Adam Powell                        MeasureSpec.EXACTLY);
53397341bdc5bea1d7bf777de65228039142d249f38Adam Powell            } else {
53497341bdc5bea1d7bf777de65228039142d249f38Adam Powell                childWidthSpec = MeasureSpec.makeMeasureSpec(lp.width, MeasureSpec.EXACTLY);
53597341bdc5bea1d7bf777de65228039142d249f38Adam Powell            }
53697341bdc5bea1d7bf777de65228039142d249f38Adam Powell
53797341bdc5bea1d7bf777de65228039142d249f38Adam Powell            int childHeightSpec;
53897341bdc5bea1d7bf777de65228039142d249f38Adam Powell            if (lp.height == LayoutParams.WRAP_CONTENT) {
53997341bdc5bea1d7bf777de65228039142d249f38Adam Powell                childHeightSpec = MeasureSpec.makeMeasureSpec(maxLayoutHeight, MeasureSpec.AT_MOST);
54097341bdc5bea1d7bf777de65228039142d249f38Adam Powell            } else if (lp.height == LayoutParams.FILL_PARENT) {
54197341bdc5bea1d7bf777de65228039142d249f38Adam Powell                childHeightSpec = MeasureSpec.makeMeasureSpec(maxLayoutHeight, MeasureSpec.EXACTLY);
54297341bdc5bea1d7bf777de65228039142d249f38Adam Powell            } else {
54397341bdc5bea1d7bf777de65228039142d249f38Adam Powell                childHeightSpec = MeasureSpec.makeMeasureSpec(lp.height, MeasureSpec.EXACTLY);
54497341bdc5bea1d7bf777de65228039142d249f38Adam Powell            }
54597341bdc5bea1d7bf777de65228039142d249f38Adam Powell
54697341bdc5bea1d7bf777de65228039142d249f38Adam Powell            child.measure(childWidthSpec, childHeightSpec);
54797341bdc5bea1d7bf777de65228039142d249f38Adam Powell            final int childWidth = child.getMeasuredWidth();
54897341bdc5bea1d7bf777de65228039142d249f38Adam Powell            final int childHeight = child.getMeasuredHeight();
54997341bdc5bea1d7bf777de65228039142d249f38Adam Powell
55097341bdc5bea1d7bf777de65228039142d249f38Adam Powell            if (heightMode == MeasureSpec.AT_MOST && childHeight > layoutHeight) {
55197341bdc5bea1d7bf777de65228039142d249f38Adam Powell                layoutHeight = Math.min(childHeight, maxLayoutHeight);
55297341bdc5bea1d7bf777de65228039142d249f38Adam Powell            }
55397341bdc5bea1d7bf777de65228039142d249f38Adam Powell
55497341bdc5bea1d7bf777de65228039142d249f38Adam Powell            widthRemaining -= childWidth;
5550eefe9ad0819b223006533cbc79a35d66684af32Adam Powell            canSlide |= lp.slideable = widthRemaining < 0;
5560eefe9ad0819b223006533cbc79a35d66684af32Adam Powell            if (lp.slideable) {
5570eefe9ad0819b223006533cbc79a35d66684af32Adam Powell                mSlideableView = child;
5580eefe9ad0819b223006533cbc79a35d66684af32Adam Powell            }
55997341bdc5bea1d7bf777de65228039142d249f38Adam Powell        }
56097341bdc5bea1d7bf777de65228039142d249f38Adam Powell
56197341bdc5bea1d7bf777de65228039142d249f38Adam Powell        // Resolve weight and make sure non-sliding panels are smaller than the full screen.
56297341bdc5bea1d7bf777de65228039142d249f38Adam Powell        if (canSlide || weightSum > 0) {
5636688e113ad2519dc07edf56acbd0f42ce209a585Sérgio Faria            final int fixedPanelWidthLimit = widthAvailable - mOverhangSize;
56497341bdc5bea1d7bf777de65228039142d249f38Adam Powell
56597341bdc5bea1d7bf777de65228039142d249f38Adam Powell            for (int i = 0; i < childCount; i++) {
56697341bdc5bea1d7bf777de65228039142d249f38Adam Powell                final View child = getChildAt(i);
5670eefe9ad0819b223006533cbc79a35d66684af32Adam Powell
5680eefe9ad0819b223006533cbc79a35d66684af32Adam Powell                if (child.getVisibility() == GONE) {
5690eefe9ad0819b223006533cbc79a35d66684af32Adam Powell                    continue;
5700eefe9ad0819b223006533cbc79a35d66684af32Adam Powell                }
5710eefe9ad0819b223006533cbc79a35d66684af32Adam Powell
57297341bdc5bea1d7bf777de65228039142d249f38Adam Powell                final LayoutParams lp = (LayoutParams) child.getLayoutParams();
57397341bdc5bea1d7bf777de65228039142d249f38Adam Powell
574dc56c78a7e2d06c9aabd3e90448c81671d8c05b1Adam Powell                if (child.getVisibility() == GONE) {
575dc56c78a7e2d06c9aabd3e90448c81671d8c05b1Adam Powell                    continue;
576dc56c78a7e2d06c9aabd3e90448c81671d8c05b1Adam Powell                }
577dc56c78a7e2d06c9aabd3e90448c81671d8c05b1Adam Powell
57897341bdc5bea1d7bf777de65228039142d249f38Adam Powell                final boolean skippedFirstPass = lp.width == 0 && lp.weight > 0;
57997341bdc5bea1d7bf777de65228039142d249f38Adam Powell                final int measuredWidth = skippedFirstPass ? 0 : child.getMeasuredWidth();
5800eefe9ad0819b223006533cbc79a35d66684af32Adam Powell                if (canSlide && child != mSlideableView) {
58197341bdc5bea1d7bf777de65228039142d249f38Adam Powell                    if (lp.width < 0 && (measuredWidth > fixedPanelWidthLimit || lp.weight > 0)) {
58297341bdc5bea1d7bf777de65228039142d249f38Adam Powell                        // Fixed panels in a sliding configuration should
58397341bdc5bea1d7bf777de65228039142d249f38Adam Powell                        // be clamped to the fixed panel limit.
58497341bdc5bea1d7bf777de65228039142d249f38Adam Powell                        final int childHeightSpec;
58597341bdc5bea1d7bf777de65228039142d249f38Adam Powell                        if (skippedFirstPass) {
58697341bdc5bea1d7bf777de65228039142d249f38Adam Powell                            // Do initial height measurement if we skipped measuring this view
58797341bdc5bea1d7bf777de65228039142d249f38Adam Powell                            // the first time around.
58897341bdc5bea1d7bf777de65228039142d249f38Adam Powell                            if (lp.height == LayoutParams.WRAP_CONTENT) {
58997341bdc5bea1d7bf777de65228039142d249f38Adam Powell                                childHeightSpec = MeasureSpec.makeMeasureSpec(maxLayoutHeight,
59097341bdc5bea1d7bf777de65228039142d249f38Adam Powell                                        MeasureSpec.AT_MOST);
59197341bdc5bea1d7bf777de65228039142d249f38Adam Powell                            } else if (lp.height == LayoutParams.FILL_PARENT) {
59297341bdc5bea1d7bf777de65228039142d249f38Adam Powell                                childHeightSpec = MeasureSpec.makeMeasureSpec(maxLayoutHeight,
59397341bdc5bea1d7bf777de65228039142d249f38Adam Powell                                        MeasureSpec.EXACTLY);
59497341bdc5bea1d7bf777de65228039142d249f38Adam Powell                            } else {
59597341bdc5bea1d7bf777de65228039142d249f38Adam Powell                                childHeightSpec = MeasureSpec.makeMeasureSpec(lp.height,
59697341bdc5bea1d7bf777de65228039142d249f38Adam Powell                                        MeasureSpec.EXACTLY);
59797341bdc5bea1d7bf777de65228039142d249f38Adam Powell                            }
59897341bdc5bea1d7bf777de65228039142d249f38Adam Powell                        } else {
59997341bdc5bea1d7bf777de65228039142d249f38Adam Powell                            childHeightSpec = MeasureSpec.makeMeasureSpec(
60097341bdc5bea1d7bf777de65228039142d249f38Adam Powell                                    child.getMeasuredHeight(), MeasureSpec.EXACTLY);
60197341bdc5bea1d7bf777de65228039142d249f38Adam Powell                        }
60297341bdc5bea1d7bf777de65228039142d249f38Adam Powell                        final int childWidthSpec = MeasureSpec.makeMeasureSpec(
60397341bdc5bea1d7bf777de65228039142d249f38Adam Powell                                fixedPanelWidthLimit, MeasureSpec.EXACTLY);
60497341bdc5bea1d7bf777de65228039142d249f38Adam Powell                        child.measure(childWidthSpec, childHeightSpec);
60597341bdc5bea1d7bf777de65228039142d249f38Adam Powell                    }
60697341bdc5bea1d7bf777de65228039142d249f38Adam Powell                } else if (lp.weight > 0) {
60797341bdc5bea1d7bf777de65228039142d249f38Adam Powell                    int childHeightSpec;
60897341bdc5bea1d7bf777de65228039142d249f38Adam Powell                    if (lp.width == 0) {
60997341bdc5bea1d7bf777de65228039142d249f38Adam Powell                        // This was skipped the first time; figure out a real height spec.
61097341bdc5bea1d7bf777de65228039142d249f38Adam Powell                        if (lp.height == LayoutParams.WRAP_CONTENT) {
61197341bdc5bea1d7bf777de65228039142d249f38Adam Powell                            childHeightSpec = MeasureSpec.makeMeasureSpec(maxLayoutHeight,
61297341bdc5bea1d7bf777de65228039142d249f38Adam Powell                                    MeasureSpec.AT_MOST);
61397341bdc5bea1d7bf777de65228039142d249f38Adam Powell                        } else if (lp.height == LayoutParams.FILL_PARENT) {
61497341bdc5bea1d7bf777de65228039142d249f38Adam Powell                            childHeightSpec = MeasureSpec.makeMeasureSpec(maxLayoutHeight,
61597341bdc5bea1d7bf777de65228039142d249f38Adam Powell                                    MeasureSpec.EXACTLY);
61697341bdc5bea1d7bf777de65228039142d249f38Adam Powell                        } else {
61797341bdc5bea1d7bf777de65228039142d249f38Adam Powell                            childHeightSpec = MeasureSpec.makeMeasureSpec(lp.height,
61897341bdc5bea1d7bf777de65228039142d249f38Adam Powell                                    MeasureSpec.EXACTLY);
61997341bdc5bea1d7bf777de65228039142d249f38Adam Powell                        }
62097341bdc5bea1d7bf777de65228039142d249f38Adam Powell                    } else {
62197341bdc5bea1d7bf777de65228039142d249f38Adam Powell                        childHeightSpec = MeasureSpec.makeMeasureSpec(
62297341bdc5bea1d7bf777de65228039142d249f38Adam Powell                                child.getMeasuredHeight(), MeasureSpec.EXACTLY);
62397341bdc5bea1d7bf777de65228039142d249f38Adam Powell                    }
62497341bdc5bea1d7bf777de65228039142d249f38Adam Powell
62597341bdc5bea1d7bf777de65228039142d249f38Adam Powell                    if (canSlide) {
62697341bdc5bea1d7bf777de65228039142d249f38Adam Powell                        // Consume available space
62797341bdc5bea1d7bf777de65228039142d249f38Adam Powell                        final int horizontalMargin = lp.leftMargin + lp.rightMargin;
6286688e113ad2519dc07edf56acbd0f42ce209a585Sérgio Faria                        final int newWidth = widthAvailable - horizontalMargin;
62997341bdc5bea1d7bf777de65228039142d249f38Adam Powell                        final int childWidthSpec = MeasureSpec.makeMeasureSpec(
63097341bdc5bea1d7bf777de65228039142d249f38Adam Powell                                newWidth, MeasureSpec.EXACTLY);
63197341bdc5bea1d7bf777de65228039142d249f38Adam Powell                        if (measuredWidth != newWidth) {
63297341bdc5bea1d7bf777de65228039142d249f38Adam Powell                            child.measure(childWidthSpec, childHeightSpec);
63397341bdc5bea1d7bf777de65228039142d249f38Adam Powell                        }
63497341bdc5bea1d7bf777de65228039142d249f38Adam Powell                    } else {
63597341bdc5bea1d7bf777de65228039142d249f38Adam Powell                        // Distribute the extra width proportionally similar to LinearLayout
63697341bdc5bea1d7bf777de65228039142d249f38Adam Powell                        final int widthToDistribute = Math.max(0, widthRemaining);
63797341bdc5bea1d7bf777de65228039142d249f38Adam Powell                        final int addedWidth = (int) (lp.weight * widthToDistribute / weightSum);
63897341bdc5bea1d7bf777de65228039142d249f38Adam Powell                        final int childWidthSpec = MeasureSpec.makeMeasureSpec(
63997341bdc5bea1d7bf777de65228039142d249f38Adam Powell                                measuredWidth + addedWidth, MeasureSpec.EXACTLY);
64097341bdc5bea1d7bf777de65228039142d249f38Adam Powell                        child.measure(childWidthSpec, childHeightSpec);
64197341bdc5bea1d7bf777de65228039142d249f38Adam Powell                    }
64297341bdc5bea1d7bf777de65228039142d249f38Adam Powell                }
64397341bdc5bea1d7bf777de65228039142d249f38Adam Powell            }
64497341bdc5bea1d7bf777de65228039142d249f38Adam Powell        }
64597341bdc5bea1d7bf777de65228039142d249f38Adam Powell
6466688e113ad2519dc07edf56acbd0f42ce209a585Sérgio Faria        final int measuredWidth = widthSize;
6476688e113ad2519dc07edf56acbd0f42ce209a585Sérgio Faria        final int measuredHeight = layoutHeight + getPaddingTop() + getPaddingBottom();
6486688e113ad2519dc07edf56acbd0f42ce209a585Sérgio Faria
6496688e113ad2519dc07edf56acbd0f42ce209a585Sérgio Faria        setMeasuredDimension(measuredWidth, measuredHeight);
65097341bdc5bea1d7bf777de65228039142d249f38Adam Powell        mCanSlide = canSlide;
6516688e113ad2519dc07edf56acbd0f42ce209a585Sérgio Faria
652471f0f4e84c7d1f96e48fb26713f246d69c3241fAdam Powell        if (mDragHelper.getViewDragState() != ViewDragHelper.STATE_IDLE && !canSlide) {
6530eefe9ad0819b223006533cbc79a35d66684af32Adam Powell            // Cancel scrolling in progress, it's no longer relevant.
654471f0f4e84c7d1f96e48fb26713f246d69c3241fAdam Powell            mDragHelper.abort();
65597341bdc5bea1d7bf777de65228039142d249f38Adam Powell        }
65697341bdc5bea1d7bf777de65228039142d249f38Adam Powell    }
65797341bdc5bea1d7bf777de65228039142d249f38Adam Powell
65897341bdc5bea1d7bf777de65228039142d249f38Adam Powell    @Override
65997341bdc5bea1d7bf777de65228039142d249f38Adam Powell    protected void onLayout(boolean changed, int l, int t, int r, int b) {
66019780f88506df4aeb57456fd6747af1b6848a11cfafaisland        final boolean isLayoutRtl = isLayoutRtlSupport();
66119780f88506df4aeb57456fd6747af1b6848a11cfafaisland        if (isLayoutRtl) {
66219780f88506df4aeb57456fd6747af1b6848a11cfafaisland            mDragHelper.setEdgeTrackingEnabled(ViewDragHelper.EDGE_RIGHT);
66319780f88506df4aeb57456fd6747af1b6848a11cfafaisland        } else {
66419780f88506df4aeb57456fd6747af1b6848a11cfafaisland            mDragHelper.setEdgeTrackingEnabled(ViewDragHelper.EDGE_LEFT);
66519780f88506df4aeb57456fd6747af1b6848a11cfafaisland        }
66697341bdc5bea1d7bf777de65228039142d249f38Adam Powell        final int width = r - l;
66719780f88506df4aeb57456fd6747af1b6848a11cfafaisland        final int paddingStart = isLayoutRtl ? getPaddingRight() : getPaddingLeft();
66819780f88506df4aeb57456fd6747af1b6848a11cfafaisland        final int paddingEnd = isLayoutRtl ? getPaddingLeft() : getPaddingRight();
66997341bdc5bea1d7bf777de65228039142d249f38Adam Powell        final int paddingTop = getPaddingTop();
67097341bdc5bea1d7bf777de65228039142d249f38Adam Powell
6716debd2bbcae1cd285d2e21db633998b7801f9f40Adam Powell        final int childCount = getChildCount();
67219780f88506df4aeb57456fd6747af1b6848a11cfafaisland        int xStart = paddingStart;
67397341bdc5bea1d7bf777de65228039142d249f38Adam Powell        int nextXStart = xStart;
67497341bdc5bea1d7bf777de65228039142d249f38Adam Powell
675d44315a54e002b20365189f03a09011f2bf6ba07Adam Powell        if (mFirstLayout) {
676d44315a54e002b20365189f03a09011f2bf6ba07Adam Powell            mSlideOffset = mCanSlide && mPreservedOpenState ? 1.f : 0.f;
677d44315a54e002b20365189f03a09011f2bf6ba07Adam Powell        }
678d44315a54e002b20365189f03a09011f2bf6ba07Adam Powell
67997341bdc5bea1d7bf777de65228039142d249f38Adam Powell        for (int i = 0; i < childCount; i++) {
68097341bdc5bea1d7bf777de65228039142d249f38Adam Powell            final View child = getChildAt(i);
6810eefe9ad0819b223006533cbc79a35d66684af32Adam Powell
6820eefe9ad0819b223006533cbc79a35d66684af32Adam Powell            if (child.getVisibility() == GONE) {
6830eefe9ad0819b223006533cbc79a35d66684af32Adam Powell                continue;
6840eefe9ad0819b223006533cbc79a35d66684af32Adam Powell            }
6850eefe9ad0819b223006533cbc79a35d66684af32Adam Powell
68697341bdc5bea1d7bf777de65228039142d249f38Adam Powell            final LayoutParams lp = (LayoutParams) child.getLayoutParams();
68797341bdc5bea1d7bf777de65228039142d249f38Adam Powell
68897341bdc5bea1d7bf777de65228039142d249f38Adam Powell            final int childWidth = child.getMeasuredWidth();
6896debd2bbcae1cd285d2e21db633998b7801f9f40Adam Powell            int offset = 0;
69097341bdc5bea1d7bf777de65228039142d249f38Adam Powell
6910eefe9ad0819b223006533cbc79a35d66684af32Adam Powell            if (lp.slideable) {
6926debd2bbcae1cd285d2e21db633998b7801f9f40Adam Powell                final int margin = lp.leftMargin + lp.rightMargin;
6936debd2bbcae1cd285d2e21db633998b7801f9f40Adam Powell                final int range = Math.min(nextXStart,
69419780f88506df4aeb57456fd6747af1b6848a11cfafaisland                        width - paddingEnd - mOverhangSize) - xStart - margin;
6950eefe9ad0819b223006533cbc79a35d66684af32Adam Powell                mSlideRange = range;
69619780f88506df4aeb57456fd6747af1b6848a11cfafaisland                final int lpMargin = isLayoutRtl ? lp.rightMargin : lp.leftMargin;
69719780f88506df4aeb57456fd6747af1b6848a11cfafaisland                lp.dimWhenOffset = xStart + lpMargin + range + childWidth / 2 >
69819780f88506df4aeb57456fd6747af1b6848a11cfafaisland                        width - paddingEnd;
699ed97d103ed92fece435d8bf24398ecd2c2a5d02aMark Wagner                final int pos = (int) (range * mSlideOffset);
70019780f88506df4aeb57456fd6747af1b6848a11cfafaisland                xStart += pos + lpMargin;
701ed97d103ed92fece435d8bf24398ecd2c2a5d02aMark Wagner                mSlideOffset = (float) pos / mSlideRange;
702dc56c78a7e2d06c9aabd3e90448c81671d8c05b1Adam Powell            } else if (mCanSlide && mParallaxBy != 0) {
7030eefe9ad0819b223006533cbc79a35d66684af32Adam Powell                offset = (int) ((1 - mSlideOffset) * mParallaxBy);
7046debd2bbcae1cd285d2e21db633998b7801f9f40Adam Powell                xStart = nextXStart;
70597341bdc5bea1d7bf777de65228039142d249f38Adam Powell            } else {
70697341bdc5bea1d7bf777de65228039142d249f38Adam Powell                xStart = nextXStart;
70797341bdc5bea1d7bf777de65228039142d249f38Adam Powell            }
70897341bdc5bea1d7bf777de65228039142d249f38Adam Powell
70919780f88506df4aeb57456fd6747af1b6848a11cfafaisland            final int childRight;
71019780f88506df4aeb57456fd6747af1b6848a11cfafaisland            final int childLeft;
71119780f88506df4aeb57456fd6747af1b6848a11cfafaisland            if (isLayoutRtl) {
71219780f88506df4aeb57456fd6747af1b6848a11cfafaisland                childRight = width - xStart + offset;
71319780f88506df4aeb57456fd6747af1b6848a11cfafaisland                childLeft = childRight - childWidth;
71419780f88506df4aeb57456fd6747af1b6848a11cfafaisland            } else {
71519780f88506df4aeb57456fd6747af1b6848a11cfafaisland                childLeft = xStart - offset;
71619780f88506df4aeb57456fd6747af1b6848a11cfafaisland                childRight = childLeft + childWidth;
71719780f88506df4aeb57456fd6747af1b6848a11cfafaisland            }
71819780f88506df4aeb57456fd6747af1b6848a11cfafaisland
71997341bdc5bea1d7bf777de65228039142d249f38Adam Powell            final int childTop = paddingTop;
72097341bdc5bea1d7bf777de65228039142d249f38Adam Powell            final int childBottom = childTop + child.getMeasuredHeight();
72197341bdc5bea1d7bf777de65228039142d249f38Adam Powell            child.layout(childLeft, paddingTop, childRight, childBottom);
72297341bdc5bea1d7bf777de65228039142d249f38Adam Powell
7236debd2bbcae1cd285d2e21db633998b7801f9f40Adam Powell            nextXStart += child.getWidth();
72497341bdc5bea1d7bf777de65228039142d249f38Adam Powell        }
72589e17886e6149bddfdb08a242c9e88889596419cAdam Powell
72658898b639b18392580694bc6c902479274331bf2Adam Powell        if (mFirstLayout) {
72758898b639b18392580694bc6c902479274331bf2Adam Powell            if (mCanSlide) {
72858898b639b18392580694bc6c902479274331bf2Adam Powell                if (mParallaxBy != 0) {
72958898b639b18392580694bc6c902479274331bf2Adam Powell                    parallaxOtherViews(mSlideOffset);
73058898b639b18392580694bc6c902479274331bf2Adam Powell                }
73158898b639b18392580694bc6c902479274331bf2Adam Powell                if (((LayoutParams) mSlideableView.getLayoutParams()).dimWhenOffset) {
73258898b639b18392580694bc6c902479274331bf2Adam Powell                    dimChildView(mSlideableView, mSlideOffset, mSliderFadeColor);
73358898b639b18392580694bc6c902479274331bf2Adam Powell                }
73458898b639b18392580694bc6c902479274331bf2Adam Powell            } else {
73558898b639b18392580694bc6c902479274331bf2Adam Powell                // Reset the dim level of all children; it's irrelevant when nothing moves.
73658898b639b18392580694bc6c902479274331bf2Adam Powell                for (int i = 0; i < childCount; i++) {
73758898b639b18392580694bc6c902479274331bf2Adam Powell                    dimChildView(getChildAt(i), 0, mSliderFadeColor);
73858898b639b18392580694bc6c902479274331bf2Adam Powell                }
73989e17886e6149bddfdb08a242c9e88889596419cAdam Powell            }
740c89f53833f1e272d32f7928837f0704fa33be309Adam Powell            updateObscuredViewsVisibility(mSlideableView);
74189e17886e6149bddfdb08a242c9e88889596419cAdam Powell        }
74289e17886e6149bddfdb08a242c9e88889596419cAdam Powell
74389e17886e6149bddfdb08a242c9e88889596419cAdam Powell        mFirstLayout = false;
74489e17886e6149bddfdb08a242c9e88889596419cAdam Powell    }
74589e17886e6149bddfdb08a242c9e88889596419cAdam Powell
74689e17886e6149bddfdb08a242c9e88889596419cAdam Powell    @Override
74789e17886e6149bddfdb08a242c9e88889596419cAdam Powell    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
74889e17886e6149bddfdb08a242c9e88889596419cAdam Powell        super.onSizeChanged(w, h, oldw, oldh);
74989e17886e6149bddfdb08a242c9e88889596419cAdam Powell        // Recalculate sliding panes and their details
75072c7316b081c3134f7b0566f703dfee7c970eadeAdam Powell        if (w != oldw) {
75172c7316b081c3134f7b0566f703dfee7c970eadeAdam Powell            mFirstLayout = true;
75272c7316b081c3134f7b0566f703dfee7c970eadeAdam Powell        }
75389e17886e6149bddfdb08a242c9e88889596419cAdam Powell    }
75489e17886e6149bddfdb08a242c9e88889596419cAdam Powell
75589e17886e6149bddfdb08a242c9e88889596419cAdam Powell    @Override
75689e17886e6149bddfdb08a242c9e88889596419cAdam Powell    public void requestChildFocus(View child, View focused) {
75789e17886e6149bddfdb08a242c9e88889596419cAdam Powell        super.requestChildFocus(child, focused);
75889e17886e6149bddfdb08a242c9e88889596419cAdam Powell        if (!isInTouchMode() && !mCanSlide) {
75989e17886e6149bddfdb08a242c9e88889596419cAdam Powell            mPreservedOpenState = child == mSlideableView;
76089e17886e6149bddfdb08a242c9e88889596419cAdam Powell        }
76197341bdc5bea1d7bf777de65228039142d249f38Adam Powell    }
76297341bdc5bea1d7bf777de65228039142d249f38Adam Powell
76397341bdc5bea1d7bf777de65228039142d249f38Adam Powell    @Override
76497341bdc5bea1d7bf777de65228039142d249f38Adam Powell    public boolean onInterceptTouchEvent(MotionEvent ev) {
76589e17886e6149bddfdb08a242c9e88889596419cAdam Powell        final int action = MotionEventCompat.getActionMasked(ev);
76689e17886e6149bddfdb08a242c9e88889596419cAdam Powell
76789e17886e6149bddfdb08a242c9e88889596419cAdam Powell        // Preserve the open state based on the last view that was touched.
76889e17886e6149bddfdb08a242c9e88889596419cAdam Powell        if (!mCanSlide && action == MotionEvent.ACTION_DOWN && getChildCount() > 1) {
76989e17886e6149bddfdb08a242c9e88889596419cAdam Powell            // After the first things will be slideable.
77089e17886e6149bddfdb08a242c9e88889596419cAdam Powell            final View secondChild = getChildAt(1);
77189e17886e6149bddfdb08a242c9e88889596419cAdam Powell            if (secondChild != null) {
77289e17886e6149bddfdb08a242c9e88889596419cAdam Powell                mPreservedOpenState = !mDragHelper.isViewUnder(secondChild,
77389e17886e6149bddfdb08a242c9e88889596419cAdam Powell                        (int) ev.getX(), (int) ev.getY());
77489e17886e6149bddfdb08a242c9e88889596419cAdam Powell            }
77589e17886e6149bddfdb08a242c9e88889596419cAdam Powell        }
7760eefe9ad0819b223006533cbc79a35d66684af32Adam Powell
7770eefe9ad0819b223006533cbc79a35d66684af32Adam Powell        if (!mCanSlide || (mIsUnableToDrag && action != MotionEvent.ACTION_DOWN)) {
7786580cf4b7e74a2a017ed95b0dc50155b9995edebAdam Powell            mDragHelper.cancel();
77997341bdc5bea1d7bf777de65228039142d249f38Adam Powell            return super.onInterceptTouchEvent(ev);
78097341bdc5bea1d7bf777de65228039142d249f38Adam Powell        }
78197341bdc5bea1d7bf777de65228039142d249f38Adam Powell
78297341bdc5bea1d7bf777de65228039142d249f38Adam Powell        if (action == MotionEvent.ACTION_CANCEL || action == MotionEvent.ACTION_UP) {
7836580cf4b7e74a2a017ed95b0dc50155b9995edebAdam Powell            mDragHelper.cancel();
78497341bdc5bea1d7bf777de65228039142d249f38Adam Powell            return false;
78597341bdc5bea1d7bf777de65228039142d249f38Adam Powell        }
78697341bdc5bea1d7bf777de65228039142d249f38Adam Powell
78797341bdc5bea1d7bf777de65228039142d249f38Adam Powell        boolean interceptTap = false;
78897341bdc5bea1d7bf777de65228039142d249f38Adam Powell
78997341bdc5bea1d7bf777de65228039142d249f38Adam Powell        switch (action) {
7906580cf4b7e74a2a017ed95b0dc50155b9995edebAdam Powell            case MotionEvent.ACTION_DOWN: {
79197341bdc5bea1d7bf777de65228039142d249f38Adam Powell                mIsUnableToDrag = false;
7926580cf4b7e74a2a017ed95b0dc50155b9995edebAdam Powell                final float x = ev.getX();
7936580cf4b7e74a2a017ed95b0dc50155b9995edebAdam Powell                final float y = ev.getY();
794ee3f0ffb0199e295cbf48aa1a61c8ae7056526abAdam Powell                mInitialMotionX = x;
795ee3f0ffb0199e295cbf48aa1a61c8ae7056526abAdam Powell                mInitialMotionY = y;
79689e17886e6149bddfdb08a242c9e88889596419cAdam Powell
7976580cf4b7e74a2a017ed95b0dc50155b9995edebAdam Powell                if (mDragHelper.isViewUnder(mSlideableView, (int) x, (int) y) &&
7981d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell                        isDimmed(mSlideableView)) {
799c56ba65d20be8742ff717907a3a2cd81dd0e5f3cAdam Powell                    interceptTap = true;
80097341bdc5bea1d7bf777de65228039142d249f38Adam Powell                }
80197341bdc5bea1d7bf777de65228039142d249f38Adam Powell                break;
80297341bdc5bea1d7bf777de65228039142d249f38Adam Powell            }
80329836199390f71d05b15eedb487c1f7465776f1dAdam Powell
80429836199390f71d05b15eedb487c1f7465776f1dAdam Powell            case MotionEvent.ACTION_MOVE: {
80529836199390f71d05b15eedb487c1f7465776f1dAdam Powell                final float x = ev.getX();
80629836199390f71d05b15eedb487c1f7465776f1dAdam Powell                final float y = ev.getY();
80729836199390f71d05b15eedb487c1f7465776f1dAdam Powell                final float adx = Math.abs(x - mInitialMotionX);
80829836199390f71d05b15eedb487c1f7465776f1dAdam Powell                final float ady = Math.abs(y - mInitialMotionY);
80929836199390f71d05b15eedb487c1f7465776f1dAdam Powell                final int slop = mDragHelper.getTouchSlop();
81029836199390f71d05b15eedb487c1f7465776f1dAdam Powell                if (adx > slop && ady > adx) {
81129836199390f71d05b15eedb487c1f7465776f1dAdam Powell                    mDragHelper.cancel();
81229836199390f71d05b15eedb487c1f7465776f1dAdam Powell                    mIsUnableToDrag = true;
81329836199390f71d05b15eedb487c1f7465776f1dAdam Powell                    return false;
81429836199390f71d05b15eedb487c1f7465776f1dAdam Powell                }
81529836199390f71d05b15eedb487c1f7465776f1dAdam Powell            }
81697341bdc5bea1d7bf777de65228039142d249f38Adam Powell        }
81797341bdc5bea1d7bf777de65228039142d249f38Adam Powell
81829836199390f71d05b15eedb487c1f7465776f1dAdam Powell        final boolean interceptForDrag = mDragHelper.shouldInterceptTouchEvent(ev);
81929836199390f71d05b15eedb487c1f7465776f1dAdam Powell
820c56ba65d20be8742ff717907a3a2cd81dd0e5f3cAdam Powell        return interceptForDrag || interceptTap;
82197341bdc5bea1d7bf777de65228039142d249f38Adam Powell    }
82297341bdc5bea1d7bf777de65228039142d249f38Adam Powell
82397341bdc5bea1d7bf777de65228039142d249f38Adam Powell    @Override
82497341bdc5bea1d7bf777de65228039142d249f38Adam Powell    public boolean onTouchEvent(MotionEvent ev) {
82597341bdc5bea1d7bf777de65228039142d249f38Adam Powell        if (!mCanSlide) {
82697341bdc5bea1d7bf777de65228039142d249f38Adam Powell            return super.onTouchEvent(ev);
82797341bdc5bea1d7bf777de65228039142d249f38Adam Powell        }
82897341bdc5bea1d7bf777de65228039142d249f38Adam Powell
829c56ba65d20be8742ff717907a3a2cd81dd0e5f3cAdam Powell        mDragHelper.processTouchEvent(ev);
83097341bdc5bea1d7bf777de65228039142d249f38Adam Powell
83197341bdc5bea1d7bf777de65228039142d249f38Adam Powell        final int action = ev.getAction();
8326debd2bbcae1cd285d2e21db633998b7801f9f40Adam Powell        boolean wantTouchEvents = true;
83397341bdc5bea1d7bf777de65228039142d249f38Adam Powell
83497341bdc5bea1d7bf777de65228039142d249f38Adam Powell        switch (action & MotionEventCompat.ACTION_MASK) {
83597341bdc5bea1d7bf777de65228039142d249f38Adam Powell            case MotionEvent.ACTION_DOWN: {
83697341bdc5bea1d7bf777de65228039142d249f38Adam Powell                final float x = ev.getX();
83797341bdc5bea1d7bf777de65228039142d249f38Adam Powell                final float y = ev.getY();
838ee3f0ffb0199e295cbf48aa1a61c8ae7056526abAdam Powell                mInitialMotionX = x;
839ee3f0ffb0199e295cbf48aa1a61c8ae7056526abAdam Powell                mInitialMotionY = y;
84097341bdc5bea1d7bf777de65228039142d249f38Adam Powell                break;
84197341bdc5bea1d7bf777de65228039142d249f38Adam Powell            }
84297341bdc5bea1d7bf777de65228039142d249f38Adam Powell
84397341bdc5bea1d7bf777de65228039142d249f38Adam Powell            case MotionEvent.ACTION_UP: {
844ee3f0ffb0199e295cbf48aa1a61c8ae7056526abAdam Powell                if (isDimmed(mSlideableView)) {
8456580cf4b7e74a2a017ed95b0dc50155b9995edebAdam Powell                    final float x = ev.getX();
8466580cf4b7e74a2a017ed95b0dc50155b9995edebAdam Powell                    final float y = ev.getY();
847ee3f0ffb0199e295cbf48aa1a61c8ae7056526abAdam Powell                    final float dx = x - mInitialMotionX;
848ee3f0ffb0199e295cbf48aa1a61c8ae7056526abAdam Powell                    final float dy = y - mInitialMotionY;
8491d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell                    final int slop = mDragHelper.getTouchSlop();
8501d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell                    if (dx * dx + dy * dy < slop * slop &&
8516580cf4b7e74a2a017ed95b0dc50155b9995edebAdam Powell                            mDragHelper.isViewUnder(mSlideableView, (int) x, (int) y)) {
852ee3f0ffb0199e295cbf48aa1a61c8ae7056526abAdam Powell                        // Taps close a dimmed open pane.
853ee3f0ffb0199e295cbf48aa1a61c8ae7056526abAdam Powell                        closePane(mSlideableView, 0);
854ee3f0ffb0199e295cbf48aa1a61c8ae7056526abAdam Powell                        break;
855ee3f0ffb0199e295cbf48aa1a61c8ae7056526abAdam Powell                    }
856ee3f0ffb0199e295cbf48aa1a61c8ae7056526abAdam Powell                }
85797341bdc5bea1d7bf777de65228039142d249f38Adam Powell                break;
85897341bdc5bea1d7bf777de65228039142d249f38Adam Powell            }
85997341bdc5bea1d7bf777de65228039142d249f38Adam Powell        }
86097341bdc5bea1d7bf777de65228039142d249f38Adam Powell
86197341bdc5bea1d7bf777de65228039142d249f38Adam Powell        return wantTouchEvents;
86297341bdc5bea1d7bf777de65228039142d249f38Adam Powell    }
86397341bdc5bea1d7bf777de65228039142d249f38Adam Powell
86489e17886e6149bddfdb08a242c9e88889596419cAdam Powell    private boolean closePane(View pane, int initialVelocity) {
86589e17886e6149bddfdb08a242c9e88889596419cAdam Powell        if (mFirstLayout || smoothSlideTo(0.f, initialVelocity)) {
86689e17886e6149bddfdb08a242c9e88889596419cAdam Powell            mPreservedOpenState = false;
86789e17886e6149bddfdb08a242c9e88889596419cAdam Powell            return true;
8680eefe9ad0819b223006533cbc79a35d66684af32Adam Powell        }
86989e17886e6149bddfdb08a242c9e88889596419cAdam Powell        return false;
87097341bdc5bea1d7bf777de65228039142d249f38Adam Powell    }
87197341bdc5bea1d7bf777de65228039142d249f38Adam Powell
87289e17886e6149bddfdb08a242c9e88889596419cAdam Powell    private boolean openPane(View pane, int initialVelocity) {
87389e17886e6149bddfdb08a242c9e88889596419cAdam Powell        if (mFirstLayout || smoothSlideTo(1.f, initialVelocity)) {
87489e17886e6149bddfdb08a242c9e88889596419cAdam Powell            mPreservedOpenState = true;
87589e17886e6149bddfdb08a242c9e88889596419cAdam Powell            return true;
8760eefe9ad0819b223006533cbc79a35d66684af32Adam Powell        }
87789e17886e6149bddfdb08a242c9e88889596419cAdam Powell        return false;
87897341bdc5bea1d7bf777de65228039142d249f38Adam Powell    }
87997341bdc5bea1d7bf777de65228039142d249f38Adam Powell
88097341bdc5bea1d7bf777de65228039142d249f38Adam Powell    /**
88189e17886e6149bddfdb08a242c9e88889596419cAdam Powell     * @deprecated Renamed to {@link #openPane()} - this method is going away soon!
88297341bdc5bea1d7bf777de65228039142d249f38Adam Powell     */
88389e17886e6149bddfdb08a242c9e88889596419cAdam Powell    @Deprecated
88497341bdc5bea1d7bf777de65228039142d249f38Adam Powell    public void smoothSlideOpen() {
88589e17886e6149bddfdb08a242c9e88889596419cAdam Powell        openPane();
88689e17886e6149bddfdb08a242c9e88889596419cAdam Powell    }
88789e17886e6149bddfdb08a242c9e88889596419cAdam Powell
88889e17886e6149bddfdb08a242c9e88889596419cAdam Powell    /**
88989e17886e6149bddfdb08a242c9e88889596419cAdam Powell     * Open the sliding pane if it is currently slideable. If first layout
89089e17886e6149bddfdb08a242c9e88889596419cAdam Powell     * has already completed this will animate.
89189e17886e6149bddfdb08a242c9e88889596419cAdam Powell     *
89289e17886e6149bddfdb08a242c9e88889596419cAdam Powell     * @return true if the pane was slideable and is now open/in the process of opening
89389e17886e6149bddfdb08a242c9e88889596419cAdam Powell     */
89489e17886e6149bddfdb08a242c9e88889596419cAdam Powell    public boolean openPane() {
89589e17886e6149bddfdb08a242c9e88889596419cAdam Powell        return openPane(mSlideableView, 0);
89697341bdc5bea1d7bf777de65228039142d249f38Adam Powell    }
89797341bdc5bea1d7bf777de65228039142d249f38Adam Powell
89897341bdc5bea1d7bf777de65228039142d249f38Adam Powell    /**
89989e17886e6149bddfdb08a242c9e88889596419cAdam Powell     * @deprecated Renamed to {@link #closePane()} - this method is going away soon!
90097341bdc5bea1d7bf777de65228039142d249f38Adam Powell     */
90189e17886e6149bddfdb08a242c9e88889596419cAdam Powell    @Deprecated
90297341bdc5bea1d7bf777de65228039142d249f38Adam Powell    public void smoothSlideClosed() {
90389e17886e6149bddfdb08a242c9e88889596419cAdam Powell        closePane();
90489e17886e6149bddfdb08a242c9e88889596419cAdam Powell    }
90589e17886e6149bddfdb08a242c9e88889596419cAdam Powell
90689e17886e6149bddfdb08a242c9e88889596419cAdam Powell    /**
90789e17886e6149bddfdb08a242c9e88889596419cAdam Powell     * Close the sliding pane if it is currently slideable. If first layout
90889e17886e6149bddfdb08a242c9e88889596419cAdam Powell     * has already completed this will animate.
90989e17886e6149bddfdb08a242c9e88889596419cAdam Powell     *
91089e17886e6149bddfdb08a242c9e88889596419cAdam Powell     * @return true if the pane was slideable and is now closed/in the process of closing
91189e17886e6149bddfdb08a242c9e88889596419cAdam Powell     */
91289e17886e6149bddfdb08a242c9e88889596419cAdam Powell    public boolean closePane() {
91389e17886e6149bddfdb08a242c9e88889596419cAdam Powell        return closePane(mSlideableView, 0);
91497341bdc5bea1d7bf777de65228039142d249f38Adam Powell    }
91597341bdc5bea1d7bf777de65228039142d249f38Adam Powell
91697341bdc5bea1d7bf777de65228039142d249f38Adam Powell    /**
91789e17886e6149bddfdb08a242c9e88889596419cAdam Powell     * Check if the layout is completely open. It can be open either because the slider
91889e17886e6149bddfdb08a242c9e88889596419cAdam Powell     * itself is open revealing the left pane, or if all content fits without sliding.
91989e17886e6149bddfdb08a242c9e88889596419cAdam Powell     *
92097341bdc5bea1d7bf777de65228039142d249f38Adam Powell     * @return true if sliding panels are completely open
92197341bdc5bea1d7bf777de65228039142d249f38Adam Powell     */
92297341bdc5bea1d7bf777de65228039142d249f38Adam Powell    public boolean isOpen() {
9230eefe9ad0819b223006533cbc79a35d66684af32Adam Powell        return !mCanSlide || mSlideOffset == 1;
92497341bdc5bea1d7bf777de65228039142d249f38Adam Powell    }
92597341bdc5bea1d7bf777de65228039142d249f38Adam Powell
92697341bdc5bea1d7bf777de65228039142d249f38Adam Powell    /**
92797341bdc5bea1d7bf777de65228039142d249f38Adam Powell     * @return true if content in this layout can be slid open and closed
92889e17886e6149bddfdb08a242c9e88889596419cAdam Powell     * @deprecated Renamed to {@link #isSlideable()} - this method is going away soon!
92997341bdc5bea1d7bf777de65228039142d249f38Adam Powell     */
93089e17886e6149bddfdb08a242c9e88889596419cAdam Powell    @Deprecated
93197341bdc5bea1d7bf777de65228039142d249f38Adam Powell    public boolean canSlide() {
93297341bdc5bea1d7bf777de65228039142d249f38Adam Powell        return mCanSlide;
93397341bdc5bea1d7bf777de65228039142d249f38Adam Powell    }
93497341bdc5bea1d7bf777de65228039142d249f38Adam Powell
93589e17886e6149bddfdb08a242c9e88889596419cAdam Powell    /**
93689e17886e6149bddfdb08a242c9e88889596419cAdam Powell     * Check if the content in this layout cannot fully fit side by side and therefore
93789e17886e6149bddfdb08a242c9e88889596419cAdam Powell     * the content pane can be slid back and forth.
93889e17886e6149bddfdb08a242c9e88889596419cAdam Powell     *
93989e17886e6149bddfdb08a242c9e88889596419cAdam Powell     * @return true if content in this layout can be slid open and closed
94089e17886e6149bddfdb08a242c9e88889596419cAdam Powell     */
94189e17886e6149bddfdb08a242c9e88889596419cAdam Powell    public boolean isSlideable() {
94289e17886e6149bddfdb08a242c9e88889596419cAdam Powell        return mCanSlide;
94389e17886e6149bddfdb08a242c9e88889596419cAdam Powell    }
94489e17886e6149bddfdb08a242c9e88889596419cAdam Powell
945d44315a54e002b20365189f03a09011f2bf6ba07Adam Powell    private void onPanelDragged(int newLeft) {
946a7f2dd4b8892a97edbe90470dcd20504d4131e5fAdam Powell        if (mSlideableView == null) {
947a7f2dd4b8892a97edbe90470dcd20504d4131e5fAdam Powell            // This can happen if we're aborting motion during layout because everything now fits.
948a7f2dd4b8892a97edbe90470dcd20504d4131e5fAdam Powell            mSlideOffset = 0;
949a7f2dd4b8892a97edbe90470dcd20504d4131e5fAdam Powell            return;
950a7f2dd4b8892a97edbe90470dcd20504d4131e5fAdam Powell        }
95119780f88506df4aeb57456fd6747af1b6848a11cfafaisland        final boolean isLayoutRtl = isLayoutRtlSupport();
9520eefe9ad0819b223006533cbc79a35d66684af32Adam Powell        final LayoutParams lp = (LayoutParams) mSlideableView.getLayoutParams();
95397341bdc5bea1d7bf777de65228039142d249f38Adam Powell
95419780f88506df4aeb57456fd6747af1b6848a11cfafaisland        int childWidth = mSlideableView.getWidth();
95519780f88506df4aeb57456fd6747af1b6848a11cfafaisland        final int newStart = isLayoutRtl ? getWidth() - newLeft - childWidth : newLeft;
95619780f88506df4aeb57456fd6747af1b6848a11cfafaisland
95719780f88506df4aeb57456fd6747af1b6848a11cfafaisland        final int paddingStart = isLayoutRtl ? getPaddingRight() : getPaddingLeft();
95819780f88506df4aeb57456fd6747af1b6848a11cfafaisland        final int lpMargin = isLayoutRtl ? lp.rightMargin : lp.leftMargin;
95919780f88506df4aeb57456fd6747af1b6848a11cfafaisland        final int startBound = paddingStart + lpMargin;
96019780f88506df4aeb57456fd6747af1b6848a11cfafaisland
96119780f88506df4aeb57456fd6747af1b6848a11cfafaisland        mSlideOffset = (float) (newStart - startBound) / mSlideRange;
96297341bdc5bea1d7bf777de65228039142d249f38Adam Powell
9636debd2bbcae1cd285d2e21db633998b7801f9f40Adam Powell        if (mParallaxBy != 0) {
9640eefe9ad0819b223006533cbc79a35d66684af32Adam Powell            parallaxOtherViews(mSlideOffset);
9656debd2bbcae1cd285d2e21db633998b7801f9f40Adam Powell        }
9666debd2bbcae1cd285d2e21db633998b7801f9f40Adam Powell
967ee3f0ffb0199e295cbf48aa1a61c8ae7056526abAdam Powell        if (lp.dimWhenOffset) {
96881e2f002d1b4ebf2d951eb9f239858b8a9481a24Adam Powell            dimChildView(mSlideableView, mSlideOffset, mSliderFadeColor);
969ee3f0ffb0199e295cbf48aa1a61c8ae7056526abAdam Powell        }
9700eefe9ad0819b223006533cbc79a35d66684af32Adam Powell        dispatchOnPanelSlide(mSlideableView);
97197341bdc5bea1d7bf777de65228039142d249f38Adam Powell    }
97297341bdc5bea1d7bf777de65228039142d249f38Adam Powell
97381e2f002d1b4ebf2d951eb9f239858b8a9481a24Adam Powell    private void dimChildView(View v, float mag, int fadeColor) {
97497341bdc5bea1d7bf777de65228039142d249f38Adam Powell        final LayoutParams lp = (LayoutParams) v.getLayoutParams();
97597341bdc5bea1d7bf777de65228039142d249f38Adam Powell
97681e2f002d1b4ebf2d951eb9f239858b8a9481a24Adam Powell        if (mag > 0 && fadeColor != 0) {
97781e2f002d1b4ebf2d951eb9f239858b8a9481a24Adam Powell            final int baseAlpha = (fadeColor & 0xff000000) >>> 24;
978ee3f0ffb0199e295cbf48aa1a61c8ae7056526abAdam Powell            int imag = (int) (baseAlpha * mag);
97981e2f002d1b4ebf2d951eb9f239858b8a9481a24Adam Powell            int color = imag << 24 | (fadeColor & 0xffffff);
98097341bdc5bea1d7bf777de65228039142d249f38Adam Powell            if (lp.dimPaint == null) {
98197341bdc5bea1d7bf777de65228039142d249f38Adam Powell                lp.dimPaint = new Paint();
98297341bdc5bea1d7bf777de65228039142d249f38Adam Powell            }
983ee3f0ffb0199e295cbf48aa1a61c8ae7056526abAdam Powell            lp.dimPaint.setColorFilter(new PorterDuffColorFilter(color, PorterDuff.Mode.SRC_OVER));
98497341bdc5bea1d7bf777de65228039142d249f38Adam Powell            if (ViewCompat.getLayerType(v) != ViewCompat.LAYER_TYPE_HARDWARE) {
98597341bdc5bea1d7bf777de65228039142d249f38Adam Powell                ViewCompat.setLayerType(v, ViewCompat.LAYER_TYPE_HARDWARE, lp.dimPaint);
98697341bdc5bea1d7bf777de65228039142d249f38Adam Powell            }
98797341bdc5bea1d7bf777de65228039142d249f38Adam Powell            invalidateChildRegion(v);
98897341bdc5bea1d7bf777de65228039142d249f38Adam Powell        } else if (ViewCompat.getLayerType(v) != ViewCompat.LAYER_TYPE_NONE) {
98958898b639b18392580694bc6c902479274331bf2Adam Powell            if (lp.dimPaint != null) {
99058898b639b18392580694bc6c902479274331bf2Adam Powell                lp.dimPaint.setColorFilter(null);
99158898b639b18392580694bc6c902479274331bf2Adam Powell            }
992f4445e06a8490b056cd892c4bc640dfd17905d6cAdam Powell            final DisableLayerRunnable dlr = new DisableLayerRunnable(v);
993f4445e06a8490b056cd892c4bc640dfd17905d6cAdam Powell            mPostedRunnables.add(dlr);
994f4445e06a8490b056cd892c4bc640dfd17905d6cAdam Powell            ViewCompat.postOnAnimation(this, dlr);
99597341bdc5bea1d7bf777de65228039142d249f38Adam Powell        }
99697341bdc5bea1d7bf777de65228039142d249f38Adam Powell    }
99797341bdc5bea1d7bf777de65228039142d249f38Adam Powell
99897341bdc5bea1d7bf777de65228039142d249f38Adam Powell    @Override
99997341bdc5bea1d7bf777de65228039142d249f38Adam Powell    protected boolean drawChild(Canvas canvas, View child, long drawingTime) {
10001e43161e9e1f1dc10637a68d5c2304c1f95c9c46Adam Powell        final LayoutParams lp = (LayoutParams) child.getLayoutParams();
10011e43161e9e1f1dc10637a68d5c2304c1f95c9c46Adam Powell        boolean result;
10021e43161e9e1f1dc10637a68d5c2304c1f95c9c46Adam Powell        final int save = canvas.save(Canvas.CLIP_SAVE_FLAG);
10031e43161e9e1f1dc10637a68d5c2304c1f95c9c46Adam Powell
10041e43161e9e1f1dc10637a68d5c2304c1f95c9c46Adam Powell        if (mCanSlide && !lp.slideable && mSlideableView != null) {
10051e43161e9e1f1dc10637a68d5c2304c1f95c9c46Adam Powell            // Clip against the slider; no sense drawing what will immediately be covered.
10061e43161e9e1f1dc10637a68d5c2304c1f95c9c46Adam Powell            canvas.getClipBounds(mTmpRect);
100719780f88506df4aeb57456fd6747af1b6848a11cfafaisland            if (isLayoutRtlSupport()) {
100819780f88506df4aeb57456fd6747af1b6848a11cfafaisland                mTmpRect.left = Math.max(mTmpRect.left, mSlideableView.getRight());
100919780f88506df4aeb57456fd6747af1b6848a11cfafaisland            } else {
101019780f88506df4aeb57456fd6747af1b6848a11cfafaisland                mTmpRect.right = Math.min(mTmpRect.right, mSlideableView.getLeft());
101119780f88506df4aeb57456fd6747af1b6848a11cfafaisland            }
10121e43161e9e1f1dc10637a68d5c2304c1f95c9c46Adam Powell            canvas.clipRect(mTmpRect);
101397341bdc5bea1d7bf777de65228039142d249f38Adam Powell        }
101497341bdc5bea1d7bf777de65228039142d249f38Adam Powell
10151e43161e9e1f1dc10637a68d5c2304c1f95c9c46Adam Powell        if (Build.VERSION.SDK_INT >= 11) { // HC
10161e43161e9e1f1dc10637a68d5c2304c1f95c9c46Adam Powell            result = super.drawChild(canvas, child, drawingTime);
101797341bdc5bea1d7bf777de65228039142d249f38Adam Powell        } else {
10181e43161e9e1f1dc10637a68d5c2304c1f95c9c46Adam Powell            if (lp.dimWhenOffset && mSlideOffset > 0) {
10191e43161e9e1f1dc10637a68d5c2304c1f95c9c46Adam Powell                if (!child.isDrawingCacheEnabled()) {
10201e43161e9e1f1dc10637a68d5c2304c1f95c9c46Adam Powell                    child.setDrawingCacheEnabled(true);
10211e43161e9e1f1dc10637a68d5c2304c1f95c9c46Adam Powell                }
10221e43161e9e1f1dc10637a68d5c2304c1f95c9c46Adam Powell                final Bitmap cache = child.getDrawingCache();
1023b5a259b30fd4646294ac4d7ea00bd041406b07eeAdam Powell                if (cache != null) {
1024b5a259b30fd4646294ac4d7ea00bd041406b07eeAdam Powell                    canvas.drawBitmap(cache, child.getLeft(), child.getTop(), lp.dimPaint);
1025b5a259b30fd4646294ac4d7ea00bd041406b07eeAdam Powell                    result = false;
1026b5a259b30fd4646294ac4d7ea00bd041406b07eeAdam Powell                } else {
1027b5a259b30fd4646294ac4d7ea00bd041406b07eeAdam Powell                    Log.e(TAG, "drawChild: child view " + child + " returned null drawing cache");
1028b5a259b30fd4646294ac4d7ea00bd041406b07eeAdam Powell                    result = super.drawChild(canvas, child, drawingTime);
1029b5a259b30fd4646294ac4d7ea00bd041406b07eeAdam Powell                }
10301e43161e9e1f1dc10637a68d5c2304c1f95c9c46Adam Powell            } else {
10311e43161e9e1f1dc10637a68d5c2304c1f95c9c46Adam Powell                if (child.isDrawingCacheEnabled()) {
10321e43161e9e1f1dc10637a68d5c2304c1f95c9c46Adam Powell                    child.setDrawingCacheEnabled(false);
10331e43161e9e1f1dc10637a68d5c2304c1f95c9c46Adam Powell                }
10341e43161e9e1f1dc10637a68d5c2304c1f95c9c46Adam Powell                result = super.drawChild(canvas, child, drawingTime);
103597341bdc5bea1d7bf777de65228039142d249f38Adam Powell            }
103697341bdc5bea1d7bf777de65228039142d249f38Adam Powell        }
10371e43161e9e1f1dc10637a68d5c2304c1f95c9c46Adam Powell
10381e43161e9e1f1dc10637a68d5c2304c1f95c9c46Adam Powell        canvas.restoreToCount(save);
10391e43161e9e1f1dc10637a68d5c2304c1f95c9c46Adam Powell
10401e43161e9e1f1dc10637a68d5c2304c1f95c9c46Adam Powell        return result;
104197341bdc5bea1d7bf777de65228039142d249f38Adam Powell    }
104297341bdc5bea1d7bf777de65228039142d249f38Adam Powell
104397341bdc5bea1d7bf777de65228039142d249f38Adam Powell    private void invalidateChildRegion(View v) {
104497341bdc5bea1d7bf777de65228039142d249f38Adam Powell        IMPL.invalidateChildRegion(this, v);
104597341bdc5bea1d7bf777de65228039142d249f38Adam Powell    }
104697341bdc5bea1d7bf777de65228039142d249f38Adam Powell
104797341bdc5bea1d7bf777de65228039142d249f38Adam Powell    /**
104897341bdc5bea1d7bf777de65228039142d249f38Adam Powell     * Smoothly animate mDraggingPane to the target X position within its range.
104997341bdc5bea1d7bf777de65228039142d249f38Adam Powell     *
105097341bdc5bea1d7bf777de65228039142d249f38Adam Powell     * @param slideOffset position to animate to
105197341bdc5bea1d7bf777de65228039142d249f38Adam Powell     * @param velocity initial velocity in case of fling, or 0.
105297341bdc5bea1d7bf777de65228039142d249f38Adam Powell     */
105389e17886e6149bddfdb08a242c9e88889596419cAdam Powell    boolean smoothSlideTo(float slideOffset, int velocity) {
10540eefe9ad0819b223006533cbc79a35d66684af32Adam Powell        if (!mCanSlide) {
105597341bdc5bea1d7bf777de65228039142d249f38Adam Powell            // Nothing to do.
105689e17886e6149bddfdb08a242c9e88889596419cAdam Powell            return false;
105797341bdc5bea1d7bf777de65228039142d249f38Adam Powell        }
105897341bdc5bea1d7bf777de65228039142d249f38Adam Powell
105919780f88506df4aeb57456fd6747af1b6848a11cfafaisland        final boolean isLayoutRtl = isLayoutRtlSupport();
10600eefe9ad0819b223006533cbc79a35d66684af32Adam Powell        final LayoutParams lp = (LayoutParams) mSlideableView.getLayoutParams();
106197341bdc5bea1d7bf777de65228039142d249f38Adam Powell
106219780f88506df4aeb57456fd6747af1b6848a11cfafaisland        int x;
106319780f88506df4aeb57456fd6747af1b6848a11cfafaisland        if (isLayoutRtl) {
106419780f88506df4aeb57456fd6747af1b6848a11cfafaisland            int startBound = getPaddingRight() + lp.rightMargin;
106519780f88506df4aeb57456fd6747af1b6848a11cfafaisland            int childWidth = mSlideableView.getWidth();
106619780f88506df4aeb57456fd6747af1b6848a11cfafaisland            x = (int) (getWidth() - (startBound + slideOffset * mSlideRange + childWidth));
106719780f88506df4aeb57456fd6747af1b6848a11cfafaisland        } else {
106819780f88506df4aeb57456fd6747af1b6848a11cfafaisland            int startBound = getPaddingLeft() + lp.leftMargin;
106919780f88506df4aeb57456fd6747af1b6848a11cfafaisland            x = (int) (startBound + slideOffset * mSlideRange);
107019780f88506df4aeb57456fd6747af1b6848a11cfafaisland        }
107197341bdc5bea1d7bf777de65228039142d249f38Adam Powell
1072c56ba65d20be8742ff717907a3a2cd81dd0e5f3cAdam Powell        if (mDragHelper.smoothSlideViewTo(mSlideableView, x, mSlideableView.getTop())) {
1073c89f53833f1e272d32f7928837f0704fa33be309Adam Powell            setAllChildrenVisible();
1074c56ba65d20be8742ff717907a3a2cd81dd0e5f3cAdam Powell            ViewCompat.postInvalidateOnAnimation(this);
107589e17886e6149bddfdb08a242c9e88889596419cAdam Powell            return true;
107697341bdc5bea1d7bf777de65228039142d249f38Adam Powell        }
107789e17886e6149bddfdb08a242c9e88889596419cAdam Powell        return false;
107897341bdc5bea1d7bf777de65228039142d249f38Adam Powell    }
107997341bdc5bea1d7bf777de65228039142d249f38Adam Powell
108097341bdc5bea1d7bf777de65228039142d249f38Adam Powell    @Override
108197341bdc5bea1d7bf777de65228039142d249f38Adam Powell    public void computeScroll() {
1082c56ba65d20be8742ff717907a3a2cd81dd0e5f3cAdam Powell        if (mDragHelper.continueSettling(true)) {
10830eefe9ad0819b223006533cbc79a35d66684af32Adam Powell            if (!mCanSlide) {
1084c56ba65d20be8742ff717907a3a2cd81dd0e5f3cAdam Powell                mDragHelper.abort();
108597341bdc5bea1d7bf777de65228039142d249f38Adam Powell                return;
108697341bdc5bea1d7bf777de65228039142d249f38Adam Powell            }
108797341bdc5bea1d7bf777de65228039142d249f38Adam Powell
108897341bdc5bea1d7bf777de65228039142d249f38Adam Powell            ViewCompat.postInvalidateOnAnimation(this);
108997341bdc5bea1d7bf777de65228039142d249f38Adam Powell        }
109097341bdc5bea1d7bf777de65228039142d249f38Adam Powell    }
109197341bdc5bea1d7bf777de65228039142d249f38Adam Powell
1092ee3f0ffb0199e295cbf48aa1a61c8ae7056526abAdam Powell    /**
109319780f88506df4aeb57456fd6747af1b6848a11cfafaisland     * @deprecated Renamed to {@link #setShadowDrawableLeft(Drawable d)} to support LTR (left to
109419780f88506df4aeb57456fd6747af1b6848a11cfafaisland     * right language) and {@link #setShadowDrawableRight(Drawable d)} to support RTL (right to left
109519780f88506df4aeb57456fd6747af1b6848a11cfafaisland     * language) during opening/closing.
109619780f88506df4aeb57456fd6747af1b6848a11cfafaisland     *
109719780f88506df4aeb57456fd6747af1b6848a11cfafaisland     * @param d drawable to use as a shadow
109819780f88506df4aeb57456fd6747af1b6848a11cfafaisland     */
109919780f88506df4aeb57456fd6747af1b6848a11cfafaisland    @Deprecated
110019780f88506df4aeb57456fd6747af1b6848a11cfafaisland    public void setShadowDrawable(Drawable d) {
110119780f88506df4aeb57456fd6747af1b6848a11cfafaisland        setShadowDrawableLeft(d);
110219780f88506df4aeb57456fd6747af1b6848a11cfafaisland    }
110319780f88506df4aeb57456fd6747af1b6848a11cfafaisland
110419780f88506df4aeb57456fd6747af1b6848a11cfafaisland    /**
1105ee3f0ffb0199e295cbf48aa1a61c8ae7056526abAdam Powell     * Set a drawable to use as a shadow cast by the right pane onto the left pane
1106ee3f0ffb0199e295cbf48aa1a61c8ae7056526abAdam Powell     * during opening/closing.
1107ee3f0ffb0199e295cbf48aa1a61c8ae7056526abAdam Powell     *
1108ee3f0ffb0199e295cbf48aa1a61c8ae7056526abAdam Powell     * @param d drawable to use as a shadow
1109ee3f0ffb0199e295cbf48aa1a61c8ae7056526abAdam Powell     */
111019780f88506df4aeb57456fd6747af1b6848a11cfafaisland    public void setShadowDrawableLeft(Drawable d) {
111119780f88506df4aeb57456fd6747af1b6848a11cfafaisland        mShadowDrawableLeft = d;
111219780f88506df4aeb57456fd6747af1b6848a11cfafaisland    }
111319780f88506df4aeb57456fd6747af1b6848a11cfafaisland
111419780f88506df4aeb57456fd6747af1b6848a11cfafaisland    /**
111519780f88506df4aeb57456fd6747af1b6848a11cfafaisland     * Set a drawable to use as a shadow cast by the left pane onto the right pane
111619780f88506df4aeb57456fd6747af1b6848a11cfafaisland     * during opening/closing to support right to left language.
111719780f88506df4aeb57456fd6747af1b6848a11cfafaisland     *
111819780f88506df4aeb57456fd6747af1b6848a11cfafaisland     * @param d drawable to use as a shadow
111919780f88506df4aeb57456fd6747af1b6848a11cfafaisland     */
112019780f88506df4aeb57456fd6747af1b6848a11cfafaisland    public void setShadowDrawableRight(Drawable d) {
112119780f88506df4aeb57456fd6747af1b6848a11cfafaisland        mShadowDrawableRight = d;
1122ee3f0ffb0199e295cbf48aa1a61c8ae7056526abAdam Powell    }
1123ee3f0ffb0199e295cbf48aa1a61c8ae7056526abAdam Powell
1124ee3f0ffb0199e295cbf48aa1a61c8ae7056526abAdam Powell    /**
1125ee3f0ffb0199e295cbf48aa1a61c8ae7056526abAdam Powell     * Set a drawable to use as a shadow cast by the right pane onto the left pane
1126ee3f0ffb0199e295cbf48aa1a61c8ae7056526abAdam Powell     * during opening/closing.
1127ee3f0ffb0199e295cbf48aa1a61c8ae7056526abAdam Powell     *
1128ee3f0ffb0199e295cbf48aa1a61c8ae7056526abAdam Powell     * @param resId Resource ID of a drawable to use
1129d805095048f6be52cddbd572ee343c4639ba8187Alan Viverette     * @deprecated Renamed to {@link #setShadowResourceLeft(int)} to support LTR (left to
1130d805095048f6be52cddbd572ee343c4639ba8187Alan Viverette     * right language) and {@link #setShadowResourceRight(int)} to support RTL (right to left
1131d805095048f6be52cddbd572ee343c4639ba8187Alan Viverette     * language) during opening/closing.
1132ee3f0ffb0199e295cbf48aa1a61c8ae7056526abAdam Powell     */
113319780f88506df4aeb57456fd6747af1b6848a11cfafaisland    @Deprecated
1134a3ff3273e976adf19770651dcf473fa67b38eb22Tor Norbye    public void setShadowResource(@DrawableRes int resId) {
1135ee3f0ffb0199e295cbf48aa1a61c8ae7056526abAdam Powell        setShadowDrawable(getResources().getDrawable(resId));
1136ee3f0ffb0199e295cbf48aa1a61c8ae7056526abAdam Powell    }
1137ee3f0ffb0199e295cbf48aa1a61c8ae7056526abAdam Powell
113819780f88506df4aeb57456fd6747af1b6848a11cfafaisland    /**
113919780f88506df4aeb57456fd6747af1b6848a11cfafaisland     * Set a drawable to use as a shadow cast by the right pane onto the left pane
114019780f88506df4aeb57456fd6747af1b6848a11cfafaisland     * during opening/closing.
114119780f88506df4aeb57456fd6747af1b6848a11cfafaisland     *
114219780f88506df4aeb57456fd6747af1b6848a11cfafaisland     * @param resId Resource ID of a drawable to use
114319780f88506df4aeb57456fd6747af1b6848a11cfafaisland     */
114419780f88506df4aeb57456fd6747af1b6848a11cfafaisland    public void setShadowResourceLeft(int resId) {
114519780f88506df4aeb57456fd6747af1b6848a11cfafaisland        setShadowDrawableLeft(getResources().getDrawable(resId));
114619780f88506df4aeb57456fd6747af1b6848a11cfafaisland    }
114719780f88506df4aeb57456fd6747af1b6848a11cfafaisland
114819780f88506df4aeb57456fd6747af1b6848a11cfafaisland    /**
114919780f88506df4aeb57456fd6747af1b6848a11cfafaisland     * Set a drawable to use as a shadow cast by the left pane onto the right pane
115019780f88506df4aeb57456fd6747af1b6848a11cfafaisland     * during opening/closing to support right to left language.
115119780f88506df4aeb57456fd6747af1b6848a11cfafaisland     *
115219780f88506df4aeb57456fd6747af1b6848a11cfafaisland     * @param resId Resource ID of a drawable to use
115319780f88506df4aeb57456fd6747af1b6848a11cfafaisland     */
115419780f88506df4aeb57456fd6747af1b6848a11cfafaisland    public void setShadowResourceRight(int resId) {
115519780f88506df4aeb57456fd6747af1b6848a11cfafaisland        setShadowDrawableRight(getResources().getDrawable(resId));
115619780f88506df4aeb57456fd6747af1b6848a11cfafaisland    }
115719780f88506df4aeb57456fd6747af1b6848a11cfafaisland
115819780f88506df4aeb57456fd6747af1b6848a11cfafaisland
1159ee3f0ffb0199e295cbf48aa1a61c8ae7056526abAdam Powell    @Override
1160ee3f0ffb0199e295cbf48aa1a61c8ae7056526abAdam Powell    public void draw(Canvas c) {
1161ee3f0ffb0199e295cbf48aa1a61c8ae7056526abAdam Powell        super.draw(c);
116219780f88506df4aeb57456fd6747af1b6848a11cfafaisland        final boolean isLayoutRtl = isLayoutRtlSupport();
116319780f88506df4aeb57456fd6747af1b6848a11cfafaisland        Drawable shadowDrawable;
116419780f88506df4aeb57456fd6747af1b6848a11cfafaisland        if (isLayoutRtl) {
116519780f88506df4aeb57456fd6747af1b6848a11cfafaisland            shadowDrawable = mShadowDrawableRight;
116619780f88506df4aeb57456fd6747af1b6848a11cfafaisland        } else {
116719780f88506df4aeb57456fd6747af1b6848a11cfafaisland            shadowDrawable = mShadowDrawableLeft;
116819780f88506df4aeb57456fd6747af1b6848a11cfafaisland        }
1169ee3f0ffb0199e295cbf48aa1a61c8ae7056526abAdam Powell
11701e43161e9e1f1dc10637a68d5c2304c1f95c9c46Adam Powell        final View shadowView = getChildCount() > 1 ? getChildAt(1) : null;
117119780f88506df4aeb57456fd6747af1b6848a11cfafaisland        if (shadowView == null || shadowDrawable == null) {
11723783c4b814bf70711fc4d674e9c7fbc34b1e5a83Adam Powell            // No need to draw a shadow if we don't have one.
1173ee3f0ffb0199e295cbf48aa1a61c8ae7056526abAdam Powell            return;
1174ee3f0ffb0199e295cbf48aa1a61c8ae7056526abAdam Powell        }
1175ee3f0ffb0199e295cbf48aa1a61c8ae7056526abAdam Powell
11761e43161e9e1f1dc10637a68d5c2304c1f95c9c46Adam Powell        final int top = shadowView.getTop();
11771e43161e9e1f1dc10637a68d5c2304c1f95c9c46Adam Powell        final int bottom = shadowView.getBottom();
117819780f88506df4aeb57456fd6747af1b6848a11cfafaisland
117919780f88506df4aeb57456fd6747af1b6848a11cfafaisland        final int shadowWidth = shadowDrawable.getIntrinsicWidth();
118019780f88506df4aeb57456fd6747af1b6848a11cfafaisland        final int left;
118119780f88506df4aeb57456fd6747af1b6848a11cfafaisland        final int right;
118219780f88506df4aeb57456fd6747af1b6848a11cfafaisland        if (isLayoutRtlSupport()) {
118319780f88506df4aeb57456fd6747af1b6848a11cfafaisland            left = shadowView.getRight();
118419780f88506df4aeb57456fd6747af1b6848a11cfafaisland            right = left + shadowWidth;
118519780f88506df4aeb57456fd6747af1b6848a11cfafaisland        } else {
118619780f88506df4aeb57456fd6747af1b6848a11cfafaisland            right = shadowView.getLeft();
118719780f88506df4aeb57456fd6747af1b6848a11cfafaisland            left = right - shadowWidth;
118819780f88506df4aeb57456fd6747af1b6848a11cfafaisland        }
118919780f88506df4aeb57456fd6747af1b6848a11cfafaisland
119019780f88506df4aeb57456fd6747af1b6848a11cfafaisland        shadowDrawable.setBounds(left, top, right, bottom);
119119780f88506df4aeb57456fd6747af1b6848a11cfafaisland        shadowDrawable.draw(c);
1192ee3f0ffb0199e295cbf48aa1a61c8ae7056526abAdam Powell    }
1193ee3f0ffb0199e295cbf48aa1a61c8ae7056526abAdam Powell
11946debd2bbcae1cd285d2e21db633998b7801f9f40Adam Powell    private void parallaxOtherViews(float slideOffset) {
119519780f88506df4aeb57456fd6747af1b6848a11cfafaisland        final boolean isLayoutRtl = isLayoutRtlSupport();
1196ee3f0ffb0199e295cbf48aa1a61c8ae7056526abAdam Powell        final LayoutParams slideLp = (LayoutParams) mSlideableView.getLayoutParams();
119719780f88506df4aeb57456fd6747af1b6848a11cfafaisland        final boolean dimViews = slideLp.dimWhenOffset &&
119819780f88506df4aeb57456fd6747af1b6848a11cfafaisland                (isLayoutRtl ? slideLp.rightMargin : slideLp.leftMargin) <= 0;
11996debd2bbcae1cd285d2e21db633998b7801f9f40Adam Powell        final int childCount = getChildCount();
12006debd2bbcae1cd285d2e21db633998b7801f9f40Adam Powell        for (int i = 0; i < childCount; i++) {
12016debd2bbcae1cd285d2e21db633998b7801f9f40Adam Powell            final View v = getChildAt(i);
12020eefe9ad0819b223006533cbc79a35d66684af32Adam Powell            if (v == mSlideableView) continue;
12036debd2bbcae1cd285d2e21db633998b7801f9f40Adam Powell
12040eefe9ad0819b223006533cbc79a35d66684af32Adam Powell            final int oldOffset = (int) ((1 - mParallaxOffset) * mParallaxBy);
12050eefe9ad0819b223006533cbc79a35d66684af32Adam Powell            mParallaxOffset = slideOffset;
12066debd2bbcae1cd285d2e21db633998b7801f9f40Adam Powell            final int newOffset = (int) ((1 - slideOffset) * mParallaxBy);
1207ad9696cf0da9b65c4a52f00fe5adaa17b99a05caAdam Powell            final int dx = oldOffset - newOffset;
1208ad9696cf0da9b65c4a52f00fe5adaa17b99a05caAdam Powell
120919780f88506df4aeb57456fd6747af1b6848a11cfafaisland            v.offsetLeftAndRight(isLayoutRtl ? -dx : dx);
1210ee3f0ffb0199e295cbf48aa1a61c8ae7056526abAdam Powell
1211ee3f0ffb0199e295cbf48aa1a61c8ae7056526abAdam Powell            if (dimViews) {
121219780f88506df4aeb57456fd6747af1b6848a11cfafaisland                dimChildView(v, isLayoutRtl ? mParallaxOffset - 1 :
121319780f88506df4aeb57456fd6747af1b6848a11cfafaisland                    1 - mParallaxOffset, mCoveredFadeColor);
1214ee3f0ffb0199e295cbf48aa1a61c8ae7056526abAdam Powell            }
12156debd2bbcae1cd285d2e21db633998b7801f9f40Adam Powell        }
12166debd2bbcae1cd285d2e21db633998b7801f9f40Adam Powell    }
12176debd2bbcae1cd285d2e21db633998b7801f9f40Adam Powell
121897341bdc5bea1d7bf777de65228039142d249f38Adam Powell    /**
121997341bdc5bea1d7bf777de65228039142d249f38Adam Powell     * Tests scrollability within child views of v given a delta of dx.
122097341bdc5bea1d7bf777de65228039142d249f38Adam Powell     *
122197341bdc5bea1d7bf777de65228039142d249f38Adam Powell     * @param v View to test for horizontal scrollability
122297341bdc5bea1d7bf777de65228039142d249f38Adam Powell     * @param checkV Whether the view v passed should itself be checked for scrollability (true),
122397341bdc5bea1d7bf777de65228039142d249f38Adam Powell     *               or just its children (false).
122497341bdc5bea1d7bf777de65228039142d249f38Adam Powell     * @param dx Delta scrolled in pixels
122597341bdc5bea1d7bf777de65228039142d249f38Adam Powell     * @param x X coordinate of the active touch point
122697341bdc5bea1d7bf777de65228039142d249f38Adam Powell     * @param y Y coordinate of the active touch point
122797341bdc5bea1d7bf777de65228039142d249f38Adam Powell     * @return true if child views of v can be scrolled by delta of dx.
122897341bdc5bea1d7bf777de65228039142d249f38Adam Powell     */
122997341bdc5bea1d7bf777de65228039142d249f38Adam Powell    protected boolean canScroll(View v, boolean checkV, int dx, int x, int y) {
123097341bdc5bea1d7bf777de65228039142d249f38Adam Powell        if (v instanceof ViewGroup) {
123197341bdc5bea1d7bf777de65228039142d249f38Adam Powell            final ViewGroup group = (ViewGroup) v;
123297341bdc5bea1d7bf777de65228039142d249f38Adam Powell            final int scrollX = v.getScrollX();
123397341bdc5bea1d7bf777de65228039142d249f38Adam Powell            final int scrollY = v.getScrollY();
123497341bdc5bea1d7bf777de65228039142d249f38Adam Powell            final int count = group.getChildCount();
123597341bdc5bea1d7bf777de65228039142d249f38Adam Powell            // Count backwards - let topmost views consume scroll distance first.
123697341bdc5bea1d7bf777de65228039142d249f38Adam Powell            for (int i = count - 1; i >= 0; i--) {
123797341bdc5bea1d7bf777de65228039142d249f38Adam Powell                // TODO: Add versioned support here for transformed views.
123897341bdc5bea1d7bf777de65228039142d249f38Adam Powell                // This will not work for transformed views in Honeycomb+
123997341bdc5bea1d7bf777de65228039142d249f38Adam Powell                final View child = group.getChildAt(i);
124097341bdc5bea1d7bf777de65228039142d249f38Adam Powell                if (x + scrollX >= child.getLeft() && x + scrollX < child.getRight() &&
124197341bdc5bea1d7bf777de65228039142d249f38Adam Powell                        y + scrollY >= child.getTop() && y + scrollY < child.getBottom() &&
124297341bdc5bea1d7bf777de65228039142d249f38Adam Powell                        canScroll(child, true, dx, x + scrollX - child.getLeft(),
124397341bdc5bea1d7bf777de65228039142d249f38Adam Powell                                y + scrollY - child.getTop())) {
124497341bdc5bea1d7bf777de65228039142d249f38Adam Powell                    return true;
124597341bdc5bea1d7bf777de65228039142d249f38Adam Powell                }
124697341bdc5bea1d7bf777de65228039142d249f38Adam Powell            }
124797341bdc5bea1d7bf777de65228039142d249f38Adam Powell        }
124897341bdc5bea1d7bf777de65228039142d249f38Adam Powell
124919780f88506df4aeb57456fd6747af1b6848a11cfafaisland        return checkV && ViewCompat.canScrollHorizontally(v, (isLayoutRtlSupport() ? dx : -dx));
125097341bdc5bea1d7bf777de65228039142d249f38Adam Powell    }
125197341bdc5bea1d7bf777de65228039142d249f38Adam Powell
12520eefe9ad0819b223006533cbc79a35d66684af32Adam Powell    boolean isDimmed(View child) {
12530eefe9ad0819b223006533cbc79a35d66684af32Adam Powell        if (child == null) {
12540eefe9ad0819b223006533cbc79a35d66684af32Adam Powell            return false;
12550eefe9ad0819b223006533cbc79a35d66684af32Adam Powell        }
125697341bdc5bea1d7bf777de65228039142d249f38Adam Powell        final LayoutParams lp = (LayoutParams) child.getLayoutParams();
12570eefe9ad0819b223006533cbc79a35d66684af32Adam Powell        return mCanSlide && lp.dimWhenOffset && mSlideOffset > 0;
125897341bdc5bea1d7bf777de65228039142d249f38Adam Powell    }
125997341bdc5bea1d7bf777de65228039142d249f38Adam Powell
126097341bdc5bea1d7bf777de65228039142d249f38Adam Powell    @Override
126197341bdc5bea1d7bf777de65228039142d249f38Adam Powell    protected ViewGroup.LayoutParams generateDefaultLayoutParams() {
126297341bdc5bea1d7bf777de65228039142d249f38Adam Powell        return new LayoutParams();
126397341bdc5bea1d7bf777de65228039142d249f38Adam Powell    }
126497341bdc5bea1d7bf777de65228039142d249f38Adam Powell
126597341bdc5bea1d7bf777de65228039142d249f38Adam Powell    @Override
126697341bdc5bea1d7bf777de65228039142d249f38Adam Powell    protected ViewGroup.LayoutParams generateLayoutParams(ViewGroup.LayoutParams p) {
126797341bdc5bea1d7bf777de65228039142d249f38Adam Powell        return p instanceof MarginLayoutParams
126897341bdc5bea1d7bf777de65228039142d249f38Adam Powell                ? new LayoutParams((MarginLayoutParams) p)
126997341bdc5bea1d7bf777de65228039142d249f38Adam Powell                : new LayoutParams(p);
127097341bdc5bea1d7bf777de65228039142d249f38Adam Powell    }
127197341bdc5bea1d7bf777de65228039142d249f38Adam Powell
127297341bdc5bea1d7bf777de65228039142d249f38Adam Powell    @Override
127397341bdc5bea1d7bf777de65228039142d249f38Adam Powell    protected boolean checkLayoutParams(ViewGroup.LayoutParams p) {
127497341bdc5bea1d7bf777de65228039142d249f38Adam Powell        return p instanceof LayoutParams && super.checkLayoutParams(p);
127597341bdc5bea1d7bf777de65228039142d249f38Adam Powell    }
127697341bdc5bea1d7bf777de65228039142d249f38Adam Powell
127797341bdc5bea1d7bf777de65228039142d249f38Adam Powell    @Override
127897341bdc5bea1d7bf777de65228039142d249f38Adam Powell    public ViewGroup.LayoutParams generateLayoutParams(AttributeSet attrs) {
127997341bdc5bea1d7bf777de65228039142d249f38Adam Powell        return new LayoutParams(getContext(), attrs);
128097341bdc5bea1d7bf777de65228039142d249f38Adam Powell    }
128197341bdc5bea1d7bf777de65228039142d249f38Adam Powell
12821d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell    @Override
12831d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell    protected Parcelable onSaveInstanceState() {
12841d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell        Parcelable superState = super.onSaveInstanceState();
12851d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell
12861d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell        SavedState ss = new SavedState(superState);
128789e17886e6149bddfdb08a242c9e88889596419cAdam Powell        ss.isOpen = isSlideable() ? isOpen() : mPreservedOpenState;
12881d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell
12891d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell        return ss;
12901d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell    }
12911d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell
12921d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell    @Override
12931d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell    protected void onRestoreInstanceState(Parcelable state) {
1294bb58a82daf11bf3c056d1cd5887aa26435d37b69Aurimas Liutikas        if (!(state instanceof SavedState)) {
1295bb58a82daf11bf3c056d1cd5887aa26435d37b69Aurimas Liutikas            super.onRestoreInstanceState(state);
1296bb58a82daf11bf3c056d1cd5887aa26435d37b69Aurimas Liutikas            return;
1297bb58a82daf11bf3c056d1cd5887aa26435d37b69Aurimas Liutikas        }
1298bb58a82daf11bf3c056d1cd5887aa26435d37b69Aurimas Liutikas
12991d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell        SavedState ss = (SavedState) state;
13001d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell        super.onRestoreInstanceState(ss.getSuperState());
13011d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell
130289e17886e6149bddfdb08a242c9e88889596419cAdam Powell        if (ss.isOpen) {
130389e17886e6149bddfdb08a242c9e88889596419cAdam Powell            openPane();
130489e17886e6149bddfdb08a242c9e88889596419cAdam Powell        } else {
130589e17886e6149bddfdb08a242c9e88889596419cAdam Powell            closePane();
130689e17886e6149bddfdb08a242c9e88889596419cAdam Powell        }
130789e17886e6149bddfdb08a242c9e88889596419cAdam Powell        mPreservedOpenState = ss.isOpen;
13081d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell    }
13091d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell
1310c56ba65d20be8742ff717907a3a2cd81dd0e5f3cAdam Powell    private class DragHelperCallback extends ViewDragHelper.Callback {
1311c56ba65d20be8742ff717907a3a2cd81dd0e5f3cAdam Powell
1312c56ba65d20be8742ff717907a3a2cd81dd0e5f3cAdam Powell        @Override
1313c56ba65d20be8742ff717907a3a2cd81dd0e5f3cAdam Powell        public boolean tryCaptureView(View child, int pointerId) {
1314c56ba65d20be8742ff717907a3a2cd81dd0e5f3cAdam Powell            if (mIsUnableToDrag) {
1315c56ba65d20be8742ff717907a3a2cd81dd0e5f3cAdam Powell                return false;
1316c56ba65d20be8742ff717907a3a2cd81dd0e5f3cAdam Powell            }
1317c56ba65d20be8742ff717907a3a2cd81dd0e5f3cAdam Powell
1318c56ba65d20be8742ff717907a3a2cd81dd0e5f3cAdam Powell            return ((LayoutParams) child.getLayoutParams()).slideable;
1319c56ba65d20be8742ff717907a3a2cd81dd0e5f3cAdam Powell        }
1320c56ba65d20be8742ff717907a3a2cd81dd0e5f3cAdam Powell
1321c56ba65d20be8742ff717907a3a2cd81dd0e5f3cAdam Powell        @Override
1322c56ba65d20be8742ff717907a3a2cd81dd0e5f3cAdam Powell        public void onViewDragStateChanged(int state) {
1323471f0f4e84c7d1f96e48fb26713f246d69c3241fAdam Powell            if (mDragHelper.getViewDragState() == ViewDragHelper.STATE_IDLE) {
13246580cf4b7e74a2a017ed95b0dc50155b9995edebAdam Powell                if (mSlideOffset == 0) {
1325c89f53833f1e272d32f7928837f0704fa33be309Adam Powell                    updateObscuredViewsVisibility(mSlideableView);
13266580cf4b7e74a2a017ed95b0dc50155b9995edebAdam Powell                    dispatchOnPanelClosed(mSlideableView);
132772c7316b081c3134f7b0566f703dfee7c970eadeAdam Powell                    mPreservedOpenState = false;
13286580cf4b7e74a2a017ed95b0dc50155b9995edebAdam Powell                } else {
13296580cf4b7e74a2a017ed95b0dc50155b9995edebAdam Powell                    dispatchOnPanelOpened(mSlideableView);
133072c7316b081c3134f7b0566f703dfee7c970eadeAdam Powell                    mPreservedOpenState = true;
13316580cf4b7e74a2a017ed95b0dc50155b9995edebAdam Powell                }
1332c56ba65d20be8742ff717907a3a2cd81dd0e5f3cAdam Powell            }
1333c56ba65d20be8742ff717907a3a2cd81dd0e5f3cAdam Powell        }
1334c56ba65d20be8742ff717907a3a2cd81dd0e5f3cAdam Powell
1335c56ba65d20be8742ff717907a3a2cd81dd0e5f3cAdam Powell        @Override
1336c89f53833f1e272d32f7928837f0704fa33be309Adam Powell        public void onViewCaptured(View capturedChild, int activePointerId) {
1337c89f53833f1e272d32f7928837f0704fa33be309Adam Powell            // Make all child views visible in preparation for sliding things around
1338c89f53833f1e272d32f7928837f0704fa33be309Adam Powell            setAllChildrenVisible();
1339c89f53833f1e272d32f7928837f0704fa33be309Adam Powell        }
1340c89f53833f1e272d32f7928837f0704fa33be309Adam Powell
1341c89f53833f1e272d32f7928837f0704fa33be309Adam Powell        @Override
13421d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell        public void onViewPositionChanged(View changedView, int left, int top, int dx, int dy) {
1343d44315a54e002b20365189f03a09011f2bf6ba07Adam Powell            onPanelDragged(left);
1344c56ba65d20be8742ff717907a3a2cd81dd0e5f3cAdam Powell            invalidate();
1345c56ba65d20be8742ff717907a3a2cd81dd0e5f3cAdam Powell        }
1346c56ba65d20be8742ff717907a3a2cd81dd0e5f3cAdam Powell
1347c56ba65d20be8742ff717907a3a2cd81dd0e5f3cAdam Powell        @Override
1348c56ba65d20be8742ff717907a3a2cd81dd0e5f3cAdam Powell        public void onViewReleased(View releasedChild, float xvel, float yvel) {
1349c56ba65d20be8742ff717907a3a2cd81dd0e5f3cAdam Powell            final LayoutParams lp = (LayoutParams) releasedChild.getLayoutParams();
135019780f88506df4aeb57456fd6747af1b6848a11cfafaisland
135119780f88506df4aeb57456fd6747af1b6848a11cfafaisland            int left;
135219780f88506df4aeb57456fd6747af1b6848a11cfafaisland            if (isLayoutRtlSupport()) {
135319780f88506df4aeb57456fd6747af1b6848a11cfafaisland                int startToRight =  getPaddingRight() + lp.rightMargin;
13547099553551ccfc346e22843e0541ed4393c9c4edfafaisland                if (xvel < 0 || (xvel == 0 && mSlideOffset > 0.5f)) {
135519780f88506df4aeb57456fd6747af1b6848a11cfafaisland                    startToRight += mSlideRange;
135619780f88506df4aeb57456fd6747af1b6848a11cfafaisland                }
135719780f88506df4aeb57456fd6747af1b6848a11cfafaisland                int childWidth = mSlideableView.getWidth();
135819780f88506df4aeb57456fd6747af1b6848a11cfafaisland                left = getWidth() - startToRight - childWidth;
135919780f88506df4aeb57456fd6747af1b6848a11cfafaisland            } else {
136019780f88506df4aeb57456fd6747af1b6848a11cfafaisland                left = getPaddingLeft() + lp.leftMargin;
136119780f88506df4aeb57456fd6747af1b6848a11cfafaisland                if (xvel > 0 || (xvel == 0 && mSlideOffset > 0.5f)) {
136219780f88506df4aeb57456fd6747af1b6848a11cfafaisland                    left += mSlideRange;
136319780f88506df4aeb57456fd6747af1b6848a11cfafaisland                }
1364c56ba65d20be8742ff717907a3a2cd81dd0e5f3cAdam Powell            }
1365c56ba65d20be8742ff717907a3a2cd81dd0e5f3cAdam Powell            mDragHelper.settleCapturedViewAt(left, releasedChild.getTop());
1366c56ba65d20be8742ff717907a3a2cd81dd0e5f3cAdam Powell            invalidate();
1367c56ba65d20be8742ff717907a3a2cd81dd0e5f3cAdam Powell        }
1368c56ba65d20be8742ff717907a3a2cd81dd0e5f3cAdam Powell
1369c56ba65d20be8742ff717907a3a2cd81dd0e5f3cAdam Powell        @Override
1370c56ba65d20be8742ff717907a3a2cd81dd0e5f3cAdam Powell        public int getViewHorizontalDragRange(View child) {
1371c56ba65d20be8742ff717907a3a2cd81dd0e5f3cAdam Powell            return mSlideRange;
1372c56ba65d20be8742ff717907a3a2cd81dd0e5f3cAdam Powell        }
1373c56ba65d20be8742ff717907a3a2cd81dd0e5f3cAdam Powell
1374c56ba65d20be8742ff717907a3a2cd81dd0e5f3cAdam Powell        @Override
13751d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell        public int clampViewPositionHorizontal(View child, int left, int dx) {
1376c56ba65d20be8742ff717907a3a2cd81dd0e5f3cAdam Powell            final LayoutParams lp = (LayoutParams) mSlideableView.getLayoutParams();
1377c56ba65d20be8742ff717907a3a2cd81dd0e5f3cAdam Powell
137819780f88506df4aeb57456fd6747af1b6848a11cfafaisland            final int newLeft;
137919780f88506df4aeb57456fd6747af1b6848a11cfafaisland            if (isLayoutRtlSupport()) {
138019780f88506df4aeb57456fd6747af1b6848a11cfafaisland                int startBound = getWidth() -
138119780f88506df4aeb57456fd6747af1b6848a11cfafaisland                        (getPaddingRight() + lp.rightMargin + mSlideableView.getWidth());
138219780f88506df4aeb57456fd6747af1b6848a11cfafaisland                int endBound =  startBound - mSlideRange;
138319780f88506df4aeb57456fd6747af1b6848a11cfafaisland                newLeft = Math.max(Math.min(left, startBound), endBound);
138419780f88506df4aeb57456fd6747af1b6848a11cfafaisland            } else {
138519780f88506df4aeb57456fd6747af1b6848a11cfafaisland                int startBound = getPaddingLeft() + lp.leftMargin;
138619780f88506df4aeb57456fd6747af1b6848a11cfafaisland                int endBound = startBound + mSlideRange;
138719780f88506df4aeb57456fd6747af1b6848a11cfafaisland                newLeft = Math.min(Math.max(left, startBound), endBound);
138819780f88506df4aeb57456fd6747af1b6848a11cfafaisland            }
13891d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell            return newLeft;
1390c56ba65d20be8742ff717907a3a2cd81dd0e5f3cAdam Powell        }
1391c56ba65d20be8742ff717907a3a2cd81dd0e5f3cAdam Powell
1392c56ba65d20be8742ff717907a3a2cd81dd0e5f3cAdam Powell        @Override
13936688e113ad2519dc07edf56acbd0f42ce209a585Sérgio Faria        public int clampViewPositionVertical(View child, int top, int dy) {
13946688e113ad2519dc07edf56acbd0f42ce209a585Sérgio Faria            // Make sure we never move views vertically.
13956688e113ad2519dc07edf56acbd0f42ce209a585Sérgio Faria            // This could happen if the child has less height than its parent.
13966688e113ad2519dc07edf56acbd0f42ce209a585Sérgio Faria            return child.getTop();
13976688e113ad2519dc07edf56acbd0f42ce209a585Sérgio Faria        }
13986688e113ad2519dc07edf56acbd0f42ce209a585Sérgio Faria
13996688e113ad2519dc07edf56acbd0f42ce209a585Sérgio Faria        @Override
1400c56ba65d20be8742ff717907a3a2cd81dd0e5f3cAdam Powell        public void onEdgeDragStarted(int edgeFlags, int pointerId) {
1401c56ba65d20be8742ff717907a3a2cd81dd0e5f3cAdam Powell            mDragHelper.captureChildView(mSlideableView, pointerId);
1402c56ba65d20be8742ff717907a3a2cd81dd0e5f3cAdam Powell        }
1403c56ba65d20be8742ff717907a3a2cd81dd0e5f3cAdam Powell    }
1404c56ba65d20be8742ff717907a3a2cd81dd0e5f3cAdam Powell
140597341bdc5bea1d7bf777de65228039142d249f38Adam Powell    public static class LayoutParams extends ViewGroup.MarginLayoutParams {
140697341bdc5bea1d7bf777de65228039142d249f38Adam Powell        private static final int[] ATTRS = new int[] {
140797341bdc5bea1d7bf777de65228039142d249f38Adam Powell            android.R.attr.layout_weight
140897341bdc5bea1d7bf777de65228039142d249f38Adam Powell        };
140997341bdc5bea1d7bf777de65228039142d249f38Adam Powell
14106debd2bbcae1cd285d2e21db633998b7801f9f40Adam Powell        /**
14116debd2bbcae1cd285d2e21db633998b7801f9f40Adam Powell         * The weighted proportion of how much of the leftover space
14126debd2bbcae1cd285d2e21db633998b7801f9f40Adam Powell         * this child should consume after measurement.
14136debd2bbcae1cd285d2e21db633998b7801f9f40Adam Powell         */
141497341bdc5bea1d7bf777de65228039142d249f38Adam Powell        public float weight = 0;
141597341bdc5bea1d7bf777de65228039142d249f38Adam Powell
141697341bdc5bea1d7bf777de65228039142d249f38Adam Powell        /**
14170eefe9ad0819b223006533cbc79a35d66684af32Adam Powell         * True if this pane is the slideable pane in the layout.
141897341bdc5bea1d7bf777de65228039142d249f38Adam Powell         */
14190eefe9ad0819b223006533cbc79a35d66684af32Adam Powell        boolean slideable;
142097341bdc5bea1d7bf777de65228039142d249f38Adam Powell
142197341bdc5bea1d7bf777de65228039142d249f38Adam Powell        /**
142297341bdc5bea1d7bf777de65228039142d249f38Adam Powell         * True if this view should be drawn dimmed
142397341bdc5bea1d7bf777de65228039142d249f38Adam Powell         * when it's been offset from its default position.
142497341bdc5bea1d7bf777de65228039142d249f38Adam Powell         */
142597341bdc5bea1d7bf777de65228039142d249f38Adam Powell        boolean dimWhenOffset;
142697341bdc5bea1d7bf777de65228039142d249f38Adam Powell
142797341bdc5bea1d7bf777de65228039142d249f38Adam Powell        Paint dimPaint;
142897341bdc5bea1d7bf777de65228039142d249f38Adam Powell
142997341bdc5bea1d7bf777de65228039142d249f38Adam Powell        public LayoutParams() {
143097341bdc5bea1d7bf777de65228039142d249f38Adam Powell            super(FILL_PARENT, FILL_PARENT);
143197341bdc5bea1d7bf777de65228039142d249f38Adam Powell        }
143297341bdc5bea1d7bf777de65228039142d249f38Adam Powell
143397341bdc5bea1d7bf777de65228039142d249f38Adam Powell        public LayoutParams(int width, int height) {
143497341bdc5bea1d7bf777de65228039142d249f38Adam Powell            super(width, height);
143597341bdc5bea1d7bf777de65228039142d249f38Adam Powell        }
143697341bdc5bea1d7bf777de65228039142d249f38Adam Powell
143797341bdc5bea1d7bf777de65228039142d249f38Adam Powell        public LayoutParams(android.view.ViewGroup.LayoutParams source) {
143897341bdc5bea1d7bf777de65228039142d249f38Adam Powell            super(source);
143997341bdc5bea1d7bf777de65228039142d249f38Adam Powell        }
144097341bdc5bea1d7bf777de65228039142d249f38Adam Powell
144197341bdc5bea1d7bf777de65228039142d249f38Adam Powell        public LayoutParams(MarginLayoutParams source) {
144297341bdc5bea1d7bf777de65228039142d249f38Adam Powell            super(source);
144397341bdc5bea1d7bf777de65228039142d249f38Adam Powell        }
144497341bdc5bea1d7bf777de65228039142d249f38Adam Powell
144597341bdc5bea1d7bf777de65228039142d249f38Adam Powell        public LayoutParams(LayoutParams source) {
144697341bdc5bea1d7bf777de65228039142d249f38Adam Powell            super(source);
144797341bdc5bea1d7bf777de65228039142d249f38Adam Powell            this.weight = source.weight;
144897341bdc5bea1d7bf777de65228039142d249f38Adam Powell        }
144997341bdc5bea1d7bf777de65228039142d249f38Adam Powell
145097341bdc5bea1d7bf777de65228039142d249f38Adam Powell        public LayoutParams(Context c, AttributeSet attrs) {
145197341bdc5bea1d7bf777de65228039142d249f38Adam Powell            super(c, attrs);
145297341bdc5bea1d7bf777de65228039142d249f38Adam Powell
145397341bdc5bea1d7bf777de65228039142d249f38Adam Powell            final TypedArray a = c.obtainStyledAttributes(attrs, ATTRS);
14540eefe9ad0819b223006533cbc79a35d66684af32Adam Powell            this.weight = a.getFloat(0, 0);
145597341bdc5bea1d7bf777de65228039142d249f38Adam Powell            a.recycle();
145697341bdc5bea1d7bf777de65228039142d249f38Adam Powell        }
145797341bdc5bea1d7bf777de65228039142d249f38Adam Powell
145897341bdc5bea1d7bf777de65228039142d249f38Adam Powell    }
145997341bdc5bea1d7bf777de65228039142d249f38Adam Powell
146005f5ba020fa6caa658c75b6d77436aa980ca0fccChris Banes    static class SavedState extends AbsSavedState {
146197341bdc5bea1d7bf777de65228039142d249f38Adam Powell        boolean isOpen;
146297341bdc5bea1d7bf777de65228039142d249f38Adam Powell
146397341bdc5bea1d7bf777de65228039142d249f38Adam Powell        SavedState(Parcelable superState) {
146497341bdc5bea1d7bf777de65228039142d249f38Adam Powell            super(superState);
146597341bdc5bea1d7bf777de65228039142d249f38Adam Powell        }
146697341bdc5bea1d7bf777de65228039142d249f38Adam Powell
146705f5ba020fa6caa658c75b6d77436aa980ca0fccChris Banes        private SavedState(Parcel in, ClassLoader loader) {
146805f5ba020fa6caa658c75b6d77436aa980ca0fccChris Banes            super(in, loader);
146997341bdc5bea1d7bf777de65228039142d249f38Adam Powell            isOpen = in.readInt() != 0;
147097341bdc5bea1d7bf777de65228039142d249f38Adam Powell        }
147197341bdc5bea1d7bf777de65228039142d249f38Adam Powell
147297341bdc5bea1d7bf777de65228039142d249f38Adam Powell        @Override
147397341bdc5bea1d7bf777de65228039142d249f38Adam Powell        public void writeToParcel(Parcel out, int flags) {
147497341bdc5bea1d7bf777de65228039142d249f38Adam Powell            super.writeToParcel(out, flags);
147597341bdc5bea1d7bf777de65228039142d249f38Adam Powell            out.writeInt(isOpen ? 1 : 0);
147697341bdc5bea1d7bf777de65228039142d249f38Adam Powell        }
147797341bdc5bea1d7bf777de65228039142d249f38Adam Powell
147805f5ba020fa6caa658c75b6d77436aa980ca0fccChris Banes        public static final Creator<SavedState> CREATOR = ParcelableCompat.newCreator(
147905f5ba020fa6caa658c75b6d77436aa980ca0fccChris Banes                new ParcelableCompatCreatorCallbacks<SavedState>() {
148005f5ba020fa6caa658c75b6d77436aa980ca0fccChris Banes                    @Override
148105f5ba020fa6caa658c75b6d77436aa980ca0fccChris Banes                    public SavedState createFromParcel(Parcel in, ClassLoader loader) {
148205f5ba020fa6caa658c75b6d77436aa980ca0fccChris Banes                        return new SavedState(in, loader);
148305f5ba020fa6caa658c75b6d77436aa980ca0fccChris Banes                    }
148497341bdc5bea1d7bf777de65228039142d249f38Adam Powell
148505f5ba020fa6caa658c75b6d77436aa980ca0fccChris Banes                    @Override
148605f5ba020fa6caa658c75b6d77436aa980ca0fccChris Banes                    public SavedState[] newArray(int size) {
148705f5ba020fa6caa658c75b6d77436aa980ca0fccChris Banes                        return new SavedState[size];
148805f5ba020fa6caa658c75b6d77436aa980ca0fccChris Banes                    }
148905f5ba020fa6caa658c75b6d77436aa980ca0fccChris Banes                });
149097341bdc5bea1d7bf777de65228039142d249f38Adam Powell    }
149197341bdc5bea1d7bf777de65228039142d249f38Adam Powell
149297341bdc5bea1d7bf777de65228039142d249f38Adam Powell    interface SlidingPanelLayoutImpl {
149397341bdc5bea1d7bf777de65228039142d249f38Adam Powell        void invalidateChildRegion(SlidingPaneLayout parent, View child);
149497341bdc5bea1d7bf777de65228039142d249f38Adam Powell    }
149597341bdc5bea1d7bf777de65228039142d249f38Adam Powell
149697341bdc5bea1d7bf777de65228039142d249f38Adam Powell    static class SlidingPanelLayoutImplBase implements SlidingPanelLayoutImpl {
149797341bdc5bea1d7bf777de65228039142d249f38Adam Powell        public void invalidateChildRegion(SlidingPaneLayout parent, View child) {
149897341bdc5bea1d7bf777de65228039142d249f38Adam Powell            ViewCompat.postInvalidateOnAnimation(parent, child.getLeft(), child.getTop(),
149997341bdc5bea1d7bf777de65228039142d249f38Adam Powell                    child.getRight(), child.getBottom());
150097341bdc5bea1d7bf777de65228039142d249f38Adam Powell        }
150197341bdc5bea1d7bf777de65228039142d249f38Adam Powell    }
150297341bdc5bea1d7bf777de65228039142d249f38Adam Powell
150397341bdc5bea1d7bf777de65228039142d249f38Adam Powell    static class SlidingPanelLayoutImplJB extends SlidingPanelLayoutImplBase {
150497341bdc5bea1d7bf777de65228039142d249f38Adam Powell        /*
150597341bdc5bea1d7bf777de65228039142d249f38Adam Powell         * Private API hacks! Nasty! Bad!
150697341bdc5bea1d7bf777de65228039142d249f38Adam Powell         *
150797341bdc5bea1d7bf777de65228039142d249f38Adam Powell         * In Jellybean, some optimizations in the hardware UI renderer
150897341bdc5bea1d7bf777de65228039142d249f38Adam Powell         * prevent a changed Paint on a View using a hardware layer from having
150997341bdc5bea1d7bf777de65228039142d249f38Adam Powell         * the intended effect. This twiddles some internal bits on the view to force
151097341bdc5bea1d7bf777de65228039142d249f38Adam Powell         * it to recreate the display list.
151197341bdc5bea1d7bf777de65228039142d249f38Adam Powell         */
151297341bdc5bea1d7bf777de65228039142d249f38Adam Powell        private Method mGetDisplayList;
151397341bdc5bea1d7bf777de65228039142d249f38Adam Powell        private Field mRecreateDisplayList;
151497341bdc5bea1d7bf777de65228039142d249f38Adam Powell
151597341bdc5bea1d7bf777de65228039142d249f38Adam Powell        SlidingPanelLayoutImplJB() {
151697341bdc5bea1d7bf777de65228039142d249f38Adam Powell            try {
151797341bdc5bea1d7bf777de65228039142d249f38Adam Powell                mGetDisplayList = View.class.getDeclaredMethod("getDisplayList", (Class[]) null);
151897341bdc5bea1d7bf777de65228039142d249f38Adam Powell            } catch (NoSuchMethodException e) {
151997341bdc5bea1d7bf777de65228039142d249f38Adam Powell                Log.e(TAG, "Couldn't fetch getDisplayList method; dimming won't work right.", e);
152097341bdc5bea1d7bf777de65228039142d249f38Adam Powell            }
152197341bdc5bea1d7bf777de65228039142d249f38Adam Powell            try {
152297341bdc5bea1d7bf777de65228039142d249f38Adam Powell                mRecreateDisplayList = View.class.getDeclaredField("mRecreateDisplayList");
152397341bdc5bea1d7bf777de65228039142d249f38Adam Powell                mRecreateDisplayList.setAccessible(true);
152497341bdc5bea1d7bf777de65228039142d249f38Adam Powell            } catch (NoSuchFieldException e) {
152597341bdc5bea1d7bf777de65228039142d249f38Adam Powell                Log.e(TAG, "Couldn't fetch mRecreateDisplayList field; dimming will be slow.", e);
152697341bdc5bea1d7bf777de65228039142d249f38Adam Powell            }
152797341bdc5bea1d7bf777de65228039142d249f38Adam Powell        }
152897341bdc5bea1d7bf777de65228039142d249f38Adam Powell
152997341bdc5bea1d7bf777de65228039142d249f38Adam Powell        @Override
153097341bdc5bea1d7bf777de65228039142d249f38Adam Powell        public void invalidateChildRegion(SlidingPaneLayout parent, View child) {
153197341bdc5bea1d7bf777de65228039142d249f38Adam Powell            if (mGetDisplayList != null && mRecreateDisplayList != null) {
153297341bdc5bea1d7bf777de65228039142d249f38Adam Powell                try {
153397341bdc5bea1d7bf777de65228039142d249f38Adam Powell                    mRecreateDisplayList.setBoolean(child, true);
153497341bdc5bea1d7bf777de65228039142d249f38Adam Powell                    mGetDisplayList.invoke(child, (Object[]) null);
153597341bdc5bea1d7bf777de65228039142d249f38Adam Powell                } catch (Exception e) {
153697341bdc5bea1d7bf777de65228039142d249f38Adam Powell                    Log.e(TAG, "Error refreshing display list state", e);
153797341bdc5bea1d7bf777de65228039142d249f38Adam Powell                }
153897341bdc5bea1d7bf777de65228039142d249f38Adam Powell            } else {
153997341bdc5bea1d7bf777de65228039142d249f38Adam Powell                // Slow path. REALLY slow path. Let's hope we don't get here.
154097341bdc5bea1d7bf777de65228039142d249f38Adam Powell                child.invalidate();
154197341bdc5bea1d7bf777de65228039142d249f38Adam Powell                return;
154297341bdc5bea1d7bf777de65228039142d249f38Adam Powell            }
154397341bdc5bea1d7bf777de65228039142d249f38Adam Powell            super.invalidateChildRegion(parent, child);
154497341bdc5bea1d7bf777de65228039142d249f38Adam Powell        }
154597341bdc5bea1d7bf777de65228039142d249f38Adam Powell    }
15466debd2bbcae1cd285d2e21db633998b7801f9f40Adam Powell
15476debd2bbcae1cd285d2e21db633998b7801f9f40Adam Powell    static class SlidingPanelLayoutImplJBMR1 extends SlidingPanelLayoutImplBase {
15486debd2bbcae1cd285d2e21db633998b7801f9f40Adam Powell        @Override
15496debd2bbcae1cd285d2e21db633998b7801f9f40Adam Powell        public void invalidateChildRegion(SlidingPaneLayout parent, View child) {
15506debd2bbcae1cd285d2e21db633998b7801f9f40Adam Powell            ViewCompat.setLayerPaint(child, ((LayoutParams) child.getLayoutParams()).dimPaint);
15516debd2bbcae1cd285d2e21db633998b7801f9f40Adam Powell        }
15526debd2bbcae1cd285d2e21db633998b7801f9f40Adam Powell    }
1553c89f53833f1e272d32f7928837f0704fa33be309Adam Powell
1554c89f53833f1e272d32f7928837f0704fa33be309Adam Powell    class AccessibilityDelegate extends AccessibilityDelegateCompat {
15553cf6141d516a0a6170823b1bda5c0b6d7500e76cAdam Powell        private final Rect mTmpRect = new Rect();
15563cf6141d516a0a6170823b1bda5c0b6d7500e76cAdam Powell
1557c89f53833f1e272d32f7928837f0704fa33be309Adam Powell        @Override
1558c89f53833f1e272d32f7928837f0704fa33be309Adam Powell        public void onInitializeAccessibilityNodeInfo(View host, AccessibilityNodeInfoCompat info) {
15593cf6141d516a0a6170823b1bda5c0b6d7500e76cAdam Powell            final AccessibilityNodeInfoCompat superNode = AccessibilityNodeInfoCompat.obtain(info);
15603cf6141d516a0a6170823b1bda5c0b6d7500e76cAdam Powell            super.onInitializeAccessibilityNodeInfo(host, superNode);
156151e43399398d051db26ecc85d6de34f310e77dbbAlan Viverette            copyNodeInfoNoChildren(info, superNode);
156251e43399398d051db26ecc85d6de34f310e77dbbAlan Viverette            superNode.recycle();
15633cf6141d516a0a6170823b1bda5c0b6d7500e76cAdam Powell
156451e43399398d051db26ecc85d6de34f310e77dbbAlan Viverette            info.setClassName(SlidingPaneLayout.class.getName());
15653cf6141d516a0a6170823b1bda5c0b6d7500e76cAdam Powell            info.setSource(host);
156651e43399398d051db26ecc85d6de34f310e77dbbAlan Viverette
15673cf6141d516a0a6170823b1bda5c0b6d7500e76cAdam Powell            final ViewParent parent = ViewCompat.getParentForAccessibility(host);
15683cf6141d516a0a6170823b1bda5c0b6d7500e76cAdam Powell            if (parent instanceof View) {
15693cf6141d516a0a6170823b1bda5c0b6d7500e76cAdam Powell                info.setParent((View) parent);
15703cf6141d516a0a6170823b1bda5c0b6d7500e76cAdam Powell            }
15713cf6141d516a0a6170823b1bda5c0b6d7500e76cAdam Powell
157251e43399398d051db26ecc85d6de34f310e77dbbAlan Viverette            // This is a best-approximation of addChildrenForAccessibility()
157351e43399398d051db26ecc85d6de34f310e77dbbAlan Viverette            // that accounts for filtering.
1574c89f53833f1e272d32f7928837f0704fa33be309Adam Powell            final int childCount = getChildCount();
1575c89f53833f1e272d32f7928837f0704fa33be309Adam Powell            for (int i = 0; i < childCount; i++) {
1576c89f53833f1e272d32f7928837f0704fa33be309Adam Powell                final View child = getChildAt(i);
157751e43399398d051db26ecc85d6de34f310e77dbbAlan Viverette                if (!filter(child) && (child.getVisibility() == View.VISIBLE)) {
1578f803407db4a369e3c176798d5318faaacb85e12bAlan Viverette                    // Force importance to "yes" since we can't read the value.
1579f803407db4a369e3c176798d5318faaacb85e12bAlan Viverette                    ViewCompat.setImportantForAccessibility(
1580f803407db4a369e3c176798d5318faaacb85e12bAlan Viverette                            child, ViewCompat.IMPORTANT_FOR_ACCESSIBILITY_YES);
1581c89f53833f1e272d32f7928837f0704fa33be309Adam Powell                    info.addChild(child);
1582c89f53833f1e272d32f7928837f0704fa33be309Adam Powell                }
1583c89f53833f1e272d32f7928837f0704fa33be309Adam Powell            }
1584c89f53833f1e272d32f7928837f0704fa33be309Adam Powell        }
1585c89f53833f1e272d32f7928837f0704fa33be309Adam Powell
1586c89f53833f1e272d32f7928837f0704fa33be309Adam Powell        @Override
158751e43399398d051db26ecc85d6de34f310e77dbbAlan Viverette        public void onInitializeAccessibilityEvent(View host, AccessibilityEvent event) {
158851e43399398d051db26ecc85d6de34f310e77dbbAlan Viverette            super.onInitializeAccessibilityEvent(host, event);
158951e43399398d051db26ecc85d6de34f310e77dbbAlan Viverette
159051e43399398d051db26ecc85d6de34f310e77dbbAlan Viverette            event.setClassName(SlidingPaneLayout.class.getName());
159151e43399398d051db26ecc85d6de34f310e77dbbAlan Viverette        }
159251e43399398d051db26ecc85d6de34f310e77dbbAlan Viverette
159351e43399398d051db26ecc85d6de34f310e77dbbAlan Viverette        @Override
1594c89f53833f1e272d32f7928837f0704fa33be309Adam Powell        public boolean onRequestSendAccessibilityEvent(ViewGroup host, View child,
1595c89f53833f1e272d32f7928837f0704fa33be309Adam Powell                AccessibilityEvent event) {
1596c89f53833f1e272d32f7928837f0704fa33be309Adam Powell            if (!filter(child)) {
1597c89f53833f1e272d32f7928837f0704fa33be309Adam Powell                return super.onRequestSendAccessibilityEvent(host, child, event);
1598c89f53833f1e272d32f7928837f0704fa33be309Adam Powell            }
1599c89f53833f1e272d32f7928837f0704fa33be309Adam Powell            return false;
1600c89f53833f1e272d32f7928837f0704fa33be309Adam Powell        }
1601c89f53833f1e272d32f7928837f0704fa33be309Adam Powell
1602c89f53833f1e272d32f7928837f0704fa33be309Adam Powell        public boolean filter(View child) {
1603c89f53833f1e272d32f7928837f0704fa33be309Adam Powell            return isDimmed(child);
1604c89f53833f1e272d32f7928837f0704fa33be309Adam Powell        }
16053cf6141d516a0a6170823b1bda5c0b6d7500e76cAdam Powell
16063cf6141d516a0a6170823b1bda5c0b6d7500e76cAdam Powell        /**
16073cf6141d516a0a6170823b1bda5c0b6d7500e76cAdam Powell         * This should really be in AccessibilityNodeInfoCompat, but there unfortunately
16083cf6141d516a0a6170823b1bda5c0b6d7500e76cAdam Powell         * seem to be a few elements that are not easily cloneable using the underlying API.
16093cf6141d516a0a6170823b1bda5c0b6d7500e76cAdam Powell         * Leave it private here as it's not general-purpose useful.
16103cf6141d516a0a6170823b1bda5c0b6d7500e76cAdam Powell         */
16113cf6141d516a0a6170823b1bda5c0b6d7500e76cAdam Powell        private void copyNodeInfoNoChildren(AccessibilityNodeInfoCompat dest,
16123cf6141d516a0a6170823b1bda5c0b6d7500e76cAdam Powell                AccessibilityNodeInfoCompat src) {
16133cf6141d516a0a6170823b1bda5c0b6d7500e76cAdam Powell            final Rect rect = mTmpRect;
16143cf6141d516a0a6170823b1bda5c0b6d7500e76cAdam Powell
16153cf6141d516a0a6170823b1bda5c0b6d7500e76cAdam Powell            src.getBoundsInParent(rect);
16163cf6141d516a0a6170823b1bda5c0b6d7500e76cAdam Powell            dest.setBoundsInParent(rect);
16173cf6141d516a0a6170823b1bda5c0b6d7500e76cAdam Powell
16183cf6141d516a0a6170823b1bda5c0b6d7500e76cAdam Powell            src.getBoundsInScreen(rect);
16193cf6141d516a0a6170823b1bda5c0b6d7500e76cAdam Powell            dest.setBoundsInScreen(rect);
16203cf6141d516a0a6170823b1bda5c0b6d7500e76cAdam Powell
16213cf6141d516a0a6170823b1bda5c0b6d7500e76cAdam Powell            dest.setVisibleToUser(src.isVisibleToUser());
16223cf6141d516a0a6170823b1bda5c0b6d7500e76cAdam Powell            dest.setPackageName(src.getPackageName());
16233cf6141d516a0a6170823b1bda5c0b6d7500e76cAdam Powell            dest.setClassName(src.getClassName());
16243cf6141d516a0a6170823b1bda5c0b6d7500e76cAdam Powell            dest.setContentDescription(src.getContentDescription());
16253cf6141d516a0a6170823b1bda5c0b6d7500e76cAdam Powell
16263cf6141d516a0a6170823b1bda5c0b6d7500e76cAdam Powell            dest.setEnabled(src.isEnabled());
16273cf6141d516a0a6170823b1bda5c0b6d7500e76cAdam Powell            dest.setClickable(src.isClickable());
16283cf6141d516a0a6170823b1bda5c0b6d7500e76cAdam Powell            dest.setFocusable(src.isFocusable());
16293cf6141d516a0a6170823b1bda5c0b6d7500e76cAdam Powell            dest.setFocused(src.isFocused());
16303cf6141d516a0a6170823b1bda5c0b6d7500e76cAdam Powell            dest.setAccessibilityFocused(src.isAccessibilityFocused());
16313cf6141d516a0a6170823b1bda5c0b6d7500e76cAdam Powell            dest.setSelected(src.isSelected());
16323cf6141d516a0a6170823b1bda5c0b6d7500e76cAdam Powell            dest.setLongClickable(src.isLongClickable());
16333cf6141d516a0a6170823b1bda5c0b6d7500e76cAdam Powell
16343cf6141d516a0a6170823b1bda5c0b6d7500e76cAdam Powell            dest.addAction(src.getActions());
163551e43399398d051db26ecc85d6de34f310e77dbbAlan Viverette
163651e43399398d051db26ecc85d6de34f310e77dbbAlan Viverette            dest.setMovementGranularities(src.getMovementGranularities());
16373cf6141d516a0a6170823b1bda5c0b6d7500e76cAdam Powell        }
1638c89f53833f1e272d32f7928837f0704fa33be309Adam Powell    }
1639f4445e06a8490b056cd892c4bc640dfd17905d6cAdam Powell
1640f4445e06a8490b056cd892c4bc640dfd17905d6cAdam Powell    private class DisableLayerRunnable implements Runnable {
1641f4445e06a8490b056cd892c4bc640dfd17905d6cAdam Powell        final View mChildView;
1642f4445e06a8490b056cd892c4bc640dfd17905d6cAdam Powell
1643f4445e06a8490b056cd892c4bc640dfd17905d6cAdam Powell        DisableLayerRunnable(View childView) {
1644f4445e06a8490b056cd892c4bc640dfd17905d6cAdam Powell            mChildView = childView;
1645f4445e06a8490b056cd892c4bc640dfd17905d6cAdam Powell        }
1646f4445e06a8490b056cd892c4bc640dfd17905d6cAdam Powell
1647f4445e06a8490b056cd892c4bc640dfd17905d6cAdam Powell        @Override
1648f4445e06a8490b056cd892c4bc640dfd17905d6cAdam Powell        public void run() {
1649f4445e06a8490b056cd892c4bc640dfd17905d6cAdam Powell            if (mChildView.getParent() == SlidingPaneLayout.this) {
1650f4445e06a8490b056cd892c4bc640dfd17905d6cAdam Powell                ViewCompat.setLayerType(mChildView, ViewCompat.LAYER_TYPE_NONE, null);
1651f4445e06a8490b056cd892c4bc640dfd17905d6cAdam Powell                invalidateChildRegion(mChildView);
1652f4445e06a8490b056cd892c4bc640dfd17905d6cAdam Powell            }
1653f4445e06a8490b056cd892c4bc640dfd17905d6cAdam Powell            mPostedRunnables.remove(this);
1654f4445e06a8490b056cd892c4bc640dfd17905d6cAdam Powell        }
1655f4445e06a8490b056cd892c4bc640dfd17905d6cAdam Powell    }
165619780f88506df4aeb57456fd6747af1b6848a11cfafaisland
165719780f88506df4aeb57456fd6747af1b6848a11cfafaisland    private boolean isLayoutRtlSupport() {
165819780f88506df4aeb57456fd6747af1b6848a11cfafaisland        return ViewCompat.getLayoutDirection(this) == ViewCompat.LAYOUT_DIRECTION_RTL;
165919780f88506df4aeb57456fd6747af1b6848a11cfafaisland    }
166097341bdc5bea1d7bf777de65228039142d249f38Adam Powell}
1661