DrawerLayout.java revision 1d26501f0c8e9f3577f651938a03f6b3a1a672c7
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; 241d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powellimport android.support.v4.view.GravityCompat; 251d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powellimport android.support.v4.view.MotionEventCompat; 261d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powellimport android.support.v4.view.ViewCompat; 271d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powellimport android.util.AttributeSet; 281d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powellimport android.util.Log; 291d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powellimport android.view.Gravity; 301d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powellimport android.view.MotionEvent; 311d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powellimport android.view.View; 321d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powellimport android.view.ViewGroup; 331d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 341d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell/** 351d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * DrawerLayout acts as a top-level container for window content that allows for 361d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * interactive "drawer" views to be pulled out from the edge of the window. 371d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * 381d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * <p>Drawer positioning and layout is controlled using the <code>android:layout_gravity</code> 391d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * attribute on child views corresponding to </p> 401d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * 411d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * <p>As per the Android Design guide, any drawers positioned to the left/start should 421d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * always contain content for navigating around the application, whereas any drawers 431d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * positioned to the right/end should always contain actions to take on the current content. 441d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * This preserves the same navigation left, actions right structure present in the Action Bar 451d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * and elsewhere.</p> 461d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell */ 471d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powellpublic class DrawerLayout extends ViewGroup { 481d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell private static final String TAG = "DrawerLayout"; 491d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 501d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell private static final int INVALID_POINTER = -1; 511d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 521d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell /** 531d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * Indicates that any drawers are in an idle, settled state. No animation is in progress. 541d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell */ 551d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell public static final int STATE_IDLE = ViewDragHelper.STATE_IDLE; 561d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 571d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell /** 581d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * Indicates that a drawer is currently being dragged by the user. 591d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell */ 601d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell public static final int STATE_DRAGGING = ViewDragHelper.STATE_DRAGGING; 611d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 621d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell /** 631d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * Indicates that a drawer is in the process of settling to a final position. 641d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell */ 651d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell public static final int STATE_SETTLING = ViewDragHelper.STATE_SETTLING; 661d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 671d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell private static final int MIN_DRAWER_MARGIN = 64; // dp 681d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 691d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell private static final int DRAWER_PEEK_DISTANCE = 16; // dp 701d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 711d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell private static final int DEFAULT_SCRIM_COLOR = 0x99000000; 721d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 731d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell private static final int[] LAYOUT_ATTRS = new int[] { 741d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell android.R.attr.layout_gravity 751d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell }; 761d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 771d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell private int mMinDrawerMargin; 781d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell private int mDrawerPeekDistance; 791d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 801d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell private int mScrimColor = DEFAULT_SCRIM_COLOR; 811d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell private float mScrimOpacity; 821d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell private Paint mScrimPaint = new Paint(); 831d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 841d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell private final ViewDragHelper mLeftDragger; 851d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell private final ViewDragHelper mRightDragger; 861d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell private int mDrawerState; 871d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 881d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell private DrawerListener mListener; 891d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 901d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell private float mInitialMotionX; 911d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell private float mInitialMotionY; 921d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 931d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell /** 941d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * Listener for monitoring events about drawers. 951d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell */ 961d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell public interface DrawerListener { 971d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell /** 981d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * Called when a drawer's position changes. 991d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * @param drawerView The child view that was moved 1001d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * @param slideOffset The new offset of this drawer within its range, from 0-1 1011d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell */ 1021d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell public void onDrawerSlide(View drawerView, float slideOffset); 1031d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 1041d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell /** 1051d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * Called when a drawer has settled in a completely open state. 1061d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * The drawer is interactive at this point. 1071d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * 1081d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * @param drawerView Drawer view that is now open 1091d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell */ 1101d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell public void onDrawerOpened(View drawerView); 1111d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 1121d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell /** 1131d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * Called when a drawer has settled in a completely closed state. 1141d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * 1151d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * @param drawerView Drawer view that is now closed 1161d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell */ 1171d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell public void onDrawerClosed(View drawerView); 1181d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 1191d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell /** 1201d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * Called when the drawer motion state changes. The new state will 1211d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * be one of {@link #STATE_IDLE}, {@link #STATE_DRAGGING} or {@link #STATE_SETTLING}. 1221d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * 1231d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * @param newState The new drawer motion state 1241d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell */ 1251d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell public void onDrawerStateChanged(int newState); 1261d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 1271d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 1281d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell public DrawerLayout(Context context) { 1291d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell this(context, null); 1301d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 1311d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 1321d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell public DrawerLayout(Context context, AttributeSet attrs) { 1331d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell this(context, attrs, 0); 1341d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 1351d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 1361d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell public DrawerLayout(Context context, AttributeSet attrs, int defStyle) { 1371d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell super(context, attrs, defStyle); 1381d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 1391d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final float density = getResources().getDisplayMetrics().density; 1401d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell mMinDrawerMargin = (int) (MIN_DRAWER_MARGIN * density + 0.5f); 1411d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell mDrawerPeekDistance = (int) (DRAWER_PEEK_DISTANCE * density + 0.5f); 1421d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 1431d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final ViewDragCallback leftCallback = new ViewDragCallback(Gravity.LEFT); 1441d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final ViewDragCallback rightCallback = new ViewDragCallback(Gravity.RIGHT); 1451d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 1461d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell mLeftDragger = ViewDragHelper.create(this, 0.5f, leftCallback); 1471d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell mLeftDragger.setEdgeTrackingEnabled(ViewDragHelper.EDGE_LEFT); 1481d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell leftCallback.setDragger(mLeftDragger); 1491d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 1501d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell mRightDragger = ViewDragHelper.create(this, 0.5f, rightCallback); 1511d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell mRightDragger.setEdgeTrackingEnabled(ViewDragHelper.EDGE_RIGHT); 1521d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell rightCallback.setDragger(mRightDragger); 1531d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 1541d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 1551d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell /** 1561d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * Set a listener to be notified of drawer events. 1571d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * 1581d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * @param listener Listener to notify when drawer events occur 1591d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * @see DrawerListener 1601d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell */ 1611d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell public void setDrawerListener(DrawerListener listener) { 1621d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell mListener = listener; 1631d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 1641d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 1651d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell /** 1661d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * Resolve the shared state of all drawers from the component ViewDragHelpers. 1671d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * Should be called whenever a ViewDragHelper's state changes. 1681d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell */ 1691d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell void updateDrawerState(int forGravity) { 1701d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final int leftState = mLeftDragger.getViewDragState(); 1711d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final int rightState = mRightDragger.getViewDragState(); 1721d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 1731d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final int state; 1741d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell if (leftState == STATE_DRAGGING || rightState == STATE_DRAGGING) { 1751d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell state = STATE_DRAGGING; 1761d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } else if (leftState == STATE_SETTLING || rightState == STATE_SETTLING) { 1771d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell state = STATE_SETTLING; 1781d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } else { 1791d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell state = STATE_IDLE; 1801d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 1811d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 1821d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell if (state != mDrawerState) { 1831d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell mDrawerState = state; 1841d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final View activeDrawer = findDrawerWithGravity(forGravity); 1851d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell if (state == STATE_IDLE && activeDrawer != null) { 1861d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final LayoutParams lp = (LayoutParams) activeDrawer.getLayoutParams(); 1871d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell if (lp.onscreen == 0) { 1881d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell dispatchOnDrawerClosed(activeDrawer); 1891d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } else if (lp.onscreen == 1) { 1901d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell dispatchOnDrawerOpened(activeDrawer); 1911d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 1921d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 1931d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell if (mListener != null) { 1941d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell mListener.onDrawerStateChanged(state); 1951d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 1961d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 1971d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 1981d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 1991d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell void dispatchOnDrawerClosed(View drawerView) { 2001d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final LayoutParams lp = (LayoutParams) drawerView.getLayoutParams(); 2011d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell if (lp.knownOpen) { 2021d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell lp.knownOpen = false; 2031d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell if (mListener != null) { 2041d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell mListener.onDrawerClosed(drawerView); 2051d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 2061d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 2071d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 2081d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 2091d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell void dispatchOnDrawerOpened(View drawerView) { 2101d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final LayoutParams lp = (LayoutParams) drawerView.getLayoutParams(); 2111d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell if (!lp.knownOpen) { 2121d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell lp.knownOpen = true; 2131d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell if (mListener != null) { 2141d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell mListener.onDrawerOpened(drawerView); 2151d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 2161d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 2171d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 2181d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 2191d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell void dispatchOnDrawerSlide(View drawerView, float slideOffset) { 2201d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell if (mListener != null) { 2211d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell mListener.onDrawerSlide(drawerView, slideOffset); 2221d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 2231d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 2241d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 2251d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell void setDrawerViewOffset(View drawerView, float slideOffset) { 2261d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final LayoutParams lp = (LayoutParams) drawerView.getLayoutParams(); 2271d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell if (slideOffset == lp.onscreen) { 2281d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell return; 2291d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 2301d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 2311d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell lp.onscreen = slideOffset; 2321d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell dispatchOnDrawerSlide(drawerView, slideOffset); 2331d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 2341d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 2351d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell float getDrawerViewOffset(View drawerView) { 2361d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell return ((LayoutParams) drawerView.getLayoutParams()).onscreen; 2371d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 2381d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 2391d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell int getDrawerViewGravity(View drawerView) { 2401d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final int gravity = ((LayoutParams) drawerView.getLayoutParams()).gravity; 2411d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell return GravityCompat.getAbsoluteGravity(gravity, ViewCompat.getLayoutDirection(drawerView)); 2421d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 2431d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 2441d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell boolean checkDrawerViewGravity(View drawerView, int checkFor) { 2451d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final int absGrav = getDrawerViewGravity(drawerView); 2461d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell return (absGrav & checkFor) == checkFor; 2471d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 2481d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 2491d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell void moveDrawerToOffset(View drawerView, float slideOffset) { 2501d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final float oldOffset = getDrawerViewOffset(drawerView); 2511d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final int width = drawerView.getWidth(); 2521d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final int oldPos = (int) (width * oldOffset); 2531d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final int newPos = (int) (width * slideOffset); 2541d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final int dx = newPos - oldPos; 2551d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 2561d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell drawerView.offsetLeftAndRight(checkDrawerViewGravity(drawerView, Gravity.LEFT) ? dx : -dx); 2571d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell setDrawerViewOffset(drawerView, slideOffset); 2581d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 2591d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 2601d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell View findDrawerWithGravity(int gravity) { 2611d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final int childCount = getChildCount(); 2621d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell for (int i = 0; i < childCount; i++) { 2631d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final View child = getChildAt(i); 2641d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final int childGravity = getDrawerViewGravity(child); 2651d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell if ((childGravity & Gravity.HORIZONTAL_GRAVITY_MASK) == 2661d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell (gravity & Gravity.HORIZONTAL_GRAVITY_MASK)) { 2671d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell return child; 2681d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 2691d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 2701d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell return null; 2711d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 2721d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 2731d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell /** 2741d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * Simple gravity to string - only supports LEFT and RIGHT for debugging output. 2751d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * 2761d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * @param gravity Absolute gravity value 2771d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * @return LEFT or RIGHT as appropriate, or a hex string 2781d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell */ 2791d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell static String gravityToString(int gravity) { 2801d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell if ((gravity & Gravity.LEFT) == Gravity.LEFT) { 2811d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell return "LEFT"; 2821d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 2831d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell if ((gravity & Gravity.RIGHT) == Gravity.RIGHT) { 2841d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell return "RIGHT"; 2851d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 2861d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell return Integer.toHexString(gravity); 2871d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 2881d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 2891d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell @Override 2901d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 2911d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final int widthMode = MeasureSpec.getMode(widthMeasureSpec); 2921d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final int heightMode = MeasureSpec.getMode(heightMeasureSpec); 2931d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final int widthSize = MeasureSpec.getSize(widthMeasureSpec); 2941d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final int heightSize = MeasureSpec.getSize(heightMeasureSpec); 2951d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 2961d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell if (widthMode != MeasureSpec.EXACTLY || heightMode != MeasureSpec.EXACTLY) { 2971d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell throw new IllegalArgumentException( 2981d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell "DrawerLayout must be measured with MeasureSpec.EXACTLY."); 2991d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 3001d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 3011d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell setMeasuredDimension(widthSize, heightSize); 3021d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 3031d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell // Gravity value for each drawer we've seen. Only one of each permitted. 3041d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell int foundDrawers = 0; 3051d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final int childCount = getChildCount(); 3061d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell for (int i = 0; i < childCount; i++) { 3071d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final View child = getChildAt(i); 3081d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 3091d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell if (child.getVisibility() == GONE) { 3101d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell continue; 3111d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 3121d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 3131d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell if (isContentView(child)) { 3141d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell // Content views get measured at exactly the layout's size. 3151d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell child.measure(widthMeasureSpec, heightMeasureSpec); 3161d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } else if (isDrawerView(child)) { 3171d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final int childGravity = 3181d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell getDrawerViewGravity(child) & Gravity.HORIZONTAL_GRAVITY_MASK; 3191d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell if ((foundDrawers & childGravity) != 0) { 3201d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell throw new IllegalStateException("Child drawer has absolute gravity " + 3211d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell gravityToString(childGravity) + " but this " + TAG + " already has a " + 3221d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell "drawer view along that edge"); 3231d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 3241d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final int drawerWidthSpec = getChildMeasureSpec(widthMeasureSpec, mMinDrawerMargin, 3251d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell child.getLayoutParams().width); 3261d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell child.measure(drawerWidthSpec, heightMeasureSpec); 3271d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } else { 3281d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell throw new IllegalStateException("Child " + child + " at index " + i + 3291d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell " does not have a valid layout_gravity - must be Gravity.LEFT, " + 3301d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell "Gravity.RIGHT or Gravity.NO_GRAVITY"); 3311d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 3321d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 3331d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 3341d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 3351d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell @Override 3361d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell protected void onLayout(boolean changed, int l, int t, int r, int b) { 3371d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final int childCount = getChildCount(); 3381d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell for (int i = 0; i < childCount; i++) { 3391d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final View child = getChildAt(i); 3401d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 3411d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell if (child.getVisibility() == GONE) { 3421d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell continue; 3431d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 3441d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 3451d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell if (isContentView(child)) { 3461d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell child.layout(0, 0, child.getMeasuredWidth(), child.getMeasuredHeight()); 3471d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } else { // Drawer, if it wasn't onMeasure would have thrown an exception. 3481d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final LayoutParams lp = (LayoutParams) child.getLayoutParams(); 3491d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 3501d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final int childWidth = child.getMeasuredWidth(); 3511d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell int childLeft; 3521d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 3531d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell if (checkDrawerViewGravity(child, Gravity.LEFT)) { 3541d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell childLeft = -childWidth + (int) (childWidth * lp.onscreen); 3551d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } else { // Right; onMeasure checked for us. 3561d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell childLeft = r - l - (int) (childWidth * lp.onscreen); 3571d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 3581d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 3591d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell child.layout(childLeft, 0, childLeft + childWidth, child.getMeasuredHeight()); 3601d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 3611d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 3621d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 3631d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 3641d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell @Override 3651d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell public void computeScroll() { 3661d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final int childCount = getChildCount(); 3671d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell float scrimOpacity = 0; 3681d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell for (int i = 0; i < childCount; i++) { 3691d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final float onscreen = ((LayoutParams) getChildAt(i).getLayoutParams()).onscreen; 3701d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell scrimOpacity = Math.max(scrimOpacity, onscreen); 3711d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 3721d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell mScrimOpacity = scrimOpacity; 3731d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 3741d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell // "|" used on purpose; both need to run. 3751d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell if (mLeftDragger.continueSettling(true) | mRightDragger.continueSettling(true)) { 3761d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell ViewCompat.postInvalidateOnAnimation(this); 3771d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 3781d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 3791d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 3801d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell @Override 3811d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell protected boolean drawChild(Canvas canvas, View child, long drawingTime) { 3821d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final int restoreCount = canvas.save(); 3831d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final boolean result = super.drawChild(canvas, child, drawingTime); 3841d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell canvas.restoreToCount(restoreCount); 3851d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell if (mScrimOpacity > 0 && isContentView(child)) { 3861d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final int baseAlpha = (mScrimColor & 0xff000000) >>> 24; 3871d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final int imag = (int) (baseAlpha * mScrimOpacity); 3881d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final int color = imag << 24 | (mScrimColor & 0xffffff); 3891d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell mScrimPaint.setColor(color); 3901d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 3911d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell canvas.drawRect(0, 0, getWidth(), getHeight(), mScrimPaint); 3921d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 3931d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell return result; 3941d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 3951d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 3961d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell boolean isContentView(View child) { 3971d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell return ((LayoutParams) child.getLayoutParams()).gravity == Gravity.NO_GRAVITY; 3981d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 3991d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 4001d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell boolean isDrawerView(View child) { 4011d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final int gravity = ((LayoutParams) child.getLayoutParams()).gravity; 4021d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final int absGravity = GravityCompat.getAbsoluteGravity(gravity, 4031d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell ViewCompat.getLayoutDirection(child)); 4041d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell return (absGravity & (Gravity.LEFT | Gravity.RIGHT)) != 0; 4051d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 4061d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 4071d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell @Override 4081d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell public boolean onInterceptTouchEvent(MotionEvent ev) { 4091d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final int action = MotionEventCompat.getActionMasked(ev); 4101d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 4111d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell // "|" used deliberately here; both methods should be invoked. 4121d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final boolean interceptForDrag = mLeftDragger.shouldInterceptTouchEvent(ev) | 4131d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell mRightDragger.shouldInterceptTouchEvent(ev); 4141d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 4151d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell boolean interceptForTap = false; 4161d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 4171d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell switch (action) { 4181d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell case MotionEvent.ACTION_DOWN: { 4191d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final float x = ev.getX(); 4201d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final float y = ev.getY(); 4211d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell mInitialMotionX = x; 4221d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell mInitialMotionY = y; 4231d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell if (mScrimOpacity > 0 && 4241d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell isContentView(mLeftDragger.findTopChildUnder((int) x, (int) y))) { 4251d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell interceptForTap = true; 4261d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 4271d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell break; 4281d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 4291d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 4301d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell case MotionEvent.ACTION_CANCEL: 4311d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell case MotionEvent.ACTION_UP: { 4321d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell closeDrawers(true); 4331d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 4341d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 4351d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell return interceptForDrag || interceptForTap; 4361d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 4371d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 4381d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell @Override 4391d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell public void requestDisallowInterceptTouchEvent(boolean disallowIntercept) { 4401d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell super.requestDisallowInterceptTouchEvent(disallowIntercept); 4411d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell if (disallowIntercept) { 4421d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell closeDrawers(true); 4431d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 4441d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 4451d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 4461d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell @Override 4471d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell public boolean onTouchEvent(MotionEvent ev) { 4481d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell mLeftDragger.processTouchEvent(ev); 4491d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell mRightDragger.processTouchEvent(ev); 4501d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 4511d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final int action = ev.getAction(); 4521d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell boolean wantTouchEvents = true; 4531d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 4541d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell switch (action & MotionEventCompat.ACTION_MASK) { 4551d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell case MotionEvent.ACTION_DOWN: { 4561d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final float x = ev.getX(); 4571d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final float y = ev.getY(); 4581d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell mInitialMotionX = x; 4591d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell mInitialMotionY = y; 4601d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell break; 4611d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 4621d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 4631d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell case MotionEvent.ACTION_UP: { 4641d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final float x = ev.getX(); 4651d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final float y = ev.getY(); 4661d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell boolean peekingOnly = true; 4671d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell if (isContentView(mLeftDragger.findTopChildUnder((int) x, (int) y))) { 4681d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final float dx = x - mInitialMotionX; 4691d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final float dy = y - mInitialMotionY; 4701d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final int slop = mLeftDragger.getTouchSlop(); 4711d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell if (dx * dx + dy * dy < slop * slop) { 4721d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell // Taps close a dimmed open pane. 4731d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell peekingOnly = false; 4741d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 4751d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 4761d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell closeDrawers(peekingOnly); 4771d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell break; 4781d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 4791d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 4801d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell case MotionEvent.ACTION_CANCEL: { 4811d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell closeDrawers(true); 4821d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell break; 4831d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 4841d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 4851d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 4861d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell return wantTouchEvents; 4871d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 4881d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 4891d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell /** 4901d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * Close all currently open drawer views by animating them out of view. 4911d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell */ 4921d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell public void closeDrawers() { 4931d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell closeDrawers(false); 4941d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 4951d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 4961d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell void closeDrawers(boolean peekingOnly) { 4971d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell boolean needsInvalidate = false; 4981d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final int childCount = getChildCount(); 4991d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell for (int i = 0; i < childCount; i++) { 5001d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final View child = getChildAt(i); 5011d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final LayoutParams lp = (LayoutParams) child.getLayoutParams(); 5021d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 5031d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell if (!isDrawerView(child) || (peekingOnly && !lp.isPeeking)) { 5041d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell continue; 5051d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 5061d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 5071d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final int childWidth = child.getWidth(); 5081d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 5091d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell if (checkDrawerViewGravity(child, Gravity.LEFT)) { 5101d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell needsInvalidate |= mLeftDragger.smoothSlideViewTo(child, 5111d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell -childWidth, child.getTop()); 5121d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } else { 5131d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell needsInvalidate |= mRightDragger.smoothSlideViewTo(child, 5141d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell getWidth(), child.getTop()); 5151d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 5161d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 5171d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell lp.isPeeking = false; 5181d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 5191d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 5201d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell if (needsInvalidate) { 5211d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell invalidate(); 5221d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 5231d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 5241d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 5251d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell /** 5261d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * Open the specified drawer view by animating it into view. 5271d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * 5281d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * @param drawerView Drawer view to open 5291d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell */ 5301d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell public void openDrawer(View drawerView) { 5311d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell if (!isDrawerView(drawerView)) { 5321d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell throw new IllegalArgumentException("View " + drawerView + " is not a sliding drawer"); 5331d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 5341d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 5351d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell if (checkDrawerViewGravity(drawerView, Gravity.LEFT)) { 5361d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell mLeftDragger.smoothSlideViewTo(drawerView, 0, drawerView.getTop()); 5371d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } else { 5381d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell mRightDragger.smoothSlideViewTo(drawerView, getWidth() - drawerView.getWidth(), 5391d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell drawerView.getTop()); 5401d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 5411d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell invalidate(); 5421d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 5431d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 5441d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell /** 5451d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * Open the specified drawer by animating it out of view. 5461d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * 5471d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * @param gravity Gravity.LEFT to move the left drawer or Gravity.RIGHT for the right. 5481d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * GravityCompat.START or GravityCompat.END may also be used. 5491d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell */ 5501d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell public void openDrawer(int gravity) { 5511d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final int absGravity = GravityCompat.getAbsoluteGravity(gravity, 5521d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell ViewCompat.getLayoutDirection(this)); 5531d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final View drawerView = findDrawerWithGravity(absGravity); 5541d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 5551d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell if (drawerView == null) { 5561d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell throw new IllegalArgumentException("No drawer view found with absolute gravity " + 5571d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell gravityToString(absGravity)); 5581d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 5591d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell openDrawer(drawerView); 5601d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 5611d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 5621d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell /** 5631d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * Close the specified drawer view by animating it into view. 5641d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * 5651d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * @param drawerView Drawer view to close 5661d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell */ 5671d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell public void closeDrawer(View drawerView) { 5681d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell if (!isDrawerView(drawerView)) { 5691d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell throw new IllegalArgumentException("View " + drawerView + " is not a sliding drawer"); 5701d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 5711d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 5721d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell if (checkDrawerViewGravity(drawerView, Gravity.LEFT)) { 5731d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell mLeftDragger.smoothSlideViewTo(drawerView, -drawerView.getWidth(), drawerView.getTop()); 5741d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } else { 5751d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell mRightDragger.smoothSlideViewTo(drawerView, getWidth(), drawerView.getTop()); 5761d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 5771d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell invalidate(); 5781d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 5791d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 5801d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell /** 5811d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * Close the specified drawer by animating it out of view. 5821d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * 5831d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * @param gravity Gravity.LEFT to move the left drawer or Gravity.RIGHT for the right. 5841d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * GravityCompat.START or GravityCompat.END may also be used. 5851d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell */ 5861d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell public void closeDrawer(int gravity) { 5871d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final int absGravity = GravityCompat.getAbsoluteGravity(gravity, 5881d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell ViewCompat.getLayoutDirection(this)); 5891d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final View drawerView = findDrawerWithGravity(absGravity); 5901d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 5911d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell if (drawerView == null) { 5921d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell throw new IllegalArgumentException("No drawer view found with absolute gravity " + 5931d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell gravityToString(absGravity)); 5941d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 5951d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell closeDrawer(drawerView); 5961d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 5971d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 5981d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell @Override 5991d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell protected ViewGroup.LayoutParams generateDefaultLayoutParams() { 6001d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell return new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT); 6011d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 6021d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 6031d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell @Override 6041d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell protected ViewGroup.LayoutParams generateLayoutParams(ViewGroup.LayoutParams p) { 6051d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell return p instanceof LayoutParams 6061d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell ? new LayoutParams((LayoutParams) p) 6071d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell : new LayoutParams(p); 6081d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 6091d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 6101d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell @Override 6111d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell protected boolean checkLayoutParams(ViewGroup.LayoutParams p) { 6121d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell return p instanceof LayoutParams && super.checkLayoutParams(p); 6131d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 6141d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 6151d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell @Override 6161d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell public ViewGroup.LayoutParams generateLayoutParams(AttributeSet attrs) { 6171d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell return new LayoutParams(getContext(), attrs); 6181d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 6191d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 6201d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell private class ViewDragCallback extends ViewDragHelper.Callback { 6211d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 6221d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell private final int mGravity; 6231d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell private ViewDragHelper mDragger; 6241d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 6251d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell public ViewDragCallback(int gravity) { 6261d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell mGravity = gravity; 6271d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 6281d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 6291d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell public void setDragger(ViewDragHelper dragger) { 6301d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell mDragger = dragger; 6311d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 6321d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 6331d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell @Override 6341d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell public boolean tryCaptureView(View child, int pointerId) { 6351d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell // Only capture views where the gravity matches what we're looking for. 6361d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell // This lets us use two ViewDragHelpers, one for each side drawer. 6371d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell return isDrawerView(child) && checkDrawerViewGravity(child, mGravity); 6381d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 6391d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 6401d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell @Override 6411d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell public void onViewDragStateChanged(int state) { 6421d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell updateDrawerState(mGravity); 6431d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 6441d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 6451d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell @Override 6461d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell public void onViewPositionChanged(View changedView, int left, int top, int dx, int dy) { 6471d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell float offset; 6481d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final int childWidth = changedView.getWidth(); 6491d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 6501d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell // This reverses the positioning shown in onLayout. 6511d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell if (checkDrawerViewGravity(changedView, Gravity.LEFT)) { 6521d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell offset = (float) (childWidth + left) / childWidth; 6531d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } else { 6541d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final int width = getWidth(); 6551d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell offset = (float) (width - left) / childWidth; 6561d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 6571d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell setDrawerViewOffset(changedView, offset); 6581d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell invalidate(); 6591d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 6601d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 6611d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell @Override 6621d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell public void onViewCaptured(View capturedChild, int activePointerId) { 6631d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final LayoutParams lp = (LayoutParams) capturedChild.getLayoutParams(); 6641d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell lp.isPeeking = false; 6651d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 6661d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell closeOtherDrawer(); 6671d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 6681d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 6691d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell private void closeOtherDrawer() { 6701d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final int otherGrav = mGravity == Gravity.LEFT ? Gravity.RIGHT : Gravity.LEFT; 6711d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final View toClose = findDrawerWithGravity(otherGrav); 6721d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell if (toClose != null) { 6731d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell closeDrawer(toClose); 6741d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 6751d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 6761d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 6771d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell @Override 6781d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell public void onViewReleased(View releasedChild, float xvel, float yvel) { 6791d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell // Offset is how open the drawer is, therefore left/right values 6801d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell // are reversed from one another. 6811d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final float offset = getDrawerViewOffset(releasedChild); 6821d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final int childWidth = releasedChild.getWidth(); 6831d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 6841d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell int left; 6851d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell if (checkDrawerViewGravity(releasedChild, Gravity.LEFT)) { 6861d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell left = xvel > 0 || xvel == 0 && offset > 0.5f ? 0 : -childWidth; 6871d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } else { 6881d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final int width = getWidth(); 6891d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell left = xvel < 0 || xvel == 0 && offset < 0.5f ? width - childWidth : width; 6901d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 6911d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 6921d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell mDragger.settleCapturedViewAt(left, releasedChild.getTop()); 6931d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell invalidate(); 6941d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 6951d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 6961d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell @Override 6971d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell public void onEdgeTouched(int edgeFlags, int pointerId) { 6981d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final View toCapture; 6991d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final int childLeft; 7001d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell if ((edgeFlags & ViewDragHelper.EDGE_LEFT) == ViewDragHelper.EDGE_LEFT) { 7011d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell toCapture = findDrawerWithGravity(Gravity.LEFT); 7021d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell childLeft = -toCapture.getWidth() + mDrawerPeekDistance; 7031d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } else { 7041d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell toCapture = findDrawerWithGravity(Gravity.RIGHT); 7051d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell childLeft = getWidth() - mDrawerPeekDistance; 7061d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 7071d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 7081d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell if (toCapture != null) { 7091d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell mDragger.smoothSlideViewTo(toCapture, childLeft, toCapture.getTop()); 7101d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell ((LayoutParams) toCapture.getLayoutParams()).isPeeking = true; 7111d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell invalidate(); 7121d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 7131d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell closeOtherDrawer(); 7141d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 7151d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 7161d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 7171d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell @Override 7181d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell public void onEdgeDragStarted(int edgeFlags, int pointerId) { 7191d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final View toCapture; 7201d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell if ((edgeFlags & ViewDragHelper.EDGE_LEFT) == ViewDragHelper.EDGE_LEFT) { 7211d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell toCapture = findDrawerWithGravity(Gravity.LEFT); 7221d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } else { 7231d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell toCapture = findDrawerWithGravity(Gravity.RIGHT); 7241d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 7251d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 7261d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell if (toCapture != null) { 7271d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell mDragger.captureChildView(toCapture, pointerId); 7281d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 7291d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 7301d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 7311d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell @Override 7321d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell public int getViewHorizontalDragRange(View child) { 7331d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell return child.getWidth(); 7341d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 7351d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 7361d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell @Override 7371d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell public int clampViewPositionHorizontal(View child, int left, int dx) { 7381d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell if (checkDrawerViewGravity(child, Gravity.LEFT)) { 7391d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell return Math.max(-child.getWidth(), Math.min(left, 0)); 7401d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } else { 7411d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final int width = getWidth(); 7421d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell return Math.max(width - child.getWidth(), Math.min(left, width)); 7431d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 7441d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 7451d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 7461d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 7471d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell public static class LayoutParams extends ViewGroup.LayoutParams { 7481d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 7491d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell public int gravity = Gravity.NO_GRAVITY; 7501d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell float onscreen; 7511d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell boolean isPeeking; 7521d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell boolean knownOpen; 7531d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 7541d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell public LayoutParams(Context c, AttributeSet attrs) { 7551d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell super(c, attrs); 7561d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 7571d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final TypedArray a = c.obtainStyledAttributes(attrs, LAYOUT_ATTRS); 7581d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell this.gravity = a.getInt(0, Gravity.NO_GRAVITY); 7591d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell a.recycle(); 7601d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 7611d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 7621d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell public LayoutParams(int width, int height) { 7631d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell super(width, height); 7641d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 7651d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 7661d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell public LayoutParams(int width, int height, int gravity) { 7671d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell this(width, height); 7681d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell this.gravity = gravity; 7691d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 7701d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 7711d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell public LayoutParams(LayoutParams source) { 7721d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell super(source); 7731d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell this.gravity = source.gravity; 7741d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 7751d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 7761d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell public LayoutParams(ViewGroup.LayoutParams source) { 7771d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell super(source); 7781d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 7791d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 7801d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell} 781