DrawerLayout.java revision cde2707260e8241ffb816a03cbf5d52c28004b8a
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; 25b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powellimport android.graphics.drawable.Drawable; 2657902cff6c54c245feea589b06d12dba8f1a2a24Adam Powellimport android.os.Parcel; 2757902cff6c54c245feea589b06d12dba8f1a2a24Adam Powellimport android.os.Parcelable; 28cde2707260e8241ffb816a03cbf5d52c28004b8aAdam Powellimport android.os.SystemClock; 291d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powellimport android.support.v4.view.GravityCompat; 30791f31bbba40b8b51694a1b2cdc804f360786ed1Adam Powellimport android.support.v4.view.KeyEventCompat; 311d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powellimport android.support.v4.view.MotionEventCompat; 321d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powellimport android.support.v4.view.ViewCompat; 331d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powellimport android.util.AttributeSet; 341d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powellimport android.view.Gravity; 35791f31bbba40b8b51694a1b2cdc804f360786ed1Adam Powellimport android.view.KeyEvent; 361d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powellimport android.view.MotionEvent; 371d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powellimport android.view.View; 381d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powellimport android.view.ViewGroup; 391d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 401d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell/** 411d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * DrawerLayout acts as a top-level container for window content that allows for 421d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * interactive "drawer" views to be pulled out from the edge of the window. 431d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * 441d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * <p>Drawer positioning and layout is controlled using the <code>android:layout_gravity</code> 451d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * attribute on child views corresponding to </p> 461d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * 471d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * <p>As per the Android Design guide, any drawers positioned to the left/start should 481d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * always contain content for navigating around the application, whereas any drawers 491d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * positioned to the right/end should always contain actions to take on the current content. 501d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * This preserves the same navigation left, actions right structure present in the Action Bar 511d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * and elsewhere.</p> 521d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell */ 531d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powellpublic class DrawerLayout extends ViewGroup { 541d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell private static final String TAG = "DrawerLayout"; 551d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 561d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell /** 571d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * Indicates that any drawers are in an idle, settled state. No animation is in progress. 581d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell */ 591d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell public static final int STATE_IDLE = ViewDragHelper.STATE_IDLE; 601d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 611d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell /** 621d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * Indicates that a drawer is currently being dragged by the user. 631d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell */ 641d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell public static final int STATE_DRAGGING = ViewDragHelper.STATE_DRAGGING; 651d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 661d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell /** 671d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * Indicates that a drawer is in the process of settling to a final position. 681d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell */ 691d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell public static final int STATE_SETTLING = ViewDragHelper.STATE_SETTLING; 701d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 710492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell /** 720492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell * The drawer is unlocked. 730492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell */ 740492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell public static final int LOCK_MODE_UNLOCKED = 0; 750492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell 760492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell /** 770492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell * The drawer is locked closed. The user may not open it, though 780492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell * the app may open it programmatically. 790492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell */ 800492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell public static final int LOCK_MODE_LOCKED_CLOSED = 1; 810492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell 820492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell /** 830492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell * The drawer is locked open. The user may not close it, though the app 840492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell * may close it programmatically. 850492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell */ 860492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell public static final int LOCK_MODE_LOCKED_OPEN = 2; 870492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell 881d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell private static final int MIN_DRAWER_MARGIN = 64; // dp 891d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 901d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell private static final int DEFAULT_SCRIM_COLOR = 0x99000000; 911d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 92ea7b10f4d5531713506e98c8093e7aab811f21f3Adam Powell /** 931732720ad57fe6d01392cd06551f1a25cff0333cAdam Powell * Length of time to delay before peeking the drawer. 941732720ad57fe6d01392cd06551f1a25cff0333cAdam Powell */ 951732720ad57fe6d01392cd06551f1a25cff0333cAdam Powell private static final int PEEK_DELAY = 160; // ms 961732720ad57fe6d01392cd06551f1a25cff0333cAdam Powell 971732720ad57fe6d01392cd06551f1a25cff0333cAdam Powell /** 98ea7b10f4d5531713506e98c8093e7aab811f21f3Adam Powell * Experimental feature. 99ea7b10f4d5531713506e98c8093e7aab811f21f3Adam Powell */ 100ea7b10f4d5531713506e98c8093e7aab811f21f3Adam Powell private static final boolean ALLOW_EDGE_LOCK = false; 101ea7b10f4d5531713506e98c8093e7aab811f21f3Adam Powell 1021d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell private static final int[] LAYOUT_ATTRS = new int[] { 1031d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell android.R.attr.layout_gravity 1041d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell }; 1051d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 1061d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell private int mMinDrawerMargin; 1071d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 1081d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell private int mScrimColor = DEFAULT_SCRIM_COLOR; 1091d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell private float mScrimOpacity; 1101d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell private Paint mScrimPaint = new Paint(); 1111d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 1121d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell private final ViewDragHelper mLeftDragger; 1131d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell private final ViewDragHelper mRightDragger; 1141732720ad57fe6d01392cd06551f1a25cff0333cAdam Powell private final ViewDragCallback mLeftCallback; 1151732720ad57fe6d01392cd06551f1a25cff0333cAdam Powell private final ViewDragCallback mRightCallback; 1161d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell private int mDrawerState; 117b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell private boolean mInLayout; 11857902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell private boolean mFirstLayout = true; 1190492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell private int mLockModeLeft; 1200492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell private int mLockModeRight; 1211732720ad57fe6d01392cd06551f1a25cff0333cAdam Powell private boolean mDisallowInterceptRequested; 122cde2707260e8241ffb816a03cbf5d52c28004b8aAdam Powell private boolean mChildrenCanceledTouch; 1231d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 1241d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell private DrawerListener mListener; 1251d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 1261d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell private float mInitialMotionX; 1271d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell private float mInitialMotionY; 1281d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 129b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell private Drawable mShadowLeft; 130b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell private Drawable mShadowRight; 131b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell 1321d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell /** 1331d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * Listener for monitoring events about drawers. 1341d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell */ 1351d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell public interface DrawerListener { 1361d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell /** 1371d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * Called when a drawer's position changes. 1381d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * @param drawerView The child view that was moved 1391d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * @param slideOffset The new offset of this drawer within its range, from 0-1 1401d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell */ 1411d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell public void onDrawerSlide(View drawerView, float slideOffset); 1421d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 1431d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell /** 1441d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * Called when a drawer has settled in a completely open state. 1451d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * The drawer is interactive at this point. 1461d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * 1471d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * @param drawerView Drawer view that is now open 1481d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell */ 1491d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell public void onDrawerOpened(View drawerView); 1501d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 1511d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell /** 1521d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * Called when a drawer has settled in a completely closed state. 1531d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * 1541d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * @param drawerView Drawer view that is now closed 1551d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell */ 1561d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell public void onDrawerClosed(View drawerView); 1571d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 1581d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell /** 1591d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * Called when the drawer motion state changes. The new state will 1601d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * be one of {@link #STATE_IDLE}, {@link #STATE_DRAGGING} or {@link #STATE_SETTLING}. 1611d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * 1621d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * @param newState The new drawer motion state 1631d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell */ 1641d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell public void onDrawerStateChanged(int newState); 1651d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 1661d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 167b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell /** 168b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell * Stub/no-op implementations of all methods of {@link DrawerListener}. 169b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell * Override this if you only care about a few of the available callback methods. 170b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell */ 171b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell public static abstract class SimpleDrawerListener implements DrawerListener { 172b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell @Override 173b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell public void onDrawerSlide(View drawerView, float slideOffset) { 174b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell } 175b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell 176b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell @Override 177b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell public void onDrawerOpened(View drawerView) { 178b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell } 179b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell 180b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell @Override 181b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell public void onDrawerClosed(View drawerView) { 182b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell } 183b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell 184b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell @Override 185b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell public void onDrawerStateChanged(int newState) { 186b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell } 187b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell } 188b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell 1891d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell public DrawerLayout(Context context) { 1901d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell this(context, null); 1911d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 1921d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 1931d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell public DrawerLayout(Context context, AttributeSet attrs) { 1941d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell this(context, attrs, 0); 1951d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 1961d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 1971d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell public DrawerLayout(Context context, AttributeSet attrs, int defStyle) { 1981d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell super(context, attrs, defStyle); 1991d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 2001d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final float density = getResources().getDisplayMetrics().density; 2011d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell mMinDrawerMargin = (int) (MIN_DRAWER_MARGIN * density + 0.5f); 2021d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 2031732720ad57fe6d01392cd06551f1a25cff0333cAdam Powell mLeftCallback = new ViewDragCallback(Gravity.LEFT); 2041732720ad57fe6d01392cd06551f1a25cff0333cAdam Powell mRightCallback = new ViewDragCallback(Gravity.RIGHT); 2051d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 2061732720ad57fe6d01392cd06551f1a25cff0333cAdam Powell mLeftDragger = ViewDragHelper.create(this, 0.5f, mLeftCallback); 2071d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell mLeftDragger.setEdgeTrackingEnabled(ViewDragHelper.EDGE_LEFT); 2081732720ad57fe6d01392cd06551f1a25cff0333cAdam Powell mLeftCallback.setDragger(mLeftDragger); 2091d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 2101732720ad57fe6d01392cd06551f1a25cff0333cAdam Powell mRightDragger = ViewDragHelper.create(this, 0.5f, mRightCallback); 2111d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell mRightDragger.setEdgeTrackingEnabled(ViewDragHelper.EDGE_RIGHT); 2121732720ad57fe6d01392cd06551f1a25cff0333cAdam Powell mRightCallback.setDragger(mRightDragger); 213791f31bbba40b8b51694a1b2cdc804f360786ed1Adam Powell 214791f31bbba40b8b51694a1b2cdc804f360786ed1Adam Powell // So that we can catch the back button 215791f31bbba40b8b51694a1b2cdc804f360786ed1Adam Powell setFocusableInTouchMode(true); 2161d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 2171d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 2181d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell /** 219b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell * Set a simple drawable used for the left or right shadow. 220b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell * The drawable provided must have a nonzero intrinsic width. 221b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell * 222b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell * @param shadowDrawable Shadow drawable to use at the edge of a drawer 223b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell * @param gravity Which drawer the shadow should apply to 224b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell */ 225b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell public void setDrawerShadow(Drawable shadowDrawable, int gravity) { 226b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell /* 227b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell * TODO Someone someday might want to set more complex drawables here. 228b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell * They're probably nuts, but we might want to consider registering callbacks, 229b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell * setting states, etc. properly. 230b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell */ 231b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell 232b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell final int absGravity = GravityCompat.getAbsoluteGravity(gravity, 233b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell ViewCompat.getLayoutDirection(this)); 234b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell if ((absGravity & Gravity.LEFT) == Gravity.LEFT) { 235b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell mShadowLeft = shadowDrawable; 236b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell invalidate(); 237b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell } 238b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell if ((absGravity & Gravity.RIGHT) == Gravity.RIGHT) { 239b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell mShadowRight = shadowDrawable; 240b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell invalidate(); 241b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell } 242b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell } 243b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell 244b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell /** 245b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell * Set a simple drawable used for the left or right shadow. 246b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell * The drawable provided must have a nonzero intrinsic width. 247b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell * 248b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell * @param resId Resource id of a shadow drawable to use at the edge of a drawer 249b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell * @param gravity Which drawer the shadow should apply to 250b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell */ 251b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell public void setDrawerShadow(int resId, int gravity) { 252b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell setDrawerShadow(getResources().getDrawable(resId), gravity); 253b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell } 254b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell 255b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell /** 256fe130779be95af79e875bdbeac7182a424b8b9a6Adam Powell * Set a color to use for the scrim that obscures primary content while a drawer is open. 257fe130779be95af79e875bdbeac7182a424b8b9a6Adam Powell * 258fe130779be95af79e875bdbeac7182a424b8b9a6Adam Powell * @param color Color to use in 0xAARRGGBB format. 259fe130779be95af79e875bdbeac7182a424b8b9a6Adam Powell */ 260fe130779be95af79e875bdbeac7182a424b8b9a6Adam Powell public void setScrimColor(int color) { 261fe130779be95af79e875bdbeac7182a424b8b9a6Adam Powell mScrimColor = color; 262fe130779be95af79e875bdbeac7182a424b8b9a6Adam Powell invalidate(); 263fe130779be95af79e875bdbeac7182a424b8b9a6Adam Powell } 264fe130779be95af79e875bdbeac7182a424b8b9a6Adam Powell 265fe130779be95af79e875bdbeac7182a424b8b9a6Adam Powell /** 2661d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * Set a listener to be notified of drawer events. 2671d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * 2681d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * @param listener Listener to notify when drawer events occur 2691d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * @see DrawerListener 2701d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell */ 2711d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell public void setDrawerListener(DrawerListener listener) { 2721d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell mListener = listener; 2731d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 2741d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 2751d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell /** 2760492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell * Enable or disable interaction with all drawers. 2770492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell * 2780492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell * <p>This allows the application to restrict the user's ability to open or close 2790492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell * any drawer within this layout. DrawerLayout will still respond to calls to 2800492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell * {@link #openDrawer(int)}, {@link #closeDrawer(int)} and friends if a drawer is locked.</p> 2810492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell * 2820492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell * <p>Locking drawers open or closed will implicitly open or close 2830492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell * any drawers as appropriate.</p> 2840492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell * 2850492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell * @param lockMode The new lock mode for the given drawer. One of {@link #LOCK_MODE_UNLOCKED}, 2860492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell * {@link #LOCK_MODE_LOCKED_CLOSED} or {@link #LOCK_MODE_LOCKED_OPEN}. 2870492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell */ 2880492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell public void setDrawerLockMode(int lockMode) { 2890492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell setDrawerLockMode(lockMode, Gravity.LEFT); 2900492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell setDrawerLockMode(lockMode, Gravity.RIGHT); 2910492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell } 2920492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell 2930492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell /** 2940492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell * Enable or disable interaction with the given drawer. 2950492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell * 2960492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell * <p>This allows the application to restrict the user's ability to open or close 2970492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell * the given drawer. DrawerLayout will still respond to calls to {@link #openDrawer(int)}, 2980492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell * {@link #closeDrawer(int)} and friends if a drawer is locked.</p> 2990492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell * 3000492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell * <p>Locking a drawer open or closed will implicitly open or close 3010492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell * that drawer as appropriate.</p> 3020492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell * 3030492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell * @param lockMode The new lock mode for the given drawer. One of {@link #LOCK_MODE_UNLOCKED}, 3040492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell * {@link #LOCK_MODE_LOCKED_CLOSED} or {@link #LOCK_MODE_LOCKED_OPEN}. 3050492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell * @param edgeGravity Gravity.LEFT, RIGHT, START or END. 3060492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell * Expresses which drawer to change the mode for. 3070492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell * 3080492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell * @see #LOCK_MODE_UNLOCKED 3090492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell * @see #LOCK_MODE_LOCKED_CLOSED 3100492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell * @see #LOCK_MODE_LOCKED_OPEN 3110492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell */ 3120492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell public void setDrawerLockMode(int lockMode, int edgeGravity) { 3130492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell final int absGrav = GravityCompat.getAbsoluteGravity(edgeGravity, 3140492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell ViewCompat.getLayoutDirection(this)); 3150492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell if (absGrav == Gravity.LEFT) { 3160492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell mLockModeLeft = lockMode; 3170492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell } else if (absGrav == Gravity.RIGHT) { 3180492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell mLockModeRight = lockMode; 3190492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell } 3200492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell if (lockMode != LOCK_MODE_UNLOCKED) { 3210492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell // Cancel interaction in progress 3220492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell final ViewDragHelper helper = absGrav == Gravity.LEFT ? mLeftDragger : mRightDragger; 3230492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell helper.cancel(); 3240492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell } 3250492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell switch (lockMode) { 3260492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell case LOCK_MODE_LOCKED_OPEN: 3270492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell final View toOpen = findDrawerWithGravity(absGrav); 3280492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell if (toOpen != null) { 3290492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell openDrawer(toOpen); 3300492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell } 3310492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell break; 3320492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell case LOCK_MODE_LOCKED_CLOSED: 3330492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell final View toClose = findDrawerWithGravity(absGrav); 3340492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell if (toClose != null) { 3350492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell closeDrawer(toClose); 3360492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell } 3370492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell break; 3380492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell // default: do nothing 3390492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell } 3400492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell } 3410492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell 3420492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell /** 3430492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell * Enable or disable interaction with the given drawer. 3440492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell * 3450492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell * <p>This allows the application to restrict the user's ability to open or close 3460492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell * the given drawer. DrawerLayout will still respond to calls to {@link #openDrawer(int)}, 3470492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell * {@link #closeDrawer(int)} and friends if a drawer is locked.</p> 3480492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell * 3490492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell * <p>Locking a drawer open or closed will implicitly open or close 3500492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell * that drawer as appropriate.</p> 3510492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell * 3520492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell * @param lockMode The new lock mode for the given drawer. One of {@link #LOCK_MODE_UNLOCKED}, 3530492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell * {@link #LOCK_MODE_LOCKED_CLOSED} or {@link #LOCK_MODE_LOCKED_OPEN}. 3540492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell * @param drawerView The drawer view to change the lock mode for 3550492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell * 3560492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell * @see #LOCK_MODE_UNLOCKED 3570492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell * @see #LOCK_MODE_LOCKED_CLOSED 3580492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell * @see #LOCK_MODE_LOCKED_OPEN 3590492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell */ 3600492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell public void setDrawerLockMode(int lockMode, View drawerView) { 3610492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell if (!isDrawerView(drawerView)) { 3620492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell throw new IllegalArgumentException("View " + drawerView + " is not a " + 3630492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell "drawer with appropriate layout_gravity"); 3640492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell } 3650492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell setDrawerLockMode(lockMode, getDrawerViewGravity(drawerView)); 3660492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell } 3670492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell 3680492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell /** 3690492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell * Check the lock mode of the drawer with the given gravity. 3700492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell * 3710492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell * @param edgeGravity Gravity of the drawer to check 3720492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell * @return one of {@link #LOCK_MODE_UNLOCKED}, {@link #LOCK_MODE_LOCKED_CLOSED} or 3730492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell * {@link #LOCK_MODE_LOCKED_OPEN}. 3740492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell */ 3750492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell public int getDrawerLockMode(int edgeGravity) { 3760492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell final int absGrav = GravityCompat.getAbsoluteGravity(edgeGravity, 3770492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell ViewCompat.getLayoutDirection(this)); 3780492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell if (absGrav == Gravity.LEFT) { 3790492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell return mLockModeLeft; 3800492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell } else if (absGrav == Gravity.RIGHT) { 3810492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell return mLockModeRight; 3820492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell } 3830492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell return LOCK_MODE_UNLOCKED; 3840492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell } 3850492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell 3860492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell /** 3870492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell * Check the lock mode of the given drawer view. 3880492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell * 3890492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell * @param drawerView Drawer view to check lock mode 3900492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell * @return one of {@link #LOCK_MODE_UNLOCKED}, {@link #LOCK_MODE_LOCKED_CLOSED} or 3910492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell * {@link #LOCK_MODE_LOCKED_OPEN}. 3920492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell */ 3930492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell public int getDrawerLockMode(View drawerView) { 3940492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell final int gravity = getDrawerViewGravity(drawerView); 3950492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell if (gravity == Gravity.LEFT) { 3960492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell return mLockModeLeft; 3970492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell } else if (gravity == Gravity.RIGHT) { 3980492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell return mLockModeRight; 3990492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell } 4000492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell 4010492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell return LOCK_MODE_UNLOCKED; 4020492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell } 4030492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell 4040492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell /** 4051d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * Resolve the shared state of all drawers from the component ViewDragHelpers. 4061d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * Should be called whenever a ViewDragHelper's state changes. 4071d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell */ 408b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell void updateDrawerState(int forGravity, int activeState, View activeDrawer) { 4091d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final int leftState = mLeftDragger.getViewDragState(); 4101d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final int rightState = mRightDragger.getViewDragState(); 4111d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 4121d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final int state; 4131d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell if (leftState == STATE_DRAGGING || rightState == STATE_DRAGGING) { 4141d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell state = STATE_DRAGGING; 4151d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } else if (leftState == STATE_SETTLING || rightState == STATE_SETTLING) { 4161d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell state = STATE_SETTLING; 4171d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } else { 4181d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell state = STATE_IDLE; 4191d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 4201d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 421b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell if (activeDrawer != null && activeState == STATE_IDLE) { 422b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell final LayoutParams lp = (LayoutParams) activeDrawer.getLayoutParams(); 423b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell if (lp.onScreen == 0) { 424b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell dispatchOnDrawerClosed(activeDrawer); 425b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell } else if (lp.onScreen == 1) { 426b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell dispatchOnDrawerOpened(activeDrawer); 427b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell } 428b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell } 429b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell 4301d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell if (state != mDrawerState) { 4311d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell mDrawerState = state; 432b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell 4331d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell if (mListener != null) { 4341d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell mListener.onDrawerStateChanged(state); 4351d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 4361d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 4371d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 4381d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 4391d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell void dispatchOnDrawerClosed(View drawerView) { 4401d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final LayoutParams lp = (LayoutParams) drawerView.getLayoutParams(); 4411d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell if (lp.knownOpen) { 4421d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell lp.knownOpen = false; 4431d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell if (mListener != null) { 4441d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell mListener.onDrawerClosed(drawerView); 4451d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 4461d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 4471d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 4481d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 4491d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell void dispatchOnDrawerOpened(View drawerView) { 4501d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final LayoutParams lp = (LayoutParams) drawerView.getLayoutParams(); 4511d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell if (!lp.knownOpen) { 4521d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell lp.knownOpen = true; 4531d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell if (mListener != null) { 4541d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell mListener.onDrawerOpened(drawerView); 4551d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 4561d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 4571d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 4581d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 4591d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell void dispatchOnDrawerSlide(View drawerView, float slideOffset) { 4601d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell if (mListener != null) { 4611d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell mListener.onDrawerSlide(drawerView, slideOffset); 4621d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 4631d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 4641d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 4651d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell void setDrawerViewOffset(View drawerView, float slideOffset) { 4661d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final LayoutParams lp = (LayoutParams) drawerView.getLayoutParams(); 467b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell if (slideOffset == lp.onScreen) { 4681d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell return; 4691d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 4701d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 471b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell lp.onScreen = slideOffset; 4721d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell dispatchOnDrawerSlide(drawerView, slideOffset); 4731d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 4741d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 4751d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell float getDrawerViewOffset(View drawerView) { 476b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell return ((LayoutParams) drawerView.getLayoutParams()).onScreen; 4771d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 4781d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 4791d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell int getDrawerViewGravity(View drawerView) { 4801d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final int gravity = ((LayoutParams) drawerView.getLayoutParams()).gravity; 4811d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell return GravityCompat.getAbsoluteGravity(gravity, ViewCompat.getLayoutDirection(drawerView)); 4821d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 4831d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 4841d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell boolean checkDrawerViewGravity(View drawerView, int checkFor) { 4851d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final int absGrav = getDrawerViewGravity(drawerView); 4861d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell return (absGrav & checkFor) == checkFor; 4871d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 4881d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 4890492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell View findOpenDrawer() { 4900492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell final int childCount = getChildCount(); 4910492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell for (int i = 0; i < childCount; i++) { 4920492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell final View child = getChildAt(i); 4930492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell if (((LayoutParams) child.getLayoutParams()).knownOpen) { 4940492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell return child; 4950492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell } 4960492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell } 4970492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell return null; 4980492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell } 4990492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell 5001d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell void moveDrawerToOffset(View drawerView, float slideOffset) { 5011d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final float oldOffset = getDrawerViewOffset(drawerView); 5021d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final int width = drawerView.getWidth(); 5031d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final int oldPos = (int) (width * oldOffset); 5041d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final int newPos = (int) (width * slideOffset); 5051d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final int dx = newPos - oldPos; 5061d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 5071d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell drawerView.offsetLeftAndRight(checkDrawerViewGravity(drawerView, Gravity.LEFT) ? dx : -dx); 5081d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell setDrawerViewOffset(drawerView, slideOffset); 5091d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 5101d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 5111d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell View findDrawerWithGravity(int gravity) { 5121d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final int childCount = getChildCount(); 5131d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell for (int i = 0; i < childCount; i++) { 5141d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final View child = getChildAt(i); 5151d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final int childGravity = getDrawerViewGravity(child); 5161d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell if ((childGravity & Gravity.HORIZONTAL_GRAVITY_MASK) == 5171d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell (gravity & Gravity.HORIZONTAL_GRAVITY_MASK)) { 5181d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell return child; 5191d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 5201d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 5211d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell return null; 5221d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 5231d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 5241d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell /** 5251d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * Simple gravity to string - only supports LEFT and RIGHT for debugging output. 5261d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * 5271d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * @param gravity Absolute gravity value 5281d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * @return LEFT or RIGHT as appropriate, or a hex string 5291d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell */ 5301d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell static String gravityToString(int gravity) { 5311d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell if ((gravity & Gravity.LEFT) == Gravity.LEFT) { 5321d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell return "LEFT"; 5331d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 5341d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell if ((gravity & Gravity.RIGHT) == Gravity.RIGHT) { 5351d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell return "RIGHT"; 5361d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 5371d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell return Integer.toHexString(gravity); 5381d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 5391d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 5401d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell @Override 54157902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell protected void onDetachedFromWindow() { 54257902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell super.onDetachedFromWindow(); 54357902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell mFirstLayout = true; 54457902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell } 54557902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell 54657902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell @Override 54757902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell protected void onAttachedToWindow() { 54857902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell super.onAttachedToWindow(); 54957902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell mFirstLayout = true; 55057902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell } 55157902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell 55257902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell @Override 5531d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 5541d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final int widthMode = MeasureSpec.getMode(widthMeasureSpec); 5551d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final int heightMode = MeasureSpec.getMode(heightMeasureSpec); 5561d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final int widthSize = MeasureSpec.getSize(widthMeasureSpec); 5571d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final int heightSize = MeasureSpec.getSize(heightMeasureSpec); 5581d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 5591d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell if (widthMode != MeasureSpec.EXACTLY || heightMode != MeasureSpec.EXACTLY) { 5601d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell throw new IllegalArgumentException( 5611d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell "DrawerLayout must be measured with MeasureSpec.EXACTLY."); 5621d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 5631d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 5641d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell setMeasuredDimension(widthSize, heightSize); 5651d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 5661d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell // Gravity value for each drawer we've seen. Only one of each permitted. 5671d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell int foundDrawers = 0; 5681d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final int childCount = getChildCount(); 5691d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell for (int i = 0; i < childCount; i++) { 5701d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final View child = getChildAt(i); 5711d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 5721d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell if (child.getVisibility() == GONE) { 5731d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell continue; 5741d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 5751d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 57600ca2532981fbd705f947a637ffd967a8d6f733bAdam Powell final LayoutParams lp = (LayoutParams) child.getLayoutParams(); 57700ca2532981fbd705f947a637ffd967a8d6f733bAdam Powell 5781d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell if (isContentView(child)) { 5791d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell // Content views get measured at exactly the layout's size. 58000ca2532981fbd705f947a637ffd967a8d6f733bAdam Powell final int contentWidthSpec = MeasureSpec.makeMeasureSpec( 58100ca2532981fbd705f947a637ffd967a8d6f733bAdam Powell widthSize - lp.leftMargin - lp.rightMargin, MeasureSpec.EXACTLY); 58200ca2532981fbd705f947a637ffd967a8d6f733bAdam Powell final int contentHeightSpec = MeasureSpec.makeMeasureSpec( 58300ca2532981fbd705f947a637ffd967a8d6f733bAdam Powell heightSize - lp.topMargin - lp.bottomMargin, MeasureSpec.EXACTLY); 58400ca2532981fbd705f947a637ffd967a8d6f733bAdam Powell child.measure(contentWidthSpec, contentHeightSpec); 5851d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } else if (isDrawerView(child)) { 5861d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final int childGravity = 5871d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell getDrawerViewGravity(child) & Gravity.HORIZONTAL_GRAVITY_MASK; 5881d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell if ((foundDrawers & childGravity) != 0) { 5891d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell throw new IllegalStateException("Child drawer has absolute gravity " + 5901d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell gravityToString(childGravity) + " but this " + TAG + " already has a " + 5911d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell "drawer view along that edge"); 5921d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 59300ca2532981fbd705f947a637ffd967a8d6f733bAdam Powell final int drawerWidthSpec = getChildMeasureSpec(widthMeasureSpec, 59400ca2532981fbd705f947a637ffd967a8d6f733bAdam Powell mMinDrawerMargin + lp.leftMargin + lp.rightMargin, 59500ca2532981fbd705f947a637ffd967a8d6f733bAdam Powell lp.width); 59600ca2532981fbd705f947a637ffd967a8d6f733bAdam Powell final int drawerHeightSpec = getChildMeasureSpec(heightMeasureSpec, 59700ca2532981fbd705f947a637ffd967a8d6f733bAdam Powell lp.topMargin + lp.bottomMargin, 59800ca2532981fbd705f947a637ffd967a8d6f733bAdam Powell lp.height); 59900ca2532981fbd705f947a637ffd967a8d6f733bAdam Powell child.measure(drawerWidthSpec, drawerHeightSpec); 6001d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } else { 6011d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell throw new IllegalStateException("Child " + child + " at index " + i + 6021d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell " does not have a valid layout_gravity - must be Gravity.LEFT, " + 6031d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell "Gravity.RIGHT or Gravity.NO_GRAVITY"); 6041d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 6051d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 6061d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 6071d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 6081d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell @Override 6091d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell protected void onLayout(boolean changed, int l, int t, int r, int b) { 610b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell mInLayout = true; 6111d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final int childCount = getChildCount(); 6121d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell for (int i = 0; i < childCount; i++) { 6131d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final View child = getChildAt(i); 6141d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 6151d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell if (child.getVisibility() == GONE) { 6161d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell continue; 6171d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 6181d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 61900ca2532981fbd705f947a637ffd967a8d6f733bAdam Powell final LayoutParams lp = (LayoutParams) child.getLayoutParams(); 62000ca2532981fbd705f947a637ffd967a8d6f733bAdam Powell 6211d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell if (isContentView(child)) { 62200ca2532981fbd705f947a637ffd967a8d6f733bAdam Powell child.layout(lp.leftMargin, lp.topMargin, 62300ca2532981fbd705f947a637ffd967a8d6f733bAdam Powell lp.leftMargin + child.getMeasuredWidth(), 62400ca2532981fbd705f947a637ffd967a8d6f733bAdam Powell lp.topMargin + child.getMeasuredHeight()); 6251d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } else { // Drawer, if it wasn't onMeasure would have thrown an exception. 6261d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final int childWidth = child.getMeasuredWidth(); 62700ca2532981fbd705f947a637ffd967a8d6f733bAdam Powell final int childHeight = child.getMeasuredHeight(); 6281d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell int childLeft; 6291d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 6301d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell if (checkDrawerViewGravity(child, Gravity.LEFT)) { 631b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell childLeft = -childWidth + (int) (childWidth * lp.onScreen); 6321d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } else { // Right; onMeasure checked for us. 633b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell childLeft = r - l - (int) (childWidth * lp.onScreen); 6341d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 6351d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 63600ca2532981fbd705f947a637ffd967a8d6f733bAdam Powell final int vgrav = lp.gravity & Gravity.VERTICAL_GRAVITY_MASK; 63700ca2532981fbd705f947a637ffd967a8d6f733bAdam Powell 63800ca2532981fbd705f947a637ffd967a8d6f733bAdam Powell switch (vgrav) { 63900ca2532981fbd705f947a637ffd967a8d6f733bAdam Powell default: 64000ca2532981fbd705f947a637ffd967a8d6f733bAdam Powell case Gravity.TOP: { 64100ca2532981fbd705f947a637ffd967a8d6f733bAdam Powell child.layout(childLeft, lp.topMargin, childLeft + childWidth, childHeight); 64200ca2532981fbd705f947a637ffd967a8d6f733bAdam Powell break; 64300ca2532981fbd705f947a637ffd967a8d6f733bAdam Powell } 64400ca2532981fbd705f947a637ffd967a8d6f733bAdam Powell 64500ca2532981fbd705f947a637ffd967a8d6f733bAdam Powell case Gravity.BOTTOM: { 64600ca2532981fbd705f947a637ffd967a8d6f733bAdam Powell final int height = b - t; 64700ca2532981fbd705f947a637ffd967a8d6f733bAdam Powell child.layout(childLeft, 64800ca2532981fbd705f947a637ffd967a8d6f733bAdam Powell height - lp.bottomMargin - child.getMeasuredHeight(), 64900ca2532981fbd705f947a637ffd967a8d6f733bAdam Powell childLeft + childWidth, 65000ca2532981fbd705f947a637ffd967a8d6f733bAdam Powell height - lp.bottomMargin); 65100ca2532981fbd705f947a637ffd967a8d6f733bAdam Powell break; 65200ca2532981fbd705f947a637ffd967a8d6f733bAdam Powell } 65300ca2532981fbd705f947a637ffd967a8d6f733bAdam Powell 65400ca2532981fbd705f947a637ffd967a8d6f733bAdam Powell case Gravity.CENTER_VERTICAL: { 65500ca2532981fbd705f947a637ffd967a8d6f733bAdam Powell final int height = b - t; 65600ca2532981fbd705f947a637ffd967a8d6f733bAdam Powell int childTop = (height - childHeight) / 2; 65700ca2532981fbd705f947a637ffd967a8d6f733bAdam Powell 65800ca2532981fbd705f947a637ffd967a8d6f733bAdam Powell // Offset for margins. If things don't fit right because of 65900ca2532981fbd705f947a637ffd967a8d6f733bAdam Powell // bad measurement before, oh well. 66000ca2532981fbd705f947a637ffd967a8d6f733bAdam Powell if (childTop < lp.topMargin) { 66100ca2532981fbd705f947a637ffd967a8d6f733bAdam Powell childTop = lp.topMargin; 66200ca2532981fbd705f947a637ffd967a8d6f733bAdam Powell } else if (childTop + childHeight > height - lp.bottomMargin) { 66300ca2532981fbd705f947a637ffd967a8d6f733bAdam Powell childTop = height - lp.bottomMargin - childHeight; 66400ca2532981fbd705f947a637ffd967a8d6f733bAdam Powell } 66500ca2532981fbd705f947a637ffd967a8d6f733bAdam Powell child.layout(childLeft, childTop, childLeft + childWidth, 66600ca2532981fbd705f947a637ffd967a8d6f733bAdam Powell childTop + childHeight); 66700ca2532981fbd705f947a637ffd967a8d6f733bAdam Powell break; 66800ca2532981fbd705f947a637ffd967a8d6f733bAdam Powell } 66900ca2532981fbd705f947a637ffd967a8d6f733bAdam Powell } 670b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell 671b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell if (lp.onScreen == 0) { 672b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell child.setVisibility(INVISIBLE); 673b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell } 6741d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 6751d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 676b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell mInLayout = false; 67757902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell mFirstLayout = false; 678b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell } 679b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell 680b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell @Override 681b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell public void requestLayout() { 682b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell if (!mInLayout) { 683b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell super.requestLayout(); 684b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell } 6851d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 6861d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 6871d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell @Override 6881d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell public void computeScroll() { 6891d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final int childCount = getChildCount(); 6901d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell float scrimOpacity = 0; 6911d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell for (int i = 0; i < childCount; i++) { 692b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell final float onscreen = ((LayoutParams) getChildAt(i).getLayoutParams()).onScreen; 6931d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell scrimOpacity = Math.max(scrimOpacity, onscreen); 6941d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 6951d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell mScrimOpacity = scrimOpacity; 6961d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 6971d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell // "|" used on purpose; both need to run. 6981d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell if (mLeftDragger.continueSettling(true) | mRightDragger.continueSettling(true)) { 6991d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell ViewCompat.postInvalidateOnAnimation(this); 7001d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 7011d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 7021d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 703b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell private static boolean hasOpaqueBackground(View v) { 704b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell final Drawable bg = v.getBackground(); 705b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell if (bg != null) { 706b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell return bg.getOpacity() == PixelFormat.OPAQUE; 707b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell } 708b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell return false; 709b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell } 710b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell 7111d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell @Override 7121d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell protected boolean drawChild(Canvas canvas, View child, long drawingTime) { 71300ca2532981fbd705f947a637ffd967a8d6f733bAdam Powell final int height = getHeight(); 714b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell final boolean drawingContent = isContentView(child); 715b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell int clipLeft = 0, clipRight = getWidth(); 716b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell 7171d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final int restoreCount = canvas.save(); 718b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell if (drawingContent) { 719b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell final int childCount = getChildCount(); 720b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell for (int i = 0; i < childCount; i++) { 721b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell final View v = getChildAt(i); 722b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell if (v == child || v.getVisibility() != VISIBLE || 72300ca2532981fbd705f947a637ffd967a8d6f733bAdam Powell !hasOpaqueBackground(v) || !isDrawerView(v) || 72400ca2532981fbd705f947a637ffd967a8d6f733bAdam Powell v.getHeight() < height) { 725b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell continue; 726b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell } 727b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell 728b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell if (checkDrawerViewGravity(v, Gravity.LEFT)) { 729b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell final int vright = v.getRight(); 730b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell if (vright > clipLeft) clipLeft = vright; 731b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell } else { 732b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell final int vleft = v.getLeft(); 733b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell if (vleft < clipRight) clipRight = vleft; 734b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell } 735b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell } 736b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell canvas.clipRect(clipLeft, 0, clipRight, getHeight()); 737b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell } 7381d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final boolean result = super.drawChild(canvas, child, drawingTime); 7391d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell canvas.restoreToCount(restoreCount); 740b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell 741b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell if (mScrimOpacity > 0 && drawingContent) { 7421d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final int baseAlpha = (mScrimColor & 0xff000000) >>> 24; 7431d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final int imag = (int) (baseAlpha * mScrimOpacity); 7441d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final int color = imag << 24 | (mScrimColor & 0xffffff); 7451d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell mScrimPaint.setColor(color); 7461d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 747b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell canvas.drawRect(clipLeft, 0, clipRight, getHeight(), mScrimPaint); 748b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell } else if (mShadowLeft != null && checkDrawerViewGravity(child, Gravity.LEFT)) { 749b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell final int shadowWidth = mShadowLeft.getIntrinsicWidth(); 750b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell final int childRight = child.getRight(); 751ea7b10f4d5531713506e98c8093e7aab811f21f3Adam Powell final int drawerPeekDistance = mLeftDragger.getEdgeSize(); 752b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell final float alpha = 753ea7b10f4d5531713506e98c8093e7aab811f21f3Adam Powell Math.max(0, Math.min((float) childRight / drawerPeekDistance, 1.f)); 754b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell mShadowLeft.setBounds(childRight, child.getTop(), 755b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell childRight + shadowWidth, child.getBottom()); 756b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell mShadowLeft.setAlpha((int) (0xff * alpha)); 757b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell mShadowLeft.draw(canvas); 758b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell } else if (mShadowRight != null && checkDrawerViewGravity(child, Gravity.RIGHT)) { 759b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell final int shadowWidth = mShadowRight.getIntrinsicWidth(); 760b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell final int childLeft = child.getLeft(); 761b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell final int showing = getWidth() - childLeft; 762ea7b10f4d5531713506e98c8093e7aab811f21f3Adam Powell final int drawerPeekDistance = mRightDragger.getEdgeSize(); 763b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell final float alpha = 764ea7b10f4d5531713506e98c8093e7aab811f21f3Adam Powell Math.max(0, Math.min((float) showing / drawerPeekDistance, 1.f)); 765b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell mShadowRight.setBounds(childLeft - shadowWidth, child.getTop(), 766b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell childLeft, child.getBottom()); 767b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell mShadowRight.setAlpha((int) (0xff * alpha)); 768b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell mShadowRight.draw(canvas); 7691d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 7701d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell return result; 7711d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 7721d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 7731d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell boolean isContentView(View child) { 7741d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell return ((LayoutParams) child.getLayoutParams()).gravity == Gravity.NO_GRAVITY; 7751d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 7761d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 7771d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell boolean isDrawerView(View child) { 7781d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final int gravity = ((LayoutParams) child.getLayoutParams()).gravity; 7791d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final int absGravity = GravityCompat.getAbsoluteGravity(gravity, 7801d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell ViewCompat.getLayoutDirection(child)); 7811d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell return (absGravity & (Gravity.LEFT | Gravity.RIGHT)) != 0; 7821d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 7831d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 7841d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell @Override 7851d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell public boolean onInterceptTouchEvent(MotionEvent ev) { 7861d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final int action = MotionEventCompat.getActionMasked(ev); 7871d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 7881d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell // "|" used deliberately here; both methods should be invoked. 7891d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final boolean interceptForDrag = mLeftDragger.shouldInterceptTouchEvent(ev) | 7901d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell mRightDragger.shouldInterceptTouchEvent(ev); 7911d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 7921d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell boolean interceptForTap = false; 7931d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 7941d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell switch (action) { 7951d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell case MotionEvent.ACTION_DOWN: { 7961d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final float x = ev.getX(); 7971d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final float y = ev.getY(); 7981d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell mInitialMotionX = x; 7991d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell mInitialMotionY = y; 8001d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell if (mScrimOpacity > 0 && 8011d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell isContentView(mLeftDragger.findTopChildUnder((int) x, (int) y))) { 8021d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell interceptForTap = true; 8031d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 8041732720ad57fe6d01392cd06551f1a25cff0333cAdam Powell mDisallowInterceptRequested = false; 805cde2707260e8241ffb816a03cbf5d52c28004b8aAdam Powell mChildrenCanceledTouch = false; 8061732720ad57fe6d01392cd06551f1a25cff0333cAdam Powell break; 8071732720ad57fe6d01392cd06551f1a25cff0333cAdam Powell } 8081732720ad57fe6d01392cd06551f1a25cff0333cAdam Powell 8091732720ad57fe6d01392cd06551f1a25cff0333cAdam Powell case MotionEvent.ACTION_MOVE: { 8101732720ad57fe6d01392cd06551f1a25cff0333cAdam Powell // If we cross the touch slop, don't perform the delayed peek for an edge touch. 8111732720ad57fe6d01392cd06551f1a25cff0333cAdam Powell if (mLeftDragger.checkTouchSlop(ViewDragHelper.DIRECTION_ALL)) { 8121732720ad57fe6d01392cd06551f1a25cff0333cAdam Powell mLeftCallback.removeCallbacks(); 8131732720ad57fe6d01392cd06551f1a25cff0333cAdam Powell mRightCallback.removeCallbacks(); 8141732720ad57fe6d01392cd06551f1a25cff0333cAdam Powell } 8151d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell break; 8161d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 8171d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 8181d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell case MotionEvent.ACTION_CANCEL: 8191d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell case MotionEvent.ACTION_UP: { 8201d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell closeDrawers(true); 8211732720ad57fe6d01392cd06551f1a25cff0333cAdam Powell mDisallowInterceptRequested = false; 822cde2707260e8241ffb816a03cbf5d52c28004b8aAdam Powell mChildrenCanceledTouch = false; 8231d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 8241d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 8251732720ad57fe6d01392cd06551f1a25cff0333cAdam Powell 826cde2707260e8241ffb816a03cbf5d52c28004b8aAdam Powell return interceptForDrag || interceptForTap || hasPeekingDrawer() || mChildrenCanceledTouch; 8271d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 8281d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 8291d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell @Override 8301d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell public boolean onTouchEvent(MotionEvent ev) { 8311d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell mLeftDragger.processTouchEvent(ev); 8321d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell mRightDragger.processTouchEvent(ev); 8331d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 8341d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final int action = ev.getAction(); 8351d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell boolean wantTouchEvents = true; 8361d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 8371d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell switch (action & MotionEventCompat.ACTION_MASK) { 8381d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell case MotionEvent.ACTION_DOWN: { 8391d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final float x = ev.getX(); 8401d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final float y = ev.getY(); 8411d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell mInitialMotionX = x; 8421d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell mInitialMotionY = y; 8431732720ad57fe6d01392cd06551f1a25cff0333cAdam Powell mDisallowInterceptRequested = false; 844cde2707260e8241ffb816a03cbf5d52c28004b8aAdam Powell mChildrenCanceledTouch = false; 8451d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell break; 8461d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 8471d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 8481d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell case MotionEvent.ACTION_UP: { 8491d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final float x = ev.getX(); 8501d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final float y = ev.getY(); 8511d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell boolean peekingOnly = true; 8528bc268e9c40e4ae375a0d65dc1293dccc541186fAdam Powell final View touchedView = mLeftDragger.findTopChildUnder((int) x, (int) y); 8538bc268e9c40e4ae375a0d65dc1293dccc541186fAdam Powell if (touchedView != null && isContentView(touchedView)) { 8541d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final float dx = x - mInitialMotionX; 8551d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final float dy = y - mInitialMotionY; 8561d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final int slop = mLeftDragger.getTouchSlop(); 8571d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell if (dx * dx + dy * dy < slop * slop) { 8580492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell // Taps close a dimmed open drawer but only if it isn't locked open. 8590492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell final View openDrawer = findOpenDrawer(); 8600492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell if (openDrawer != null) { 8610492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell peekingOnly = getDrawerLockMode(openDrawer) == LOCK_MODE_LOCKED_OPEN; 8620492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell } 8631d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 8641d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 8651d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell closeDrawers(peekingOnly); 8661732720ad57fe6d01392cd06551f1a25cff0333cAdam Powell mDisallowInterceptRequested = false; 8671d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell break; 8681d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 8691d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 8701d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell case MotionEvent.ACTION_CANCEL: { 8711d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell closeDrawers(true); 8721732720ad57fe6d01392cd06551f1a25cff0333cAdam Powell mDisallowInterceptRequested = false; 873cde2707260e8241ffb816a03cbf5d52c28004b8aAdam Powell mChildrenCanceledTouch = false; 8741d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell break; 8751d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 8761d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 8771d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 8781d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell return wantTouchEvents; 8791d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 8801d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 881ea7b10f4d5531713506e98c8093e7aab811f21f3Adam Powell public void requestDisallowInterceptTouchEvent(boolean disallowIntercept) { 8821732720ad57fe6d01392cd06551f1a25cff0333cAdam Powell if (!mLeftDragger.isEdgeTouched(ViewDragHelper.EDGE_LEFT) && 8831732720ad57fe6d01392cd06551f1a25cff0333cAdam Powell !mRightDragger.isEdgeTouched(ViewDragHelper.EDGE_RIGHT)) { 8841732720ad57fe6d01392cd06551f1a25cff0333cAdam Powell // If we have an edge touch we want to skip this and track it for later instead. 8851732720ad57fe6d01392cd06551f1a25cff0333cAdam Powell super.requestDisallowInterceptTouchEvent(disallowIntercept); 8861732720ad57fe6d01392cd06551f1a25cff0333cAdam Powell } 8871732720ad57fe6d01392cd06551f1a25cff0333cAdam Powell mDisallowInterceptRequested = disallowIntercept; 888ea7b10f4d5531713506e98c8093e7aab811f21f3Adam Powell if (disallowIntercept) { 889ea7b10f4d5531713506e98c8093e7aab811f21f3Adam Powell closeDrawers(true); 890ea7b10f4d5531713506e98c8093e7aab811f21f3Adam Powell } 891ea7b10f4d5531713506e98c8093e7aab811f21f3Adam Powell } 892ea7b10f4d5531713506e98c8093e7aab811f21f3Adam Powell 8931d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell /** 8941d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * Close all currently open drawer views by animating them out of view. 8951d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell */ 8961d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell public void closeDrawers() { 8971d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell closeDrawers(false); 8981d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 8991d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 9001d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell void closeDrawers(boolean peekingOnly) { 9011d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell boolean needsInvalidate = false; 9021d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final int childCount = getChildCount(); 9031d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell for (int i = 0; i < childCount; i++) { 9041d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final View child = getChildAt(i); 9051d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final LayoutParams lp = (LayoutParams) child.getLayoutParams(); 9061d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 9071d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell if (!isDrawerView(child) || (peekingOnly && !lp.isPeeking)) { 9081d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell continue; 9091d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 9101d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 9111d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final int childWidth = child.getWidth(); 9121d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 9131d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell if (checkDrawerViewGravity(child, Gravity.LEFT)) { 9141d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell needsInvalidate |= mLeftDragger.smoothSlideViewTo(child, 9151d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell -childWidth, child.getTop()); 9161d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } else { 9171d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell needsInvalidate |= mRightDragger.smoothSlideViewTo(child, 9181d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell getWidth(), child.getTop()); 9191d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 9201d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 9211d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell lp.isPeeking = false; 9221d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 9231d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 9241732720ad57fe6d01392cd06551f1a25cff0333cAdam Powell mLeftCallback.removeCallbacks(); 9251732720ad57fe6d01392cd06551f1a25cff0333cAdam Powell mRightCallback.removeCallbacks(); 9261732720ad57fe6d01392cd06551f1a25cff0333cAdam Powell 9271d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell if (needsInvalidate) { 9281d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell invalidate(); 9291d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 9301d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 9311d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 9321d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell /** 9331d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * Open the specified drawer view by animating it into view. 9341d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * 9351d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * @param drawerView Drawer view to open 9361d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell */ 9371d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell public void openDrawer(View drawerView) { 9381d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell if (!isDrawerView(drawerView)) { 9391d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell throw new IllegalArgumentException("View " + drawerView + " is not a sliding drawer"); 9401d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 9411d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 94257902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell if (mFirstLayout) { 94357902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell final LayoutParams lp = (LayoutParams) drawerView.getLayoutParams(); 94457902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell lp.onScreen = 1.f; 94557902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell lp.knownOpen = true; 9461d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } else { 94757902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell if (checkDrawerViewGravity(drawerView, Gravity.LEFT)) { 94857902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell mLeftDragger.smoothSlideViewTo(drawerView, 0, drawerView.getTop()); 94957902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell } else { 95057902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell mRightDragger.smoothSlideViewTo(drawerView, getWidth() - drawerView.getWidth(), 95157902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell drawerView.getTop()); 95257902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell } 9531d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 9541d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell invalidate(); 9551d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 9561d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 9571d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell /** 9581d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * Open the specified drawer by animating it out of view. 9591d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * 9601d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * @param gravity Gravity.LEFT to move the left drawer or Gravity.RIGHT for the right. 9611d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * GravityCompat.START or GravityCompat.END may also be used. 9621d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell */ 9631d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell public void openDrawer(int gravity) { 9641d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final int absGravity = GravityCompat.getAbsoluteGravity(gravity, 9651d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell ViewCompat.getLayoutDirection(this)); 9661d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final View drawerView = findDrawerWithGravity(absGravity); 9671d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 9681d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell if (drawerView == null) { 9691d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell throw new IllegalArgumentException("No drawer view found with absolute gravity " + 9701d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell gravityToString(absGravity)); 9711d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 9721d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell openDrawer(drawerView); 9731d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 9741d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 9751d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell /** 9761d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * Close the specified drawer view by animating it into view. 9771d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * 9781d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * @param drawerView Drawer view to close 9791d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell */ 9801d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell public void closeDrawer(View drawerView) { 9811d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell if (!isDrawerView(drawerView)) { 9821d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell throw new IllegalArgumentException("View " + drawerView + " is not a sliding drawer"); 9831d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 9841d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 98557902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell if (mFirstLayout) { 98657902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell final LayoutParams lp = (LayoutParams) drawerView.getLayoutParams(); 98757902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell lp.onScreen = 0.f; 98857902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell lp.knownOpen = false; 9891d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } else { 99057902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell if (checkDrawerViewGravity(drawerView, Gravity.LEFT)) { 99157902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell mLeftDragger.smoothSlideViewTo(drawerView, -drawerView.getWidth(), 99257902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell drawerView.getTop()); 99357902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell } else { 99457902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell mRightDragger.smoothSlideViewTo(drawerView, getWidth(), drawerView.getTop()); 99557902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell } 9961d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 9971d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell invalidate(); 9981d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 9991d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 10001d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell /** 10011d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * Close the specified drawer by animating it out of view. 10021d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * 10031d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * @param gravity Gravity.LEFT to move the left drawer or Gravity.RIGHT for the right. 10041d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * GravityCompat.START or GravityCompat.END may also be used. 10051d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell */ 10061d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell public void closeDrawer(int gravity) { 10071d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final int absGravity = GravityCompat.getAbsoluteGravity(gravity, 10081d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell ViewCompat.getLayoutDirection(this)); 10091d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final View drawerView = findDrawerWithGravity(absGravity); 10101d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 10111d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell if (drawerView == null) { 10121d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell throw new IllegalArgumentException("No drawer view found with absolute gravity " + 10131d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell gravityToString(absGravity)); 10141d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 10151d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell closeDrawer(drawerView); 10161d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 10171d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 1018b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell /** 1019b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell * Check if the given drawer view is currently in an open state. 1020b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell * To be considered "open" the drawer must have settled into its fully 1021b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell * visible state. To check for partial visibility use 1022b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell * {@link #isDrawerVisible(android.view.View)}. 1023b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell * 1024b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell * @param drawer Drawer view to check 1025b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell * @return true if the given drawer view is in an open state 1026b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell * @see #isDrawerVisible(android.view.View) 1027b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell */ 1028b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell public boolean isDrawerOpen(View drawer) { 1029b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell if (!isDrawerView(drawer)) { 1030b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell throw new IllegalArgumentException("View " + drawer + " is not a drawer"); 1031b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell } 1032b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell return ((LayoutParams) drawer.getLayoutParams()).knownOpen; 1033b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell } 1034b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell 1035b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell /** 1036b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell * Check if a given drawer view is currently visible on-screen. The drawer 1037b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell * may be only peeking onto the screen, fully extended, or anywhere inbetween. 1038b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell * 1039b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell * @param drawer Drawer view to check 1040b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell * @return true if the given drawer is visible on-screen 1041b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell * @see #isDrawerOpen(android.view.View) 1042b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell */ 1043b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell public boolean isDrawerVisible(View drawer) { 1044b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell if (!isDrawerView(drawer)) { 1045b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell throw new IllegalArgumentException("View " + drawer + " is not a drawer"); 1046b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell } 1047b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell return ((LayoutParams) drawer.getLayoutParams()).onScreen > 0; 1048b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell } 1049b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell 1050ea7b10f4d5531713506e98c8093e7aab811f21f3Adam Powell private boolean hasPeekingDrawer() { 1051ea7b10f4d5531713506e98c8093e7aab811f21f3Adam Powell final int childCount = getChildCount(); 1052ea7b10f4d5531713506e98c8093e7aab811f21f3Adam Powell for (int i = 0; i < childCount; i++) { 1053ea7b10f4d5531713506e98c8093e7aab811f21f3Adam Powell final LayoutParams lp = (LayoutParams) getChildAt(i).getLayoutParams(); 1054ea7b10f4d5531713506e98c8093e7aab811f21f3Adam Powell if (lp.isPeeking) { 1055ea7b10f4d5531713506e98c8093e7aab811f21f3Adam Powell return true; 1056ea7b10f4d5531713506e98c8093e7aab811f21f3Adam Powell } 1057ea7b10f4d5531713506e98c8093e7aab811f21f3Adam Powell } 1058ea7b10f4d5531713506e98c8093e7aab811f21f3Adam Powell return false; 1059ea7b10f4d5531713506e98c8093e7aab811f21f3Adam Powell } 1060ea7b10f4d5531713506e98c8093e7aab811f21f3Adam Powell 10611d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell @Override 10621d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell protected ViewGroup.LayoutParams generateDefaultLayoutParams() { 10631d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell return new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT); 10641d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 10651d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 10661d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell @Override 10671d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell protected ViewGroup.LayoutParams generateLayoutParams(ViewGroup.LayoutParams p) { 10681d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell return p instanceof LayoutParams 10691d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell ? new LayoutParams((LayoutParams) p) 107000ca2532981fbd705f947a637ffd967a8d6f733bAdam Powell : p instanceof ViewGroup.MarginLayoutParams 107100ca2532981fbd705f947a637ffd967a8d6f733bAdam Powell ? new LayoutParams((MarginLayoutParams) p) 10721d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell : new LayoutParams(p); 10731d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 10741d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 10751d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell @Override 10761d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell protected boolean checkLayoutParams(ViewGroup.LayoutParams p) { 10771d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell return p instanceof LayoutParams && super.checkLayoutParams(p); 10781d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 10791d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 10801d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell @Override 10811d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell public ViewGroup.LayoutParams generateLayoutParams(AttributeSet attrs) { 10821d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell return new LayoutParams(getContext(), attrs); 10831d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 10841d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 1085791f31bbba40b8b51694a1b2cdc804f360786ed1Adam Powell private boolean hasVisibleDrawer() { 10860492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell return findVisibleDrawer() != null; 10870492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell } 10880492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell 10890492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell private View findVisibleDrawer() { 1090791f31bbba40b8b51694a1b2cdc804f360786ed1Adam Powell final int childCount = getChildCount(); 1091791f31bbba40b8b51694a1b2cdc804f360786ed1Adam Powell for (int i = 0; i < childCount; i++) { 1092791f31bbba40b8b51694a1b2cdc804f360786ed1Adam Powell final View child = getChildAt(i); 1093791f31bbba40b8b51694a1b2cdc804f360786ed1Adam Powell if (isDrawerView(child) && isDrawerVisible(child)) { 10940492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell return child; 1095791f31bbba40b8b51694a1b2cdc804f360786ed1Adam Powell } 1096791f31bbba40b8b51694a1b2cdc804f360786ed1Adam Powell } 10970492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell return null; 1098791f31bbba40b8b51694a1b2cdc804f360786ed1Adam Powell } 1099791f31bbba40b8b51694a1b2cdc804f360786ed1Adam Powell 1100cde2707260e8241ffb816a03cbf5d52c28004b8aAdam Powell void cancelChildViewTouch() { 1101cde2707260e8241ffb816a03cbf5d52c28004b8aAdam Powell // Cancel child touches 1102cde2707260e8241ffb816a03cbf5d52c28004b8aAdam Powell if (!mChildrenCanceledTouch) { 1103cde2707260e8241ffb816a03cbf5d52c28004b8aAdam Powell final long now = SystemClock.uptimeMillis(); 1104cde2707260e8241ffb816a03cbf5d52c28004b8aAdam Powell final MotionEvent cancelEvent = MotionEvent.obtain(now, now, 1105cde2707260e8241ffb816a03cbf5d52c28004b8aAdam Powell MotionEvent.ACTION_CANCEL, 0.0f, 0.0f, 0); 1106cde2707260e8241ffb816a03cbf5d52c28004b8aAdam Powell final int childCount = getChildCount(); 1107cde2707260e8241ffb816a03cbf5d52c28004b8aAdam Powell for (int i = 0; i < childCount; i++) { 1108cde2707260e8241ffb816a03cbf5d52c28004b8aAdam Powell getChildAt(i).dispatchTouchEvent(cancelEvent); 1109cde2707260e8241ffb816a03cbf5d52c28004b8aAdam Powell } 1110cde2707260e8241ffb816a03cbf5d52c28004b8aAdam Powell cancelEvent.recycle(); 1111cde2707260e8241ffb816a03cbf5d52c28004b8aAdam Powell mChildrenCanceledTouch = true; 1112cde2707260e8241ffb816a03cbf5d52c28004b8aAdam Powell } 1113cde2707260e8241ffb816a03cbf5d52c28004b8aAdam Powell } 1114cde2707260e8241ffb816a03cbf5d52c28004b8aAdam Powell 1115791f31bbba40b8b51694a1b2cdc804f360786ed1Adam Powell @Override 1116791f31bbba40b8b51694a1b2cdc804f360786ed1Adam Powell public boolean onKeyDown(int keyCode, KeyEvent event) { 1117791f31bbba40b8b51694a1b2cdc804f360786ed1Adam Powell if (keyCode == KeyEvent.KEYCODE_BACK && hasVisibleDrawer()) { 1118791f31bbba40b8b51694a1b2cdc804f360786ed1Adam Powell KeyEventCompat.startTracking(event); 1119791f31bbba40b8b51694a1b2cdc804f360786ed1Adam Powell return true; 1120791f31bbba40b8b51694a1b2cdc804f360786ed1Adam Powell } 1121791f31bbba40b8b51694a1b2cdc804f360786ed1Adam Powell return super.onKeyDown(keyCode, event); 1122791f31bbba40b8b51694a1b2cdc804f360786ed1Adam Powell } 1123791f31bbba40b8b51694a1b2cdc804f360786ed1Adam Powell 1124791f31bbba40b8b51694a1b2cdc804f360786ed1Adam Powell @Override 1125791f31bbba40b8b51694a1b2cdc804f360786ed1Adam Powell public boolean onKeyUp(int keyCode, KeyEvent event) { 11260492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell if (keyCode == KeyEvent.KEYCODE_BACK) { 11270492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell final View visibleDrawer = findVisibleDrawer(); 11280492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell if (visibleDrawer != null && getDrawerLockMode(visibleDrawer) == LOCK_MODE_UNLOCKED) { 11290492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell closeDrawers(); 11300492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell } 11310492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell return visibleDrawer != null; 1132791f31bbba40b8b51694a1b2cdc804f360786ed1Adam Powell } 1133791f31bbba40b8b51694a1b2cdc804f360786ed1Adam Powell return super.onKeyUp(keyCode, event); 1134791f31bbba40b8b51694a1b2cdc804f360786ed1Adam Powell } 1135791f31bbba40b8b51694a1b2cdc804f360786ed1Adam Powell 113657902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell @Override 113757902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell protected void onRestoreInstanceState(Parcelable state) { 113857902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell final SavedState ss = (SavedState) state; 113957902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell super.onRestoreInstanceState(ss.getSuperState()); 114057902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell 114157902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell if (ss.openDrawerGravity != Gravity.NO_GRAVITY) { 114257902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell final View toOpen = findDrawerWithGravity(ss.openDrawerGravity); 114357902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell if (toOpen != null) { 114457902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell openDrawer(toOpen); 114557902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell } 114657902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell } 11478e01d24e718d603974182cd48f648369c07edec1Adam Powell 11488e01d24e718d603974182cd48f648369c07edec1Adam Powell setDrawerLockMode(ss.lockModeLeft, Gravity.LEFT); 11498e01d24e718d603974182cd48f648369c07edec1Adam Powell setDrawerLockMode(ss.lockModeRight, Gravity.RIGHT); 115057902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell } 115157902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell 115257902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell @Override 115357902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell protected Parcelable onSaveInstanceState() { 115457902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell final Parcelable superState = super.onSaveInstanceState(); 115557902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell 115657902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell final SavedState ss = new SavedState(superState); 115757902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell 115857902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell final int childCount = getChildCount(); 115957902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell for (int i = 0; i < childCount; i++) { 116057902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell final View child = getChildAt(i); 116157902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell if (!isDrawerView(child)) { 116257902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell continue; 116357902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell } 116457902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell 116557902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell final LayoutParams lp = (LayoutParams) child.getLayoutParams(); 116657902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell if (lp.knownOpen) { 116757902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell ss.openDrawerGravity = lp.gravity; 116857902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell // Only one drawer can be open at a time. 116957902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell break; 117057902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell } 117157902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell } 117257902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell 11738e01d24e718d603974182cd48f648369c07edec1Adam Powell ss.lockModeLeft = mLockModeLeft; 11748e01d24e718d603974182cd48f648369c07edec1Adam Powell ss.lockModeRight = mLockModeRight; 11758e01d24e718d603974182cd48f648369c07edec1Adam Powell 117657902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell return ss; 117757902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell } 117857902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell 117957902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell /** 118057902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell * State persisted across instances 118157902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell */ 118257902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell protected static class SavedState extends BaseSavedState { 118357902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell int openDrawerGravity = Gravity.NO_GRAVITY; 11848e01d24e718d603974182cd48f648369c07edec1Adam Powell int lockModeLeft = LOCK_MODE_UNLOCKED; 11858e01d24e718d603974182cd48f648369c07edec1Adam Powell int lockModeRight = LOCK_MODE_UNLOCKED; 118657902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell 118757902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell public SavedState(Parcel in) { 118857902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell super(in); 118957902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell openDrawerGravity = in.readInt(); 119057902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell } 119157902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell 119257902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell public SavedState(Parcelable superState) { 119357902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell super(superState); 119457902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell } 119557902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell 119657902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell @Override 119757902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell public void writeToParcel(Parcel dest, int flags) { 119857902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell super.writeToParcel(dest, flags); 119957902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell dest.writeInt(openDrawerGravity); 120057902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell } 120157902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell 120257902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell public static final Parcelable.Creator<SavedState> CREATOR = 120357902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell new Parcelable.Creator<SavedState>() { 120457902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell @Override 120557902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell public SavedState createFromParcel(Parcel source) { 120657902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell return new SavedState(source); 120757902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell } 120857902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell 120957902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell @Override 121057902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell public SavedState[] newArray(int size) { 121157902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell return new SavedState[size]; 121257902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell } 121357902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell }; 121457902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell } 121557902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell 12161d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell private class ViewDragCallback extends ViewDragHelper.Callback { 12171d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell private final int mGravity; 12181d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell private ViewDragHelper mDragger; 12191d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 12201732720ad57fe6d01392cd06551f1a25cff0333cAdam Powell private final Runnable mPeekRunnable = new Runnable() { 12211732720ad57fe6d01392cd06551f1a25cff0333cAdam Powell @Override public void run() { 12221732720ad57fe6d01392cd06551f1a25cff0333cAdam Powell peekDrawer(); 12231732720ad57fe6d01392cd06551f1a25cff0333cAdam Powell } 12241732720ad57fe6d01392cd06551f1a25cff0333cAdam Powell }; 12251732720ad57fe6d01392cd06551f1a25cff0333cAdam Powell 12261d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell public ViewDragCallback(int gravity) { 12271d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell mGravity = gravity; 12281d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 12291d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 12301d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell public void setDragger(ViewDragHelper dragger) { 12311d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell mDragger = dragger; 12321d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 12331d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 12341732720ad57fe6d01392cd06551f1a25cff0333cAdam Powell public void removeCallbacks() { 12351732720ad57fe6d01392cd06551f1a25cff0333cAdam Powell DrawerLayout.this.removeCallbacks(mPeekRunnable); 12361732720ad57fe6d01392cd06551f1a25cff0333cAdam Powell } 12371732720ad57fe6d01392cd06551f1a25cff0333cAdam Powell 12381d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell @Override 12391d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell public boolean tryCaptureView(View child, int pointerId) { 12401d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell // Only capture views where the gravity matches what we're looking for. 12411d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell // This lets us use two ViewDragHelpers, one for each side drawer. 12420492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell return isDrawerView(child) && checkDrawerViewGravity(child, mGravity) && 12430492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell getDrawerLockMode(child) == LOCK_MODE_UNLOCKED; 12441d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 12451d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 12461d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell @Override 12471d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell public void onViewDragStateChanged(int state) { 1248b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell updateDrawerState(mGravity, state, mDragger.getCapturedView()); 12491d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 12501d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 12511d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell @Override 12521d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell public void onViewPositionChanged(View changedView, int left, int top, int dx, int dy) { 12531d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell float offset; 12541d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final int childWidth = changedView.getWidth(); 12551d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 12561d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell // This reverses the positioning shown in onLayout. 12571d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell if (checkDrawerViewGravity(changedView, Gravity.LEFT)) { 12581d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell offset = (float) (childWidth + left) / childWidth; 12591d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } else { 12601d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final int width = getWidth(); 12611d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell offset = (float) (width - left) / childWidth; 12621d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 12631d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell setDrawerViewOffset(changedView, offset); 1264b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell changedView.setVisibility(offset == 0 ? INVISIBLE : VISIBLE); 12651d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell invalidate(); 12661d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 12671d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 12681d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell @Override 12691d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell public void onViewCaptured(View capturedChild, int activePointerId) { 12701d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final LayoutParams lp = (LayoutParams) capturedChild.getLayoutParams(); 12711d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell lp.isPeeking = false; 12721d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 12731d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell closeOtherDrawer(); 12741d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 12751d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 12761d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell private void closeOtherDrawer() { 12771d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final int otherGrav = mGravity == Gravity.LEFT ? Gravity.RIGHT : Gravity.LEFT; 12781d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final View toClose = findDrawerWithGravity(otherGrav); 12791d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell if (toClose != null) { 12801d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell closeDrawer(toClose); 12811d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 12821d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 12831d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 12841d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell @Override 12851d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell public void onViewReleased(View releasedChild, float xvel, float yvel) { 12861d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell // Offset is how open the drawer is, therefore left/right values 12871d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell // are reversed from one another. 12881d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final float offset = getDrawerViewOffset(releasedChild); 12891d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final int childWidth = releasedChild.getWidth(); 12901d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 12911d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell int left; 12921d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell if (checkDrawerViewGravity(releasedChild, Gravity.LEFT)) { 12931d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell left = xvel > 0 || xvel == 0 && offset > 0.5f ? 0 : -childWidth; 12941d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } else { 12951d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final int width = getWidth(); 12961d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell left = xvel < 0 || xvel == 0 && offset < 0.5f ? width - childWidth : width; 12971d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 12981d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 12991d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell mDragger.settleCapturedViewAt(left, releasedChild.getTop()); 13001d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell invalidate(); 13011d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 13021d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 13031d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell @Override 13041d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell public void onEdgeTouched(int edgeFlags, int pointerId) { 13051732720ad57fe6d01392cd06551f1a25cff0333cAdam Powell postDelayed(mPeekRunnable, PEEK_DELAY); 13061732720ad57fe6d01392cd06551f1a25cff0333cAdam Powell } 13071732720ad57fe6d01392cd06551f1a25cff0333cAdam Powell 13081732720ad57fe6d01392cd06551f1a25cff0333cAdam Powell private void peekDrawer() { 13091d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final View toCapture; 13101d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final int childLeft; 1311ea7b10f4d5531713506e98c8093e7aab811f21f3Adam Powell final int peekDistance = mDragger.getEdgeSize(); 13121732720ad57fe6d01392cd06551f1a25cff0333cAdam Powell final boolean leftEdge = mGravity == Gravity.LEFT; 1313b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell if (leftEdge) { 13141d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell toCapture = findDrawerWithGravity(Gravity.LEFT); 1315ea7b10f4d5531713506e98c8093e7aab811f21f3Adam Powell childLeft = (toCapture != null ? -toCapture.getWidth() : 0) + peekDistance; 13161d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } else { 13171d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell toCapture = findDrawerWithGravity(Gravity.RIGHT); 1318ea7b10f4d5531713506e98c8093e7aab811f21f3Adam Powell childLeft = getWidth() - peekDistance; 13191d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 13200492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell // Only peek if it would mean making the drawer more visible and the drawer isn't locked 1321b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell if (toCapture != null && ((leftEdge && toCapture.getLeft() < childLeft) || 13220492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell (!leftEdge && toCapture.getLeft() > childLeft)) && 13230492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell getDrawerLockMode(toCapture) == LOCK_MODE_UNLOCKED) { 1324b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell final LayoutParams lp = (LayoutParams) toCapture.getLayoutParams(); 13251d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell mDragger.smoothSlideViewTo(toCapture, childLeft, toCapture.getTop()); 1326b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell lp.isPeeking = true; 13271d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell invalidate(); 13281d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 13291d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell closeOtherDrawer(); 1330cde2707260e8241ffb816a03cbf5d52c28004b8aAdam Powell 1331cde2707260e8241ffb816a03cbf5d52c28004b8aAdam Powell cancelChildViewTouch(); 13321d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 13331d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 13341d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 13351d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell @Override 1336ea7b10f4d5531713506e98c8093e7aab811f21f3Adam Powell public boolean onEdgeLock(int edgeFlags) { 1337ea7b10f4d5531713506e98c8093e7aab811f21f3Adam Powell if (ALLOW_EDGE_LOCK) { 1338ea7b10f4d5531713506e98c8093e7aab811f21f3Adam Powell final View drawer = findDrawerWithGravity(mGravity); 1339ea7b10f4d5531713506e98c8093e7aab811f21f3Adam Powell if (drawer != null && !isDrawerOpen(drawer)) { 1340ea7b10f4d5531713506e98c8093e7aab811f21f3Adam Powell closeDrawer(drawer); 1341ea7b10f4d5531713506e98c8093e7aab811f21f3Adam Powell } 1342ea7b10f4d5531713506e98c8093e7aab811f21f3Adam Powell return true; 1343acc82321ad119706485db342eaa12b225fa9b667Adam Powell } 1344ea7b10f4d5531713506e98c8093e7aab811f21f3Adam Powell return false; 1345acc82321ad119706485db342eaa12b225fa9b667Adam Powell } 1346acc82321ad119706485db342eaa12b225fa9b667Adam Powell 1347acc82321ad119706485db342eaa12b225fa9b667Adam Powell @Override 13481d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell public void onEdgeDragStarted(int edgeFlags, int pointerId) { 13491d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final View toCapture; 13501d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell if ((edgeFlags & ViewDragHelper.EDGE_LEFT) == ViewDragHelper.EDGE_LEFT) { 13511d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell toCapture = findDrawerWithGravity(Gravity.LEFT); 13521d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } else { 13531d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell toCapture = findDrawerWithGravity(Gravity.RIGHT); 13541d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 13551d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 13560492ea23e32dbf509a7613d29e5791fdd44b2135Adam Powell if (toCapture != null && getDrawerLockMode(toCapture) == LOCK_MODE_UNLOCKED) { 13571d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell mDragger.captureChildView(toCapture, pointerId); 13581d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 13591d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 13601d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 13611d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell @Override 13621d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell public int getViewHorizontalDragRange(View child) { 13631d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell return child.getWidth(); 13641d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 13651d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 13661d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell @Override 13671d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell public int clampViewPositionHorizontal(View child, int left, int dx) { 13681d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell if (checkDrawerViewGravity(child, Gravity.LEFT)) { 13691d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell return Math.max(-child.getWidth(), Math.min(left, 0)); 13701d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } else { 13711d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final int width = getWidth(); 13721d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell return Math.max(width - child.getWidth(), Math.min(left, width)); 13731d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 13741d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 137500ca2532981fbd705f947a637ffd967a8d6f733bAdam Powell 137600ca2532981fbd705f947a637ffd967a8d6f733bAdam Powell @Override 137700ca2532981fbd705f947a637ffd967a8d6f733bAdam Powell public int clampViewPositionVertical(View child, int top, int dy) { 137800ca2532981fbd705f947a637ffd967a8d6f733bAdam Powell return child.getTop(); 137900ca2532981fbd705f947a637ffd967a8d6f733bAdam Powell } 13801d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 13811d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 138200ca2532981fbd705f947a637ffd967a8d6f733bAdam Powell public static class LayoutParams extends ViewGroup.MarginLayoutParams { 13831d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 13841d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell public int gravity = Gravity.NO_GRAVITY; 1385b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell float onScreen; 13861d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell boolean isPeeking; 13871d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell boolean knownOpen; 13881d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 13891d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell public LayoutParams(Context c, AttributeSet attrs) { 13901d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell super(c, attrs); 13911d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 13921d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final TypedArray a = c.obtainStyledAttributes(attrs, LAYOUT_ATTRS); 13931d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell this.gravity = a.getInt(0, Gravity.NO_GRAVITY); 13941d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell a.recycle(); 13951d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 13961d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 13971d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell public LayoutParams(int width, int height) { 13981d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell super(width, height); 13991d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 14001d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 14011d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell public LayoutParams(int width, int height, int gravity) { 14021d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell this(width, height); 14031d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell this.gravity = gravity; 14041d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 14051d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 14061d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell public LayoutParams(LayoutParams source) { 14071d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell super(source); 14081d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell this.gravity = source.gravity; 14091d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 14101d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 14111d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell public LayoutParams(ViewGroup.LayoutParams source) { 14121d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell super(source); 14131d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 141400ca2532981fbd705f947a637ffd967a8d6f733bAdam Powell 141500ca2532981fbd705f947a637ffd967a8d6f733bAdam Powell public LayoutParams(ViewGroup.MarginLayoutParams source) { 141600ca2532981fbd705f947a637ffd967a8d6f733bAdam Powell super(source); 141700ca2532981fbd705f947a637ffd967a8d6f733bAdam Powell } 14181d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 14191d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell} 1420