11d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell/* 21d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * Copyright (C) 2013 The Android Open Source Project 31d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * 41d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * Licensed under the Apache License, Version 2.0 (the "License"); 51d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * you may not use this file except in compliance with the License. 61d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * You may obtain a copy of the License at 71d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * 81d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * http://www.apache.org/licenses/LICENSE-2.0 91d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * 101d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * Unless required by applicable law or agreed to in writing, software 111d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * distributed under the License is distributed on an "AS IS" BASIS, 121d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 131d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * See the License for the specific language governing permissions and 141d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * limitations under the License. 151d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell */ 161d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 171d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 181d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powellpackage android.support.v4.widget; 191d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 201d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powellimport android.content.Context; 211d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powellimport android.content.res.TypedArray; 221d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powellimport android.graphics.Canvas; 231d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powellimport android.graphics.Paint; 24b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powellimport android.graphics.PixelFormat; 253cf6141d516a0a6170823b1bda5c0b6d7500e76cAdam Powellimport android.graphics.Rect; 26f9c35128decbd812ff2497852ccacbd1ffbbd811Adam Powellimport android.graphics.drawable.ColorDrawable; 27b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powellimport android.graphics.drawable.Drawable; 28f9c35128decbd812ff2497852ccacbd1ffbbd811Adam Powellimport android.os.Build; 2957902cff6c54c245feea589b06d12dba8f1a2a24Adam Powellimport android.os.Parcel; 3057902cff6c54c245feea589b06d12dba8f1a2a24Adam Powellimport android.os.Parcelable; 31cde2707260e8241ffb816a03cbf5d52c28004b8aAdam Powellimport android.os.SystemClock; 3270acb0c19be3831a2080e4f902324de16bfbf62eTor Norbyeimport android.support.annotation.ColorInt; 33a3ff3273e976adf19770651dcf473fa67b38eb22Tor Norbyeimport android.support.annotation.DrawableRes; 34a3ff3273e976adf19770651dcf473fa67b38eb22Tor Norbyeimport android.support.annotation.IntDef; 353eb01e183e6eef7610881c8b9c0914afbe23b442Chris Banesimport android.support.annotation.NonNull; 36a3ff3273e976adf19770651dcf473fa67b38eb22Tor Norbyeimport android.support.annotation.Nullable; 37f9c35128decbd812ff2497852ccacbd1ffbbd811Adam Powellimport android.support.v4.content.ContextCompat; 38621e41e02c0664afd4e358dfe166d6fb71e471c9Doris Liuimport android.support.v4.graphics.drawable.DrawableCompat; 3905f5ba020fa6caa658c75b6d77436aa980ca0fccChris Banesimport android.support.v4.os.ParcelableCompat; 4005f5ba020fa6caa658c75b6d77436aa980ca0fccChris Banesimport android.support.v4.os.ParcelableCompatCreatorCallbacks; 4105f5ba020fa6caa658c75b6d77436aa980ca0fccChris Banesimport android.support.v4.view.AbsSavedState; 427d0061d5605a1ac298837bee21c0d4eb4a34bd4eAdam Powellimport android.support.v4.view.AccessibilityDelegateCompat; 431d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powellimport android.support.v4.view.GravityCompat; 441d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powellimport android.support.v4.view.MotionEventCompat; 451d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powellimport android.support.v4.view.ViewCompat; 461b8262b87426b2f766b40d6ab4eaeac296d5c2feAdam Powellimport android.support.v4.view.ViewGroupCompat; 477d0061d5605a1ac298837bee21c0d4eb4a34bd4eAdam Powellimport android.support.v4.view.accessibility.AccessibilityNodeInfoCompat; 480a13063f56de4a369ee20e62494dcdda9e37f966Alan Viveretteimport android.support.v4.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat; 491d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powellimport android.util.AttributeSet; 501d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powellimport android.view.Gravity; 51791f31bbba40b8b51694a1b2cdc804f360786ed1Adam Powellimport android.view.KeyEvent; 521d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powellimport android.view.MotionEvent; 531d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powellimport android.view.View; 541d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powellimport android.view.ViewGroup; 553cf6141d516a0a6170823b1bda5c0b6d7500e76cAdam Powellimport android.view.ViewParent; 567d0061d5605a1ac298837bee21c0d4eb4a34bd4eAdam Powellimport android.view.accessibility.AccessibilityEvent; 571d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 58a3ff3273e976adf19770651dcf473fa67b38eb22Tor Norbyeimport java.lang.annotation.Retention; 59a3ff3273e976adf19770651dcf473fa67b38eb22Tor Norbyeimport java.lang.annotation.RetentionPolicy; 60fedd8cbd0fd3f6a62dabffa3970db2d3373d8db8Jun Mukaiimport java.util.ArrayList; 61526ba1382e61845ef23bf27d300883dea0966af5Alan Viveretteimport java.util.List; 62526ba1382e61845ef23bf27d300883dea0966af5Alan Viverette 631d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell/** 641d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * DrawerLayout acts as a top-level container for window content that allows for 65ebe391af34e514420acab4d07fcd26b62a57e490Kirill Grouchnikov * interactive "drawer" views to be pulled out from one or both vertical edges of the window. 661d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * 671d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * <p>Drawer positioning and layout is controlled using the <code>android:layout_gravity</code> 6809c38625b5400dcda3d872dbe865c867cc02e5ebAdam Powell * attribute on child views corresponding to which side of the view you want the drawer 69ebe391af34e514420acab4d07fcd26b62a57e490Kirill Grouchnikov * to emerge from: left or right (or start/end on platform versions that support layout direction.) 70ebe391af34e514420acab4d07fcd26b62a57e490Kirill Grouchnikov * Note that you can only have one drawer view for each vertical edge of the window. If your 71ebe391af34e514420acab4d07fcd26b62a57e490Kirill Grouchnikov * layout configures more than one drawer view per vertical edge of the window, an exception will 72ebe391af34e514420acab4d07fcd26b62a57e490Kirill Grouchnikov * be thrown at runtime. 7309c38625b5400dcda3d872dbe865c867cc02e5ebAdam Powell * </p> 7409c38625b5400dcda3d872dbe865c867cc02e5ebAdam Powell * 7509c38625b5400dcda3d872dbe865c867cc02e5ebAdam Powell * <p>To use a DrawerLayout, position your primary content view as the first child with 76ebe391af34e514420acab4d07fcd26b62a57e490Kirill Grouchnikov * width and height of <code>match_parent</code> and no <code>layout_gravity></code>. 77ebe391af34e514420acab4d07fcd26b62a57e490Kirill Grouchnikov * Add drawers as child views after the main content view and set the <code>layout_gravity</code> 78ebe391af34e514420acab4d07fcd26b62a57e490Kirill Grouchnikov * appropriately. Drawers commonly use <code>match_parent</code> for height with a fixed width.</p> 7909c38625b5400dcda3d872dbe865c867cc02e5ebAdam Powell * 8009c38625b5400dcda3d872dbe865c867cc02e5ebAdam Powell * <p>{@link DrawerListener} can be used to monitor the state and motion of drawer views. 8109c38625b5400dcda3d872dbe865c867cc02e5ebAdam Powell * Avoid performing expensive operations such as layout during animation as it can cause 8209c38625b5400dcda3d872dbe865c867cc02e5ebAdam Powell * stuttering; try to perform expensive operations during the {@link #STATE_IDLE} state. 8309c38625b5400dcda3d872dbe865c867cc02e5ebAdam Powell * {@link SimpleDrawerListener} offers default/no-op implementations of each callback method.</p> 841d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * 8595572937e188a6f5724bfe1217efd04073e2c705Scott Main * <p>As per the <a href="{@docRoot}design/patterns/navigation-drawer.html">Android Design 8695572937e188a6f5724bfe1217efd04073e2c705Scott Main * guide</a>, any drawers positioned to the left/start should 871d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * always contain content for navigating around the application, whereas any drawers 881d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * positioned to the right/end should always contain actions to take on the current content. 891d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * This preserves the same navigation left, actions right structure present in the Action Bar 901d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * and elsewhere.</p> 9195572937e188a6f5724bfe1217efd04073e2c705Scott Main * 9295572937e188a6f5724bfe1217efd04073e2c705Scott Main * <p>For more information about how to use DrawerLayout, read <a 9395572937e188a6f5724bfe1217efd04073e2c705Scott Main * href="{@docRoot}training/implementing-navigation/nav-drawer.html">Creating a Navigation 9495572937e188a6f5724bfe1217efd04073e2c705Scott Main * Drawer</a>.</p> 951d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell */ 96f9c35128decbd812ff2497852ccacbd1ffbbd811Adam Powellpublic class DrawerLayout extends ViewGroup implements DrawerLayoutImpl { 971d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell private static final String TAG = "DrawerLayout"; 981d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 99a3ff3273e976adf19770651dcf473fa67b38eb22Tor Norbye @IntDef({STATE_IDLE, STATE_DRAGGING, STATE_SETTLING}) 100a3ff3273e976adf19770651dcf473fa67b38eb22Tor Norbye @Retention(RetentionPolicy.SOURCE) 101a3ff3273e976adf19770651dcf473fa67b38eb22Tor Norbye private @interface State {} 102a3ff3273e976adf19770651dcf473fa67b38eb22Tor Norbye 1031d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell /** 1041d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * Indicates that any drawers are in an idle, settled state. No animation is in progress. 1051d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell */ 1061d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell public static final int STATE_IDLE = ViewDragHelper.STATE_IDLE; 1071d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 1081d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell /** 1091d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * Indicates that a drawer is currently being dragged by the user. 1101d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell */ 1111d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell public static final int STATE_DRAGGING = ViewDragHelper.STATE_DRAGGING; 1121d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 1131d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell /** 1141d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * Indicates that a drawer is in the process of settling to a final position. 1151d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell */ 1161d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell public static final int STATE_SETTLING = ViewDragHelper.STATE_SETTLING; 1171d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 118b518b3afec21cb8e843f00971bf6c176fe34c371Kirill Grouchnikov @IntDef({LOCK_MODE_UNLOCKED, LOCK_MODE_LOCKED_CLOSED, LOCK_MODE_LOCKED_OPEN, 119b518b3afec21cb8e843f00971bf6c176fe34c371Kirill Grouchnikov LOCK_MODE_UNDEFINED}) 120a3ff3273e976adf19770651dcf473fa67b38eb22Tor Norbye @Retention(RetentionPolicy.SOURCE) 121a3ff3273e976adf19770651dcf473fa67b38eb22Tor Norbye private @interface LockMode {} 122a3ff3273e976adf19770651dcf473fa67b38eb22Tor Norbye 1230492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell /** 1240492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell * The drawer is unlocked. 1250492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell */ 1260492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell public static final int LOCK_MODE_UNLOCKED = 0; 1270492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell 1280492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell /** 1290492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell * The drawer is locked closed. The user may not open it, though 1300492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell * the app may open it programmatically. 1310492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell */ 1320492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell public static final int LOCK_MODE_LOCKED_CLOSED = 1; 1330492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell 1340492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell /** 1350492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell * The drawer is locked open. The user may not close it, though the app 1360492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell * may close it programmatically. 1370492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell */ 1380492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell public static final int LOCK_MODE_LOCKED_OPEN = 2; 1390492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell 140b518b3afec21cb8e843f00971bf6c176fe34c371Kirill Grouchnikov /** 141b518b3afec21cb8e843f00971bf6c176fe34c371Kirill Grouchnikov * The drawer's lock state is reset to default. 142b518b3afec21cb8e843f00971bf6c176fe34c371Kirill Grouchnikov */ 143b518b3afec21cb8e843f00971bf6c176fe34c371Kirill Grouchnikov public static final int LOCK_MODE_UNDEFINED = 3; 144b518b3afec21cb8e843f00971bf6c176fe34c371Kirill Grouchnikov 145a3ff3273e976adf19770651dcf473fa67b38eb22Tor Norbye @IntDef({Gravity.LEFT, Gravity.RIGHT, GravityCompat.START, GravityCompat.END}) 146a3ff3273e976adf19770651dcf473fa67b38eb22Tor Norbye @Retention(RetentionPolicy.SOURCE) 147a3ff3273e976adf19770651dcf473fa67b38eb22Tor Norbye private @interface EdgeGravity {} 148a3ff3273e976adf19770651dcf473fa67b38eb22Tor Norbye 149a3ff3273e976adf19770651dcf473fa67b38eb22Tor Norbye 1501d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell private static final int MIN_DRAWER_MARGIN = 64; // dp 151621e41e02c0664afd4e358dfe166d6fb71e471c9Doris Liu private static final int DRAWER_ELEVATION = 10; //dp 1521d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 1531d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell private static final int DEFAULT_SCRIM_COLOR = 0x99000000; 1541d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 155ea7b10f4d5531713506e98c8093e7aab811f21f3Adam Powell /** 1561732720ad57fe6d01392cd06551f1a25cff0333cAdam Powell * Length of time to delay before peeking the drawer. 1571732720ad57fe6d01392cd06551f1a25cff0333cAdam Powell */ 1581732720ad57fe6d01392cd06551f1a25cff0333cAdam Powell private static final int PEEK_DELAY = 160; // ms 1591732720ad57fe6d01392cd06551f1a25cff0333cAdam Powell 1601732720ad57fe6d01392cd06551f1a25cff0333cAdam Powell /** 16179f95ce3e660d267831067e514ff455156c4381fAdam Powell * Minimum velocity that will be detected as a fling 16279f95ce3e660d267831067e514ff455156c4381fAdam Powell */ 16379f95ce3e660d267831067e514ff455156c4381fAdam Powell private static final int MIN_FLING_VELOCITY = 400; // dips per second 16479f95ce3e660d267831067e514ff455156c4381fAdam Powell 16579f95ce3e660d267831067e514ff455156c4381fAdam Powell /** 166ea7b10f4d5531713506e98c8093e7aab811f21f3Adam Powell * Experimental feature. 167ea7b10f4d5531713506e98c8093e7aab811f21f3Adam Powell */ 168ea7b10f4d5531713506e98c8093e7aab811f21f3Adam Powell private static final boolean ALLOW_EDGE_LOCK = false; 169ea7b10f4d5531713506e98c8093e7aab811f21f3Adam Powell 17086559d86173efb890a8edf48d935cfebfaccf049Adam Powell private static final boolean CHILDREN_DISALLOW_INTERCEPT = true; 17186559d86173efb890a8edf48d935cfebfaccf049Adam Powell 17286559d86173efb890a8edf48d935cfebfaccf049Adam Powell private static final float TOUCH_SLOP_SENSITIVITY = 1.f; 17386559d86173efb890a8edf48d935cfebfaccf049Adam Powell 174540222c3675801eaa141ace1c164c4d3499b4721Aurimas Liutikas static final int[] LAYOUT_ATTRS = new int[] { 1751d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell android.R.attr.layout_gravity 1761d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell }; 1771d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 1782bb8d4e8831b2d0f1de7f15493bb79f48c91db2aAlan Viverette /** Whether we can use NO_HIDE_DESCENDANTS accessibility importance. */ 179540222c3675801eaa141ace1c164c4d3499b4721Aurimas Liutikas static final boolean CAN_HIDE_DESCENDANTS = Build.VERSION.SDK_INT >= 19; 1802bb8d4e8831b2d0f1de7f15493bb79f48c91db2aAlan Viverette 181621e41e02c0664afd4e358dfe166d6fb71e471c9Doris Liu /** Whether the drawer shadow comes from setting elevation on the drawer. */ 182621e41e02c0664afd4e358dfe166d6fb71e471c9Doris Liu private static final boolean SET_DRAWER_SHADOW_FROM_ELEVATION = 183621e41e02c0664afd4e358dfe166d6fb71e471c9Doris Liu Build.VERSION.SDK_INT >= 21; 184621e41e02c0664afd4e358dfe166d6fb71e471c9Doris Liu 18512ba769d9e9b121829c69daf0f6350e808028a6aAlan Viverette private final ChildAccessibilityDelegate mChildAccessibilityDelegate = 18612ba769d9e9b121829c69daf0f6350e808028a6aAlan Viverette new ChildAccessibilityDelegate(); 187621e41e02c0664afd4e358dfe166d6fb71e471c9Doris Liu private float mDrawerElevation; 18812ba769d9e9b121829c69daf0f6350e808028a6aAlan Viverette 1891d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell private int mMinDrawerMargin; 1901d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 1911d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell private int mScrimColor = DEFAULT_SCRIM_COLOR; 1921d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell private float mScrimOpacity; 1931d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell private Paint mScrimPaint = new Paint(); 1941d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 1951d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell private final ViewDragHelper mLeftDragger; 1961d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell private final ViewDragHelper mRightDragger; 1971732720ad57fe6d01392cd06551f1a25cff0333cAdam Powell private final ViewDragCallback mLeftCallback; 1981732720ad57fe6d01392cd06551f1a25cff0333cAdam Powell private final ViewDragCallback mRightCallback; 1991d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell private int mDrawerState; 200b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell private boolean mInLayout; 20157902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell private boolean mFirstLayout = true; 202b518b3afec21cb8e843f00971bf6c176fe34c371Kirill Grouchnikov 203b518b3afec21cb8e843f00971bf6c176fe34c371Kirill Grouchnikov private @LockMode int mLockModeLeft = LOCK_MODE_UNDEFINED; 204b518b3afec21cb8e843f00971bf6c176fe34c371Kirill Grouchnikov private @LockMode int mLockModeRight = LOCK_MODE_UNDEFINED; 205b518b3afec21cb8e843f00971bf6c176fe34c371Kirill Grouchnikov private @LockMode int mLockModeStart = LOCK_MODE_UNDEFINED; 206b518b3afec21cb8e843f00971bf6c176fe34c371Kirill Grouchnikov private @LockMode int mLockModeEnd = LOCK_MODE_UNDEFINED; 207b518b3afec21cb8e843f00971bf6c176fe34c371Kirill Grouchnikov 2081732720ad57fe6d01392cd06551f1a25cff0333cAdam Powell private boolean mDisallowInterceptRequested; 209cde2707260e8241ffb816a03cbf5d52c28004b8aAdam Powell private boolean mChildrenCanceledTouch; 2101d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 211d805095048f6be52cddbd572ee343c4639ba8187Alan Viverette private @Nullable DrawerListener mListener; 2123eb01e183e6eef7610881c8b9c0914afbe23b442Chris Banes private List<DrawerListener> mListeners; 2131d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 2141d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell private float mInitialMotionX; 2151d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell private float mInitialMotionY; 2161d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 217f9c35128decbd812ff2497852ccacbd1ffbbd811Adam Powell private Drawable mStatusBarBackground; 218621e41e02c0664afd4e358dfe166d6fb71e471c9Doris Liu private Drawable mShadowLeftResolved; 219621e41e02c0664afd4e358dfe166d6fb71e471c9Doris Liu private Drawable mShadowRightResolved; 220b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell 221526ba1382e61845ef23bf27d300883dea0966af5Alan Viverette private CharSequence mTitleLeft; 222526ba1382e61845ef23bf27d300883dea0966af5Alan Viverette private CharSequence mTitleRight; 223526ba1382e61845ef23bf27d300883dea0966af5Alan Viverette 224f9c35128decbd812ff2497852ccacbd1ffbbd811Adam Powell private Object mLastInsets; 225f9c35128decbd812ff2497852ccacbd1ffbbd811Adam Powell private boolean mDrawStatusBarBackground; 226f9c35128decbd812ff2497852ccacbd1ffbbd811Adam Powell 227621e41e02c0664afd4e358dfe166d6fb71e471c9Doris Liu /** Shadow drawables for different gravity */ 228621e41e02c0664afd4e358dfe166d6fb71e471c9Doris Liu private Drawable mShadowStart = null; 229621e41e02c0664afd4e358dfe166d6fb71e471c9Doris Liu private Drawable mShadowEnd = null; 230621e41e02c0664afd4e358dfe166d6fb71e471c9Doris Liu private Drawable mShadowLeft = null; 231621e41e02c0664afd4e358dfe166d6fb71e471c9Doris Liu private Drawable mShadowRight = null; 232621e41e02c0664afd4e358dfe166d6fb71e471c9Doris Liu 233fedd8cbd0fd3f6a62dabffa3970db2d3373d8db8Jun Mukai private final ArrayList<View> mNonDrawerViews; 234fedd8cbd0fd3f6a62dabffa3970db2d3373d8db8Jun Mukai 2351d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell /** 2361d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * Listener for monitoring events about drawers. 2371d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell */ 2381d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell public interface DrawerListener { 2391d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell /** 2401d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * Called when a drawer's position changes. 2411d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * @param drawerView The child view that was moved 2421d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * @param slideOffset The new offset of this drawer within its range, from 0-1 2431d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell */ 2444d2c7b7c4f194034c5f17c4bee7320d808aabe4cAurimas Liutikas void onDrawerSlide(View drawerView, float slideOffset); 2451d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 2461d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell /** 2471d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * Called when a drawer has settled in a completely open state. 2481d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * The drawer is interactive at this point. 2491d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * 2501d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * @param drawerView Drawer view that is now open 2511d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell */ 2524d2c7b7c4f194034c5f17c4bee7320d808aabe4cAurimas Liutikas void onDrawerOpened(View drawerView); 2531d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 2541d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell /** 2551d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * Called when a drawer has settled in a completely closed state. 2561d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * 2571d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * @param drawerView Drawer view that is now closed 2581d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell */ 2594d2c7b7c4f194034c5f17c4bee7320d808aabe4cAurimas Liutikas void onDrawerClosed(View drawerView); 2601d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 2611d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell /** 2621d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * Called when the drawer motion state changes. The new state will 2631d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * be one of {@link #STATE_IDLE}, {@link #STATE_DRAGGING} or {@link #STATE_SETTLING}. 2641d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * 2651d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * @param newState The new drawer motion state 2661d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell */ 2674d2c7b7c4f194034c5f17c4bee7320d808aabe4cAurimas Liutikas void onDrawerStateChanged(@State int newState); 2681d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 2691d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 270b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell /** 271b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell * Stub/no-op implementations of all methods of {@link DrawerListener}. 272b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell * Override this if you only care about a few of the available callback methods. 273b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell */ 2744d2c7b7c4f194034c5f17c4bee7320d808aabe4cAurimas Liutikas public abstract static class SimpleDrawerListener implements DrawerListener { 275b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell @Override 276b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell public void onDrawerSlide(View drawerView, float slideOffset) { 277b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell } 278b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell 279b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell @Override 280b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell public void onDrawerOpened(View drawerView) { 281b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell } 282b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell 283b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell @Override 284b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell public void onDrawerClosed(View drawerView) { 285b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell } 286b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell 287b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell @Override 288b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell public void onDrawerStateChanged(int newState) { 289b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell } 290b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell } 291b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell 292f9c35128decbd812ff2497852ccacbd1ffbbd811Adam Powell interface DrawerLayoutCompatImpl { 293f9c35128decbd812ff2497852ccacbd1ffbbd811Adam Powell void configureApplyInsets(View drawerLayout); 294f9c35128decbd812ff2497852ccacbd1ffbbd811Adam Powell void dispatchChildInsets(View child, Object insets, int drawerGravity); 295f9c35128decbd812ff2497852ccacbd1ffbbd811Adam Powell void applyMarginInsets(MarginLayoutParams lp, Object insets, int drawerGravity); 296f9c35128decbd812ff2497852ccacbd1ffbbd811Adam Powell int getTopInset(Object lastInsets); 29784cdd567de45ea632670d51da5fb4545248d073bChris Banes Drawable getDefaultStatusBarBackground(Context context); 298f9c35128decbd812ff2497852ccacbd1ffbbd811Adam Powell } 299f9c35128decbd812ff2497852ccacbd1ffbbd811Adam Powell 300f9c35128decbd812ff2497852ccacbd1ffbbd811Adam Powell static class DrawerLayoutCompatImplBase implements DrawerLayoutCompatImpl { 30115375aa6fd54b036f97f99229aefab2822c8a1c9Aurimas Liutikas @Override 302f9c35128decbd812ff2497852ccacbd1ffbbd811Adam Powell public void configureApplyInsets(View drawerLayout) { 303f9c35128decbd812ff2497852ccacbd1ffbbd811Adam Powell // This space for rent 304f9c35128decbd812ff2497852ccacbd1ffbbd811Adam Powell } 305f9c35128decbd812ff2497852ccacbd1ffbbd811Adam Powell 30615375aa6fd54b036f97f99229aefab2822c8a1c9Aurimas Liutikas @Override 307f9c35128decbd812ff2497852ccacbd1ffbbd811Adam Powell public void dispatchChildInsets(View child, Object insets, int drawerGravity) { 308f9c35128decbd812ff2497852ccacbd1ffbbd811Adam Powell // This space for rent 309f9c35128decbd812ff2497852ccacbd1ffbbd811Adam Powell } 310f9c35128decbd812ff2497852ccacbd1ffbbd811Adam Powell 31115375aa6fd54b036f97f99229aefab2822c8a1c9Aurimas Liutikas @Override 312f9c35128decbd812ff2497852ccacbd1ffbbd811Adam Powell public void applyMarginInsets(MarginLayoutParams lp, Object insets, int drawerGravity) { 313f9c35128decbd812ff2497852ccacbd1ffbbd811Adam Powell // This space for rent 314f9c35128decbd812ff2497852ccacbd1ffbbd811Adam Powell } 315f9c35128decbd812ff2497852ccacbd1ffbbd811Adam Powell 31615375aa6fd54b036f97f99229aefab2822c8a1c9Aurimas Liutikas @Override 317f9c35128decbd812ff2497852ccacbd1ffbbd811Adam Powell public int getTopInset(Object insets) { 318f9c35128decbd812ff2497852ccacbd1ffbbd811Adam Powell return 0; 319f9c35128decbd812ff2497852ccacbd1ffbbd811Adam Powell } 32084cdd567de45ea632670d51da5fb4545248d073bChris Banes 32184cdd567de45ea632670d51da5fb4545248d073bChris Banes @Override 32284cdd567de45ea632670d51da5fb4545248d073bChris Banes public Drawable getDefaultStatusBarBackground(Context context) { 32384cdd567de45ea632670d51da5fb4545248d073bChris Banes return null; 32484cdd567de45ea632670d51da5fb4545248d073bChris Banes } 325f9c35128decbd812ff2497852ccacbd1ffbbd811Adam Powell } 326f9c35128decbd812ff2497852ccacbd1ffbbd811Adam Powell 327f9c35128decbd812ff2497852ccacbd1ffbbd811Adam Powell static class DrawerLayoutCompatImplApi21 implements DrawerLayoutCompatImpl { 32815375aa6fd54b036f97f99229aefab2822c8a1c9Aurimas Liutikas @Override 329f9c35128decbd812ff2497852ccacbd1ffbbd811Adam Powell public void configureApplyInsets(View drawerLayout) { 330f9c35128decbd812ff2497852ccacbd1ffbbd811Adam Powell DrawerLayoutCompatApi21.configureApplyInsets(drawerLayout); 331f9c35128decbd812ff2497852ccacbd1ffbbd811Adam Powell } 332f9c35128decbd812ff2497852ccacbd1ffbbd811Adam Powell 33315375aa6fd54b036f97f99229aefab2822c8a1c9Aurimas Liutikas @Override 334f9c35128decbd812ff2497852ccacbd1ffbbd811Adam Powell public void dispatchChildInsets(View child, Object insets, int drawerGravity) { 335f9c35128decbd812ff2497852ccacbd1ffbbd811Adam Powell DrawerLayoutCompatApi21.dispatchChildInsets(child, insets, drawerGravity); 336f9c35128decbd812ff2497852ccacbd1ffbbd811Adam Powell } 337f9c35128decbd812ff2497852ccacbd1ffbbd811Adam Powell 33815375aa6fd54b036f97f99229aefab2822c8a1c9Aurimas Liutikas @Override 339f9c35128decbd812ff2497852ccacbd1ffbbd811Adam Powell public void applyMarginInsets(MarginLayoutParams lp, Object insets, int drawerGravity) { 340f9c35128decbd812ff2497852ccacbd1ffbbd811Adam Powell DrawerLayoutCompatApi21.applyMarginInsets(lp, insets, drawerGravity); 341f9c35128decbd812ff2497852ccacbd1ffbbd811Adam Powell } 342f9c35128decbd812ff2497852ccacbd1ffbbd811Adam Powell 34315375aa6fd54b036f97f99229aefab2822c8a1c9Aurimas Liutikas @Override 344f9c35128decbd812ff2497852ccacbd1ffbbd811Adam Powell public int getTopInset(Object insets) { 345f9c35128decbd812ff2497852ccacbd1ffbbd811Adam Powell return DrawerLayoutCompatApi21.getTopInset(insets); 346f9c35128decbd812ff2497852ccacbd1ffbbd811Adam Powell } 34784cdd567de45ea632670d51da5fb4545248d073bChris Banes 34884cdd567de45ea632670d51da5fb4545248d073bChris Banes @Override 34984cdd567de45ea632670d51da5fb4545248d073bChris Banes public Drawable getDefaultStatusBarBackground(Context context) { 35084cdd567de45ea632670d51da5fb4545248d073bChris Banes return DrawerLayoutCompatApi21.getDefaultStatusBarBackground(context); 35184cdd567de45ea632670d51da5fb4545248d073bChris Banes } 352f9c35128decbd812ff2497852ccacbd1ffbbd811Adam Powell } 353f9c35128decbd812ff2497852ccacbd1ffbbd811Adam Powell 354f9c35128decbd812ff2497852ccacbd1ffbbd811Adam Powell static { 355f9c35128decbd812ff2497852ccacbd1ffbbd811Adam Powell final int version = Build.VERSION.SDK_INT; 356f9c35128decbd812ff2497852ccacbd1ffbbd811Adam Powell if (version >= 21) { 357f9c35128decbd812ff2497852ccacbd1ffbbd811Adam Powell IMPL = new DrawerLayoutCompatImplApi21(); 358f9c35128decbd812ff2497852ccacbd1ffbbd811Adam Powell } else { 359f9c35128decbd812ff2497852ccacbd1ffbbd811Adam Powell IMPL = new DrawerLayoutCompatImplBase(); 360f9c35128decbd812ff2497852ccacbd1ffbbd811Adam Powell } 361f9c35128decbd812ff2497852ccacbd1ffbbd811Adam Powell } 362f9c35128decbd812ff2497852ccacbd1ffbbd811Adam Powell 363f9c35128decbd812ff2497852ccacbd1ffbbd811Adam Powell static final DrawerLayoutCompatImpl IMPL; 364f9c35128decbd812ff2497852ccacbd1ffbbd811Adam Powell 3651d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell public DrawerLayout(Context context) { 3661d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell this(context, null); 3671d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 3681d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 3691d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell public DrawerLayout(Context context, AttributeSet attrs) { 3701d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell this(context, attrs, 0); 3711d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 3721d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 3731d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell public DrawerLayout(Context context, AttributeSet attrs, int defStyle) { 3741d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell super(context, attrs, defStyle); 3754a069be655204ec079c03a09157e5d4ec223a0f7Yigit Boyar setDescendantFocusability(ViewGroup.FOCUS_AFTER_DESCENDANTS); 3761d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final float density = getResources().getDisplayMetrics().density; 3771d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell mMinDrawerMargin = (int) (MIN_DRAWER_MARGIN * density + 0.5f); 37879f95ce3e660d267831067e514ff455156c4381fAdam Powell final float minVel = MIN_FLING_VELOCITY * density; 3791d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 3801732720ad57fe6d01392cd06551f1a25cff0333cAdam Powell mLeftCallback = new ViewDragCallback(Gravity.LEFT); 3811732720ad57fe6d01392cd06551f1a25cff0333cAdam Powell mRightCallback = new ViewDragCallback(Gravity.RIGHT); 3821d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 38386559d86173efb890a8edf48d935cfebfaccf049Adam Powell mLeftDragger = ViewDragHelper.create(this, TOUCH_SLOP_SENSITIVITY, mLeftCallback); 3841d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell mLeftDragger.setEdgeTrackingEnabled(ViewDragHelper.EDGE_LEFT); 38579f95ce3e660d267831067e514ff455156c4381fAdam Powell mLeftDragger.setMinVelocity(minVel); 3861732720ad57fe6d01392cd06551f1a25cff0333cAdam Powell mLeftCallback.setDragger(mLeftDragger); 3871d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 38886559d86173efb890a8edf48d935cfebfaccf049Adam Powell mRightDragger = ViewDragHelper.create(this, TOUCH_SLOP_SENSITIVITY, mRightCallback); 3891d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell mRightDragger.setEdgeTrackingEnabled(ViewDragHelper.EDGE_RIGHT); 39079f95ce3e660d267831067e514ff455156c4381fAdam Powell mRightDragger.setMinVelocity(minVel); 3911732720ad57fe6d01392cd06551f1a25cff0333cAdam Powell mRightCallback.setDragger(mRightDragger); 392791f31bbba40b8b51694a1b2cdc804f360786ed1Adam Powell 393791f31bbba40b8b51694a1b2cdc804f360786ed1Adam Powell // So that we can catch the back button 394791f31bbba40b8b51694a1b2cdc804f360786ed1Adam Powell setFocusableInTouchMode(true); 3957d0061d5605a1ac298837bee21c0d4eb4a34bd4eAdam Powell 39612ba769d9e9b121829c69daf0f6350e808028a6aAlan Viverette ViewCompat.setImportantForAccessibility(this, 39712ba769d9e9b121829c69daf0f6350e808028a6aAlan Viverette ViewCompat.IMPORTANT_FOR_ACCESSIBILITY_YES); 39812ba769d9e9b121829c69daf0f6350e808028a6aAlan Viverette 3997d0061d5605a1ac298837bee21c0d4eb4a34bd4eAdam Powell ViewCompat.setAccessibilityDelegate(this, new AccessibilityDelegate()); 4001b8262b87426b2f766b40d6ab4eaeac296d5c2feAdam Powell ViewGroupCompat.setMotionEventSplittingEnabled(this, false); 40199cb2bbfcd84bdc2e89a5a2d11b6b69132169ea6Adam Powell if (ViewCompat.getFitsSystemWindows(this)) { 40299cb2bbfcd84bdc2e89a5a2d11b6b69132169ea6Adam Powell IMPL.configureApplyInsets(this); 40384cdd567de45ea632670d51da5fb4545248d073bChris Banes mStatusBarBackground = IMPL.getDefaultStatusBarBackground(context); 40499cb2bbfcd84bdc2e89a5a2d11b6b69132169ea6Adam Powell } 405621e41e02c0664afd4e358dfe166d6fb71e471c9Doris Liu 406621e41e02c0664afd4e358dfe166d6fb71e471c9Doris Liu mDrawerElevation = DRAWER_ELEVATION * density; 407fedd8cbd0fd3f6a62dabffa3970db2d3373d8db8Jun Mukai 408fedd8cbd0fd3f6a62dabffa3970db2d3373d8db8Jun Mukai mNonDrawerViews = new ArrayList<View>(); 409621e41e02c0664afd4e358dfe166d6fb71e471c9Doris Liu } 410621e41e02c0664afd4e358dfe166d6fb71e471c9Doris Liu 411621e41e02c0664afd4e358dfe166d6fb71e471c9Doris Liu /** 412621e41e02c0664afd4e358dfe166d6fb71e471c9Doris Liu * Sets the base elevation of the drawer(s) relative to the parent, in pixels. Note that the 413621e41e02c0664afd4e358dfe166d6fb71e471c9Doris Liu * elevation change is only supported in API 21 and above. 414621e41e02c0664afd4e358dfe166d6fb71e471c9Doris Liu * 415621e41e02c0664afd4e358dfe166d6fb71e471c9Doris Liu * @param elevation The base depth position of the view, in pixels. 416621e41e02c0664afd4e358dfe166d6fb71e471c9Doris Liu */ 417621e41e02c0664afd4e358dfe166d6fb71e471c9Doris Liu public void setDrawerElevation(float elevation) { 418621e41e02c0664afd4e358dfe166d6fb71e471c9Doris Liu mDrawerElevation = elevation; 419621e41e02c0664afd4e358dfe166d6fb71e471c9Doris Liu for (int i = 0; i < getChildCount(); i++) { 420621e41e02c0664afd4e358dfe166d6fb71e471c9Doris Liu View child = getChildAt(i); 421621e41e02c0664afd4e358dfe166d6fb71e471c9Doris Liu if (isDrawerView(child)) { 422621e41e02c0664afd4e358dfe166d6fb71e471c9Doris Liu ViewCompat.setElevation(child, mDrawerElevation); 423621e41e02c0664afd4e358dfe166d6fb71e471c9Doris Liu } 424621e41e02c0664afd4e358dfe166d6fb71e471c9Doris Liu } 425621e41e02c0664afd4e358dfe166d6fb71e471c9Doris Liu } 426621e41e02c0664afd4e358dfe166d6fb71e471c9Doris Liu 427621e41e02c0664afd4e358dfe166d6fb71e471c9Doris Liu /** 428621e41e02c0664afd4e358dfe166d6fb71e471c9Doris Liu * The base elevation of the drawer(s) relative to the parent, in pixels. Note that the 429621e41e02c0664afd4e358dfe166d6fb71e471c9Doris Liu * elevation change is only supported in API 21 and above. For unsupported API levels, 0 will 430621e41e02c0664afd4e358dfe166d6fb71e471c9Doris Liu * be returned as the elevation. 431621e41e02c0664afd4e358dfe166d6fb71e471c9Doris Liu * 432621e41e02c0664afd4e358dfe166d6fb71e471c9Doris Liu * @return The base depth position of the view, in pixels. 433621e41e02c0664afd4e358dfe166d6fb71e471c9Doris Liu */ 434621e41e02c0664afd4e358dfe166d6fb71e471c9Doris Liu public float getDrawerElevation() { 435621e41e02c0664afd4e358dfe166d6fb71e471c9Doris Liu if (SET_DRAWER_SHADOW_FROM_ELEVATION) { 436621e41e02c0664afd4e358dfe166d6fb71e471c9Doris Liu return mDrawerElevation; 437621e41e02c0664afd4e358dfe166d6fb71e471c9Doris Liu } 438621e41e02c0664afd4e358dfe166d6fb71e471c9Doris Liu return 0f; 439f9c35128decbd812ff2497852ccacbd1ffbbd811Adam Powell } 440f9c35128decbd812ff2497852ccacbd1ffbbd811Adam Powell 441f9c35128decbd812ff2497852ccacbd1ffbbd811Adam Powell /** 442f9c35128decbd812ff2497852ccacbd1ffbbd811Adam Powell * @hide Internal use only; called to apply window insets when configured 443f9c35128decbd812ff2497852ccacbd1ffbbd811Adam Powell * with fitsSystemWindows="true" 444f9c35128decbd812ff2497852ccacbd1ffbbd811Adam Powell */ 445f9c35128decbd812ff2497852ccacbd1ffbbd811Adam Powell @Override 446f9c35128decbd812ff2497852ccacbd1ffbbd811Adam Powell public void setChildInsets(Object insets, boolean draw) { 447f9c35128decbd812ff2497852ccacbd1ffbbd811Adam Powell mLastInsets = insets; 448f9c35128decbd812ff2497852ccacbd1ffbbd811Adam Powell mDrawStatusBarBackground = draw; 449f9c35128decbd812ff2497852ccacbd1ffbbd811Adam Powell setWillNotDraw(!draw && getBackground() == null); 450f9c35128decbd812ff2497852ccacbd1ffbbd811Adam Powell requestLayout(); 4511d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 4521d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 4531d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell /** 454621e41e02c0664afd4e358dfe166d6fb71e471c9Doris Liu * Set a simple drawable used for the left or right shadow. The drawable provided must have a 455621e41e02c0664afd4e358dfe166d6fb71e471c9Doris Liu * nonzero intrinsic width. For API 21 and above, an elevation will be set on the drawer 456621e41e02c0664afd4e358dfe166d6fb71e471c9Doris Liu * instead of the drawable provided. 457621e41e02c0664afd4e358dfe166d6fb71e471c9Doris Liu * 458621e41e02c0664afd4e358dfe166d6fb71e471c9Doris Liu * <p>Note that for better support for both left-to-right and right-to-left layout 459621e41e02c0664afd4e358dfe166d6fb71e471c9Doris Liu * directions, a drawable for RTL layout (in additional to the one in LTR layout) can be 460621e41e02c0664afd4e358dfe166d6fb71e471c9Doris Liu * defined with a resource qualifier "ldrtl" for API 17 and above with the gravity 461621e41e02c0664afd4e358dfe166d6fb71e471c9Doris Liu * {@link GravityCompat#START}. Alternatively, for API 23 and above, the drawable can 462621e41e02c0664afd4e358dfe166d6fb71e471c9Doris Liu * auto-mirrored such that the drawable will be mirrored in RTL layout.</p> 463b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell * 464b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell * @param shadowDrawable Shadow drawable to use at the edge of a drawer 465b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell * @param gravity Which drawer the shadow should apply to 466b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell */ 467a3ff3273e976adf19770651dcf473fa67b38eb22Tor Norbye public void setDrawerShadow(Drawable shadowDrawable, @EdgeGravity int gravity) { 468b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell /* 469b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell * TODO Someone someday might want to set more complex drawables here. 470b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell * They're probably nuts, but we might want to consider registering callbacks, 471b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell * setting states, etc. properly. 472b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell */ 473621e41e02c0664afd4e358dfe166d6fb71e471c9Doris Liu if (SET_DRAWER_SHADOW_FROM_ELEVATION) { 474621e41e02c0664afd4e358dfe166d6fb71e471c9Doris Liu // No op. Drawer shadow will come from setting an elevation on the drawer. 475621e41e02c0664afd4e358dfe166d6fb71e471c9Doris Liu return; 476b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell } 477621e41e02c0664afd4e358dfe166d6fb71e471c9Doris Liu if ((gravity & GravityCompat.START) == GravityCompat.START) { 478621e41e02c0664afd4e358dfe166d6fb71e471c9Doris Liu mShadowStart = shadowDrawable; 479621e41e02c0664afd4e358dfe166d6fb71e471c9Doris Liu } else if ((gravity & GravityCompat.END) == GravityCompat.END) { 480621e41e02c0664afd4e358dfe166d6fb71e471c9Doris Liu mShadowEnd = shadowDrawable; 481621e41e02c0664afd4e358dfe166d6fb71e471c9Doris Liu } else if ((gravity & Gravity.LEFT) == Gravity.LEFT) { 482621e41e02c0664afd4e358dfe166d6fb71e471c9Doris Liu mShadowLeft = shadowDrawable; 483621e41e02c0664afd4e358dfe166d6fb71e471c9Doris Liu } else if ((gravity & Gravity.RIGHT) == Gravity.RIGHT) { 484b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell mShadowRight = shadowDrawable; 485621e41e02c0664afd4e358dfe166d6fb71e471c9Doris Liu } else { 486621e41e02c0664afd4e358dfe166d6fb71e471c9Doris Liu return; 487b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell } 488621e41e02c0664afd4e358dfe166d6fb71e471c9Doris Liu resolveShadowDrawables(); 489621e41e02c0664afd4e358dfe166d6fb71e471c9Doris Liu invalidate(); 490b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell } 491b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell 492b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell /** 493621e41e02c0664afd4e358dfe166d6fb71e471c9Doris Liu * Set a simple drawable used for the left or right shadow. The drawable provided must have a 494621e41e02c0664afd4e358dfe166d6fb71e471c9Doris Liu * nonzero intrinsic width. For API 21 and above, an elevation will be set on the drawer 495621e41e02c0664afd4e358dfe166d6fb71e471c9Doris Liu * instead of the drawable provided. 496621e41e02c0664afd4e358dfe166d6fb71e471c9Doris Liu * 497621e41e02c0664afd4e358dfe166d6fb71e471c9Doris Liu * <p>Note that for better support for both left-to-right and right-to-left layout 498621e41e02c0664afd4e358dfe166d6fb71e471c9Doris Liu * directions, a drawable for RTL layout (in additional to the one in LTR layout) can be 499621e41e02c0664afd4e358dfe166d6fb71e471c9Doris Liu * defined with a resource qualifier "ldrtl" for API 17 and above with the gravity 500621e41e02c0664afd4e358dfe166d6fb71e471c9Doris Liu * {@link GravityCompat#START}. Alternatively, for API 23 and above, the drawable can 501621e41e02c0664afd4e358dfe166d6fb71e471c9Doris Liu * auto-mirrored such that the drawable will be mirrored in RTL layout.</p> 502b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell * 503b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell * @param resId Resource id of a shadow drawable to use at the edge of a drawer 504b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell * @param gravity Which drawer the shadow should apply to 505b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell */ 506a3ff3273e976adf19770651dcf473fa67b38eb22Tor Norbye public void setDrawerShadow(@DrawableRes int resId, @EdgeGravity int gravity) { 507e5faeaff97f60817cde21f0f92513845355a7d0dAurimas Liutikas setDrawerShadow(ContextCompat.getDrawable(getContext(), resId), gravity); 508b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell } 509b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell 510b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell /** 511fe130779be95af79e875bdbeac7182a424b8b9a6Adam Powell * Set a color to use for the scrim that obscures primary content while a drawer is open. 512fe130779be95af79e875bdbeac7182a424b8b9a6Adam Powell * 513fe130779be95af79e875bdbeac7182a424b8b9a6Adam Powell * @param color Color to use in 0xAARRGGBB format. 514fe130779be95af79e875bdbeac7182a424b8b9a6Adam Powell */ 51570acb0c19be3831a2080e4f902324de16bfbf62eTor Norbye public void setScrimColor(@ColorInt int color) { 516fe130779be95af79e875bdbeac7182a424b8b9a6Adam Powell mScrimColor = color; 517fe130779be95af79e875bdbeac7182a424b8b9a6Adam Powell invalidate(); 518fe130779be95af79e875bdbeac7182a424b8b9a6Adam Powell } 519fe130779be95af79e875bdbeac7182a424b8b9a6Adam Powell 520fe130779be95af79e875bdbeac7182a424b8b9a6Adam Powell /** 5213eb01e183e6eef7610881c8b9c0914afbe23b442Chris Banes * Set a listener to be notified of drawer events. Note that this method is deprecated 5223eb01e183e6eef7610881c8b9c0914afbe23b442Chris Banes * and you should use {@link #addDrawerListener(DrawerListener)} to add a listener and 5233eb01e183e6eef7610881c8b9c0914afbe23b442Chris Banes * {@link #removeDrawerListener(DrawerListener)} to remove a registered listener. 5241d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * 5251d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * @param listener Listener to notify when drawer events occur 526d805095048f6be52cddbd572ee343c4639ba8187Alan Viverette * @deprecated Use {@link #addDrawerListener(DrawerListener)} 5271d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * @see DrawerListener 5283eb01e183e6eef7610881c8b9c0914afbe23b442Chris Banes * @see #addDrawerListener(DrawerListener) 5293eb01e183e6eef7610881c8b9c0914afbe23b442Chris Banes * @see #removeDrawerListener(DrawerListener) 5301d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell */ 5313eb01e183e6eef7610881c8b9c0914afbe23b442Chris Banes @Deprecated 5321d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell public void setDrawerListener(DrawerListener listener) { 5333eb01e183e6eef7610881c8b9c0914afbe23b442Chris Banes // The logic in this method emulates what we had before support for multiple 5343eb01e183e6eef7610881c8b9c0914afbe23b442Chris Banes // registered listeners. 5353eb01e183e6eef7610881c8b9c0914afbe23b442Chris Banes if (mListener != null) { 5363eb01e183e6eef7610881c8b9c0914afbe23b442Chris Banes removeDrawerListener(mListener); 5373eb01e183e6eef7610881c8b9c0914afbe23b442Chris Banes } 5383eb01e183e6eef7610881c8b9c0914afbe23b442Chris Banes if (listener != null) { 5393eb01e183e6eef7610881c8b9c0914afbe23b442Chris Banes addDrawerListener(listener); 5403eb01e183e6eef7610881c8b9c0914afbe23b442Chris Banes } 5413eb01e183e6eef7610881c8b9c0914afbe23b442Chris Banes // Update the deprecated field so that we can remove the passed listener the next 5423eb01e183e6eef7610881c8b9c0914afbe23b442Chris Banes // time we're called 5431d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell mListener = listener; 5441d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 5451d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 5461d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell /** 5473eb01e183e6eef7610881c8b9c0914afbe23b442Chris Banes * Adds the specified listener to the list of listeners that will be notified of drawer events. 5483eb01e183e6eef7610881c8b9c0914afbe23b442Chris Banes * 5493eb01e183e6eef7610881c8b9c0914afbe23b442Chris Banes * @param listener Listener to notify when drawer events occur. 5503eb01e183e6eef7610881c8b9c0914afbe23b442Chris Banes * @see #removeDrawerListener(DrawerListener) 5513eb01e183e6eef7610881c8b9c0914afbe23b442Chris Banes */ 5523eb01e183e6eef7610881c8b9c0914afbe23b442Chris Banes public void addDrawerListener(@NonNull DrawerListener listener) { 5533eb01e183e6eef7610881c8b9c0914afbe23b442Chris Banes if (listener == null) { 5543eb01e183e6eef7610881c8b9c0914afbe23b442Chris Banes return; 5553eb01e183e6eef7610881c8b9c0914afbe23b442Chris Banes } 5563eb01e183e6eef7610881c8b9c0914afbe23b442Chris Banes if (mListeners == null) { 5573eb01e183e6eef7610881c8b9c0914afbe23b442Chris Banes mListeners = new ArrayList<DrawerListener>(); 5583eb01e183e6eef7610881c8b9c0914afbe23b442Chris Banes } 5593eb01e183e6eef7610881c8b9c0914afbe23b442Chris Banes mListeners.add(listener); 5603eb01e183e6eef7610881c8b9c0914afbe23b442Chris Banes } 5613eb01e183e6eef7610881c8b9c0914afbe23b442Chris Banes 5623eb01e183e6eef7610881c8b9c0914afbe23b442Chris Banes /** 5633eb01e183e6eef7610881c8b9c0914afbe23b442Chris Banes * Removes the specified listener from the list of listeners that will be notified of drawer 5643eb01e183e6eef7610881c8b9c0914afbe23b442Chris Banes * events. 5653eb01e183e6eef7610881c8b9c0914afbe23b442Chris Banes * 5663eb01e183e6eef7610881c8b9c0914afbe23b442Chris Banes * @param listener Listener to remove from being notified of drawer events 5673eb01e183e6eef7610881c8b9c0914afbe23b442Chris Banes * @see #addDrawerListener(DrawerListener) 5683eb01e183e6eef7610881c8b9c0914afbe23b442Chris Banes */ 5693eb01e183e6eef7610881c8b9c0914afbe23b442Chris Banes public void removeDrawerListener(@NonNull DrawerListener listener) { 5703eb01e183e6eef7610881c8b9c0914afbe23b442Chris Banes if (listener == null) { 5713eb01e183e6eef7610881c8b9c0914afbe23b442Chris Banes return; 5723eb01e183e6eef7610881c8b9c0914afbe23b442Chris Banes } 573c19888d785a8ae316c580086c7a8c3fb30f41870Kirill Grouchnikov if (mListeners == null) { 574c19888d785a8ae316c580086c7a8c3fb30f41870Kirill Grouchnikov // This can happen if this method is called before the first call to addDrawerListener 575c19888d785a8ae316c580086c7a8c3fb30f41870Kirill Grouchnikov return; 576c19888d785a8ae316c580086c7a8c3fb30f41870Kirill Grouchnikov } 5773eb01e183e6eef7610881c8b9c0914afbe23b442Chris Banes mListeners.remove(listener); 5783eb01e183e6eef7610881c8b9c0914afbe23b442Chris Banes } 5793eb01e183e6eef7610881c8b9c0914afbe23b442Chris Banes 5803eb01e183e6eef7610881c8b9c0914afbe23b442Chris Banes /** 5810492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell * Enable or disable interaction with all drawers. 5820492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell * 5830492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell * <p>This allows the application to restrict the user's ability to open or close 5840492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell * any drawer within this layout. DrawerLayout will still respond to calls to 5850492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell * {@link #openDrawer(int)}, {@link #closeDrawer(int)} and friends if a drawer is locked.</p> 5860492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell * 5870492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell * <p>Locking drawers open or closed will implicitly open or close 5880492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell * any drawers as appropriate.</p> 5890492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell * 5900492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell * @param lockMode The new lock mode for the given drawer. One of {@link #LOCK_MODE_UNLOCKED}, 5910492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell * {@link #LOCK_MODE_LOCKED_CLOSED} or {@link #LOCK_MODE_LOCKED_OPEN}. 5920492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell */ 593a3ff3273e976adf19770651dcf473fa67b38eb22Tor Norbye public void setDrawerLockMode(@LockMode int lockMode) { 5940492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell setDrawerLockMode(lockMode, Gravity.LEFT); 5950492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell setDrawerLockMode(lockMode, Gravity.RIGHT); 5960492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell } 5970492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell 5980492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell /** 5990492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell * Enable or disable interaction with the given drawer. 6000492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell * 6010492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell * <p>This allows the application to restrict the user's ability to open or close 6020492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell * the given drawer. DrawerLayout will still respond to calls to {@link #openDrawer(int)}, 6030492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell * {@link #closeDrawer(int)} and friends if a drawer is locked.</p> 6040492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell * 6050492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell * <p>Locking a drawer open or closed will implicitly open or close 6060492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell * that drawer as appropriate.</p> 6070492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell * 6080492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell * @param lockMode The new lock mode for the given drawer. One of {@link #LOCK_MODE_UNLOCKED}, 6090492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell * {@link #LOCK_MODE_LOCKED_CLOSED} or {@link #LOCK_MODE_LOCKED_OPEN}. 6100492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell * @param edgeGravity Gravity.LEFT, RIGHT, START or END. 6110492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell * Expresses which drawer to change the mode for. 6120492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell * 6130492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell * @see #LOCK_MODE_UNLOCKED 6140492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell * @see #LOCK_MODE_LOCKED_CLOSED 6150492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell * @see #LOCK_MODE_LOCKED_OPEN 6160492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell */ 617a3ff3273e976adf19770651dcf473fa67b38eb22Tor Norbye public void setDrawerLockMode(@LockMode int lockMode, @EdgeGravity int edgeGravity) { 618f55dfacb0db5da12ad3b9e5615c3feaea372f37dAlan Viverette final int absGravity = GravityCompat.getAbsoluteGravity(edgeGravity, 6190492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell ViewCompat.getLayoutDirection(this)); 620b518b3afec21cb8e843f00971bf6c176fe34c371Kirill Grouchnikov 621b518b3afec21cb8e843f00971bf6c176fe34c371Kirill Grouchnikov switch (edgeGravity) { 622b518b3afec21cb8e843f00971bf6c176fe34c371Kirill Grouchnikov case Gravity.LEFT: 623b518b3afec21cb8e843f00971bf6c176fe34c371Kirill Grouchnikov mLockModeLeft = lockMode; 624b518b3afec21cb8e843f00971bf6c176fe34c371Kirill Grouchnikov break; 625b518b3afec21cb8e843f00971bf6c176fe34c371Kirill Grouchnikov case Gravity.RIGHT: 626b518b3afec21cb8e843f00971bf6c176fe34c371Kirill Grouchnikov mLockModeRight = lockMode; 627b518b3afec21cb8e843f00971bf6c176fe34c371Kirill Grouchnikov break; 628b518b3afec21cb8e843f00971bf6c176fe34c371Kirill Grouchnikov case GravityCompat.START: 629b518b3afec21cb8e843f00971bf6c176fe34c371Kirill Grouchnikov mLockModeStart = lockMode; 630b518b3afec21cb8e843f00971bf6c176fe34c371Kirill Grouchnikov break; 631b518b3afec21cb8e843f00971bf6c176fe34c371Kirill Grouchnikov case GravityCompat.END: 632b518b3afec21cb8e843f00971bf6c176fe34c371Kirill Grouchnikov mLockModeEnd = lockMode; 633b518b3afec21cb8e843f00971bf6c176fe34c371Kirill Grouchnikov break; 6340492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell } 635b518b3afec21cb8e843f00971bf6c176fe34c371Kirill Grouchnikov 6360492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell if (lockMode != LOCK_MODE_UNLOCKED) { 6370492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell // Cancel interaction in progress 638f55dfacb0db5da12ad3b9e5615c3feaea372f37dAlan Viverette final ViewDragHelper helper = absGravity == Gravity.LEFT ? mLeftDragger : mRightDragger; 6390492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell helper.cancel(); 6400492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell } 6410492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell switch (lockMode) { 6420492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell case LOCK_MODE_LOCKED_OPEN: 643f55dfacb0db5da12ad3b9e5615c3feaea372f37dAlan Viverette final View toOpen = findDrawerWithGravity(absGravity); 6440492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell if (toOpen != null) { 6450492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell openDrawer(toOpen); 6460492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell } 6470492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell break; 6480492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell case LOCK_MODE_LOCKED_CLOSED: 649f55dfacb0db5da12ad3b9e5615c3feaea372f37dAlan Viverette final View toClose = findDrawerWithGravity(absGravity); 6500492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell if (toClose != null) { 6510492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell closeDrawer(toClose); 6520492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell } 6534d2c7b7c4f194034c5f17c4bee7320d808aabe4cAurimas Liutikas break; 6544d2c7b7c4f194034c5f17c4bee7320d808aabe4cAurimas Liutikas // default: do nothing 6550492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell } 6560492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell } 6570492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell 6580492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell /** 6590492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell * Enable or disable interaction with the given drawer. 6600492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell * 6610492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell * <p>This allows the application to restrict the user's ability to open or close 6620492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell * the given drawer. DrawerLayout will still respond to calls to {@link #openDrawer(int)}, 6630492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell * {@link #closeDrawer(int)} and friends if a drawer is locked.</p> 6640492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell * 6650492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell * <p>Locking a drawer open or closed will implicitly open or close 6660492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell * that drawer as appropriate.</p> 6670492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell * 6680492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell * @param lockMode The new lock mode for the given drawer. One of {@link #LOCK_MODE_UNLOCKED}, 6690492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell * {@link #LOCK_MODE_LOCKED_CLOSED} or {@link #LOCK_MODE_LOCKED_OPEN}. 6700492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell * @param drawerView The drawer view to change the lock mode for 6710492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell * 6720492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell * @see #LOCK_MODE_UNLOCKED 6730492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell * @see #LOCK_MODE_LOCKED_CLOSED 6740492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell * @see #LOCK_MODE_LOCKED_OPEN 6750492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell */ 676a3ff3273e976adf19770651dcf473fa67b38eb22Tor Norbye public void setDrawerLockMode(@LockMode int lockMode, View drawerView) { 6770492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell if (!isDrawerView(drawerView)) { 6784d2c7b7c4f194034c5f17c4bee7320d808aabe4cAurimas Liutikas throw new IllegalArgumentException("View " + drawerView + " is not a " 6794d2c7b7c4f194034c5f17c4bee7320d808aabe4cAurimas Liutikas + "drawer with appropriate layout_gravity"); 6800492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell } 681f55dfacb0db5da12ad3b9e5615c3feaea372f37dAlan Viverette final int gravity = ((LayoutParams) drawerView.getLayoutParams()).gravity; 682f55dfacb0db5da12ad3b9e5615c3feaea372f37dAlan Viverette setDrawerLockMode(lockMode, gravity); 6830492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell } 6840492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell 6850492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell /** 6860492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell * Check the lock mode of the drawer with the given gravity. 6870492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell * 6880492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell * @param edgeGravity Gravity of the drawer to check 6890492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell * @return one of {@link #LOCK_MODE_UNLOCKED}, {@link #LOCK_MODE_LOCKED_CLOSED} or 6900492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell * {@link #LOCK_MODE_LOCKED_OPEN}. 6910492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell */ 692a3ff3273e976adf19770651dcf473fa67b38eb22Tor Norbye @LockMode 693a3ff3273e976adf19770651dcf473fa67b38eb22Tor Norbye public int getDrawerLockMode(@EdgeGravity int edgeGravity) { 694b518b3afec21cb8e843f00971bf6c176fe34c371Kirill Grouchnikov int layoutDirection = ViewCompat.getLayoutDirection(this); 695b518b3afec21cb8e843f00971bf6c176fe34c371Kirill Grouchnikov 696b518b3afec21cb8e843f00971bf6c176fe34c371Kirill Grouchnikov switch (edgeGravity) { 697b518b3afec21cb8e843f00971bf6c176fe34c371Kirill Grouchnikov case Gravity.LEFT: 698b518b3afec21cb8e843f00971bf6c176fe34c371Kirill Grouchnikov if (mLockModeLeft != LOCK_MODE_UNDEFINED) { 699b518b3afec21cb8e843f00971bf6c176fe34c371Kirill Grouchnikov return mLockModeLeft; 700b518b3afec21cb8e843f00971bf6c176fe34c371Kirill Grouchnikov } 7014d2c7b7c4f194034c5f17c4bee7320d808aabe4cAurimas Liutikas int leftLockMode = (layoutDirection == ViewCompat.LAYOUT_DIRECTION_LTR) 7024d2c7b7c4f194034c5f17c4bee7320d808aabe4cAurimas Liutikas ? mLockModeStart : mLockModeEnd; 703b518b3afec21cb8e843f00971bf6c176fe34c371Kirill Grouchnikov if (leftLockMode != LOCK_MODE_UNDEFINED) { 704b518b3afec21cb8e843f00971bf6c176fe34c371Kirill Grouchnikov return leftLockMode; 705b518b3afec21cb8e843f00971bf6c176fe34c371Kirill Grouchnikov } 706b518b3afec21cb8e843f00971bf6c176fe34c371Kirill Grouchnikov break; 707b518b3afec21cb8e843f00971bf6c176fe34c371Kirill Grouchnikov case Gravity.RIGHT: 708b518b3afec21cb8e843f00971bf6c176fe34c371Kirill Grouchnikov if (mLockModeRight != LOCK_MODE_UNDEFINED) { 709b518b3afec21cb8e843f00971bf6c176fe34c371Kirill Grouchnikov return mLockModeRight; 710b518b3afec21cb8e843f00971bf6c176fe34c371Kirill Grouchnikov } 7114d2c7b7c4f194034c5f17c4bee7320d808aabe4cAurimas Liutikas int rightLockMode = (layoutDirection == ViewCompat.LAYOUT_DIRECTION_LTR) 7124d2c7b7c4f194034c5f17c4bee7320d808aabe4cAurimas Liutikas ? mLockModeEnd : mLockModeStart; 713b518b3afec21cb8e843f00971bf6c176fe34c371Kirill Grouchnikov if (rightLockMode != LOCK_MODE_UNDEFINED) { 714b518b3afec21cb8e843f00971bf6c176fe34c371Kirill Grouchnikov return rightLockMode; 715b518b3afec21cb8e843f00971bf6c176fe34c371Kirill Grouchnikov } 716b518b3afec21cb8e843f00971bf6c176fe34c371Kirill Grouchnikov break; 717b518b3afec21cb8e843f00971bf6c176fe34c371Kirill Grouchnikov case GravityCompat.START: 718b518b3afec21cb8e843f00971bf6c176fe34c371Kirill Grouchnikov if (mLockModeStart != LOCK_MODE_UNDEFINED) { 719b518b3afec21cb8e843f00971bf6c176fe34c371Kirill Grouchnikov return mLockModeStart; 720b518b3afec21cb8e843f00971bf6c176fe34c371Kirill Grouchnikov } 7214d2c7b7c4f194034c5f17c4bee7320d808aabe4cAurimas Liutikas int startLockMode = (layoutDirection == ViewCompat.LAYOUT_DIRECTION_LTR) 7224d2c7b7c4f194034c5f17c4bee7320d808aabe4cAurimas Liutikas ? mLockModeLeft : mLockModeRight; 723b518b3afec21cb8e843f00971bf6c176fe34c371Kirill Grouchnikov if (startLockMode != LOCK_MODE_UNDEFINED) { 724b518b3afec21cb8e843f00971bf6c176fe34c371Kirill Grouchnikov return startLockMode; 725b518b3afec21cb8e843f00971bf6c176fe34c371Kirill Grouchnikov } 726b518b3afec21cb8e843f00971bf6c176fe34c371Kirill Grouchnikov break; 727b518b3afec21cb8e843f00971bf6c176fe34c371Kirill Grouchnikov case GravityCompat.END: 728b518b3afec21cb8e843f00971bf6c176fe34c371Kirill Grouchnikov if (mLockModeEnd != LOCK_MODE_UNDEFINED) { 729b518b3afec21cb8e843f00971bf6c176fe34c371Kirill Grouchnikov return mLockModeEnd; 730b518b3afec21cb8e843f00971bf6c176fe34c371Kirill Grouchnikov } 7314d2c7b7c4f194034c5f17c4bee7320d808aabe4cAurimas Liutikas int endLockMode = (layoutDirection == ViewCompat.LAYOUT_DIRECTION_LTR) 7324d2c7b7c4f194034c5f17c4bee7320d808aabe4cAurimas Liutikas ? mLockModeRight : mLockModeLeft; 733b518b3afec21cb8e843f00971bf6c176fe34c371Kirill Grouchnikov if (endLockMode != LOCK_MODE_UNDEFINED) { 734b518b3afec21cb8e843f00971bf6c176fe34c371Kirill Grouchnikov return endLockMode; 735b518b3afec21cb8e843f00971bf6c176fe34c371Kirill Grouchnikov } 736b518b3afec21cb8e843f00971bf6c176fe34c371Kirill Grouchnikov break; 7370492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell } 738b518b3afec21cb8e843f00971bf6c176fe34c371Kirill Grouchnikov 7390492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell return LOCK_MODE_UNLOCKED; 7400492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell } 7410492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell 7420492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell /** 7430492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell * Check the lock mode of the given drawer view. 7440492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell * 7450492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell * @param drawerView Drawer view to check lock mode 7460492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell * @return one of {@link #LOCK_MODE_UNLOCKED}, {@link #LOCK_MODE_LOCKED_CLOSED} or 7470492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell * {@link #LOCK_MODE_LOCKED_OPEN}. 7480492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell */ 749a3ff3273e976adf19770651dcf473fa67b38eb22Tor Norbye @LockMode 7500492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell public int getDrawerLockMode(View drawerView) { 751431713be0958fd0f4d878f5f25755575191fb8baKirill Grouchnikov if (!isDrawerView(drawerView)) { 752431713be0958fd0f4d878f5f25755575191fb8baKirill Grouchnikov throw new IllegalArgumentException("View " + drawerView + " is not a drawer"); 753431713be0958fd0f4d878f5f25755575191fb8baKirill Grouchnikov } 754b518b3afec21cb8e843f00971bf6c176fe34c371Kirill Grouchnikov final int drawerGravity = ((LayoutParams) drawerView.getLayoutParams()).gravity; 755b518b3afec21cb8e843f00971bf6c176fe34c371Kirill Grouchnikov return getDrawerLockMode(drawerGravity); 7560492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell } 7570492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell 7580492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell /** 759526ba1382e61845ef23bf27d300883dea0966af5Alan Viverette * Sets the title of the drawer with the given gravity. 760526ba1382e61845ef23bf27d300883dea0966af5Alan Viverette * <p> 761526ba1382e61845ef23bf27d300883dea0966af5Alan Viverette * When accessibility is turned on, this is the title that will be used to 762526ba1382e61845ef23bf27d300883dea0966af5Alan Viverette * identify the drawer to the active accessibility service. 763526ba1382e61845ef23bf27d300883dea0966af5Alan Viverette * 764526ba1382e61845ef23bf27d300883dea0966af5Alan Viverette * @param edgeGravity Gravity.LEFT, RIGHT, START or END. Expresses which 765526ba1382e61845ef23bf27d300883dea0966af5Alan Viverette * drawer to set the title for. 766526ba1382e61845ef23bf27d300883dea0966af5Alan Viverette * @param title The title for the drawer. 767526ba1382e61845ef23bf27d300883dea0966af5Alan Viverette */ 768a3ff3273e976adf19770651dcf473fa67b38eb22Tor Norbye public void setDrawerTitle(@EdgeGravity int edgeGravity, CharSequence title) { 769526ba1382e61845ef23bf27d300883dea0966af5Alan Viverette final int absGravity = GravityCompat.getAbsoluteGravity( 770526ba1382e61845ef23bf27d300883dea0966af5Alan Viverette edgeGravity, ViewCompat.getLayoutDirection(this)); 771526ba1382e61845ef23bf27d300883dea0966af5Alan Viverette if (absGravity == Gravity.LEFT) { 772526ba1382e61845ef23bf27d300883dea0966af5Alan Viverette mTitleLeft = title; 773526ba1382e61845ef23bf27d300883dea0966af5Alan Viverette } else if (absGravity == Gravity.RIGHT) { 774526ba1382e61845ef23bf27d300883dea0966af5Alan Viverette mTitleRight = title; 775526ba1382e61845ef23bf27d300883dea0966af5Alan Viverette } 776526ba1382e61845ef23bf27d300883dea0966af5Alan Viverette } 777526ba1382e61845ef23bf27d300883dea0966af5Alan Viverette 778526ba1382e61845ef23bf27d300883dea0966af5Alan Viverette /** 779526ba1382e61845ef23bf27d300883dea0966af5Alan Viverette * Returns the title of the drawer with the given gravity. 780526ba1382e61845ef23bf27d300883dea0966af5Alan Viverette * 781526ba1382e61845ef23bf27d300883dea0966af5Alan Viverette * @param edgeGravity Gravity.LEFT, RIGHT, START or END. Expresses which 782526ba1382e61845ef23bf27d300883dea0966af5Alan Viverette * drawer to return the title for. 783526ba1382e61845ef23bf27d300883dea0966af5Alan Viverette * @return The title of the drawer, or null if none set. 784526ba1382e61845ef23bf27d300883dea0966af5Alan Viverette * @see #setDrawerTitle(int, CharSequence) 785526ba1382e61845ef23bf27d300883dea0966af5Alan Viverette */ 786a3ff3273e976adf19770651dcf473fa67b38eb22Tor Norbye @Nullable 787a3ff3273e976adf19770651dcf473fa67b38eb22Tor Norbye public CharSequence getDrawerTitle(@EdgeGravity int edgeGravity) { 788526ba1382e61845ef23bf27d300883dea0966af5Alan Viverette final int absGravity = GravityCompat.getAbsoluteGravity( 789526ba1382e61845ef23bf27d300883dea0966af5Alan Viverette edgeGravity, ViewCompat.getLayoutDirection(this)); 790526ba1382e61845ef23bf27d300883dea0966af5Alan Viverette if (absGravity == Gravity.LEFT) { 791526ba1382e61845ef23bf27d300883dea0966af5Alan Viverette return mTitleLeft; 792526ba1382e61845ef23bf27d300883dea0966af5Alan Viverette } else if (absGravity == Gravity.RIGHT) { 793526ba1382e61845ef23bf27d300883dea0966af5Alan Viverette return mTitleRight; 794526ba1382e61845ef23bf27d300883dea0966af5Alan Viverette } 795526ba1382e61845ef23bf27d300883dea0966af5Alan Viverette return null; 796526ba1382e61845ef23bf27d300883dea0966af5Alan Viverette } 797526ba1382e61845ef23bf27d300883dea0966af5Alan Viverette 798526ba1382e61845ef23bf27d300883dea0966af5Alan Viverette /** 7991d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * Resolve the shared state of all drawers from the component ViewDragHelpers. 8001d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * Should be called whenever a ViewDragHelper's state changes. 8011d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell */ 802a3ff3273e976adf19770651dcf473fa67b38eb22Tor Norbye void updateDrawerState(int forGravity, @State int activeState, View activeDrawer) { 8031d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final int leftState = mLeftDragger.getViewDragState(); 8041d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final int rightState = mRightDragger.getViewDragState(); 8051d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 8061d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final int state; 8071d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell if (leftState == STATE_DRAGGING || rightState == STATE_DRAGGING) { 8081d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell state = STATE_DRAGGING; 8091d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } else if (leftState == STATE_SETTLING || rightState == STATE_SETTLING) { 8101d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell state = STATE_SETTLING; 8111d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } else { 8121d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell state = STATE_IDLE; 8131d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 8141d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 815b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell if (activeDrawer != null && activeState == STATE_IDLE) { 816b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell final LayoutParams lp = (LayoutParams) activeDrawer.getLayoutParams(); 817b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell if (lp.onScreen == 0) { 818b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell dispatchOnDrawerClosed(activeDrawer); 819b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell } else if (lp.onScreen == 1) { 820b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell dispatchOnDrawerOpened(activeDrawer); 821b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell } 822b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell } 823b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell 8241d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell if (state != mDrawerState) { 8251d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell mDrawerState = state; 826b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell 8273eb01e183e6eef7610881c8b9c0914afbe23b442Chris Banes if (mListeners != null) { 8283eb01e183e6eef7610881c8b9c0914afbe23b442Chris Banes // Notify the listeners. Do that from the end of the list so that if a listener 8293eb01e183e6eef7610881c8b9c0914afbe23b442Chris Banes // removes itself as the result of being called, it won't mess up with our iteration 8303eb01e183e6eef7610881c8b9c0914afbe23b442Chris Banes int listenerCount = mListeners.size(); 8313eb01e183e6eef7610881c8b9c0914afbe23b442Chris Banes for (int i = listenerCount - 1; i >= 0; i--) { 8323eb01e183e6eef7610881c8b9c0914afbe23b442Chris Banes mListeners.get(i).onDrawerStateChanged(state); 8333eb01e183e6eef7610881c8b9c0914afbe23b442Chris Banes } 8341d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 8351d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 8361d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 8371d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 8381d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell void dispatchOnDrawerClosed(View drawerView) { 8391d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final LayoutParams lp = (LayoutParams) drawerView.getLayoutParams(); 84067cf3e301575e3d67e3b4c3d06f4624438590dd3Kirill Grouchnikov if ((lp.openState & LayoutParams.FLAG_IS_OPENED) == 1) { 84167cf3e301575e3d67e3b4c3d06f4624438590dd3Kirill Grouchnikov lp.openState = 0; 8423eb01e183e6eef7610881c8b9c0914afbe23b442Chris Banes 8433eb01e183e6eef7610881c8b9c0914afbe23b442Chris Banes if (mListeners != null) { 8443eb01e183e6eef7610881c8b9c0914afbe23b442Chris Banes // Notify the listeners. Do that from the end of the list so that if a listener 8453eb01e183e6eef7610881c8b9c0914afbe23b442Chris Banes // removes itself as the result of being called, it won't mess up with our iteration 8463eb01e183e6eef7610881c8b9c0914afbe23b442Chris Banes int listenerCount = mListeners.size(); 8473eb01e183e6eef7610881c8b9c0914afbe23b442Chris Banes for (int i = listenerCount - 1; i >= 0; i--) { 8483eb01e183e6eef7610881c8b9c0914afbe23b442Chris Banes mListeners.get(i).onDrawerClosed(drawerView); 8493eb01e183e6eef7610881c8b9c0914afbe23b442Chris Banes } 8501d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 851aeaa8ef97eb729fbee17e984d60e9ab27795f5d0Alan Viverette 8522bb8d4e8831b2d0f1de7f15493bb79f48c91db2aAlan Viverette updateChildrenImportantForAccessibility(drawerView, false); 85312ba769d9e9b121829c69daf0f6350e808028a6aAlan Viverette 854aeaa8ef97eb729fbee17e984d60e9ab27795f5d0Alan Viverette // Only send WINDOW_STATE_CHANGE if the host has window focus. This 855aeaa8ef97eb729fbee17e984d60e9ab27795f5d0Alan Viverette // may change if support for multiple foreground windows (e.g. IME) 856aeaa8ef97eb729fbee17e984d60e9ab27795f5d0Alan Viverette // improves. 857aeaa8ef97eb729fbee17e984d60e9ab27795f5d0Alan Viverette if (hasWindowFocus()) { 858aeaa8ef97eb729fbee17e984d60e9ab27795f5d0Alan Viverette final View rootView = getRootView(); 859aeaa8ef97eb729fbee17e984d60e9ab27795f5d0Alan Viverette if (rootView != null) { 860aeaa8ef97eb729fbee17e984d60e9ab27795f5d0Alan Viverette rootView.sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED); 861aeaa8ef97eb729fbee17e984d60e9ab27795f5d0Alan Viverette } 862aeaa8ef97eb729fbee17e984d60e9ab27795f5d0Alan Viverette } 8631d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 8641d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 8651d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 8661d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell void dispatchOnDrawerOpened(View drawerView) { 8671d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final LayoutParams lp = (LayoutParams) drawerView.getLayoutParams(); 86867cf3e301575e3d67e3b4c3d06f4624438590dd3Kirill Grouchnikov if ((lp.openState & LayoutParams.FLAG_IS_OPENED) == 0) { 86967cf3e301575e3d67e3b4c3d06f4624438590dd3Kirill Grouchnikov lp.openState = LayoutParams.FLAG_IS_OPENED; 8703eb01e183e6eef7610881c8b9c0914afbe23b442Chris Banes if (mListeners != null) { 8713eb01e183e6eef7610881c8b9c0914afbe23b442Chris Banes // Notify the listeners. Do that from the end of the list so that if a listener 8723eb01e183e6eef7610881c8b9c0914afbe23b442Chris Banes // removes itself as the result of being called, it won't mess up with our iteration 8733eb01e183e6eef7610881c8b9c0914afbe23b442Chris Banes int listenerCount = mListeners.size(); 8743eb01e183e6eef7610881c8b9c0914afbe23b442Chris Banes for (int i = listenerCount - 1; i >= 0; i--) { 8753eb01e183e6eef7610881c8b9c0914afbe23b442Chris Banes mListeners.get(i).onDrawerOpened(drawerView); 8763eb01e183e6eef7610881c8b9c0914afbe23b442Chris Banes } 8771d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 87812ba769d9e9b121829c69daf0f6350e808028a6aAlan Viverette 8792bb8d4e8831b2d0f1de7f15493bb79f48c91db2aAlan Viverette updateChildrenImportantForAccessibility(drawerView, true); 88012ba769d9e9b121829c69daf0f6350e808028a6aAlan Viverette 881d2f68007428ed6785adcf572d47ed0f8c5c99556Alan Viverette // Only send WINDOW_STATE_CHANGE if the host has window focus. 882d2f68007428ed6785adcf572d47ed0f8c5c99556Alan Viverette if (hasWindowFocus()) { 883d2f68007428ed6785adcf572d47ed0f8c5c99556Alan Viverette sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED); 884d2f68007428ed6785adcf572d47ed0f8c5c99556Alan Viverette } 8851d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 8861d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 8871d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 8882bb8d4e8831b2d0f1de7f15493bb79f48c91db2aAlan Viverette private void updateChildrenImportantForAccessibility(View drawerView, boolean isDrawerOpen) { 8892bb8d4e8831b2d0f1de7f15493bb79f48c91db2aAlan Viverette final int childCount = getChildCount(); 8902bb8d4e8831b2d0f1de7f15493bb79f48c91db2aAlan Viverette for (int i = 0; i < childCount; i++) { 8912bb8d4e8831b2d0f1de7f15493bb79f48c91db2aAlan Viverette final View child = getChildAt(i); 8922bb8d4e8831b2d0f1de7f15493bb79f48c91db2aAlan Viverette if (!isDrawerOpen && !isDrawerView(child) 8932bb8d4e8831b2d0f1de7f15493bb79f48c91db2aAlan Viverette || isDrawerOpen && child == drawerView) { 8942bb8d4e8831b2d0f1de7f15493bb79f48c91db2aAlan Viverette // Drawer is closed and this is a content view or this is an 8952bb8d4e8831b2d0f1de7f15493bb79f48c91db2aAlan Viverette // open drawer view, so it should be visible. 8962bb8d4e8831b2d0f1de7f15493bb79f48c91db2aAlan Viverette ViewCompat.setImportantForAccessibility(child, 8972bb8d4e8831b2d0f1de7f15493bb79f48c91db2aAlan Viverette ViewCompat.IMPORTANT_FOR_ACCESSIBILITY_YES); 8982bb8d4e8831b2d0f1de7f15493bb79f48c91db2aAlan Viverette } else { 8992bb8d4e8831b2d0f1de7f15493bb79f48c91db2aAlan Viverette ViewCompat.setImportantForAccessibility(child, 9002bb8d4e8831b2d0f1de7f15493bb79f48c91db2aAlan Viverette ViewCompat.IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS); 9012bb8d4e8831b2d0f1de7f15493bb79f48c91db2aAlan Viverette } 9022bb8d4e8831b2d0f1de7f15493bb79f48c91db2aAlan Viverette } 9032bb8d4e8831b2d0f1de7f15493bb79f48c91db2aAlan Viverette } 9042bb8d4e8831b2d0f1de7f15493bb79f48c91db2aAlan Viverette 9051d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell void dispatchOnDrawerSlide(View drawerView, float slideOffset) { 9063eb01e183e6eef7610881c8b9c0914afbe23b442Chris Banes if (mListeners != null) { 9073eb01e183e6eef7610881c8b9c0914afbe23b442Chris Banes // Notify the listeners. Do that from the end of the list so that if a listener 9083eb01e183e6eef7610881c8b9c0914afbe23b442Chris Banes // removes itself as the result of being called, it won't mess up with our iteration 9093eb01e183e6eef7610881c8b9c0914afbe23b442Chris Banes int listenerCount = mListeners.size(); 9103eb01e183e6eef7610881c8b9c0914afbe23b442Chris Banes for (int i = listenerCount - 1; i >= 0; i--) { 9113eb01e183e6eef7610881c8b9c0914afbe23b442Chris Banes mListeners.get(i).onDrawerSlide(drawerView, slideOffset); 9123eb01e183e6eef7610881c8b9c0914afbe23b442Chris Banes } 9131d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 9141d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 9151d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 9161d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell void setDrawerViewOffset(View drawerView, float slideOffset) { 9171d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final LayoutParams lp = (LayoutParams) drawerView.getLayoutParams(); 918b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell if (slideOffset == lp.onScreen) { 9191d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell return; 9201d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 9211d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 922b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell lp.onScreen = slideOffset; 9231d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell dispatchOnDrawerSlide(drawerView, slideOffset); 9241d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 9251d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 9261d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell float getDrawerViewOffset(View drawerView) { 927b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell return ((LayoutParams) drawerView.getLayoutParams()).onScreen; 9281d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 9291d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 930f55dfacb0db5da12ad3b9e5615c3feaea372f37dAlan Viverette /** 931f55dfacb0db5da12ad3b9e5615c3feaea372f37dAlan Viverette * @return the absolute gravity of the child drawerView, resolved according 932f55dfacb0db5da12ad3b9e5615c3feaea372f37dAlan Viverette * to the current layout direction 933f55dfacb0db5da12ad3b9e5615c3feaea372f37dAlan Viverette */ 934f55dfacb0db5da12ad3b9e5615c3feaea372f37dAlan Viverette int getDrawerViewAbsoluteGravity(View drawerView) { 9351d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final int gravity = ((LayoutParams) drawerView.getLayoutParams()).gravity; 936f55dfacb0db5da12ad3b9e5615c3feaea372f37dAlan Viverette return GravityCompat.getAbsoluteGravity(gravity, ViewCompat.getLayoutDirection(this)); 9371d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 9381d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 939f55dfacb0db5da12ad3b9e5615c3feaea372f37dAlan Viverette boolean checkDrawerViewAbsoluteGravity(View drawerView, int checkFor) { 940f55dfacb0db5da12ad3b9e5615c3feaea372f37dAlan Viverette final int absGravity = getDrawerViewAbsoluteGravity(drawerView); 941f55dfacb0db5da12ad3b9e5615c3feaea372f37dAlan Viverette return (absGravity & checkFor) == checkFor; 9421d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 9431d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 9440492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell View findOpenDrawer() { 9450492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell final int childCount = getChildCount(); 9460492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell for (int i = 0; i < childCount; i++) { 9470492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell final View child = getChildAt(i); 94867cf3e301575e3d67e3b4c3d06f4624438590dd3Kirill Grouchnikov final LayoutParams childLp = (LayoutParams) child.getLayoutParams(); 94967cf3e301575e3d67e3b4c3d06f4624438590dd3Kirill Grouchnikov if ((childLp.openState & LayoutParams.FLAG_IS_OPENED) == 1) { 9500492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell return child; 9510492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell } 9520492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell } 9530492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell return null; 9540492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell } 9550492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell 9561d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell void moveDrawerToOffset(View drawerView, float slideOffset) { 9571d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final float oldOffset = getDrawerViewOffset(drawerView); 9581d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final int width = drawerView.getWidth(); 9591d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final int oldPos = (int) (width * oldOffset); 9601d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final int newPos = (int) (width * slideOffset); 9611d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final int dx = newPos - oldPos; 9621d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 963f55dfacb0db5da12ad3b9e5615c3feaea372f37dAlan Viverette drawerView.offsetLeftAndRight( 964f55dfacb0db5da12ad3b9e5615c3feaea372f37dAlan Viverette checkDrawerViewAbsoluteGravity(drawerView, Gravity.LEFT) ? dx : -dx); 9651d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell setDrawerViewOffset(drawerView, slideOffset); 9661d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 9671d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 968f55dfacb0db5da12ad3b9e5615c3feaea372f37dAlan Viverette /** 969f55dfacb0db5da12ad3b9e5615c3feaea372f37dAlan Viverette * @param gravity the gravity of the child to return. If specified as a 970f55dfacb0db5da12ad3b9e5615c3feaea372f37dAlan Viverette * relative value, it will be resolved according to the current 971f55dfacb0db5da12ad3b9e5615c3feaea372f37dAlan Viverette * layout direction. 972f55dfacb0db5da12ad3b9e5615c3feaea372f37dAlan Viverette * @return the drawer with the specified gravity 973f55dfacb0db5da12ad3b9e5615c3feaea372f37dAlan Viverette */ 9741d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell View findDrawerWithGravity(int gravity) { 975f55dfacb0db5da12ad3b9e5615c3feaea372f37dAlan Viverette final int absHorizGravity = GravityCompat.getAbsoluteGravity( 976f55dfacb0db5da12ad3b9e5615c3feaea372f37dAlan Viverette gravity, ViewCompat.getLayoutDirection(this)) & Gravity.HORIZONTAL_GRAVITY_MASK; 9771d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final int childCount = getChildCount(); 9781d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell for (int i = 0; i < childCount; i++) { 9791d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final View child = getChildAt(i); 980f55dfacb0db5da12ad3b9e5615c3feaea372f37dAlan Viverette final int childAbsGravity = getDrawerViewAbsoluteGravity(child); 981f55dfacb0db5da12ad3b9e5615c3feaea372f37dAlan Viverette if ((childAbsGravity & Gravity.HORIZONTAL_GRAVITY_MASK) == absHorizGravity) { 9821d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell return child; 9831d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 9841d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 9851d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell return null; 9861d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 9871d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 9881d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell /** 9891d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * Simple gravity to string - only supports LEFT and RIGHT for debugging output. 9901d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * 9911d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * @param gravity Absolute gravity value 9921d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * @return LEFT or RIGHT as appropriate, or a hex string 9931d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell */ 994a3ff3273e976adf19770651dcf473fa67b38eb22Tor Norbye static String gravityToString(@EdgeGravity int gravity) { 9951d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell if ((gravity & Gravity.LEFT) == Gravity.LEFT) { 9961d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell return "LEFT"; 9971d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 9981d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell if ((gravity & Gravity.RIGHT) == Gravity.RIGHT) { 9991d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell return "RIGHT"; 10001d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 10011d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell return Integer.toHexString(gravity); 10021d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 10031d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 10041d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell @Override 100557902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell protected void onDetachedFromWindow() { 100657902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell super.onDetachedFromWindow(); 100757902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell mFirstLayout = true; 100857902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell } 100957902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell 101057902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell @Override 101157902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell protected void onAttachedToWindow() { 101257902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell super.onAttachedToWindow(); 101357902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell mFirstLayout = true; 101457902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell } 101557902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell 101657902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell @Override 10171d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 1018c6f6c4511593aa49688d5425e2f6e36459076c25Adam Powell int widthMode = MeasureSpec.getMode(widthMeasureSpec); 1019c6f6c4511593aa49688d5425e2f6e36459076c25Adam Powell int heightMode = MeasureSpec.getMode(heightMeasureSpec); 1020c6f6c4511593aa49688d5425e2f6e36459076c25Adam Powell int widthSize = MeasureSpec.getSize(widthMeasureSpec); 1021c6f6c4511593aa49688d5425e2f6e36459076c25Adam Powell int heightSize = MeasureSpec.getSize(heightMeasureSpec); 10221d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 10231d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell if (widthMode != MeasureSpec.EXACTLY || heightMode != MeasureSpec.EXACTLY) { 1024c6f6c4511593aa49688d5425e2f6e36459076c25Adam Powell if (isInEditMode()) { 1025c6f6c4511593aa49688d5425e2f6e36459076c25Adam Powell // Don't crash the layout editor. Consume all of the space if specified 1026c6f6c4511593aa49688d5425e2f6e36459076c25Adam Powell // or pick a magic number from thin air otherwise. 1027c6f6c4511593aa49688d5425e2f6e36459076c25Adam Powell // TODO Better communication with tools of this bogus state. 1028c6f6c4511593aa49688d5425e2f6e36459076c25Adam Powell // It will crash on a real device. 1029c6f6c4511593aa49688d5425e2f6e36459076c25Adam Powell if (widthMode == MeasureSpec.AT_MOST) { 1030c6f6c4511593aa49688d5425e2f6e36459076c25Adam Powell widthMode = MeasureSpec.EXACTLY; 1031c6f6c4511593aa49688d5425e2f6e36459076c25Adam Powell } else if (widthMode == MeasureSpec.UNSPECIFIED) { 1032c6f6c4511593aa49688d5425e2f6e36459076c25Adam Powell widthMode = MeasureSpec.EXACTLY; 1033c6f6c4511593aa49688d5425e2f6e36459076c25Adam Powell widthSize = 300; 1034c6f6c4511593aa49688d5425e2f6e36459076c25Adam Powell } 1035c6f6c4511593aa49688d5425e2f6e36459076c25Adam Powell if (heightMode == MeasureSpec.AT_MOST) { 1036c6f6c4511593aa49688d5425e2f6e36459076c25Adam Powell heightMode = MeasureSpec.EXACTLY; 10374d2c7b7c4f194034c5f17c4bee7320d808aabe4cAurimas Liutikas } else if (heightMode == MeasureSpec.UNSPECIFIED) { 1038c6f6c4511593aa49688d5425e2f6e36459076c25Adam Powell heightMode = MeasureSpec.EXACTLY; 1039c6f6c4511593aa49688d5425e2f6e36459076c25Adam Powell heightSize = 300; 1040c6f6c4511593aa49688d5425e2f6e36459076c25Adam Powell } 1041c6f6c4511593aa49688d5425e2f6e36459076c25Adam Powell } else { 1042c6f6c4511593aa49688d5425e2f6e36459076c25Adam Powell throw new IllegalArgumentException( 1043c6f6c4511593aa49688d5425e2f6e36459076c25Adam Powell "DrawerLayout must be measured with MeasureSpec.EXACTLY."); 1044c6f6c4511593aa49688d5425e2f6e36459076c25Adam Powell } 10451d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 10461d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 10471d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell setMeasuredDimension(widthSize, heightSize); 10481d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 1049f9c35128decbd812ff2497852ccacbd1ffbbd811Adam Powell final boolean applyInsets = mLastInsets != null && ViewCompat.getFitsSystemWindows(this); 1050f9c35128decbd812ff2497852ccacbd1ffbbd811Adam Powell final int layoutDirection = ViewCompat.getLayoutDirection(this); 1051f9c35128decbd812ff2497852ccacbd1ffbbd811Adam Powell 1052e6e27ab94303516b1e196568cee520832c38710cKirill Grouchnikov // Only one drawer is permitted along each vertical edge (left / right). These two booleans 1053e6e27ab94303516b1e196568cee520832c38710cKirill Grouchnikov // are tracking the presence of the edge drawers. 1054e6e27ab94303516b1e196568cee520832c38710cKirill Grouchnikov boolean hasDrawerOnLeftEdge = false; 1055e6e27ab94303516b1e196568cee520832c38710cKirill Grouchnikov boolean hasDrawerOnRightEdge = false; 10561d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final int childCount = getChildCount(); 10571d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell for (int i = 0; i < childCount; i++) { 10581d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final View child = getChildAt(i); 10591d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 10601d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell if (child.getVisibility() == GONE) { 10611d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell continue; 10621d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 10631d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 106400ca2532981fbd705f947a637ffd967a8d6f733bAdam Powell final LayoutParams lp = (LayoutParams) child.getLayoutParams(); 106500ca2532981fbd705f947a637ffd967a8d6f733bAdam Powell 1066f9c35128decbd812ff2497852ccacbd1ffbbd811Adam Powell if (applyInsets) { 1067f9c35128decbd812ff2497852ccacbd1ffbbd811Adam Powell final int cgrav = GravityCompat.getAbsoluteGravity(lp.gravity, layoutDirection); 1068f9c35128decbd812ff2497852ccacbd1ffbbd811Adam Powell if (ViewCompat.getFitsSystemWindows(child)) { 1069f9c35128decbd812ff2497852ccacbd1ffbbd811Adam Powell IMPL.dispatchChildInsets(child, mLastInsets, cgrav); 1070f9c35128decbd812ff2497852ccacbd1ffbbd811Adam Powell } else { 1071f9c35128decbd812ff2497852ccacbd1ffbbd811Adam Powell IMPL.applyMarginInsets(lp, mLastInsets, cgrav); 1072f9c35128decbd812ff2497852ccacbd1ffbbd811Adam Powell } 1073f9c35128decbd812ff2497852ccacbd1ffbbd811Adam Powell } 1074f9c35128decbd812ff2497852ccacbd1ffbbd811Adam Powell 10751d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell if (isContentView(child)) { 10761d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell // Content views get measured at exactly the layout's size. 107700ca2532981fbd705f947a637ffd967a8d6f733bAdam Powell final int contentWidthSpec = MeasureSpec.makeMeasureSpec( 107800ca2532981fbd705f947a637ffd967a8d6f733bAdam Powell widthSize - lp.leftMargin - lp.rightMargin, MeasureSpec.EXACTLY); 107900ca2532981fbd705f947a637ffd967a8d6f733bAdam Powell final int contentHeightSpec = MeasureSpec.makeMeasureSpec( 108000ca2532981fbd705f947a637ffd967a8d6f733bAdam Powell heightSize - lp.topMargin - lp.bottomMargin, MeasureSpec.EXACTLY); 108100ca2532981fbd705f947a637ffd967a8d6f733bAdam Powell child.measure(contentWidthSpec, contentHeightSpec); 10821d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } else if (isDrawerView(child)) { 1083621e41e02c0664afd4e358dfe166d6fb71e471c9Doris Liu if (SET_DRAWER_SHADOW_FROM_ELEVATION) { 1084621e41e02c0664afd4e358dfe166d6fb71e471c9Doris Liu if (ViewCompat.getElevation(child) != mDrawerElevation) { 1085621e41e02c0664afd4e358dfe166d6fb71e471c9Doris Liu ViewCompat.setElevation(child, mDrawerElevation); 1086621e41e02c0664afd4e358dfe166d6fb71e471c9Doris Liu } 1087621e41e02c0664afd4e358dfe166d6fb71e471c9Doris Liu } 1088e6e27ab94303516b1e196568cee520832c38710cKirill Grouchnikov final @EdgeGravity int childGravity = 1089f55dfacb0db5da12ad3b9e5615c3feaea372f37dAlan Viverette getDrawerViewAbsoluteGravity(child) & Gravity.HORIZONTAL_GRAVITY_MASK; 1090e6e27ab94303516b1e196568cee520832c38710cKirill Grouchnikov // Note that the isDrawerView check guarantees that childGravity here is either 1091e6e27ab94303516b1e196568cee520832c38710cKirill Grouchnikov // LEFT or RIGHT 1092e6e27ab94303516b1e196568cee520832c38710cKirill Grouchnikov boolean isLeftEdgeDrawer = (childGravity == Gravity.LEFT); 10934d2c7b7c4f194034c5f17c4bee7320d808aabe4cAurimas Liutikas if ((isLeftEdgeDrawer && hasDrawerOnLeftEdge) 10944d2c7b7c4f194034c5f17c4bee7320d808aabe4cAurimas Liutikas || (!isLeftEdgeDrawer && hasDrawerOnRightEdge)) { 10954d2c7b7c4f194034c5f17c4bee7320d808aabe4cAurimas Liutikas throw new IllegalStateException("Child drawer has absolute gravity " 10964d2c7b7c4f194034c5f17c4bee7320d808aabe4cAurimas Liutikas + gravityToString(childGravity) + " but this " + TAG + " already has a " 10974d2c7b7c4f194034c5f17c4bee7320d808aabe4cAurimas Liutikas + "drawer view along that edge"); 10981d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 1099e6e27ab94303516b1e196568cee520832c38710cKirill Grouchnikov if (isLeftEdgeDrawer) { 1100e6e27ab94303516b1e196568cee520832c38710cKirill Grouchnikov hasDrawerOnLeftEdge = true; 1101e6e27ab94303516b1e196568cee520832c38710cKirill Grouchnikov } else { 1102e6e27ab94303516b1e196568cee520832c38710cKirill Grouchnikov hasDrawerOnRightEdge = true; 1103e6e27ab94303516b1e196568cee520832c38710cKirill Grouchnikov } 110400ca2532981fbd705f947a637ffd967a8d6f733bAdam Powell final int drawerWidthSpec = getChildMeasureSpec(widthMeasureSpec, 110500ca2532981fbd705f947a637ffd967a8d6f733bAdam Powell mMinDrawerMargin + lp.leftMargin + lp.rightMargin, 110600ca2532981fbd705f947a637ffd967a8d6f733bAdam Powell lp.width); 110700ca2532981fbd705f947a637ffd967a8d6f733bAdam Powell final int drawerHeightSpec = getChildMeasureSpec(heightMeasureSpec, 110800ca2532981fbd705f947a637ffd967a8d6f733bAdam Powell lp.topMargin + lp.bottomMargin, 110900ca2532981fbd705f947a637ffd967a8d6f733bAdam Powell lp.height); 111000ca2532981fbd705f947a637ffd967a8d6f733bAdam Powell child.measure(drawerWidthSpec, drawerHeightSpec); 11111d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } else { 11124d2c7b7c4f194034c5f17c4bee7320d808aabe4cAurimas Liutikas throw new IllegalStateException("Child " + child + " at index " + i 11134d2c7b7c4f194034c5f17c4bee7320d808aabe4cAurimas Liutikas + " does not have a valid layout_gravity - must be Gravity.LEFT, " 11144d2c7b7c4f194034c5f17c4bee7320d808aabe4cAurimas Liutikas + "Gravity.RIGHT or Gravity.NO_GRAVITY"); 11151d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 11161d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 11171d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 11181d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 1119621e41e02c0664afd4e358dfe166d6fb71e471c9Doris Liu private void resolveShadowDrawables() { 1120621e41e02c0664afd4e358dfe166d6fb71e471c9Doris Liu if (SET_DRAWER_SHADOW_FROM_ELEVATION) { 1121621e41e02c0664afd4e358dfe166d6fb71e471c9Doris Liu return; 1122621e41e02c0664afd4e358dfe166d6fb71e471c9Doris Liu } 1123621e41e02c0664afd4e358dfe166d6fb71e471c9Doris Liu mShadowLeftResolved = resolveLeftShadow(); 1124621e41e02c0664afd4e358dfe166d6fb71e471c9Doris Liu mShadowRightResolved = resolveRightShadow(); 1125621e41e02c0664afd4e358dfe166d6fb71e471c9Doris Liu } 1126621e41e02c0664afd4e358dfe166d6fb71e471c9Doris Liu 1127621e41e02c0664afd4e358dfe166d6fb71e471c9Doris Liu private Drawable resolveLeftShadow() { 1128621e41e02c0664afd4e358dfe166d6fb71e471c9Doris Liu int layoutDirection = ViewCompat.getLayoutDirection(this); 1129621e41e02c0664afd4e358dfe166d6fb71e471c9Doris Liu // Prefer shadows defined with start/end gravity over left and right. 1130621e41e02c0664afd4e358dfe166d6fb71e471c9Doris Liu if (layoutDirection == ViewCompat.LAYOUT_DIRECTION_LTR) { 1131621e41e02c0664afd4e358dfe166d6fb71e471c9Doris Liu if (mShadowStart != null) { 1132621e41e02c0664afd4e358dfe166d6fb71e471c9Doris Liu // Correct drawable layout direction, if needed. 1133621e41e02c0664afd4e358dfe166d6fb71e471c9Doris Liu mirror(mShadowStart, layoutDirection); 1134621e41e02c0664afd4e358dfe166d6fb71e471c9Doris Liu return mShadowStart; 1135621e41e02c0664afd4e358dfe166d6fb71e471c9Doris Liu } 1136621e41e02c0664afd4e358dfe166d6fb71e471c9Doris Liu } else { 1137621e41e02c0664afd4e358dfe166d6fb71e471c9Doris Liu if (mShadowEnd != null) { 1138621e41e02c0664afd4e358dfe166d6fb71e471c9Doris Liu // Correct drawable layout direction, if needed. 1139621e41e02c0664afd4e358dfe166d6fb71e471c9Doris Liu mirror(mShadowEnd, layoutDirection); 1140621e41e02c0664afd4e358dfe166d6fb71e471c9Doris Liu return mShadowEnd; 1141621e41e02c0664afd4e358dfe166d6fb71e471c9Doris Liu } 1142621e41e02c0664afd4e358dfe166d6fb71e471c9Doris Liu } 1143621e41e02c0664afd4e358dfe166d6fb71e471c9Doris Liu return mShadowLeft; 1144621e41e02c0664afd4e358dfe166d6fb71e471c9Doris Liu } 1145621e41e02c0664afd4e358dfe166d6fb71e471c9Doris Liu 1146621e41e02c0664afd4e358dfe166d6fb71e471c9Doris Liu private Drawable resolveRightShadow() { 1147621e41e02c0664afd4e358dfe166d6fb71e471c9Doris Liu int layoutDirection = ViewCompat.getLayoutDirection(this); 1148621e41e02c0664afd4e358dfe166d6fb71e471c9Doris Liu if (layoutDirection == ViewCompat.LAYOUT_DIRECTION_LTR) { 1149621e41e02c0664afd4e358dfe166d6fb71e471c9Doris Liu if (mShadowEnd != null) { 1150621e41e02c0664afd4e358dfe166d6fb71e471c9Doris Liu // Correct drawable layout direction, if needed. 1151621e41e02c0664afd4e358dfe166d6fb71e471c9Doris Liu mirror(mShadowEnd, layoutDirection); 1152621e41e02c0664afd4e358dfe166d6fb71e471c9Doris Liu return mShadowEnd; 1153621e41e02c0664afd4e358dfe166d6fb71e471c9Doris Liu } 1154621e41e02c0664afd4e358dfe166d6fb71e471c9Doris Liu } else { 1155621e41e02c0664afd4e358dfe166d6fb71e471c9Doris Liu if (mShadowStart != null) { 1156621e41e02c0664afd4e358dfe166d6fb71e471c9Doris Liu // Correct drawable layout direction, if needed. 1157621e41e02c0664afd4e358dfe166d6fb71e471c9Doris Liu mirror(mShadowStart, layoutDirection); 1158621e41e02c0664afd4e358dfe166d6fb71e471c9Doris Liu return mShadowStart; 1159621e41e02c0664afd4e358dfe166d6fb71e471c9Doris Liu } 1160621e41e02c0664afd4e358dfe166d6fb71e471c9Doris Liu } 1161621e41e02c0664afd4e358dfe166d6fb71e471c9Doris Liu return mShadowRight; 1162621e41e02c0664afd4e358dfe166d6fb71e471c9Doris Liu } 1163621e41e02c0664afd4e358dfe166d6fb71e471c9Doris Liu 1164621e41e02c0664afd4e358dfe166d6fb71e471c9Doris Liu /** 1165621e41e02c0664afd4e358dfe166d6fb71e471c9Doris Liu * Change the layout direction of the given drawable. 1166621e41e02c0664afd4e358dfe166d6fb71e471c9Doris Liu * Return true if auto-mirror is supported and drawable's layout direction can be changed. 1167621e41e02c0664afd4e358dfe166d6fb71e471c9Doris Liu * Otherwise, return false. 1168621e41e02c0664afd4e358dfe166d6fb71e471c9Doris Liu */ 1169621e41e02c0664afd4e358dfe166d6fb71e471c9Doris Liu private boolean mirror(Drawable drawable, int layoutDirection) { 1170621e41e02c0664afd4e358dfe166d6fb71e471c9Doris Liu if (drawable == null || !DrawableCompat.isAutoMirrored(drawable)) { 1171621e41e02c0664afd4e358dfe166d6fb71e471c9Doris Liu return false; 1172621e41e02c0664afd4e358dfe166d6fb71e471c9Doris Liu } 1173621e41e02c0664afd4e358dfe166d6fb71e471c9Doris Liu 1174621e41e02c0664afd4e358dfe166d6fb71e471c9Doris Liu DrawableCompat.setLayoutDirection(drawable, layoutDirection); 1175621e41e02c0664afd4e358dfe166d6fb71e471c9Doris Liu return true; 1176621e41e02c0664afd4e358dfe166d6fb71e471c9Doris Liu } 1177621e41e02c0664afd4e358dfe166d6fb71e471c9Doris Liu 11781d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell @Override 11791d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell protected void onLayout(boolean changed, int l, int t, int r, int b) { 1180b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell mInLayout = true; 1181c27e9ab4a09e40911d180fa0e25a0011a3adcd71Adam Powell final int width = r - l; 11821d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final int childCount = getChildCount(); 11831d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell for (int i = 0; i < childCount; i++) { 11841d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final View child = getChildAt(i); 11851d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 11861d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell if (child.getVisibility() == GONE) { 11871d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell continue; 11881d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 11891d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 119000ca2532981fbd705f947a637ffd967a8d6f733bAdam Powell final LayoutParams lp = (LayoutParams) child.getLayoutParams(); 119100ca2532981fbd705f947a637ffd967a8d6f733bAdam Powell 11921d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell if (isContentView(child)) { 119300ca2532981fbd705f947a637ffd967a8d6f733bAdam Powell child.layout(lp.leftMargin, lp.topMargin, 119400ca2532981fbd705f947a637ffd967a8d6f733bAdam Powell lp.leftMargin + child.getMeasuredWidth(), 119500ca2532981fbd705f947a637ffd967a8d6f733bAdam Powell lp.topMargin + child.getMeasuredHeight()); 11961d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } else { // Drawer, if it wasn't onMeasure would have thrown an exception. 11971d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final int childWidth = child.getMeasuredWidth(); 119800ca2532981fbd705f947a637ffd967a8d6f733bAdam Powell final int childHeight = child.getMeasuredHeight(); 11991d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell int childLeft; 12001d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 1201c27e9ab4a09e40911d180fa0e25a0011a3adcd71Adam Powell final float newOffset; 1202f55dfacb0db5da12ad3b9e5615c3feaea372f37dAlan Viverette if (checkDrawerViewAbsoluteGravity(child, Gravity.LEFT)) { 1203b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell childLeft = -childWidth + (int) (childWidth * lp.onScreen); 1204c27e9ab4a09e40911d180fa0e25a0011a3adcd71Adam Powell newOffset = (float) (childWidth + childLeft) / childWidth; 12051d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } else { // Right; onMeasure checked for us. 1206c27e9ab4a09e40911d180fa0e25a0011a3adcd71Adam Powell childLeft = width - (int) (childWidth * lp.onScreen); 1207c27e9ab4a09e40911d180fa0e25a0011a3adcd71Adam Powell newOffset = (float) (width - childLeft) / childWidth; 12081d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 12091d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 1210c27e9ab4a09e40911d180fa0e25a0011a3adcd71Adam Powell final boolean changeOffset = newOffset != lp.onScreen; 1211c27e9ab4a09e40911d180fa0e25a0011a3adcd71Adam Powell 121200ca2532981fbd705f947a637ffd967a8d6f733bAdam Powell final int vgrav = lp.gravity & Gravity.VERTICAL_GRAVITY_MASK; 121300ca2532981fbd705f947a637ffd967a8d6f733bAdam Powell 121400ca2532981fbd705f947a637ffd967a8d6f733bAdam Powell switch (vgrav) { 121500ca2532981fbd705f947a637ffd967a8d6f733bAdam Powell default: 121600ca2532981fbd705f947a637ffd967a8d6f733bAdam Powell case Gravity.TOP: { 12179b2fb1efe771e9927724b33242cbc3bc62b5b315Adam Powell child.layout(childLeft, lp.topMargin, childLeft + childWidth, 12189b2fb1efe771e9927724b33242cbc3bc62b5b315Adam Powell lp.topMargin + childHeight); 121900ca2532981fbd705f947a637ffd967a8d6f733bAdam Powell break; 122000ca2532981fbd705f947a637ffd967a8d6f733bAdam Powell } 122100ca2532981fbd705f947a637ffd967a8d6f733bAdam Powell 122200ca2532981fbd705f947a637ffd967a8d6f733bAdam Powell case Gravity.BOTTOM: { 122300ca2532981fbd705f947a637ffd967a8d6f733bAdam Powell final int height = b - t; 122400ca2532981fbd705f947a637ffd967a8d6f733bAdam Powell child.layout(childLeft, 122500ca2532981fbd705f947a637ffd967a8d6f733bAdam Powell height - lp.bottomMargin - child.getMeasuredHeight(), 122600ca2532981fbd705f947a637ffd967a8d6f733bAdam Powell childLeft + childWidth, 122700ca2532981fbd705f947a637ffd967a8d6f733bAdam Powell height - lp.bottomMargin); 122800ca2532981fbd705f947a637ffd967a8d6f733bAdam Powell break; 122900ca2532981fbd705f947a637ffd967a8d6f733bAdam Powell } 123000ca2532981fbd705f947a637ffd967a8d6f733bAdam Powell 123100ca2532981fbd705f947a637ffd967a8d6f733bAdam Powell case Gravity.CENTER_VERTICAL: { 123200ca2532981fbd705f947a637ffd967a8d6f733bAdam Powell final int height = b - t; 123300ca2532981fbd705f947a637ffd967a8d6f733bAdam Powell int childTop = (height - childHeight) / 2; 123400ca2532981fbd705f947a637ffd967a8d6f733bAdam Powell 123500ca2532981fbd705f947a637ffd967a8d6f733bAdam Powell // Offset for margins. If things don't fit right because of 123600ca2532981fbd705f947a637ffd967a8d6f733bAdam Powell // bad measurement before, oh well. 123700ca2532981fbd705f947a637ffd967a8d6f733bAdam Powell if (childTop < lp.topMargin) { 123800ca2532981fbd705f947a637ffd967a8d6f733bAdam Powell childTop = lp.topMargin; 123900ca2532981fbd705f947a637ffd967a8d6f733bAdam Powell } else if (childTop + childHeight > height - lp.bottomMargin) { 124000ca2532981fbd705f947a637ffd967a8d6f733bAdam Powell childTop = height - lp.bottomMargin - childHeight; 124100ca2532981fbd705f947a637ffd967a8d6f733bAdam Powell } 124200ca2532981fbd705f947a637ffd967a8d6f733bAdam Powell child.layout(childLeft, childTop, childLeft + childWidth, 124300ca2532981fbd705f947a637ffd967a8d6f733bAdam Powell childTop + childHeight); 124400ca2532981fbd705f947a637ffd967a8d6f733bAdam Powell break; 124500ca2532981fbd705f947a637ffd967a8d6f733bAdam Powell } 124600ca2532981fbd705f947a637ffd967a8d6f733bAdam Powell } 1247b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell 1248c27e9ab4a09e40911d180fa0e25a0011a3adcd71Adam Powell if (changeOffset) { 1249c27e9ab4a09e40911d180fa0e25a0011a3adcd71Adam Powell setDrawerViewOffset(child, newOffset); 1250c27e9ab4a09e40911d180fa0e25a0011a3adcd71Adam Powell } 1251c27e9ab4a09e40911d180fa0e25a0011a3adcd71Adam Powell 1252c27e9ab4a09e40911d180fa0e25a0011a3adcd71Adam Powell final int newVisibility = lp.onScreen > 0 ? VISIBLE : INVISIBLE; 1253c27e9ab4a09e40911d180fa0e25a0011a3adcd71Adam Powell if (child.getVisibility() != newVisibility) { 1254c27e9ab4a09e40911d180fa0e25a0011a3adcd71Adam Powell child.setVisibility(newVisibility); 1255b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell } 12561d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 12571d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 1258b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell mInLayout = false; 125957902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell mFirstLayout = false; 1260b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell } 1261b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell 1262b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell @Override 1263b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell public void requestLayout() { 1264b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell if (!mInLayout) { 1265b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell super.requestLayout(); 1266b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell } 12671d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 12681d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 12691d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell @Override 12701d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell public void computeScroll() { 12711d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final int childCount = getChildCount(); 12721d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell float scrimOpacity = 0; 12731d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell for (int i = 0; i < childCount; i++) { 1274b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell final float onscreen = ((LayoutParams) getChildAt(i).getLayoutParams()).onScreen; 12751d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell scrimOpacity = Math.max(scrimOpacity, onscreen); 12761d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 12771d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell mScrimOpacity = scrimOpacity; 12781d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 12791d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell // "|" used on purpose; both need to run. 12801d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell if (mLeftDragger.continueSettling(true) | mRightDragger.continueSettling(true)) { 12811d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell ViewCompat.postInvalidateOnAnimation(this); 12821d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 12831d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 12841d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 1285b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell private static boolean hasOpaqueBackground(View v) { 1286b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell final Drawable bg = v.getBackground(); 1287b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell if (bg != null) { 1288b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell return bg.getOpacity() == PixelFormat.OPAQUE; 1289b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell } 1290b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell return false; 1291b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell } 1292b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell 1293f9c35128decbd812ff2497852ccacbd1ffbbd811Adam Powell /** 1294f9c35128decbd812ff2497852ccacbd1ffbbd811Adam Powell * Set a drawable to draw in the insets area for the status bar. 1295f9c35128decbd812ff2497852ccacbd1ffbbd811Adam Powell * Note that this will only be activated if this DrawerLayout fitsSystemWindows. 1296f9c35128decbd812ff2497852ccacbd1ffbbd811Adam Powell * 1297f9c35128decbd812ff2497852ccacbd1ffbbd811Adam Powell * @param bg Background drawable to draw behind the status bar 1298f9c35128decbd812ff2497852ccacbd1ffbbd811Adam Powell */ 1299f9c35128decbd812ff2497852ccacbd1ffbbd811Adam Powell public void setStatusBarBackground(Drawable bg) { 1300f9c35128decbd812ff2497852ccacbd1ffbbd811Adam Powell mStatusBarBackground = bg; 1301cbfb6c6ffc411f1f9d302570341993bd9929ee1aScott Kennedy invalidate(); 1302f9c35128decbd812ff2497852ccacbd1ffbbd811Adam Powell } 1303f9c35128decbd812ff2497852ccacbd1ffbbd811Adam Powell 1304f9c35128decbd812ff2497852ccacbd1ffbbd811Adam Powell /** 1305753354ca64f8528ddc3b76d0ce69635de743e506Scott Kennedy * Gets the drawable used to draw in the insets area for the status bar. 1306753354ca64f8528ddc3b76d0ce69635de743e506Scott Kennedy * 1307753354ca64f8528ddc3b76d0ce69635de743e506Scott Kennedy * @return The status bar background drawable, or null if none set 1308753354ca64f8528ddc3b76d0ce69635de743e506Scott Kennedy */ 1309753354ca64f8528ddc3b76d0ce69635de743e506Scott Kennedy public Drawable getStatusBarBackgroundDrawable() { 1310753354ca64f8528ddc3b76d0ce69635de743e506Scott Kennedy return mStatusBarBackground; 1311753354ca64f8528ddc3b76d0ce69635de743e506Scott Kennedy } 1312753354ca64f8528ddc3b76d0ce69635de743e506Scott Kennedy 1313753354ca64f8528ddc3b76d0ce69635de743e506Scott Kennedy /** 1314f9c35128decbd812ff2497852ccacbd1ffbbd811Adam Powell * Set a drawable to draw in the insets area for the status bar. 1315f9c35128decbd812ff2497852ccacbd1ffbbd811Adam Powell * Note that this will only be activated if this DrawerLayout fitsSystemWindows. 1316f9c35128decbd812ff2497852ccacbd1ffbbd811Adam Powell * 1317f9c35128decbd812ff2497852ccacbd1ffbbd811Adam Powell * @param resId Resource id of a background drawable to draw behind the status bar 1318f9c35128decbd812ff2497852ccacbd1ffbbd811Adam Powell */ 1319f9c35128decbd812ff2497852ccacbd1ffbbd811Adam Powell public void setStatusBarBackground(int resId) { 1320f9c35128decbd812ff2497852ccacbd1ffbbd811Adam Powell mStatusBarBackground = resId != 0 ? ContextCompat.getDrawable(getContext(), resId) : null; 1321cbfb6c6ffc411f1f9d302570341993bd9929ee1aScott Kennedy invalidate(); 1322f9c35128decbd812ff2497852ccacbd1ffbbd811Adam Powell } 1323f9c35128decbd812ff2497852ccacbd1ffbbd811Adam Powell 1324f9c35128decbd812ff2497852ccacbd1ffbbd811Adam Powell /** 1325f9c35128decbd812ff2497852ccacbd1ffbbd811Adam Powell * Set a drawable to draw in the insets area for the status bar. 1326f9c35128decbd812ff2497852ccacbd1ffbbd811Adam Powell * Note that this will only be activated if this DrawerLayout fitsSystemWindows. 1327f9c35128decbd812ff2497852ccacbd1ffbbd811Adam Powell * 1328f9c35128decbd812ff2497852ccacbd1ffbbd811Adam Powell * @param color Color to use as a background drawable to draw behind the status bar 1329f9c35128decbd812ff2497852ccacbd1ffbbd811Adam Powell * in 0xAARRGGBB format. 1330f9c35128decbd812ff2497852ccacbd1ffbbd811Adam Powell */ 133170acb0c19be3831a2080e4f902324de16bfbf62eTor Norbye public void setStatusBarBackgroundColor(@ColorInt int color) { 1332f9c35128decbd812ff2497852ccacbd1ffbbd811Adam Powell mStatusBarBackground = new ColorDrawable(color); 1333cbfb6c6ffc411f1f9d302570341993bd9929ee1aScott Kennedy invalidate(); 1334f9c35128decbd812ff2497852ccacbd1ffbbd811Adam Powell } 1335f9c35128decbd812ff2497852ccacbd1ffbbd811Adam Powell 1336621e41e02c0664afd4e358dfe166d6fb71e471c9Doris Liu public void onRtlPropertiesChanged(int layoutDirection) { 1337621e41e02c0664afd4e358dfe166d6fb71e471c9Doris Liu resolveShadowDrawables(); 1338621e41e02c0664afd4e358dfe166d6fb71e471c9Doris Liu } 1339621e41e02c0664afd4e358dfe166d6fb71e471c9Doris Liu 1340f9c35128decbd812ff2497852ccacbd1ffbbd811Adam Powell @Override 1341f9c35128decbd812ff2497852ccacbd1ffbbd811Adam Powell public void onDraw(Canvas c) { 1342f9c35128decbd812ff2497852ccacbd1ffbbd811Adam Powell super.onDraw(c); 1343f9c35128decbd812ff2497852ccacbd1ffbbd811Adam Powell if (mDrawStatusBarBackground && mStatusBarBackground != null) { 1344f9c35128decbd812ff2497852ccacbd1ffbbd811Adam Powell final int inset = IMPL.getTopInset(mLastInsets); 1345f9c35128decbd812ff2497852ccacbd1ffbbd811Adam Powell if (inset > 0) { 1346f9c35128decbd812ff2497852ccacbd1ffbbd811Adam Powell mStatusBarBackground.setBounds(0, 0, getWidth(), inset); 1347f9c35128decbd812ff2497852ccacbd1ffbbd811Adam Powell mStatusBarBackground.draw(c); 1348f9c35128decbd812ff2497852ccacbd1ffbbd811Adam Powell } 1349f9c35128decbd812ff2497852ccacbd1ffbbd811Adam Powell } 1350f9c35128decbd812ff2497852ccacbd1ffbbd811Adam Powell } 1351f9c35128decbd812ff2497852ccacbd1ffbbd811Adam Powell 13521d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell @Override 13531d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell protected boolean drawChild(Canvas canvas, View child, long drawingTime) { 135400ca2532981fbd705f947a637ffd967a8d6f733bAdam Powell final int height = getHeight(); 1355b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell final boolean drawingContent = isContentView(child); 1356b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell int clipLeft = 0, clipRight = getWidth(); 1357b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell 13581d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final int restoreCount = canvas.save(); 1359b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell if (drawingContent) { 1360b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell final int childCount = getChildCount(); 1361b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell for (int i = 0; i < childCount; i++) { 1362b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell final View v = getChildAt(i); 13634d2c7b7c4f194034c5f17c4bee7320d808aabe4cAurimas Liutikas if (v == child || v.getVisibility() != VISIBLE 13644d2c7b7c4f194034c5f17c4bee7320d808aabe4cAurimas Liutikas || !hasOpaqueBackground(v) || !isDrawerView(v) 13654d2c7b7c4f194034c5f17c4bee7320d808aabe4cAurimas Liutikas || v.getHeight() < height) { 1366b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell continue; 1367b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell } 1368b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell 1369f55dfacb0db5da12ad3b9e5615c3feaea372f37dAlan Viverette if (checkDrawerViewAbsoluteGravity(v, Gravity.LEFT)) { 1370b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell final int vright = v.getRight(); 1371b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell if (vright > clipLeft) clipLeft = vright; 1372b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell } else { 1373b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell final int vleft = v.getLeft(); 1374b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell if (vleft < clipRight) clipRight = vleft; 1375b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell } 1376b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell } 1377b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell canvas.clipRect(clipLeft, 0, clipRight, getHeight()); 1378b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell } 13791d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final boolean result = super.drawChild(canvas, child, drawingTime); 13801d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell canvas.restoreToCount(restoreCount); 1381b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell 1382b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell if (mScrimOpacity > 0 && drawingContent) { 13831d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final int baseAlpha = (mScrimColor & 0xff000000) >>> 24; 13841d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final int imag = (int) (baseAlpha * mScrimOpacity); 13851d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final int color = imag << 24 | (mScrimColor & 0xffffff); 13861d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell mScrimPaint.setColor(color); 13871d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 1388b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell canvas.drawRect(clipLeft, 0, clipRight, getHeight(), mScrimPaint); 1389621e41e02c0664afd4e358dfe166d6fb71e471c9Doris Liu } else if (mShadowLeftResolved != null 1390621e41e02c0664afd4e358dfe166d6fb71e471c9Doris Liu && checkDrawerViewAbsoluteGravity(child, Gravity.LEFT)) { 1391621e41e02c0664afd4e358dfe166d6fb71e471c9Doris Liu final int shadowWidth = mShadowLeftResolved.getIntrinsicWidth(); 1392b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell final int childRight = child.getRight(); 1393ea7b10f4d5531713506e98c8093e7aab811f21f3Adam Powell final int drawerPeekDistance = mLeftDragger.getEdgeSize(); 1394b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell final float alpha = 1395ea7b10f4d5531713506e98c8093e7aab811f21f3Adam Powell Math.max(0, Math.min((float) childRight / drawerPeekDistance, 1.f)); 1396621e41e02c0664afd4e358dfe166d6fb71e471c9Doris Liu mShadowLeftResolved.setBounds(childRight, child.getTop(), 1397b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell childRight + shadowWidth, child.getBottom()); 1398621e41e02c0664afd4e358dfe166d6fb71e471c9Doris Liu mShadowLeftResolved.setAlpha((int) (0xff * alpha)); 1399621e41e02c0664afd4e358dfe166d6fb71e471c9Doris Liu mShadowLeftResolved.draw(canvas); 1400621e41e02c0664afd4e358dfe166d6fb71e471c9Doris Liu } else if (mShadowRightResolved != null 1401621e41e02c0664afd4e358dfe166d6fb71e471c9Doris Liu && checkDrawerViewAbsoluteGravity(child, Gravity.RIGHT)) { 1402621e41e02c0664afd4e358dfe166d6fb71e471c9Doris Liu final int shadowWidth = mShadowRightResolved.getIntrinsicWidth(); 1403b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell final int childLeft = child.getLeft(); 1404b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell final int showing = getWidth() - childLeft; 1405ea7b10f4d5531713506e98c8093e7aab811f21f3Adam Powell final int drawerPeekDistance = mRightDragger.getEdgeSize(); 1406b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell final float alpha = 1407ea7b10f4d5531713506e98c8093e7aab811f21f3Adam Powell Math.max(0, Math.min((float) showing / drawerPeekDistance, 1.f)); 1408621e41e02c0664afd4e358dfe166d6fb71e471c9Doris Liu mShadowRightResolved.setBounds(childLeft - shadowWidth, child.getTop(), 1409b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell childLeft, child.getBottom()); 1410621e41e02c0664afd4e358dfe166d6fb71e471c9Doris Liu mShadowRightResolved.setAlpha((int) (0xff * alpha)); 1411621e41e02c0664afd4e358dfe166d6fb71e471c9Doris Liu mShadowRightResolved.draw(canvas); 14121d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 14131d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell return result; 14141d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 14151d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 14161d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell boolean isContentView(View child) { 14171d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell return ((LayoutParams) child.getLayoutParams()).gravity == Gravity.NO_GRAVITY; 14181d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 14191d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 14201d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell boolean isDrawerView(View child) { 14211d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final int gravity = ((LayoutParams) child.getLayoutParams()).gravity; 14221d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final int absGravity = GravityCompat.getAbsoluteGravity(gravity, 14231d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell ViewCompat.getLayoutDirection(child)); 14240fcbafc72ac95c44e2ff99a4e1b31475e4276052Kirill Grouchnikov if ((absGravity & Gravity.LEFT) != 0) { 1425e6e27ab94303516b1e196568cee520832c38710cKirill Grouchnikov // This child is a left-edge drawer 1426e6e27ab94303516b1e196568cee520832c38710cKirill Grouchnikov return true; 1427e6e27ab94303516b1e196568cee520832c38710cKirill Grouchnikov } 14280fcbafc72ac95c44e2ff99a4e1b31475e4276052Kirill Grouchnikov if ((absGravity & Gravity.RIGHT) != 0) { 1429e6e27ab94303516b1e196568cee520832c38710cKirill Grouchnikov // This child is a right-edge drawer 1430e6e27ab94303516b1e196568cee520832c38710cKirill Grouchnikov return true; 1431e6e27ab94303516b1e196568cee520832c38710cKirill Grouchnikov } 1432e6e27ab94303516b1e196568cee520832c38710cKirill Grouchnikov return false; 14331d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 14341d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 14351d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell @Override 14361d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell public boolean onInterceptTouchEvent(MotionEvent ev) { 14371d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final int action = MotionEventCompat.getActionMasked(ev); 14381d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 14391d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell // "|" used deliberately here; both methods should be invoked. 14404d2c7b7c4f194034c5f17c4bee7320d808aabe4cAurimas Liutikas final boolean interceptForDrag = mLeftDragger.shouldInterceptTouchEvent(ev) 14414d2c7b7c4f194034c5f17c4bee7320d808aabe4cAurimas Liutikas | mRightDragger.shouldInterceptTouchEvent(ev); 14421d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 14431d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell boolean interceptForTap = false; 14441d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 14451d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell switch (action) { 14461d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell case MotionEvent.ACTION_DOWN: { 14471d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final float x = ev.getX(); 14481d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final float y = ev.getY(); 14491d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell mInitialMotionX = x; 14501d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell mInitialMotionY = y; 14512bb8d4e8831b2d0f1de7f15493bb79f48c91db2aAlan Viverette if (mScrimOpacity > 0) { 14522bb8d4e8831b2d0f1de7f15493bb79f48c91db2aAlan Viverette final View child = mLeftDragger.findTopChildUnder((int) x, (int) y); 14532bb8d4e8831b2d0f1de7f15493bb79f48c91db2aAlan Viverette if (child != null && isContentView(child)) { 14542bb8d4e8831b2d0f1de7f15493bb79f48c91db2aAlan Viverette interceptForTap = true; 14552bb8d4e8831b2d0f1de7f15493bb79f48c91db2aAlan Viverette } 14561d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 14571732720ad57fe6d01392cd06551f1a25cff0333cAdam Powell mDisallowInterceptRequested = false; 1458cde2707260e8241ffb816a03cbf5d52c28004b8aAdam Powell mChildrenCanceledTouch = false; 14591732720ad57fe6d01392cd06551f1a25cff0333cAdam Powell break; 14601732720ad57fe6d01392cd06551f1a25cff0333cAdam Powell } 14611732720ad57fe6d01392cd06551f1a25cff0333cAdam Powell 14621732720ad57fe6d01392cd06551f1a25cff0333cAdam Powell case MotionEvent.ACTION_MOVE: { 14631732720ad57fe6d01392cd06551f1a25cff0333cAdam Powell // If we cross the touch slop, don't perform the delayed peek for an edge touch. 14641732720ad57fe6d01392cd06551f1a25cff0333cAdam Powell if (mLeftDragger.checkTouchSlop(ViewDragHelper.DIRECTION_ALL)) { 14651732720ad57fe6d01392cd06551f1a25cff0333cAdam Powell mLeftCallback.removeCallbacks(); 14661732720ad57fe6d01392cd06551f1a25cff0333cAdam Powell mRightCallback.removeCallbacks(); 14671732720ad57fe6d01392cd06551f1a25cff0333cAdam Powell } 14681d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell break; 14691d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 14701d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 14711d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell case MotionEvent.ACTION_CANCEL: 14721d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell case MotionEvent.ACTION_UP: { 14731d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell closeDrawers(true); 14741732720ad57fe6d01392cd06551f1a25cff0333cAdam Powell mDisallowInterceptRequested = false; 1475cde2707260e8241ffb816a03cbf5d52c28004b8aAdam Powell mChildrenCanceledTouch = false; 14761d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 14771d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 14781732720ad57fe6d01392cd06551f1a25cff0333cAdam Powell 1479cde2707260e8241ffb816a03cbf5d52c28004b8aAdam Powell return interceptForDrag || interceptForTap || hasPeekingDrawer() || mChildrenCanceledTouch; 14801d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 14811d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 14821d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell @Override 14831d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell public boolean onTouchEvent(MotionEvent ev) { 14841d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell mLeftDragger.processTouchEvent(ev); 14851d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell mRightDragger.processTouchEvent(ev); 14861d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 14871d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final int action = ev.getAction(); 14881d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell boolean wantTouchEvents = true; 14891d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 14901d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell switch (action & MotionEventCompat.ACTION_MASK) { 14911d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell case MotionEvent.ACTION_DOWN: { 14921d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final float x = ev.getX(); 14931d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final float y = ev.getY(); 14941d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell mInitialMotionX = x; 14951d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell mInitialMotionY = y; 14961732720ad57fe6d01392cd06551f1a25cff0333cAdam Powell mDisallowInterceptRequested = false; 1497cde2707260e8241ffb816a03cbf5d52c28004b8aAdam Powell mChildrenCanceledTouch = false; 14981d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell break; 14991d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 15001d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 15011d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell case MotionEvent.ACTION_UP: { 15021d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final float x = ev.getX(); 15031d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final float y = ev.getY(); 15041d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell boolean peekingOnly = true; 15058bc268e9c40e4ae375a0d65dc1293dccc541186fAdam Powell final View touchedView = mLeftDragger.findTopChildUnder((int) x, (int) y); 15068bc268e9c40e4ae375a0d65dc1293dccc541186fAdam Powell if (touchedView != null && isContentView(touchedView)) { 15071d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final float dx = x - mInitialMotionX; 15081d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final float dy = y - mInitialMotionY; 15091d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final int slop = mLeftDragger.getTouchSlop(); 15101d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell if (dx * dx + dy * dy < slop * slop) { 15110492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell // Taps close a dimmed open drawer but only if it isn't locked open. 15120492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell final View openDrawer = findOpenDrawer(); 15130492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell if (openDrawer != null) { 15140492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell peekingOnly = getDrawerLockMode(openDrawer) == LOCK_MODE_LOCKED_OPEN; 15150492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell } 15161d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 15171d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 15181d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell closeDrawers(peekingOnly); 15191732720ad57fe6d01392cd06551f1a25cff0333cAdam Powell mDisallowInterceptRequested = false; 15201d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell break; 15211d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 15221d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 15231d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell case MotionEvent.ACTION_CANCEL: { 15241d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell closeDrawers(true); 15251732720ad57fe6d01392cd06551f1a25cff0333cAdam Powell mDisallowInterceptRequested = false; 1526cde2707260e8241ffb816a03cbf5d52c28004b8aAdam Powell mChildrenCanceledTouch = false; 15271d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell break; 15281d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 15291d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 15301d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 15311d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell return wantTouchEvents; 15321d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 15331d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 153415375aa6fd54b036f97f99229aefab2822c8a1c9Aurimas Liutikas @Override 1535ea7b10f4d5531713506e98c8093e7aab811f21f3Adam Powell public void requestDisallowInterceptTouchEvent(boolean disallowIntercept) { 15364d2c7b7c4f194034c5f17c4bee7320d808aabe4cAurimas Liutikas if (CHILDREN_DISALLOW_INTERCEPT 15374d2c7b7c4f194034c5f17c4bee7320d808aabe4cAurimas Liutikas || (!mLeftDragger.isEdgeTouched(ViewDragHelper.EDGE_LEFT) 15384d2c7b7c4f194034c5f17c4bee7320d808aabe4cAurimas Liutikas && !mRightDragger.isEdgeTouched(ViewDragHelper.EDGE_RIGHT))) { 15391732720ad57fe6d01392cd06551f1a25cff0333cAdam Powell // If we have an edge touch we want to skip this and track it for later instead. 15401732720ad57fe6d01392cd06551f1a25cff0333cAdam Powell super.requestDisallowInterceptTouchEvent(disallowIntercept); 15411732720ad57fe6d01392cd06551f1a25cff0333cAdam Powell } 15421732720ad57fe6d01392cd06551f1a25cff0333cAdam Powell mDisallowInterceptRequested = disallowIntercept; 1543ea7b10f4d5531713506e98c8093e7aab811f21f3Adam Powell if (disallowIntercept) { 1544ea7b10f4d5531713506e98c8093e7aab811f21f3Adam Powell closeDrawers(true); 1545ea7b10f4d5531713506e98c8093e7aab811f21f3Adam Powell } 1546ea7b10f4d5531713506e98c8093e7aab811f21f3Adam Powell } 1547ea7b10f4d5531713506e98c8093e7aab811f21f3Adam Powell 15481d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell /** 15491d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * Close all currently open drawer views by animating them out of view. 15501d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell */ 15511d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell public void closeDrawers() { 15521d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell closeDrawers(false); 15531d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 15541d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 15551d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell void closeDrawers(boolean peekingOnly) { 15561d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell boolean needsInvalidate = false; 15571d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final int childCount = getChildCount(); 15581d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell for (int i = 0; i < childCount; i++) { 15591d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final View child = getChildAt(i); 15601d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final LayoutParams lp = (LayoutParams) child.getLayoutParams(); 15611d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 15621d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell if (!isDrawerView(child) || (peekingOnly && !lp.isPeeking)) { 15631d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell continue; 15641d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 15651d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 15661d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final int childWidth = child.getWidth(); 15671d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 1568f55dfacb0db5da12ad3b9e5615c3feaea372f37dAlan Viverette if (checkDrawerViewAbsoluteGravity(child, Gravity.LEFT)) { 15691d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell needsInvalidate |= mLeftDragger.smoothSlideViewTo(child, 15701d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell -childWidth, child.getTop()); 15711d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } else { 15721d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell needsInvalidate |= mRightDragger.smoothSlideViewTo(child, 15731d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell getWidth(), child.getTop()); 15741d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 15751d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 15761d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell lp.isPeeking = false; 15771d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 15781d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 15791732720ad57fe6d01392cd06551f1a25cff0333cAdam Powell mLeftCallback.removeCallbacks(); 15801732720ad57fe6d01392cd06551f1a25cff0333cAdam Powell mRightCallback.removeCallbacks(); 15811732720ad57fe6d01392cd06551f1a25cff0333cAdam Powell 15821d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell if (needsInvalidate) { 15831d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell invalidate(); 15841d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 15851d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 15861d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 15871d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell /** 15881d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * Open the specified drawer view by animating it into view. 15891d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * 15901d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * @param drawerView Drawer view to open 15911d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell */ 15921d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell public void openDrawer(View drawerView) { 1593ee4afb511cf51d082e3226f442799a59725bdac2Aurimas Liutikas openDrawer(drawerView, true); 1594ee4afb511cf51d082e3226f442799a59725bdac2Aurimas Liutikas } 1595ee4afb511cf51d082e3226f442799a59725bdac2Aurimas Liutikas 1596ee4afb511cf51d082e3226f442799a59725bdac2Aurimas Liutikas /** 1597ee4afb511cf51d082e3226f442799a59725bdac2Aurimas Liutikas * Open the specified drawer view. 1598ee4afb511cf51d082e3226f442799a59725bdac2Aurimas Liutikas * 1599ee4afb511cf51d082e3226f442799a59725bdac2Aurimas Liutikas * @param drawerView Drawer view to open 1600ee4afb511cf51d082e3226f442799a59725bdac2Aurimas Liutikas * @param animate Whether opening of the drawer should be animated. 1601ee4afb511cf51d082e3226f442799a59725bdac2Aurimas Liutikas */ 1602ee4afb511cf51d082e3226f442799a59725bdac2Aurimas Liutikas public void openDrawer(View drawerView, boolean animate) { 16031d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell if (!isDrawerView(drawerView)) { 16041d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell throw new IllegalArgumentException("View " + drawerView + " is not a sliding drawer"); 16051d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 16061d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 160767cf3e301575e3d67e3b4c3d06f4624438590dd3Kirill Grouchnikov final LayoutParams lp = (LayoutParams) drawerView.getLayoutParams(); 160857902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell if (mFirstLayout) { 160957902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell lp.onScreen = 1.f; 161067cf3e301575e3d67e3b4c3d06f4624438590dd3Kirill Grouchnikov lp.openState = LayoutParams.FLAG_IS_OPENED; 161149733ad715bcf68cc178f53e17a79380d332e5ccAlan Viverette 16122bb8d4e8831b2d0f1de7f15493bb79f48c91db2aAlan Viverette updateChildrenImportantForAccessibility(drawerView, true); 1613ee4afb511cf51d082e3226f442799a59725bdac2Aurimas Liutikas } else if (animate) { 161467cf3e301575e3d67e3b4c3d06f4624438590dd3Kirill Grouchnikov lp.openState |= LayoutParams.FLAG_IS_OPENING; 161567cf3e301575e3d67e3b4c3d06f4624438590dd3Kirill Grouchnikov 1616f55dfacb0db5da12ad3b9e5615c3feaea372f37dAlan Viverette if (checkDrawerViewAbsoluteGravity(drawerView, Gravity.LEFT)) { 161757902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell mLeftDragger.smoothSlideViewTo(drawerView, 0, drawerView.getTop()); 161857902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell } else { 161957902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell mRightDragger.smoothSlideViewTo(drawerView, getWidth() - drawerView.getWidth(), 162057902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell drawerView.getTop()); 162157902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell } 1622ee4afb511cf51d082e3226f442799a59725bdac2Aurimas Liutikas } else { 1623ee4afb511cf51d082e3226f442799a59725bdac2Aurimas Liutikas moveDrawerToOffset(drawerView, 1.f); 1624ee4afb511cf51d082e3226f442799a59725bdac2Aurimas Liutikas updateDrawerState(lp.gravity, STATE_IDLE, drawerView); 1625ee4afb511cf51d082e3226f442799a59725bdac2Aurimas Liutikas drawerView.setVisibility(VISIBLE); 16261d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 16271d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell invalidate(); 16281d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 16291d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 16301d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell /** 16311d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * Open the specified drawer by animating it out of view. 16321d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * 16331d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * @param gravity Gravity.LEFT to move the left drawer or Gravity.RIGHT for the right. 16341d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * GravityCompat.START or GravityCompat.END may also be used. 16351d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell */ 1636a3ff3273e976adf19770651dcf473fa67b38eb22Tor Norbye public void openDrawer(@EdgeGravity int gravity) { 1637ee4afb511cf51d082e3226f442799a59725bdac2Aurimas Liutikas openDrawer(gravity, true); 1638ee4afb511cf51d082e3226f442799a59725bdac2Aurimas Liutikas } 1639ee4afb511cf51d082e3226f442799a59725bdac2Aurimas Liutikas 1640ee4afb511cf51d082e3226f442799a59725bdac2Aurimas Liutikas /** 1641ee4afb511cf51d082e3226f442799a59725bdac2Aurimas Liutikas * Open the specified drawer. 1642ee4afb511cf51d082e3226f442799a59725bdac2Aurimas Liutikas * 1643ee4afb511cf51d082e3226f442799a59725bdac2Aurimas Liutikas * @param gravity Gravity.LEFT to move the left drawer or Gravity.RIGHT for the right. 1644ee4afb511cf51d082e3226f442799a59725bdac2Aurimas Liutikas * GravityCompat.START or GravityCompat.END may also be used. 1645ee4afb511cf51d082e3226f442799a59725bdac2Aurimas Liutikas * @param animate Whether opening of the drawer should be animated. 1646ee4afb511cf51d082e3226f442799a59725bdac2Aurimas Liutikas */ 1647ee4afb511cf51d082e3226f442799a59725bdac2Aurimas Liutikas public void openDrawer(@EdgeGravity int gravity, boolean animate) { 1648f55dfacb0db5da12ad3b9e5615c3feaea372f37dAlan Viverette final View drawerView = findDrawerWithGravity(gravity); 16491d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell if (drawerView == null) { 16504d2c7b7c4f194034c5f17c4bee7320d808aabe4cAurimas Liutikas throw new IllegalArgumentException("No drawer view found with gravity " 16514d2c7b7c4f194034c5f17c4bee7320d808aabe4cAurimas Liutikas + gravityToString(gravity)); 16521d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 1653ee4afb511cf51d082e3226f442799a59725bdac2Aurimas Liutikas openDrawer(drawerView, animate); 16541d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 16551d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 16561d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell /** 16571d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * Close the specified drawer view by animating it into view. 16581d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * 16591d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * @param drawerView Drawer view to close 16601d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell */ 16611d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell public void closeDrawer(View drawerView) { 1662ee4afb511cf51d082e3226f442799a59725bdac2Aurimas Liutikas closeDrawer(drawerView, true); 1663ee4afb511cf51d082e3226f442799a59725bdac2Aurimas Liutikas } 1664ee4afb511cf51d082e3226f442799a59725bdac2Aurimas Liutikas 1665ee4afb511cf51d082e3226f442799a59725bdac2Aurimas Liutikas /** 1666ee4afb511cf51d082e3226f442799a59725bdac2Aurimas Liutikas * Close the specified drawer view. 1667ee4afb511cf51d082e3226f442799a59725bdac2Aurimas Liutikas * 1668ee4afb511cf51d082e3226f442799a59725bdac2Aurimas Liutikas * @param drawerView Drawer view to close 1669ee4afb511cf51d082e3226f442799a59725bdac2Aurimas Liutikas * @param animate Whether closing of the drawer should be animated. 1670ee4afb511cf51d082e3226f442799a59725bdac2Aurimas Liutikas */ 1671ee4afb511cf51d082e3226f442799a59725bdac2Aurimas Liutikas public void closeDrawer(View drawerView, boolean animate) { 16721d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell if (!isDrawerView(drawerView)) { 16731d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell throw new IllegalArgumentException("View " + drawerView + " is not a sliding drawer"); 16741d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 16751d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 167667cf3e301575e3d67e3b4c3d06f4624438590dd3Kirill Grouchnikov final LayoutParams lp = (LayoutParams) drawerView.getLayoutParams(); 167757902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell if (mFirstLayout) { 167857902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell lp.onScreen = 0.f; 167967cf3e301575e3d67e3b4c3d06f4624438590dd3Kirill Grouchnikov lp.openState = 0; 1680ee4afb511cf51d082e3226f442799a59725bdac2Aurimas Liutikas } else if (animate) { 168167cf3e301575e3d67e3b4c3d06f4624438590dd3Kirill Grouchnikov lp.openState |= LayoutParams.FLAG_IS_CLOSING; 168267cf3e301575e3d67e3b4c3d06f4624438590dd3Kirill Grouchnikov 1683f55dfacb0db5da12ad3b9e5615c3feaea372f37dAlan Viverette if (checkDrawerViewAbsoluteGravity(drawerView, Gravity.LEFT)) { 168457902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell mLeftDragger.smoothSlideViewTo(drawerView, -drawerView.getWidth(), 168557902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell drawerView.getTop()); 168657902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell } else { 168757902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell mRightDragger.smoothSlideViewTo(drawerView, getWidth(), drawerView.getTop()); 168857902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell } 1689ee4afb511cf51d082e3226f442799a59725bdac2Aurimas Liutikas } else { 1690ee4afb511cf51d082e3226f442799a59725bdac2Aurimas Liutikas moveDrawerToOffset(drawerView, 0.f); 1691ee4afb511cf51d082e3226f442799a59725bdac2Aurimas Liutikas updateDrawerState(lp.gravity, STATE_IDLE, drawerView); 1692ee4afb511cf51d082e3226f442799a59725bdac2Aurimas Liutikas drawerView.setVisibility(INVISIBLE); 16931d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 16941d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell invalidate(); 16951d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 16961d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 16971d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell /** 16981d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * Close the specified drawer by animating it out of view. 16991d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * 17001d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * @param gravity Gravity.LEFT to move the left drawer or Gravity.RIGHT for the right. 17011d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * GravityCompat.START or GravityCompat.END may also be used. 17021d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell */ 1703a3ff3273e976adf19770651dcf473fa67b38eb22Tor Norbye public void closeDrawer(@EdgeGravity int gravity) { 1704ee4afb511cf51d082e3226f442799a59725bdac2Aurimas Liutikas closeDrawer(gravity, true); 1705ee4afb511cf51d082e3226f442799a59725bdac2Aurimas Liutikas } 1706ee4afb511cf51d082e3226f442799a59725bdac2Aurimas Liutikas 1707ee4afb511cf51d082e3226f442799a59725bdac2Aurimas Liutikas /** 1708ee4afb511cf51d082e3226f442799a59725bdac2Aurimas Liutikas * Close the specified drawer. 1709ee4afb511cf51d082e3226f442799a59725bdac2Aurimas Liutikas * 1710ee4afb511cf51d082e3226f442799a59725bdac2Aurimas Liutikas * @param gravity Gravity.LEFT to move the left drawer or Gravity.RIGHT for the right. 1711ee4afb511cf51d082e3226f442799a59725bdac2Aurimas Liutikas * GravityCompat.START or GravityCompat.END may also be used. 1712ee4afb511cf51d082e3226f442799a59725bdac2Aurimas Liutikas * @param animate Whether closing of the drawer should be animated. 1713ee4afb511cf51d082e3226f442799a59725bdac2Aurimas Liutikas */ 1714ee4afb511cf51d082e3226f442799a59725bdac2Aurimas Liutikas public void closeDrawer(@EdgeGravity int gravity, boolean animate) { 1715f55dfacb0db5da12ad3b9e5615c3feaea372f37dAlan Viverette final View drawerView = findDrawerWithGravity(gravity); 17161d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell if (drawerView == null) { 17174d2c7b7c4f194034c5f17c4bee7320d808aabe4cAurimas Liutikas throw new IllegalArgumentException("No drawer view found with gravity " 17184d2c7b7c4f194034c5f17c4bee7320d808aabe4cAurimas Liutikas + gravityToString(gravity)); 17191d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 1720ee4afb511cf51d082e3226f442799a59725bdac2Aurimas Liutikas closeDrawer(drawerView, animate); 17211d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 17221d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 1723b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell /** 1724b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell * Check if the given drawer view is currently in an open state. 1725b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell * To be considered "open" the drawer must have settled into its fully 1726b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell * visible state. To check for partial visibility use 1727b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell * {@link #isDrawerVisible(android.view.View)}. 1728b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell * 1729b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell * @param drawer Drawer view to check 1730b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell * @return true if the given drawer view is in an open state 1731b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell * @see #isDrawerVisible(android.view.View) 1732b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell */ 1733b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell public boolean isDrawerOpen(View drawer) { 1734b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell if (!isDrawerView(drawer)) { 1735b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell throw new IllegalArgumentException("View " + drawer + " is not a drawer"); 1736b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell } 173767cf3e301575e3d67e3b4c3d06f4624438590dd3Kirill Grouchnikov LayoutParams drawerLp = (LayoutParams) drawer.getLayoutParams(); 173867cf3e301575e3d67e3b4c3d06f4624438590dd3Kirill Grouchnikov return (drawerLp.openState & LayoutParams.FLAG_IS_OPENED) == 1; 1739b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell } 1740b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell 1741b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell /** 174279f95ce3e660d267831067e514ff455156c4381fAdam Powell * Check if the given drawer view is currently in an open state. 174379f95ce3e660d267831067e514ff455156c4381fAdam Powell * To be considered "open" the drawer must have settled into its fully 174479f95ce3e660d267831067e514ff455156c4381fAdam Powell * visible state. If there is no drawer with the given gravity this method 174579f95ce3e660d267831067e514ff455156c4381fAdam Powell * will return false. 174679f95ce3e660d267831067e514ff455156c4381fAdam Powell * 174779f95ce3e660d267831067e514ff455156c4381fAdam Powell * @param drawerGravity Gravity of the drawer to check 174879f95ce3e660d267831067e514ff455156c4381fAdam Powell * @return true if the given drawer view is in an open state 174979f95ce3e660d267831067e514ff455156c4381fAdam Powell */ 1750a3ff3273e976adf19770651dcf473fa67b38eb22Tor Norbye public boolean isDrawerOpen(@EdgeGravity int drawerGravity) { 175179f95ce3e660d267831067e514ff455156c4381fAdam Powell final View drawerView = findDrawerWithGravity(drawerGravity); 175279f95ce3e660d267831067e514ff455156c4381fAdam Powell if (drawerView != null) { 175379f95ce3e660d267831067e514ff455156c4381fAdam Powell return isDrawerOpen(drawerView); 175479f95ce3e660d267831067e514ff455156c4381fAdam Powell } 175579f95ce3e660d267831067e514ff455156c4381fAdam Powell return false; 175679f95ce3e660d267831067e514ff455156c4381fAdam Powell } 175779f95ce3e660d267831067e514ff455156c4381fAdam Powell 175879f95ce3e660d267831067e514ff455156c4381fAdam Powell /** 1759b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell * Check if a given drawer view is currently visible on-screen. The drawer 1760b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell * may be only peeking onto the screen, fully extended, or anywhere inbetween. 1761b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell * 1762b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell * @param drawer Drawer view to check 1763b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell * @return true if the given drawer is visible on-screen 1764b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell * @see #isDrawerOpen(android.view.View) 1765b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell */ 1766b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell public boolean isDrawerVisible(View drawer) { 1767b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell if (!isDrawerView(drawer)) { 1768b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell throw new IllegalArgumentException("View " + drawer + " is not a drawer"); 1769b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell } 1770b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell return ((LayoutParams) drawer.getLayoutParams()).onScreen > 0; 1771b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell } 1772b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell 177379f95ce3e660d267831067e514ff455156c4381fAdam Powell /** 177479f95ce3e660d267831067e514ff455156c4381fAdam Powell * Check if a given drawer view is currently visible on-screen. The drawer 1775a3ff3273e976adf19770651dcf473fa67b38eb22Tor Norbye * may be only peeking onto the screen, fully extended, or anywhere in between. 177679f95ce3e660d267831067e514ff455156c4381fAdam Powell * If there is no drawer with the given gravity this method will return false. 177779f95ce3e660d267831067e514ff455156c4381fAdam Powell * 177879f95ce3e660d267831067e514ff455156c4381fAdam Powell * @param drawerGravity Gravity of the drawer to check 177979f95ce3e660d267831067e514ff455156c4381fAdam Powell * @return true if the given drawer is visible on-screen 178079f95ce3e660d267831067e514ff455156c4381fAdam Powell */ 1781a3ff3273e976adf19770651dcf473fa67b38eb22Tor Norbye public boolean isDrawerVisible(@EdgeGravity int drawerGravity) { 178279f95ce3e660d267831067e514ff455156c4381fAdam Powell final View drawerView = findDrawerWithGravity(drawerGravity); 178379f95ce3e660d267831067e514ff455156c4381fAdam Powell if (drawerView != null) { 178479f95ce3e660d267831067e514ff455156c4381fAdam Powell return isDrawerVisible(drawerView); 178579f95ce3e660d267831067e514ff455156c4381fAdam Powell } 178679f95ce3e660d267831067e514ff455156c4381fAdam Powell return false; 178779f95ce3e660d267831067e514ff455156c4381fAdam Powell } 178879f95ce3e660d267831067e514ff455156c4381fAdam Powell 1789ea7b10f4d5531713506e98c8093e7aab811f21f3Adam Powell private boolean hasPeekingDrawer() { 1790ea7b10f4d5531713506e98c8093e7aab811f21f3Adam Powell final int childCount = getChildCount(); 1791ea7b10f4d5531713506e98c8093e7aab811f21f3Adam Powell for (int i = 0; i < childCount; i++) { 1792ea7b10f4d5531713506e98c8093e7aab811f21f3Adam Powell final LayoutParams lp = (LayoutParams) getChildAt(i).getLayoutParams(); 1793ea7b10f4d5531713506e98c8093e7aab811f21f3Adam Powell if (lp.isPeeking) { 1794ea7b10f4d5531713506e98c8093e7aab811f21f3Adam Powell return true; 1795ea7b10f4d5531713506e98c8093e7aab811f21f3Adam Powell } 1796ea7b10f4d5531713506e98c8093e7aab811f21f3Adam Powell } 1797ea7b10f4d5531713506e98c8093e7aab811f21f3Adam Powell return false; 1798ea7b10f4d5531713506e98c8093e7aab811f21f3Adam Powell } 1799ea7b10f4d5531713506e98c8093e7aab811f21f3Adam Powell 18001d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell @Override 18011d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell protected ViewGroup.LayoutParams generateDefaultLayoutParams() { 1802e12dfa03641ad9cf0ddf272675bbe7d1198adbfdAurimas Liutikas return new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT); 18031d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 18041d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 18051d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell @Override 18061d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell protected ViewGroup.LayoutParams generateLayoutParams(ViewGroup.LayoutParams p) { 18071d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell return p instanceof LayoutParams 18081d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell ? new LayoutParams((LayoutParams) p) 180900ca2532981fbd705f947a637ffd967a8d6f733bAdam Powell : p instanceof ViewGroup.MarginLayoutParams 181000ca2532981fbd705f947a637ffd967a8d6f733bAdam Powell ? new LayoutParams((MarginLayoutParams) p) 18111d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell : new LayoutParams(p); 18121d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 18131d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 18141d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell @Override 18151d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell protected boolean checkLayoutParams(ViewGroup.LayoutParams p) { 18161d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell return p instanceof LayoutParams && super.checkLayoutParams(p); 18171d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 18181d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 18191d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell @Override 18201d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell public ViewGroup.LayoutParams generateLayoutParams(AttributeSet attrs) { 18211d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell return new LayoutParams(getContext(), attrs); 18221d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 18231d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 1824fedd8cbd0fd3f6a62dabffa3970db2d3373d8db8Jun Mukai @Override 1825fedd8cbd0fd3f6a62dabffa3970db2d3373d8db8Jun Mukai public void addFocusables(ArrayList<View> views, int direction, int focusableMode) { 1826fedd8cbd0fd3f6a62dabffa3970db2d3373d8db8Jun Mukai if (getDescendantFocusability() == FOCUS_BLOCK_DESCENDANTS) { 1827fedd8cbd0fd3f6a62dabffa3970db2d3373d8db8Jun Mukai return; 1828fedd8cbd0fd3f6a62dabffa3970db2d3373d8db8Jun Mukai } 1829fedd8cbd0fd3f6a62dabffa3970db2d3373d8db8Jun Mukai 1830fedd8cbd0fd3f6a62dabffa3970db2d3373d8db8Jun Mukai // Only the views in the open drawers are focusables. Add normal child views when 1831fedd8cbd0fd3f6a62dabffa3970db2d3373d8db8Jun Mukai // no drawers are opened. 1832fedd8cbd0fd3f6a62dabffa3970db2d3373d8db8Jun Mukai final int childCount = getChildCount(); 1833fedd8cbd0fd3f6a62dabffa3970db2d3373d8db8Jun Mukai boolean isDrawerOpen = false; 1834fedd8cbd0fd3f6a62dabffa3970db2d3373d8db8Jun Mukai for (int i = 0; i < childCount; i++) { 1835fedd8cbd0fd3f6a62dabffa3970db2d3373d8db8Jun Mukai final View child = getChildAt(i); 1836fedd8cbd0fd3f6a62dabffa3970db2d3373d8db8Jun Mukai if (isDrawerView(child)) { 1837fedd8cbd0fd3f6a62dabffa3970db2d3373d8db8Jun Mukai if (isDrawerOpen(child)) { 1838fedd8cbd0fd3f6a62dabffa3970db2d3373d8db8Jun Mukai isDrawerOpen = true; 1839fedd8cbd0fd3f6a62dabffa3970db2d3373d8db8Jun Mukai child.addFocusables(views, direction, focusableMode); 1840fedd8cbd0fd3f6a62dabffa3970db2d3373d8db8Jun Mukai } 1841fedd8cbd0fd3f6a62dabffa3970db2d3373d8db8Jun Mukai } else { 1842fedd8cbd0fd3f6a62dabffa3970db2d3373d8db8Jun Mukai mNonDrawerViews.add(child); 1843fedd8cbd0fd3f6a62dabffa3970db2d3373d8db8Jun Mukai } 1844fedd8cbd0fd3f6a62dabffa3970db2d3373d8db8Jun Mukai } 1845fedd8cbd0fd3f6a62dabffa3970db2d3373d8db8Jun Mukai 1846fedd8cbd0fd3f6a62dabffa3970db2d3373d8db8Jun Mukai if (!isDrawerOpen) { 1847fedd8cbd0fd3f6a62dabffa3970db2d3373d8db8Jun Mukai final int nonDrawerViewsCount = mNonDrawerViews.size(); 1848fedd8cbd0fd3f6a62dabffa3970db2d3373d8db8Jun Mukai for (int i = 0; i < nonDrawerViewsCount; ++i) { 1849fedd8cbd0fd3f6a62dabffa3970db2d3373d8db8Jun Mukai final View child = mNonDrawerViews.get(i); 1850fedd8cbd0fd3f6a62dabffa3970db2d3373d8db8Jun Mukai if (child.getVisibility() == View.VISIBLE) { 1851fedd8cbd0fd3f6a62dabffa3970db2d3373d8db8Jun Mukai child.addFocusables(views, direction, focusableMode); 1852fedd8cbd0fd3f6a62dabffa3970db2d3373d8db8Jun Mukai } 1853fedd8cbd0fd3f6a62dabffa3970db2d3373d8db8Jun Mukai } 1854fedd8cbd0fd3f6a62dabffa3970db2d3373d8db8Jun Mukai } 1855fedd8cbd0fd3f6a62dabffa3970db2d3373d8db8Jun Mukai 1856fedd8cbd0fd3f6a62dabffa3970db2d3373d8db8Jun Mukai mNonDrawerViews.clear(); 1857fedd8cbd0fd3f6a62dabffa3970db2d3373d8db8Jun Mukai } 1858fedd8cbd0fd3f6a62dabffa3970db2d3373d8db8Jun Mukai 1859791f31bbba40b8b51694a1b2cdc804f360786ed1Adam Powell private boolean hasVisibleDrawer() { 18600492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell return findVisibleDrawer() != null; 18610492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell } 18620492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell 1863540222c3675801eaa141ace1c164c4d3499b4721Aurimas Liutikas View findVisibleDrawer() { 1864791f31bbba40b8b51694a1b2cdc804f360786ed1Adam Powell final int childCount = getChildCount(); 1865791f31bbba40b8b51694a1b2cdc804f360786ed1Adam Powell for (int i = 0; i < childCount; i++) { 1866791f31bbba40b8b51694a1b2cdc804f360786ed1Adam Powell final View child = getChildAt(i); 1867791f31bbba40b8b51694a1b2cdc804f360786ed1Adam Powell if (isDrawerView(child) && isDrawerVisible(child)) { 18680492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell return child; 1869791f31bbba40b8b51694a1b2cdc804f360786ed1Adam Powell } 1870791f31bbba40b8b51694a1b2cdc804f360786ed1Adam Powell } 18710492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell return null; 1872791f31bbba40b8b51694a1b2cdc804f360786ed1Adam Powell } 1873791f31bbba40b8b51694a1b2cdc804f360786ed1Adam Powell 1874cde2707260e8241ffb816a03cbf5d52c28004b8aAdam Powell void cancelChildViewTouch() { 1875cde2707260e8241ffb816a03cbf5d52c28004b8aAdam Powell // Cancel child touches 1876cde2707260e8241ffb816a03cbf5d52c28004b8aAdam Powell if (!mChildrenCanceledTouch) { 1877cde2707260e8241ffb816a03cbf5d52c28004b8aAdam Powell final long now = SystemClock.uptimeMillis(); 1878cde2707260e8241ffb816a03cbf5d52c28004b8aAdam Powell final MotionEvent cancelEvent = MotionEvent.obtain(now, now, 1879cde2707260e8241ffb816a03cbf5d52c28004b8aAdam Powell MotionEvent.ACTION_CANCEL, 0.0f, 0.0f, 0); 1880cde2707260e8241ffb816a03cbf5d52c28004b8aAdam Powell final int childCount = getChildCount(); 1881cde2707260e8241ffb816a03cbf5d52c28004b8aAdam Powell for (int i = 0; i < childCount; i++) { 1882cde2707260e8241ffb816a03cbf5d52c28004b8aAdam Powell getChildAt(i).dispatchTouchEvent(cancelEvent); 1883cde2707260e8241ffb816a03cbf5d52c28004b8aAdam Powell } 1884cde2707260e8241ffb816a03cbf5d52c28004b8aAdam Powell cancelEvent.recycle(); 1885cde2707260e8241ffb816a03cbf5d52c28004b8aAdam Powell mChildrenCanceledTouch = true; 1886cde2707260e8241ffb816a03cbf5d52c28004b8aAdam Powell } 1887cde2707260e8241ffb816a03cbf5d52c28004b8aAdam Powell } 1888cde2707260e8241ffb816a03cbf5d52c28004b8aAdam Powell 1889791f31bbba40b8b51694a1b2cdc804f360786ed1Adam Powell @Override 1890791f31bbba40b8b51694a1b2cdc804f360786ed1Adam Powell public boolean onKeyDown(int keyCode, KeyEvent event) { 1891791f31bbba40b8b51694a1b2cdc804f360786ed1Adam Powell if (keyCode == KeyEvent.KEYCODE_BACK && hasVisibleDrawer()) { 18921b3e9466b4c4d72f28bb4448672ef8bab19b6f3eKirill Grouchnikov event.startTracking(); 1893791f31bbba40b8b51694a1b2cdc804f360786ed1Adam Powell return true; 1894791f31bbba40b8b51694a1b2cdc804f360786ed1Adam Powell } 1895791f31bbba40b8b51694a1b2cdc804f360786ed1Adam Powell return super.onKeyDown(keyCode, event); 1896791f31bbba40b8b51694a1b2cdc804f360786ed1Adam Powell } 1897791f31bbba40b8b51694a1b2cdc804f360786ed1Adam Powell 1898791f31bbba40b8b51694a1b2cdc804f360786ed1Adam Powell @Override 1899791f31bbba40b8b51694a1b2cdc804f360786ed1Adam Powell public boolean onKeyUp(int keyCode, KeyEvent event) { 19000492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell if (keyCode == KeyEvent.KEYCODE_BACK) { 19010492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell final View visibleDrawer = findVisibleDrawer(); 19020492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell if (visibleDrawer != null && getDrawerLockMode(visibleDrawer) == LOCK_MODE_UNLOCKED) { 19030492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell closeDrawers(); 19040492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell } 19050492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell return visibleDrawer != null; 1906791f31bbba40b8b51694a1b2cdc804f360786ed1Adam Powell } 1907791f31bbba40b8b51694a1b2cdc804f360786ed1Adam Powell return super.onKeyUp(keyCode, event); 1908791f31bbba40b8b51694a1b2cdc804f360786ed1Adam Powell } 1909791f31bbba40b8b51694a1b2cdc804f360786ed1Adam Powell 191057902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell @Override 191157902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell protected void onRestoreInstanceState(Parcelable state) { 1912bb58a82daf11bf3c056d1cd5887aa26435d37b69Aurimas Liutikas if (!(state instanceof SavedState)) { 1913bb58a82daf11bf3c056d1cd5887aa26435d37b69Aurimas Liutikas super.onRestoreInstanceState(state); 1914bb58a82daf11bf3c056d1cd5887aa26435d37b69Aurimas Liutikas return; 1915bb58a82daf11bf3c056d1cd5887aa26435d37b69Aurimas Liutikas } 1916bb58a82daf11bf3c056d1cd5887aa26435d37b69Aurimas Liutikas 191757902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell final SavedState ss = (SavedState) state; 191857902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell super.onRestoreInstanceState(ss.getSuperState()); 191957902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell 192057902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell if (ss.openDrawerGravity != Gravity.NO_GRAVITY) { 192157902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell final View toOpen = findDrawerWithGravity(ss.openDrawerGravity); 192257902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell if (toOpen != null) { 192357902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell openDrawer(toOpen); 192457902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell } 192557902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell } 19268e01d24e718d603974182cd48f648369c07edec1Adam Powell 1927b518b3afec21cb8e843f00971bf6c176fe34c371Kirill Grouchnikov if (ss.lockModeLeft != LOCK_MODE_UNDEFINED) { 1928b518b3afec21cb8e843f00971bf6c176fe34c371Kirill Grouchnikov setDrawerLockMode(ss.lockModeLeft, Gravity.LEFT); 1929b518b3afec21cb8e843f00971bf6c176fe34c371Kirill Grouchnikov } 1930b518b3afec21cb8e843f00971bf6c176fe34c371Kirill Grouchnikov if (ss.lockModeRight != LOCK_MODE_UNDEFINED) { 1931b518b3afec21cb8e843f00971bf6c176fe34c371Kirill Grouchnikov setDrawerLockMode(ss.lockModeRight, Gravity.RIGHT); 1932b518b3afec21cb8e843f00971bf6c176fe34c371Kirill Grouchnikov } 1933b518b3afec21cb8e843f00971bf6c176fe34c371Kirill Grouchnikov if (ss.lockModeStart != LOCK_MODE_UNDEFINED) { 1934b518b3afec21cb8e843f00971bf6c176fe34c371Kirill Grouchnikov setDrawerLockMode(ss.lockModeStart, GravityCompat.START); 1935b518b3afec21cb8e843f00971bf6c176fe34c371Kirill Grouchnikov } 1936b518b3afec21cb8e843f00971bf6c176fe34c371Kirill Grouchnikov if (ss.lockModeEnd != LOCK_MODE_UNDEFINED) { 1937b518b3afec21cb8e843f00971bf6c176fe34c371Kirill Grouchnikov setDrawerLockMode(ss.lockModeEnd, GravityCompat.END); 1938b518b3afec21cb8e843f00971bf6c176fe34c371Kirill Grouchnikov } 193957902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell } 194057902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell 194157902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell @Override 194257902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell protected Parcelable onSaveInstanceState() { 194357902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell final Parcelable superState = super.onSaveInstanceState(); 194457902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell final SavedState ss = new SavedState(superState); 194557902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell 194667cf3e301575e3d67e3b4c3d06f4624438590dd3Kirill Grouchnikov final int childCount = getChildCount(); 194767cf3e301575e3d67e3b4c3d06f4624438590dd3Kirill Grouchnikov for (int i = 0; i < childCount; i++) { 194867cf3e301575e3d67e3b4c3d06f4624438590dd3Kirill Grouchnikov final View child = getChildAt(i); 194967cf3e301575e3d67e3b4c3d06f4624438590dd3Kirill Grouchnikov LayoutParams lp = (LayoutParams) child.getLayoutParams(); 195067cf3e301575e3d67e3b4c3d06f4624438590dd3Kirill Grouchnikov // Is the current child fully opened (that is, not closing)? 195167cf3e301575e3d67e3b4c3d06f4624438590dd3Kirill Grouchnikov boolean isOpenedAndNotClosing = (lp.openState == LayoutParams.FLAG_IS_OPENED); 195267cf3e301575e3d67e3b4c3d06f4624438590dd3Kirill Grouchnikov // Is the current child opening? 195367cf3e301575e3d67e3b4c3d06f4624438590dd3Kirill Grouchnikov boolean isClosedAndOpening = (lp.openState == LayoutParams.FLAG_IS_OPENING); 195467cf3e301575e3d67e3b4c3d06f4624438590dd3Kirill Grouchnikov if (isOpenedAndNotClosing || isClosedAndOpening) { 195567cf3e301575e3d67e3b4c3d06f4624438590dd3Kirill Grouchnikov // If one of the conditions above holds, save the child's gravity 195667cf3e301575e3d67e3b4c3d06f4624438590dd3Kirill Grouchnikov // so that we open that child during state restore. 195767cf3e301575e3d67e3b4c3d06f4624438590dd3Kirill Grouchnikov ss.openDrawerGravity = lp.gravity; 195867cf3e301575e3d67e3b4c3d06f4624438590dd3Kirill Grouchnikov break; 195967cf3e301575e3d67e3b4c3d06f4624438590dd3Kirill Grouchnikov } 196057902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell } 196157902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell 19628e01d24e718d603974182cd48f648369c07edec1Adam Powell ss.lockModeLeft = mLockModeLeft; 19638e01d24e718d603974182cd48f648369c07edec1Adam Powell ss.lockModeRight = mLockModeRight; 1964b518b3afec21cb8e843f00971bf6c176fe34c371Kirill Grouchnikov ss.lockModeStart = mLockModeStart; 1965b518b3afec21cb8e843f00971bf6c176fe34c371Kirill Grouchnikov ss.lockModeEnd = mLockModeEnd; 19668e01d24e718d603974182cd48f648369c07edec1Adam Powell 196757902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell return ss; 196857902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell } 196957902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell 197012ba769d9e9b121829c69daf0f6350e808028a6aAlan Viverette @Override 197112ba769d9e9b121829c69daf0f6350e808028a6aAlan Viverette public void addView(View child, int index, ViewGroup.LayoutParams params) { 19722bb8d4e8831b2d0f1de7f15493bb79f48c91db2aAlan Viverette super.addView(child, index, params); 19732bb8d4e8831b2d0f1de7f15493bb79f48c91db2aAlan Viverette 19742bb8d4e8831b2d0f1de7f15493bb79f48c91db2aAlan Viverette final View openDrawer = findOpenDrawer(); 19752bb8d4e8831b2d0f1de7f15493bb79f48c91db2aAlan Viverette if (openDrawer != null || isDrawerView(child)) { 19762bb8d4e8831b2d0f1de7f15493bb79f48c91db2aAlan Viverette // A drawer is already open or the new view is a drawer, so the 19772bb8d4e8831b2d0f1de7f15493bb79f48c91db2aAlan Viverette // new view should start out hidden. 197812ba769d9e9b121829c69daf0f6350e808028a6aAlan Viverette ViewCompat.setImportantForAccessibility(child, 197912ba769d9e9b121829c69daf0f6350e808028a6aAlan Viverette ViewCompat.IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS); 19802bb8d4e8831b2d0f1de7f15493bb79f48c91db2aAlan Viverette } else { 19812bb8d4e8831b2d0f1de7f15493bb79f48c91db2aAlan Viverette // Otherwise this is a content view and no drawer is open, so the 19822bb8d4e8831b2d0f1de7f15493bb79f48c91db2aAlan Viverette // new view should start out visible. 198312ba769d9e9b121829c69daf0f6350e808028a6aAlan Viverette ViewCompat.setImportantForAccessibility(child, 198412ba769d9e9b121829c69daf0f6350e808028a6aAlan Viverette ViewCompat.IMPORTANT_FOR_ACCESSIBILITY_YES); 198512ba769d9e9b121829c69daf0f6350e808028a6aAlan Viverette } 19862bb8d4e8831b2d0f1de7f15493bb79f48c91db2aAlan Viverette 19872bb8d4e8831b2d0f1de7f15493bb79f48c91db2aAlan Viverette // We only need a delegate here if the framework doesn't understand 19882bb8d4e8831b2d0f1de7f15493bb79f48c91db2aAlan Viverette // NO_HIDE_DESCENDANTS importance. 19892bb8d4e8831b2d0f1de7f15493bb79f48c91db2aAlan Viverette if (!CAN_HIDE_DESCENDANTS) { 19902bb8d4e8831b2d0f1de7f15493bb79f48c91db2aAlan Viverette ViewCompat.setAccessibilityDelegate(child, mChildAccessibilityDelegate); 19912bb8d4e8831b2d0f1de7f15493bb79f48c91db2aAlan Viverette } 199212ba769d9e9b121829c69daf0f6350e808028a6aAlan Viverette } 199312ba769d9e9b121829c69daf0f6350e808028a6aAlan Viverette 1994540222c3675801eaa141ace1c164c4d3499b4721Aurimas Liutikas static boolean includeChildForAccessibility(View child) { 199512ba769d9e9b121829c69daf0f6350e808028a6aAlan Viverette // If the child is not important for accessibility we make 199612ba769d9e9b121829c69daf0f6350e808028a6aAlan Viverette // sure this hides the entire subtree rooted at it as the 199712ba769d9e9b121829c69daf0f6350e808028a6aAlan Viverette // IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDATS is not 199812ba769d9e9b121829c69daf0f6350e808028a6aAlan Viverette // supported on older platforms but we want to hide the entire 199912ba769d9e9b121829c69daf0f6350e808028a6aAlan Viverette // content and not opened drawers if a drawer is opened. 200012ba769d9e9b121829c69daf0f6350e808028a6aAlan Viverette return ViewCompat.getImportantForAccessibility(child) 200112ba769d9e9b121829c69daf0f6350e808028a6aAlan Viverette != ViewCompat.IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS 200212ba769d9e9b121829c69daf0f6350e808028a6aAlan Viverette && ViewCompat.getImportantForAccessibility(child) 200312ba769d9e9b121829c69daf0f6350e808028a6aAlan Viverette != ViewCompat.IMPORTANT_FOR_ACCESSIBILITY_NO; 200412ba769d9e9b121829c69daf0f6350e808028a6aAlan Viverette } 200512ba769d9e9b121829c69daf0f6350e808028a6aAlan Viverette 200657902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell /** 200757902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell * State persisted across instances 200857902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell */ 200905f5ba020fa6caa658c75b6d77436aa980ca0fccChris Banes protected static class SavedState extends AbsSavedState { 201057902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell int openDrawerGravity = Gravity.NO_GRAVITY; 2011b518b3afec21cb8e843f00971bf6c176fe34c371Kirill Grouchnikov @LockMode int lockModeLeft; 2012b518b3afec21cb8e843f00971bf6c176fe34c371Kirill Grouchnikov @LockMode int lockModeRight; 2013b518b3afec21cb8e843f00971bf6c176fe34c371Kirill Grouchnikov @LockMode int lockModeStart; 2014b518b3afec21cb8e843f00971bf6c176fe34c371Kirill Grouchnikov @LockMode int lockModeEnd; 201557902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell 201605f5ba020fa6caa658c75b6d77436aa980ca0fccChris Banes public SavedState(Parcel in, ClassLoader loader) { 201705f5ba020fa6caa658c75b6d77436aa980ca0fccChris Banes super(in, loader); 201857902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell openDrawerGravity = in.readInt(); 2019b518b3afec21cb8e843f00971bf6c176fe34c371Kirill Grouchnikov lockModeLeft = in.readInt(); 2020b518b3afec21cb8e843f00971bf6c176fe34c371Kirill Grouchnikov lockModeRight = in.readInt(); 2021b518b3afec21cb8e843f00971bf6c176fe34c371Kirill Grouchnikov lockModeStart = in.readInt(); 2022b518b3afec21cb8e843f00971bf6c176fe34c371Kirill Grouchnikov lockModeEnd = in.readInt(); 202357902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell } 202457902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell 202557902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell public SavedState(Parcelable superState) { 202657902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell super(superState); 202757902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell } 202857902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell 202957902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell @Override 203057902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell public void writeToParcel(Parcel dest, int flags) { 203157902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell super.writeToParcel(dest, flags); 203257902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell dest.writeInt(openDrawerGravity); 2033b518b3afec21cb8e843f00971bf6c176fe34c371Kirill Grouchnikov dest.writeInt(lockModeLeft); 2034b518b3afec21cb8e843f00971bf6c176fe34c371Kirill Grouchnikov dest.writeInt(lockModeRight); 2035b518b3afec21cb8e843f00971bf6c176fe34c371Kirill Grouchnikov dest.writeInt(lockModeStart); 2036b518b3afec21cb8e843f00971bf6c176fe34c371Kirill Grouchnikov dest.writeInt(lockModeEnd); 203757902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell } 203857902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell 203905f5ba020fa6caa658c75b6d77436aa980ca0fccChris Banes public static final Creator<SavedState> CREATOR = ParcelableCompat.newCreator( 204005f5ba020fa6caa658c75b6d77436aa980ca0fccChris Banes new ParcelableCompatCreatorCallbacks<SavedState>() { 204105f5ba020fa6caa658c75b6d77436aa980ca0fccChris Banes @Override 204205f5ba020fa6caa658c75b6d77436aa980ca0fccChris Banes public SavedState createFromParcel(Parcel in, ClassLoader loader) { 204305f5ba020fa6caa658c75b6d77436aa980ca0fccChris Banes return new SavedState(in, loader); 204405f5ba020fa6caa658c75b6d77436aa980ca0fccChris Banes } 204557902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell 204605f5ba020fa6caa658c75b6d77436aa980ca0fccChris Banes @Override 204705f5ba020fa6caa658c75b6d77436aa980ca0fccChris Banes public SavedState[] newArray(int size) { 204805f5ba020fa6caa658c75b6d77436aa980ca0fccChris Banes return new SavedState[size]; 204905f5ba020fa6caa658c75b6d77436aa980ca0fccChris Banes } 205005f5ba020fa6caa658c75b6d77436aa980ca0fccChris Banes }); 205157902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell } 205257902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell 20531d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell private class ViewDragCallback extends ViewDragHelper.Callback { 2054f55dfacb0db5da12ad3b9e5615c3feaea372f37dAlan Viverette private final int mAbsGravity; 20551d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell private ViewDragHelper mDragger; 20561d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 20571732720ad57fe6d01392cd06551f1a25cff0333cAdam Powell private final Runnable mPeekRunnable = new Runnable() { 20581732720ad57fe6d01392cd06551f1a25cff0333cAdam Powell @Override public void run() { 20591732720ad57fe6d01392cd06551f1a25cff0333cAdam Powell peekDrawer(); 20601732720ad57fe6d01392cd06551f1a25cff0333cAdam Powell } 20611732720ad57fe6d01392cd06551f1a25cff0333cAdam Powell }; 20621732720ad57fe6d01392cd06551f1a25cff0333cAdam Powell 20634d2c7b7c4f194034c5f17c4bee7320d808aabe4cAurimas Liutikas ViewDragCallback(int gravity) { 2064f55dfacb0db5da12ad3b9e5615c3feaea372f37dAlan Viverette mAbsGravity = gravity; 20651d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 20661d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 20671d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell public void setDragger(ViewDragHelper dragger) { 20681d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell mDragger = dragger; 20691d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 20701d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 20711732720ad57fe6d01392cd06551f1a25cff0333cAdam Powell public void removeCallbacks() { 20721732720ad57fe6d01392cd06551f1a25cff0333cAdam Powell DrawerLayout.this.removeCallbacks(mPeekRunnable); 20731732720ad57fe6d01392cd06551f1a25cff0333cAdam Powell } 20741732720ad57fe6d01392cd06551f1a25cff0333cAdam Powell 20751d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell @Override 20761d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell public boolean tryCaptureView(View child, int pointerId) { 20771d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell // Only capture views where the gravity matches what we're looking for. 20781d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell // This lets us use two ViewDragHelpers, one for each side drawer. 2079f55dfacb0db5da12ad3b9e5615c3feaea372f37dAlan Viverette return isDrawerView(child) && checkDrawerViewAbsoluteGravity(child, mAbsGravity) 2080f55dfacb0db5da12ad3b9e5615c3feaea372f37dAlan Viverette && getDrawerLockMode(child) == LOCK_MODE_UNLOCKED; 20811d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 20821d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 20831d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell @Override 20841d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell public void onViewDragStateChanged(int state) { 2085f55dfacb0db5da12ad3b9e5615c3feaea372f37dAlan Viverette updateDrawerState(mAbsGravity, state, mDragger.getCapturedView()); 20861d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 20871d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 20881d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell @Override 20891d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell public void onViewPositionChanged(View changedView, int left, int top, int dx, int dy) { 20901d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell float offset; 20911d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final int childWidth = changedView.getWidth(); 20921d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 20931d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell // This reverses the positioning shown in onLayout. 2094f55dfacb0db5da12ad3b9e5615c3feaea372f37dAlan Viverette if (checkDrawerViewAbsoluteGravity(changedView, Gravity.LEFT)) { 20951d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell offset = (float) (childWidth + left) / childWidth; 20961d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } else { 20971d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final int width = getWidth(); 20981d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell offset = (float) (width - left) / childWidth; 20991d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 21001d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell setDrawerViewOffset(changedView, offset); 2101b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell changedView.setVisibility(offset == 0 ? INVISIBLE : VISIBLE); 21021d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell invalidate(); 21031d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 21041d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 21051d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell @Override 21061d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell public void onViewCaptured(View capturedChild, int activePointerId) { 21071d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final LayoutParams lp = (LayoutParams) capturedChild.getLayoutParams(); 21081d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell lp.isPeeking = false; 21091d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 21101d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell closeOtherDrawer(); 21111d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 21121d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 21131d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell private void closeOtherDrawer() { 2114f55dfacb0db5da12ad3b9e5615c3feaea372f37dAlan Viverette final int otherGrav = mAbsGravity == Gravity.LEFT ? Gravity.RIGHT : Gravity.LEFT; 21151d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final View toClose = findDrawerWithGravity(otherGrav); 21161d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell if (toClose != null) { 21171d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell closeDrawer(toClose); 21181d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 21191d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 21201d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 21211d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell @Override 21221d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell public void onViewReleased(View releasedChild, float xvel, float yvel) { 21231d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell // Offset is how open the drawer is, therefore left/right values 21241d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell // are reversed from one another. 21251d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final float offset = getDrawerViewOffset(releasedChild); 21261d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final int childWidth = releasedChild.getWidth(); 21271d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 21281d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell int left; 2129f55dfacb0db5da12ad3b9e5615c3feaea372f37dAlan Viverette if (checkDrawerViewAbsoluteGravity(releasedChild, Gravity.LEFT)) { 21301d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell left = xvel > 0 || xvel == 0 && offset > 0.5f ? 0 : -childWidth; 21311d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } else { 21321d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final int width = getWidth(); 21337d690eb050d901c7a7b4ebc3896471124ef98f7cAdam Powell left = xvel < 0 || xvel == 0 && offset > 0.5f ? width - childWidth : width; 21341d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 21351d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 21361d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell mDragger.settleCapturedViewAt(left, releasedChild.getTop()); 21371d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell invalidate(); 21381d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 21391d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 21401d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell @Override 21411d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell public void onEdgeTouched(int edgeFlags, int pointerId) { 21421732720ad57fe6d01392cd06551f1a25cff0333cAdam Powell postDelayed(mPeekRunnable, PEEK_DELAY); 21431732720ad57fe6d01392cd06551f1a25cff0333cAdam Powell } 21441732720ad57fe6d01392cd06551f1a25cff0333cAdam Powell 2145540222c3675801eaa141ace1c164c4d3499b4721Aurimas Liutikas void peekDrawer() { 21461d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final View toCapture; 21471d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final int childLeft; 2148ea7b10f4d5531713506e98c8093e7aab811f21f3Adam Powell final int peekDistance = mDragger.getEdgeSize(); 2149f55dfacb0db5da12ad3b9e5615c3feaea372f37dAlan Viverette final boolean leftEdge = mAbsGravity == Gravity.LEFT; 2150b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell if (leftEdge) { 21511d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell toCapture = findDrawerWithGravity(Gravity.LEFT); 2152ea7b10f4d5531713506e98c8093e7aab811f21f3Adam Powell childLeft = (toCapture != null ? -toCapture.getWidth() : 0) + peekDistance; 21531d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } else { 21541d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell toCapture = findDrawerWithGravity(Gravity.RIGHT); 2155ea7b10f4d5531713506e98c8093e7aab811f21f3Adam Powell childLeft = getWidth() - peekDistance; 21561d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 21570492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell // Only peek if it would mean making the drawer more visible and the drawer isn't locked 21584d2c7b7c4f194034c5f17c4bee7320d808aabe4cAurimas Liutikas if (toCapture != null && ((leftEdge && toCapture.getLeft() < childLeft) 21594d2c7b7c4f194034c5f17c4bee7320d808aabe4cAurimas Liutikas || (!leftEdge && toCapture.getLeft() > childLeft)) 21604d2c7b7c4f194034c5f17c4bee7320d808aabe4cAurimas Liutikas && getDrawerLockMode(toCapture) == LOCK_MODE_UNLOCKED) { 2161b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell final LayoutParams lp = (LayoutParams) toCapture.getLayoutParams(); 21621d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell mDragger.smoothSlideViewTo(toCapture, childLeft, toCapture.getTop()); 2163b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell lp.isPeeking = true; 21641d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell invalidate(); 21651d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 21661d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell closeOtherDrawer(); 2167cde2707260e8241ffb816a03cbf5d52c28004b8aAdam Powell 2168cde2707260e8241ffb816a03cbf5d52c28004b8aAdam Powell cancelChildViewTouch(); 21691d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 21701d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 21711d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 21721d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell @Override 2173ea7b10f4d5531713506e98c8093e7aab811f21f3Adam Powell public boolean onEdgeLock(int edgeFlags) { 2174ea7b10f4d5531713506e98c8093e7aab811f21f3Adam Powell if (ALLOW_EDGE_LOCK) { 2175f55dfacb0db5da12ad3b9e5615c3feaea372f37dAlan Viverette final View drawer = findDrawerWithGravity(mAbsGravity); 2176ea7b10f4d5531713506e98c8093e7aab811f21f3Adam Powell if (drawer != null && !isDrawerOpen(drawer)) { 2177ea7b10f4d5531713506e98c8093e7aab811f21f3Adam Powell closeDrawer(drawer); 2178ea7b10f4d5531713506e98c8093e7aab811f21f3Adam Powell } 2179ea7b10f4d5531713506e98c8093e7aab811f21f3Adam Powell return true; 2180acc82321ad119706485db342eaa12b225fa9b667Adam Powell } 2181ea7b10f4d5531713506e98c8093e7aab811f21f3Adam Powell return false; 2182acc82321ad119706485db342eaa12b225fa9b667Adam Powell } 2183acc82321ad119706485db342eaa12b225fa9b667Adam Powell 2184acc82321ad119706485db342eaa12b225fa9b667Adam Powell @Override 21851d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell public void onEdgeDragStarted(int edgeFlags, int pointerId) { 21861d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final View toCapture; 21871d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell if ((edgeFlags & ViewDragHelper.EDGE_LEFT) == ViewDragHelper.EDGE_LEFT) { 21881d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell toCapture = findDrawerWithGravity(Gravity.LEFT); 21891d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } else { 21901d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell toCapture = findDrawerWithGravity(Gravity.RIGHT); 21911d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 21921d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 21930492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell if (toCapture != null && getDrawerLockMode(toCapture) == LOCK_MODE_UNLOCKED) { 21941d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell mDragger.captureChildView(toCapture, pointerId); 21951d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 21961d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 21971d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 21981d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell @Override 21991d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell public int getViewHorizontalDragRange(View child) { 22008a28dd16be442db2ee6275baf72079777627f37eChet Haase return isDrawerView(child) ? child.getWidth() : 0; 22011d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 22021d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 22031d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell @Override 22041d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell public int clampViewPositionHorizontal(View child, int left, int dx) { 2205f55dfacb0db5da12ad3b9e5615c3feaea372f37dAlan Viverette if (checkDrawerViewAbsoluteGravity(child, Gravity.LEFT)) { 22061d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell return Math.max(-child.getWidth(), Math.min(left, 0)); 22071d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } else { 22081d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final int width = getWidth(); 22091d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell return Math.max(width - child.getWidth(), Math.min(left, width)); 22101d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 22111d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 221200ca2532981fbd705f947a637ffd967a8d6f733bAdam Powell 221300ca2532981fbd705f947a637ffd967a8d6f733bAdam Powell @Override 221400ca2532981fbd705f947a637ffd967a8d6f733bAdam Powell public int clampViewPositionVertical(View child, int top, int dy) { 221500ca2532981fbd705f947a637ffd967a8d6f733bAdam Powell return child.getTop(); 221600ca2532981fbd705f947a637ffd967a8d6f733bAdam Powell } 22171d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 22181d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 221900ca2532981fbd705f947a637ffd967a8d6f733bAdam Powell public static class LayoutParams extends ViewGroup.MarginLayoutParams { 222067cf3e301575e3d67e3b4c3d06f4624438590dd3Kirill Grouchnikov private static final int FLAG_IS_OPENED = 0x1; 222167cf3e301575e3d67e3b4c3d06f4624438590dd3Kirill Grouchnikov private static final int FLAG_IS_OPENING = 0x2; 222267cf3e301575e3d67e3b4c3d06f4624438590dd3Kirill Grouchnikov private static final int FLAG_IS_CLOSING = 0x4; 22231d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 22241d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell public int gravity = Gravity.NO_GRAVITY; 2225540222c3675801eaa141ace1c164c4d3499b4721Aurimas Liutikas float onScreen; 2226540222c3675801eaa141ace1c164c4d3499b4721Aurimas Liutikas boolean isPeeking; 2227540222c3675801eaa141ace1c164c4d3499b4721Aurimas Liutikas int openState; 22281d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 22291d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell public LayoutParams(Context c, AttributeSet attrs) { 22301d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell super(c, attrs); 22311d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 22321d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final TypedArray a = c.obtainStyledAttributes(attrs, LAYOUT_ATTRS); 22331d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell this.gravity = a.getInt(0, Gravity.NO_GRAVITY); 22341d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell a.recycle(); 22351d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 22361d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 22371d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell public LayoutParams(int width, int height) { 22381d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell super(width, height); 22391d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 22401d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 22411d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell public LayoutParams(int width, int height, int gravity) { 22421d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell this(width, height); 22431d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell this.gravity = gravity; 22441d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 22451d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 22461d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell public LayoutParams(LayoutParams source) { 22471d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell super(source); 22481d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell this.gravity = source.gravity; 22491d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 22501d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 22511d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell public LayoutParams(ViewGroup.LayoutParams source) { 22521d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell super(source); 22531d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 225400ca2532981fbd705f947a637ffd967a8d6f733bAdam Powell 225500ca2532981fbd705f947a637ffd967a8d6f733bAdam Powell public LayoutParams(ViewGroup.MarginLayoutParams source) { 225600ca2532981fbd705f947a637ffd967a8d6f733bAdam Powell super(source); 225700ca2532981fbd705f947a637ffd967a8d6f733bAdam Powell } 22581d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 22597d0061d5605a1ac298837bee21c0d4eb4a34bd4eAdam Powell 22607d0061d5605a1ac298837bee21c0d4eb4a34bd4eAdam Powell class AccessibilityDelegate extends AccessibilityDelegateCompat { 22613cf6141d516a0a6170823b1bda5c0b6d7500e76cAdam Powell private final Rect mTmpRect = new Rect(); 22623cf6141d516a0a6170823b1bda5c0b6d7500e76cAdam Powell 22637d0061d5605a1ac298837bee21c0d4eb4a34bd4eAdam Powell @Override 22647d0061d5605a1ac298837bee21c0d4eb4a34bd4eAdam Powell public void onInitializeAccessibilityNodeInfo(View host, AccessibilityNodeInfoCompat info) { 22652bb8d4e8831b2d0f1de7f15493bb79f48c91db2aAlan Viverette if (CAN_HIDE_DESCENDANTS) { 22662bb8d4e8831b2d0f1de7f15493bb79f48c91db2aAlan Viverette super.onInitializeAccessibilityNodeInfo(host, info); 22672bb8d4e8831b2d0f1de7f15493bb79f48c91db2aAlan Viverette } else { 22682bb8d4e8831b2d0f1de7f15493bb79f48c91db2aAlan Viverette // Obtain a node for the host, then manually generate the list 22692bb8d4e8831b2d0f1de7f15493bb79f48c91db2aAlan Viverette // of children to only include non-obscured views. 22702bb8d4e8831b2d0f1de7f15493bb79f48c91db2aAlan Viverette final AccessibilityNodeInfoCompat superNode = 22712bb8d4e8831b2d0f1de7f15493bb79f48c91db2aAlan Viverette AccessibilityNodeInfoCompat.obtain(info); 22722bb8d4e8831b2d0f1de7f15493bb79f48c91db2aAlan Viverette super.onInitializeAccessibilityNodeInfo(host, superNode); 22732bb8d4e8831b2d0f1de7f15493bb79f48c91db2aAlan Viverette 22742bb8d4e8831b2d0f1de7f15493bb79f48c91db2aAlan Viverette info.setSource(host); 22752bb8d4e8831b2d0f1de7f15493bb79f48c91db2aAlan Viverette final ViewParent parent = ViewCompat.getParentForAccessibility(host); 22762bb8d4e8831b2d0f1de7f15493bb79f48c91db2aAlan Viverette if (parent instanceof View) { 22772bb8d4e8831b2d0f1de7f15493bb79f48c91db2aAlan Viverette info.setParent((View) parent); 22782bb8d4e8831b2d0f1de7f15493bb79f48c91db2aAlan Viverette } 22792bb8d4e8831b2d0f1de7f15493bb79f48c91db2aAlan Viverette copyNodeInfoNoChildren(info, superNode); 22802bb8d4e8831b2d0f1de7f15493bb79f48c91db2aAlan Viverette superNode.recycle(); 22813cf6141d516a0a6170823b1bda5c0b6d7500e76cAdam Powell 22822bb8d4e8831b2d0f1de7f15493bb79f48c91db2aAlan Viverette addChildrenForAccessibility(info, (ViewGroup) host); 22833cf6141d516a0a6170823b1bda5c0b6d7500e76cAdam Powell } 22843cf6141d516a0a6170823b1bda5c0b6d7500e76cAdam Powell 22852bb8d4e8831b2d0f1de7f15493bb79f48c91db2aAlan Viverette info.setClassName(DrawerLayout.class.getName()); 22864b1190de13d6408e24cbda5f77e6148f54206fd0Alan Viverette 22874b1190de13d6408e24cbda5f77e6148f54206fd0Alan Viverette // This view reports itself as focusable so that it can intercept 22884b1190de13d6408e24cbda5f77e6148f54206fd0Alan Viverette // the back button, but we should prevent this view from reporting 22894b1190de13d6408e24cbda5f77e6148f54206fd0Alan Viverette // itself as focusable to accessibility services. 22904b1190de13d6408e24cbda5f77e6148f54206fd0Alan Viverette info.setFocusable(false); 22914b1190de13d6408e24cbda5f77e6148f54206fd0Alan Viverette info.setFocused(false); 22920a13063f56de4a369ee20e62494dcdda9e37f966Alan Viverette info.removeAction(AccessibilityActionCompat.ACTION_FOCUS); 22930a13063f56de4a369ee20e62494dcdda9e37f966Alan Viverette info.removeAction(AccessibilityActionCompat.ACTION_CLEAR_FOCUS); 2294d6edbe712f21ea4924ab9fb49ebd8c94d1e03884Alan Viverette } 2295d6edbe712f21ea4924ab9fb49ebd8c94d1e03884Alan Viverette 2296526ba1382e61845ef23bf27d300883dea0966af5Alan Viverette @Override 2297526ba1382e61845ef23bf27d300883dea0966af5Alan Viverette public void onInitializeAccessibilityEvent(View host, AccessibilityEvent event) { 2298526ba1382e61845ef23bf27d300883dea0966af5Alan Viverette super.onInitializeAccessibilityEvent(host, event); 2299526ba1382e61845ef23bf27d300883dea0966af5Alan Viverette 2300526ba1382e61845ef23bf27d300883dea0966af5Alan Viverette event.setClassName(DrawerLayout.class.getName()); 2301aeaa8ef97eb729fbee17e984d60e9ab27795f5d0Alan Viverette } 2302526ba1382e61845ef23bf27d300883dea0966af5Alan Viverette 2303aeaa8ef97eb729fbee17e984d60e9ab27795f5d0Alan Viverette @Override 2304aeaa8ef97eb729fbee17e984d60e9ab27795f5d0Alan Viverette public boolean dispatchPopulateAccessibilityEvent(View host, AccessibilityEvent event) { 2305526ba1382e61845ef23bf27d300883dea0966af5Alan Viverette // Special case to handle window state change events. As far as 2306aeaa8ef97eb729fbee17e984d60e9ab27795f5d0Alan Viverette // accessibility services are concerned, state changes from 2307aeaa8ef97eb729fbee17e984d60e9ab27795f5d0Alan Viverette // DrawerLayout invalidate the entire contents of the screen (like 2308aeaa8ef97eb729fbee17e984d60e9ab27795f5d0Alan Viverette // an Activity or Dialog) and they should announce the title of the 2309aeaa8ef97eb729fbee17e984d60e9ab27795f5d0Alan Viverette // new content. 2310526ba1382e61845ef23bf27d300883dea0966af5Alan Viverette if (event.getEventType() == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED) { 2311526ba1382e61845ef23bf27d300883dea0966af5Alan Viverette final List<CharSequence> eventText = event.getText(); 2312526ba1382e61845ef23bf27d300883dea0966af5Alan Viverette final View visibleDrawer = findVisibleDrawer(); 2313526ba1382e61845ef23bf27d300883dea0966af5Alan Viverette if (visibleDrawer != null) { 2314526ba1382e61845ef23bf27d300883dea0966af5Alan Viverette final int edgeGravity = getDrawerViewAbsoluteGravity(visibleDrawer); 2315526ba1382e61845ef23bf27d300883dea0966af5Alan Viverette final CharSequence title = getDrawerTitle(edgeGravity); 2316526ba1382e61845ef23bf27d300883dea0966af5Alan Viverette if (title != null) { 2317526ba1382e61845ef23bf27d300883dea0966af5Alan Viverette eventText.add(title); 2318526ba1382e61845ef23bf27d300883dea0966af5Alan Viverette } 2319526ba1382e61845ef23bf27d300883dea0966af5Alan Viverette } 2320aeaa8ef97eb729fbee17e984d60e9ab27795f5d0Alan Viverette 2321aeaa8ef97eb729fbee17e984d60e9ab27795f5d0Alan Viverette return true; 2322526ba1382e61845ef23bf27d300883dea0966af5Alan Viverette } 2323aeaa8ef97eb729fbee17e984d60e9ab27795f5d0Alan Viverette 2324aeaa8ef97eb729fbee17e984d60e9ab27795f5d0Alan Viverette return super.dispatchPopulateAccessibilityEvent(host, event); 2325526ba1382e61845ef23bf27d300883dea0966af5Alan Viverette } 2326526ba1382e61845ef23bf27d300883dea0966af5Alan Viverette 23272bb8d4e8831b2d0f1de7f15493bb79f48c91db2aAlan Viverette @Override 23282bb8d4e8831b2d0f1de7f15493bb79f48c91db2aAlan Viverette public boolean onRequestSendAccessibilityEvent(ViewGroup host, View child, 23292bb8d4e8831b2d0f1de7f15493bb79f48c91db2aAlan Viverette AccessibilityEvent event) { 23302bb8d4e8831b2d0f1de7f15493bb79f48c91db2aAlan Viverette if (CAN_HIDE_DESCENDANTS || includeChildForAccessibility(child)) { 23312bb8d4e8831b2d0f1de7f15493bb79f48c91db2aAlan Viverette return super.onRequestSendAccessibilityEvent(host, child, event); 23322bb8d4e8831b2d0f1de7f15493bb79f48c91db2aAlan Viverette } 23332bb8d4e8831b2d0f1de7f15493bb79f48c91db2aAlan Viverette return false; 23342bb8d4e8831b2d0f1de7f15493bb79f48c91db2aAlan Viverette } 23352bb8d4e8831b2d0f1de7f15493bb79f48c91db2aAlan Viverette 2336d6edbe712f21ea4924ab9fb49ebd8c94d1e03884Alan Viverette private void addChildrenForAccessibility(AccessibilityNodeInfoCompat info, ViewGroup v) { 2337d6edbe712f21ea4924ab9fb49ebd8c94d1e03884Alan Viverette final int childCount = v.getChildCount(); 23387d0061d5605a1ac298837bee21c0d4eb4a34bd4eAdam Powell for (int i = 0; i < childCount; i++) { 2339d6edbe712f21ea4924ab9fb49ebd8c94d1e03884Alan Viverette final View child = v.getChildAt(i); 234049733ad715bcf68cc178f53e17a79380d332e5ccAlan Viverette if (includeChildForAccessibility(child)) { 234112ba769d9e9b121829c69daf0f6350e808028a6aAlan Viverette info.addChild(child); 23427d0061d5605a1ac298837bee21c0d4eb4a34bd4eAdam Powell } 23437d0061d5605a1ac298837bee21c0d4eb4a34bd4eAdam Powell } 23447d0061d5605a1ac298837bee21c0d4eb4a34bd4eAdam Powell } 23457d0061d5605a1ac298837bee21c0d4eb4a34bd4eAdam Powell 23463cf6141d516a0a6170823b1bda5c0b6d7500e76cAdam Powell /** 23473cf6141d516a0a6170823b1bda5c0b6d7500e76cAdam Powell * This should really be in AccessibilityNodeInfoCompat, but there unfortunately 23483cf6141d516a0a6170823b1bda5c0b6d7500e76cAdam Powell * seem to be a few elements that are not easily cloneable using the underlying API. 23493cf6141d516a0a6170823b1bda5c0b6d7500e76cAdam Powell * Leave it private here as it's not general-purpose useful. 23503cf6141d516a0a6170823b1bda5c0b6d7500e76cAdam Powell */ 23513cf6141d516a0a6170823b1bda5c0b6d7500e76cAdam Powell private void copyNodeInfoNoChildren(AccessibilityNodeInfoCompat dest, 23523cf6141d516a0a6170823b1bda5c0b6d7500e76cAdam Powell AccessibilityNodeInfoCompat src) { 23533cf6141d516a0a6170823b1bda5c0b6d7500e76cAdam Powell final Rect rect = mTmpRect; 23543cf6141d516a0a6170823b1bda5c0b6d7500e76cAdam Powell 23553cf6141d516a0a6170823b1bda5c0b6d7500e76cAdam Powell src.getBoundsInParent(rect); 23563cf6141d516a0a6170823b1bda5c0b6d7500e76cAdam Powell dest.setBoundsInParent(rect); 23573cf6141d516a0a6170823b1bda5c0b6d7500e76cAdam Powell 23583cf6141d516a0a6170823b1bda5c0b6d7500e76cAdam Powell src.getBoundsInScreen(rect); 23593cf6141d516a0a6170823b1bda5c0b6d7500e76cAdam Powell dest.setBoundsInScreen(rect); 23603cf6141d516a0a6170823b1bda5c0b6d7500e76cAdam Powell 23613cf6141d516a0a6170823b1bda5c0b6d7500e76cAdam Powell dest.setVisibleToUser(src.isVisibleToUser()); 23623cf6141d516a0a6170823b1bda5c0b6d7500e76cAdam Powell dest.setPackageName(src.getPackageName()); 23633cf6141d516a0a6170823b1bda5c0b6d7500e76cAdam Powell dest.setClassName(src.getClassName()); 23643cf6141d516a0a6170823b1bda5c0b6d7500e76cAdam Powell dest.setContentDescription(src.getContentDescription()); 23653cf6141d516a0a6170823b1bda5c0b6d7500e76cAdam Powell 23663cf6141d516a0a6170823b1bda5c0b6d7500e76cAdam Powell dest.setEnabled(src.isEnabled()); 23673cf6141d516a0a6170823b1bda5c0b6d7500e76cAdam Powell dest.setClickable(src.isClickable()); 23683cf6141d516a0a6170823b1bda5c0b6d7500e76cAdam Powell dest.setFocusable(src.isFocusable()); 23693cf6141d516a0a6170823b1bda5c0b6d7500e76cAdam Powell dest.setFocused(src.isFocused()); 23703cf6141d516a0a6170823b1bda5c0b6d7500e76cAdam Powell dest.setAccessibilityFocused(src.isAccessibilityFocused()); 23713cf6141d516a0a6170823b1bda5c0b6d7500e76cAdam Powell dest.setSelected(src.isSelected()); 23723cf6141d516a0a6170823b1bda5c0b6d7500e76cAdam Powell dest.setLongClickable(src.isLongClickable()); 23733cf6141d516a0a6170823b1bda5c0b6d7500e76cAdam Powell 23743cf6141d516a0a6170823b1bda5c0b6d7500e76cAdam Powell dest.addAction(src.getActions()); 23753cf6141d516a0a6170823b1bda5c0b6d7500e76cAdam Powell } 23767d0061d5605a1ac298837bee21c0d4eb4a34bd4eAdam Powell } 237712ba769d9e9b121829c69daf0f6350e808028a6aAlan Viverette 237812ba769d9e9b121829c69daf0f6350e808028a6aAlan Viverette final class ChildAccessibilityDelegate extends AccessibilityDelegateCompat { 237912ba769d9e9b121829c69daf0f6350e808028a6aAlan Viverette @Override 238012ba769d9e9b121829c69daf0f6350e808028a6aAlan Viverette public void onInitializeAccessibilityNodeInfo(View child, 238112ba769d9e9b121829c69daf0f6350e808028a6aAlan Viverette AccessibilityNodeInfoCompat info) { 238212ba769d9e9b121829c69daf0f6350e808028a6aAlan Viverette super.onInitializeAccessibilityNodeInfo(child, info); 23832bb8d4e8831b2d0f1de7f15493bb79f48c91db2aAlan Viverette 238449733ad715bcf68cc178f53e17a79380d332e5ccAlan Viverette if (!includeChildForAccessibility(child)) { 238512ba769d9e9b121829c69daf0f6350e808028a6aAlan Viverette // If we are ignoring the sub-tree rooted at the child, 238612ba769d9e9b121829c69daf0f6350e808028a6aAlan Viverette // break the connection to the rest of the node tree. 238749733ad715bcf68cc178f53e17a79380d332e5ccAlan Viverette // For details refer to includeChildForAccessibility. 238812ba769d9e9b121829c69daf0f6350e808028a6aAlan Viverette info.setParent(null); 238912ba769d9e9b121829c69daf0f6350e808028a6aAlan Viverette } 239012ba769d9e9b121829c69daf0f6350e808028a6aAlan Viverette } 239112ba769d9e9b121829c69daf0f6350e808028a6aAlan Viverette } 23921d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell} 2393