DrawerLayout.java revision 8bc268e9c40e4ae375a0d65dc1293dccc541186f
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; 281d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powellimport android.support.v4.view.GravityCompat; 29791f31bbba40b8b51694a1b2cdc804f360786ed1Adam Powellimport android.support.v4.view.KeyEventCompat; 301d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powellimport android.support.v4.view.MotionEventCompat; 311d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powellimport android.support.v4.view.ViewCompat; 321d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powellimport android.util.AttributeSet; 331d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powellimport android.view.Gravity; 34791f31bbba40b8b51694a1b2cdc804f360786ed1Adam Powellimport android.view.KeyEvent; 351d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powellimport android.view.MotionEvent; 361d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powellimport android.view.View; 371d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powellimport android.view.ViewGroup; 381d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 391d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell/** 401d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * DrawerLayout acts as a top-level container for window content that allows for 411d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * interactive "drawer" views to be pulled out from the edge of the window. 421d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * 431d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * <p>Drawer positioning and layout is controlled using the <code>android:layout_gravity</code> 441d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * attribute on child views corresponding to </p> 451d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * 461d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * <p>As per the Android Design guide, any drawers positioned to the left/start should 471d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * always contain content for navigating around the application, whereas any drawers 481d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * positioned to the right/end should always contain actions to take on the current content. 491d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * This preserves the same navigation left, actions right structure present in the Action Bar 501d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * and elsewhere.</p> 511d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell */ 521d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powellpublic class DrawerLayout extends ViewGroup { 531d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell private static final String TAG = "DrawerLayout"; 541d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 551d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell private static final int INVALID_POINTER = -1; 561d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 571d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell /** 581d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * Indicates that any drawers are in an idle, settled state. No animation is in progress. 591d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell */ 601d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell public static final int STATE_IDLE = ViewDragHelper.STATE_IDLE; 611d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 621d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell /** 631d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * Indicates that a drawer is currently being dragged by the user. 641d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell */ 651d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell public static final int STATE_DRAGGING = ViewDragHelper.STATE_DRAGGING; 661d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 671d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell /** 681d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * Indicates that a drawer is in the process of settling to a final position. 691d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell */ 701d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell public static final int STATE_SETTLING = ViewDragHelper.STATE_SETTLING; 711d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 721d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell private static final int MIN_DRAWER_MARGIN = 64; // dp 731d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 741d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell private static final int DRAWER_PEEK_DISTANCE = 16; // dp 751d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 761d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell private static final int DEFAULT_SCRIM_COLOR = 0x99000000; 771d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 781d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell private static final int[] LAYOUT_ATTRS = new int[] { 791d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell android.R.attr.layout_gravity 801d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell }; 811d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 821d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell private int mMinDrawerMargin; 831d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell private int mDrawerPeekDistance; 841d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 851d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell private int mScrimColor = DEFAULT_SCRIM_COLOR; 861d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell private float mScrimOpacity; 871d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell private Paint mScrimPaint = new Paint(); 881d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 891d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell private final ViewDragHelper mLeftDragger; 901d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell private final ViewDragHelper mRightDragger; 911d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell private int mDrawerState; 92b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell private boolean mInLayout; 9357902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell private boolean mFirstLayout = true; 941d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 951d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell private DrawerListener mListener; 961d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 971d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell private float mInitialMotionX; 981d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell private float mInitialMotionY; 991d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 100b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell private Drawable mShadowLeft; 101b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell private Drawable mShadowRight; 102b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell 1031d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell /** 1041d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * Listener for monitoring events about drawers. 1051d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell */ 1061d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell public interface DrawerListener { 1071d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell /** 1081d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * Called when a drawer's position changes. 1091d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * @param drawerView The child view that was moved 1101d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * @param slideOffset The new offset of this drawer within its range, from 0-1 1111d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell */ 1121d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell public void onDrawerSlide(View drawerView, float slideOffset); 1131d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 1141d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell /** 1151d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * Called when a drawer has settled in a completely open state. 1161d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * The drawer is interactive at this point. 1171d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * 1181d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * @param drawerView Drawer view that is now open 1191d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell */ 1201d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell public void onDrawerOpened(View drawerView); 1211d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 1221d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell /** 1231d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * Called when a drawer has settled in a completely closed state. 1241d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * 1251d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * @param drawerView Drawer view that is now closed 1261d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell */ 1271d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell public void onDrawerClosed(View drawerView); 1281d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 1291d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell /** 1301d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * Called when the drawer motion state changes. The new state will 1311d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * be one of {@link #STATE_IDLE}, {@link #STATE_DRAGGING} or {@link #STATE_SETTLING}. 1321d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * 1331d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * @param newState The new drawer motion state 1341d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell */ 1351d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell public void onDrawerStateChanged(int newState); 1361d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 1371d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 138b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell /** 139b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell * Stub/no-op implementations of all methods of {@link DrawerListener}. 140b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell * Override this if you only care about a few of the available callback methods. 141b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell */ 142b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell public static abstract class SimpleDrawerListener implements DrawerListener { 143b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell @Override 144b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell public void onDrawerSlide(View drawerView, float slideOffset) { 145b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell } 146b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell 147b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell @Override 148b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell public void onDrawerOpened(View drawerView) { 149b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell } 150b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell 151b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell @Override 152b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell public void onDrawerClosed(View drawerView) { 153b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell } 154b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell 155b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell @Override 156b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell public void onDrawerStateChanged(int newState) { 157b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell } 158b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell } 159b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell 1601d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell public DrawerLayout(Context context) { 1611d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell this(context, null); 1621d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 1631d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 1641d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell public DrawerLayout(Context context, AttributeSet attrs) { 1651d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell this(context, attrs, 0); 1661d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 1671d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 1681d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell public DrawerLayout(Context context, AttributeSet attrs, int defStyle) { 1691d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell super(context, attrs, defStyle); 1701d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 1711d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final float density = getResources().getDisplayMetrics().density; 1721d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell mMinDrawerMargin = (int) (MIN_DRAWER_MARGIN * density + 0.5f); 1731d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell mDrawerPeekDistance = (int) (DRAWER_PEEK_DISTANCE * density + 0.5f); 1741d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 1751d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final ViewDragCallback leftCallback = new ViewDragCallback(Gravity.LEFT); 1761d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final ViewDragCallback rightCallback = new ViewDragCallback(Gravity.RIGHT); 1771d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 1781d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell mLeftDragger = ViewDragHelper.create(this, 0.5f, leftCallback); 1791d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell mLeftDragger.setEdgeTrackingEnabled(ViewDragHelper.EDGE_LEFT); 1801d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell leftCallback.setDragger(mLeftDragger); 1811d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 1821d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell mRightDragger = ViewDragHelper.create(this, 0.5f, rightCallback); 1831d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell mRightDragger.setEdgeTrackingEnabled(ViewDragHelper.EDGE_RIGHT); 1841d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell rightCallback.setDragger(mRightDragger); 185791f31bbba40b8b51694a1b2cdc804f360786ed1Adam Powell 186791f31bbba40b8b51694a1b2cdc804f360786ed1Adam Powell // So that we can catch the back button 187791f31bbba40b8b51694a1b2cdc804f360786ed1Adam Powell setFocusableInTouchMode(true); 1881d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 1891d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 1901d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell /** 191b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell * Set a simple drawable used for the left or right shadow. 192b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell * The drawable provided must have a nonzero intrinsic width. 193b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell * 194b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell * @param shadowDrawable Shadow drawable to use at the edge of a drawer 195b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell * @param gravity Which drawer the shadow should apply to 196b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell */ 197b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell public void setDrawerShadow(Drawable shadowDrawable, int gravity) { 198b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell /* 199b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell * TODO Someone someday might want to set more complex drawables here. 200b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell * They're probably nuts, but we might want to consider registering callbacks, 201b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell * setting states, etc. properly. 202b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell */ 203b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell 204b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell final int absGravity = GravityCompat.getAbsoluteGravity(gravity, 205b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell ViewCompat.getLayoutDirection(this)); 206b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell if ((absGravity & Gravity.LEFT) == Gravity.LEFT) { 207b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell mShadowLeft = shadowDrawable; 208b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell invalidate(); 209b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell } 210b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell if ((absGravity & Gravity.RIGHT) == Gravity.RIGHT) { 211b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell mShadowRight = shadowDrawable; 212b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell invalidate(); 213b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell } 214b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell } 215b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell 216b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell /** 217b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell * Set a simple drawable used for the left or right shadow. 218b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell * The drawable provided must have a nonzero intrinsic width. 219b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell * 220b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell * @param resId Resource id of a shadow drawable to use at the edge of a drawer 221b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell * @param gravity Which drawer the shadow should apply to 222b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell */ 223b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell public void setDrawerShadow(int resId, int gravity) { 224b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell setDrawerShadow(getResources().getDrawable(resId), gravity); 225b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell } 226b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell 227b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell /** 2281d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * Set a listener to be notified of drawer events. 2291d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * 2301d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * @param listener Listener to notify when drawer events occur 2311d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * @see DrawerListener 2321d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell */ 2331d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell public void setDrawerListener(DrawerListener listener) { 2341d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell mListener = listener; 2351d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 2361d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 2371d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell /** 2381d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * Resolve the shared state of all drawers from the component ViewDragHelpers. 2391d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * Should be called whenever a ViewDragHelper's state changes. 2401d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell */ 241b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell void updateDrawerState(int forGravity, int activeState, View activeDrawer) { 2421d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final int leftState = mLeftDragger.getViewDragState(); 2431d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final int rightState = mRightDragger.getViewDragState(); 2441d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 2451d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final int state; 2461d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell if (leftState == STATE_DRAGGING || rightState == STATE_DRAGGING) { 2471d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell state = STATE_DRAGGING; 2481d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } else if (leftState == STATE_SETTLING || rightState == STATE_SETTLING) { 2491d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell state = STATE_SETTLING; 2501d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } else { 2511d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell state = STATE_IDLE; 2521d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 2531d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 254b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell if (activeDrawer != null && activeState == STATE_IDLE) { 255b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell final LayoutParams lp = (LayoutParams) activeDrawer.getLayoutParams(); 256b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell if (lp.onScreen == 0) { 257b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell dispatchOnDrawerClosed(activeDrawer); 258b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell } else if (lp.onScreen == 1) { 259b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell dispatchOnDrawerOpened(activeDrawer); 260b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell } 261b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell } 262b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell 2631d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell if (state != mDrawerState) { 2641d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell mDrawerState = state; 265b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell 2661d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell if (mListener != null) { 2671d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell mListener.onDrawerStateChanged(state); 2681d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 2691d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 2701d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 2711d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 2721d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell void dispatchOnDrawerClosed(View drawerView) { 2731d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final LayoutParams lp = (LayoutParams) drawerView.getLayoutParams(); 2741d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell if (lp.knownOpen) { 2751d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell lp.knownOpen = false; 2761d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell if (mListener != null) { 2771d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell mListener.onDrawerClosed(drawerView); 2781d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 2791d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 2801d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 2811d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 2821d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell void dispatchOnDrawerOpened(View drawerView) { 2831d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final LayoutParams lp = (LayoutParams) drawerView.getLayoutParams(); 2841d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell if (!lp.knownOpen) { 2851d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell lp.knownOpen = true; 2861d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell if (mListener != null) { 2871d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell mListener.onDrawerOpened(drawerView); 2881d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 2891d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 2901d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 2911d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 2921d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell void dispatchOnDrawerSlide(View drawerView, float slideOffset) { 2931d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell if (mListener != null) { 2941d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell mListener.onDrawerSlide(drawerView, slideOffset); 2951d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 2961d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 2971d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 2981d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell void setDrawerViewOffset(View drawerView, float slideOffset) { 2991d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final LayoutParams lp = (LayoutParams) drawerView.getLayoutParams(); 300b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell if (slideOffset == lp.onScreen) { 3011d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell return; 3021d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 3031d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 304b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell lp.onScreen = slideOffset; 3051d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell dispatchOnDrawerSlide(drawerView, slideOffset); 3061d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 3071d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 3081d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell float getDrawerViewOffset(View drawerView) { 309b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell return ((LayoutParams) drawerView.getLayoutParams()).onScreen; 3101d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 3111d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 3121d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell int getDrawerViewGravity(View drawerView) { 3131d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final int gravity = ((LayoutParams) drawerView.getLayoutParams()).gravity; 3141d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell return GravityCompat.getAbsoluteGravity(gravity, ViewCompat.getLayoutDirection(drawerView)); 3151d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 3161d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 3171d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell boolean checkDrawerViewGravity(View drawerView, int checkFor) { 3181d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final int absGrav = getDrawerViewGravity(drawerView); 3191d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell return (absGrav & checkFor) == checkFor; 3201d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 3211d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 3221d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell void moveDrawerToOffset(View drawerView, float slideOffset) { 3231d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final float oldOffset = getDrawerViewOffset(drawerView); 3241d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final int width = drawerView.getWidth(); 3251d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final int oldPos = (int) (width * oldOffset); 3261d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final int newPos = (int) (width * slideOffset); 3271d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final int dx = newPos - oldPos; 3281d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 3291d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell drawerView.offsetLeftAndRight(checkDrawerViewGravity(drawerView, Gravity.LEFT) ? dx : -dx); 3301d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell setDrawerViewOffset(drawerView, slideOffset); 3311d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 3321d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 3331d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell View findDrawerWithGravity(int gravity) { 3341d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final int childCount = getChildCount(); 3351d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell for (int i = 0; i < childCount; i++) { 3361d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final View child = getChildAt(i); 3371d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final int childGravity = getDrawerViewGravity(child); 3381d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell if ((childGravity & Gravity.HORIZONTAL_GRAVITY_MASK) == 3391d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell (gravity & Gravity.HORIZONTAL_GRAVITY_MASK)) { 3401d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell return child; 3411d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 3421d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 3431d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell return null; 3441d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 3451d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 3461d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell /** 3471d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * Simple gravity to string - only supports LEFT and RIGHT for debugging output. 3481d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * 3491d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * @param gravity Absolute gravity value 3501d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * @return LEFT or RIGHT as appropriate, or a hex string 3511d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell */ 3521d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell static String gravityToString(int gravity) { 3531d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell if ((gravity & Gravity.LEFT) == Gravity.LEFT) { 3541d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell return "LEFT"; 3551d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 3561d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell if ((gravity & Gravity.RIGHT) == Gravity.RIGHT) { 3571d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell return "RIGHT"; 3581d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 3591d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell return Integer.toHexString(gravity); 3601d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 3611d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 3621d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell @Override 36357902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell protected void onDetachedFromWindow() { 36457902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell super.onDetachedFromWindow(); 36557902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell mFirstLayout = true; 36657902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell } 36757902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell 36857902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell @Override 36957902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell protected void onAttachedToWindow() { 37057902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell super.onAttachedToWindow(); 37157902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell mFirstLayout = true; 37257902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell } 37357902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell 37457902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell @Override 3751d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 3761d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final int widthMode = MeasureSpec.getMode(widthMeasureSpec); 3771d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final int heightMode = MeasureSpec.getMode(heightMeasureSpec); 3781d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final int widthSize = MeasureSpec.getSize(widthMeasureSpec); 3791d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final int heightSize = MeasureSpec.getSize(heightMeasureSpec); 3801d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 3811d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell if (widthMode != MeasureSpec.EXACTLY || heightMode != MeasureSpec.EXACTLY) { 3821d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell throw new IllegalArgumentException( 3831d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell "DrawerLayout must be measured with MeasureSpec.EXACTLY."); 3841d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 3851d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 3861d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell setMeasuredDimension(widthSize, heightSize); 3871d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 3881d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell // Gravity value for each drawer we've seen. Only one of each permitted. 3891d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell int foundDrawers = 0; 3901d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final int childCount = getChildCount(); 3911d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell for (int i = 0; i < childCount; i++) { 3921d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final View child = getChildAt(i); 3931d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 3941d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell if (child.getVisibility() == GONE) { 3951d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell continue; 3961d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 3971d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 3981d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell if (isContentView(child)) { 3991d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell // Content views get measured at exactly the layout's size. 4001d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell child.measure(widthMeasureSpec, heightMeasureSpec); 4011d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } else if (isDrawerView(child)) { 4021d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final int childGravity = 4031d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell getDrawerViewGravity(child) & Gravity.HORIZONTAL_GRAVITY_MASK; 4041d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell if ((foundDrawers & childGravity) != 0) { 4051d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell throw new IllegalStateException("Child drawer has absolute gravity " + 4061d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell gravityToString(childGravity) + " but this " + TAG + " already has a " + 4071d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell "drawer view along that edge"); 4081d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 4091d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final int drawerWidthSpec = getChildMeasureSpec(widthMeasureSpec, mMinDrawerMargin, 4101d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell child.getLayoutParams().width); 4111d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell child.measure(drawerWidthSpec, heightMeasureSpec); 4121d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } else { 4131d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell throw new IllegalStateException("Child " + child + " at index " + i + 4141d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell " does not have a valid layout_gravity - must be Gravity.LEFT, " + 4151d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell "Gravity.RIGHT or Gravity.NO_GRAVITY"); 4161d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 4171d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 4181d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 4191d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 4201d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell @Override 4211d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell protected void onLayout(boolean changed, int l, int t, int r, int b) { 422b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell mInLayout = true; 4231d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final int childCount = getChildCount(); 4241d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell for (int i = 0; i < childCount; i++) { 4251d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final View child = getChildAt(i); 4261d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 4271d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell if (child.getVisibility() == GONE) { 4281d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell continue; 4291d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 4301d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 4311d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell if (isContentView(child)) { 4321d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell child.layout(0, 0, child.getMeasuredWidth(), child.getMeasuredHeight()); 4331d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } else { // Drawer, if it wasn't onMeasure would have thrown an exception. 4341d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final LayoutParams lp = (LayoutParams) child.getLayoutParams(); 4351d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 4361d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final int childWidth = child.getMeasuredWidth(); 4371d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell int childLeft; 4381d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 4391d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell if (checkDrawerViewGravity(child, Gravity.LEFT)) { 440b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell childLeft = -childWidth + (int) (childWidth * lp.onScreen); 4411d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } else { // Right; onMeasure checked for us. 442b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell childLeft = r - l - (int) (childWidth * lp.onScreen); 4431d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 4441d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 4451d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell child.layout(childLeft, 0, childLeft + childWidth, child.getMeasuredHeight()); 446b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell 447b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell if (lp.onScreen == 0) { 448b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell child.setVisibility(INVISIBLE); 449b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell } 4501d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 4511d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 452b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell mInLayout = false; 45357902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell mFirstLayout = false; 454b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell } 455b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell 456b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell @Override 457b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell public void requestLayout() { 458b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell if (!mInLayout) { 459b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell super.requestLayout(); 460b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell } 4611d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 4621d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 4631d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell @Override 4641d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell public void computeScroll() { 4651d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final int childCount = getChildCount(); 4661d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell float scrimOpacity = 0; 4671d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell for (int i = 0; i < childCount; i++) { 468b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell final float onscreen = ((LayoutParams) getChildAt(i).getLayoutParams()).onScreen; 4691d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell scrimOpacity = Math.max(scrimOpacity, onscreen); 4701d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 4711d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell mScrimOpacity = scrimOpacity; 4721d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 4731d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell // "|" used on purpose; both need to run. 4741d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell if (mLeftDragger.continueSettling(true) | mRightDragger.continueSettling(true)) { 4751d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell ViewCompat.postInvalidateOnAnimation(this); 4761d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 4771d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 4781d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 479b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell private static boolean hasOpaqueBackground(View v) { 480b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell final Drawable bg = v.getBackground(); 481b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell if (bg != null) { 482b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell return bg.getOpacity() == PixelFormat.OPAQUE; 483b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell } 484b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell return false; 485b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell } 486b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell 4871d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell @Override 4881d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell protected boolean drawChild(Canvas canvas, View child, long drawingTime) { 489b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell final boolean drawingContent = isContentView(child); 490b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell int clipLeft = 0, clipRight = getWidth(); 491b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell 4921d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final int restoreCount = canvas.save(); 493b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell if (drawingContent) { 494b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell final int childCount = getChildCount(); 495b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell for (int i = 0; i < childCount; i++) { 496b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell final View v = getChildAt(i); 497b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell if (v == child || v.getVisibility() != VISIBLE || 498b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell !hasOpaqueBackground(v) || !isDrawerView(v)) { 499b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell continue; 500b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell } 501b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell 502b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell if (checkDrawerViewGravity(v, Gravity.LEFT)) { 503b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell final int vright = v.getRight(); 504b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell if (vright > clipLeft) clipLeft = vright; 505b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell } else { 506b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell final int vleft = v.getLeft(); 507b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell if (vleft < clipRight) clipRight = vleft; 508b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell } 509b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell } 510b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell canvas.clipRect(clipLeft, 0, clipRight, getHeight()); 511b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell } 5121d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final boolean result = super.drawChild(canvas, child, drawingTime); 5131d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell canvas.restoreToCount(restoreCount); 514b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell 515b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell if (mScrimOpacity > 0 && drawingContent) { 5161d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final int baseAlpha = (mScrimColor & 0xff000000) >>> 24; 5171d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final int imag = (int) (baseAlpha * mScrimOpacity); 5181d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final int color = imag << 24 | (mScrimColor & 0xffffff); 5191d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell mScrimPaint.setColor(color); 5201d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 521b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell canvas.drawRect(clipLeft, 0, clipRight, getHeight(), mScrimPaint); 522b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell } else if (mShadowLeft != null && checkDrawerViewGravity(child, Gravity.LEFT)) { 523b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell final int shadowWidth = mShadowLeft.getIntrinsicWidth(); 524b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell final int childRight = child.getRight(); 525b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell final float alpha = 526b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell Math.max(0, Math.min((float) childRight / mDrawerPeekDistance, 1.f)); 527b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell mShadowLeft.setBounds(childRight, child.getTop(), 528b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell childRight + shadowWidth, child.getBottom()); 529b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell mShadowLeft.setAlpha((int) (0xff * alpha)); 530b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell mShadowLeft.draw(canvas); 531b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell } else if (mShadowRight != null && checkDrawerViewGravity(child, Gravity.RIGHT)) { 532b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell final int shadowWidth = mShadowRight.getIntrinsicWidth(); 533b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell final int childLeft = child.getLeft(); 534b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell final int showing = getWidth() - childLeft; 535b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell final float alpha = 536b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell Math.max(0, Math.min((float) showing / mDrawerPeekDistance, 1.f)); 537b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell mShadowRight.setBounds(childLeft - shadowWidth, child.getTop(), 538b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell childLeft, child.getBottom()); 539b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell mShadowRight.setAlpha((int) (0xff * alpha)); 540b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell mShadowRight.draw(canvas); 5411d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 5421d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell return result; 5431d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 5441d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 5451d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell boolean isContentView(View child) { 5461d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell return ((LayoutParams) child.getLayoutParams()).gravity == Gravity.NO_GRAVITY; 5471d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 5481d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 5491d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell boolean isDrawerView(View child) { 5501d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final int gravity = ((LayoutParams) child.getLayoutParams()).gravity; 5511d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final int absGravity = GravityCompat.getAbsoluteGravity(gravity, 5521d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell ViewCompat.getLayoutDirection(child)); 5531d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell return (absGravity & (Gravity.LEFT | Gravity.RIGHT)) != 0; 5541d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 5551d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 5561d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell @Override 5571d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell public boolean onInterceptTouchEvent(MotionEvent ev) { 5581d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final int action = MotionEventCompat.getActionMasked(ev); 5591d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 5601d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell // "|" used deliberately here; both methods should be invoked. 5611d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final boolean interceptForDrag = mLeftDragger.shouldInterceptTouchEvent(ev) | 5621d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell mRightDragger.shouldInterceptTouchEvent(ev); 5631d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 5641d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell boolean interceptForTap = false; 5651d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 5661d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell switch (action) { 5671d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell case MotionEvent.ACTION_DOWN: { 5681d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final float x = ev.getX(); 5691d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final float y = ev.getY(); 5701d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell mInitialMotionX = x; 5711d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell mInitialMotionY = y; 5721d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell if (mScrimOpacity > 0 && 5731d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell isContentView(mLeftDragger.findTopChildUnder((int) x, (int) y))) { 5741d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell interceptForTap = true; 5751d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 5761d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell break; 5771d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 5781d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 5791d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell case MotionEvent.ACTION_CANCEL: 5801d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell case MotionEvent.ACTION_UP: { 5811d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell closeDrawers(true); 5821d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 5831d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 5841d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell return interceptForDrag || interceptForTap; 5851d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 5861d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 5871d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell @Override 5881d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell public void requestDisallowInterceptTouchEvent(boolean disallowIntercept) { 58932a53a670d1f6ff07454135a22e970f2154260dcAdam Powell final int childCount = getChildCount(); 59032a53a670d1f6ff07454135a22e970f2154260dcAdam Powell for (int i = 0; i < childCount; i++) { 59132a53a670d1f6ff07454135a22e970f2154260dcAdam Powell final LayoutParams lp = (LayoutParams) getChildAt(i).getLayoutParams(); 59232a53a670d1f6ff07454135a22e970f2154260dcAdam Powell 59332a53a670d1f6ff07454135a22e970f2154260dcAdam Powell if (lp.isPeeking) { 59432a53a670d1f6ff07454135a22e970f2154260dcAdam Powell // Don't disallow intercept at all if we have a peeking view, we're probably 59532a53a670d1f6ff07454135a22e970f2154260dcAdam Powell // going to intercept it later anyway. 59632a53a670d1f6ff07454135a22e970f2154260dcAdam Powell return; 59732a53a670d1f6ff07454135a22e970f2154260dcAdam Powell } 59832a53a670d1f6ff07454135a22e970f2154260dcAdam Powell } 5991d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell super.requestDisallowInterceptTouchEvent(disallowIntercept); 6001d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell if (disallowIntercept) { 6011d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell closeDrawers(true); 6021d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 6031d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 6041d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 6051d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell @Override 6061d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell public boolean onTouchEvent(MotionEvent ev) { 6071d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell mLeftDragger.processTouchEvent(ev); 6081d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell mRightDragger.processTouchEvent(ev); 6091d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 6101d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final int action = ev.getAction(); 6111d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell boolean wantTouchEvents = true; 6121d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 6131d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell switch (action & MotionEventCompat.ACTION_MASK) { 6141d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell case MotionEvent.ACTION_DOWN: { 6151d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final float x = ev.getX(); 6161d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final float y = ev.getY(); 6171d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell mInitialMotionX = x; 6181d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell mInitialMotionY = y; 6191d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell break; 6201d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 6211d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 6221d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell case MotionEvent.ACTION_UP: { 6231d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final float x = ev.getX(); 6241d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final float y = ev.getY(); 6251d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell boolean peekingOnly = true; 6268bc268e9c40e4ae375a0d65dc1293dccc541186fAdam Powell final View touchedView = mLeftDragger.findTopChildUnder((int) x, (int) y); 6278bc268e9c40e4ae375a0d65dc1293dccc541186fAdam Powell if (touchedView != null && isContentView(touchedView)) { 6281d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final float dx = x - mInitialMotionX; 6291d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final float dy = y - mInitialMotionY; 6301d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final int slop = mLeftDragger.getTouchSlop(); 6311d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell if (dx * dx + dy * dy < slop * slop) { 6321d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell // Taps close a dimmed open pane. 6331d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell peekingOnly = false; 6341d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 6351d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 6361d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell closeDrawers(peekingOnly); 6371d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell break; 6381d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 6391d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 6401d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell case MotionEvent.ACTION_CANCEL: { 6411d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell closeDrawers(true); 6421d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell break; 6431d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 6441d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 6451d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 6461d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell return wantTouchEvents; 6471d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 6481d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 6491d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell /** 6501d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * Close all currently open drawer views by animating them out of view. 6511d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell */ 6521d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell public void closeDrawers() { 6531d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell closeDrawers(false); 6541d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 6551d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 6561d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell void closeDrawers(boolean peekingOnly) { 6571d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell boolean needsInvalidate = false; 6581d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final int childCount = getChildCount(); 6591d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell for (int i = 0; i < childCount; i++) { 6601d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final View child = getChildAt(i); 6611d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final LayoutParams lp = (LayoutParams) child.getLayoutParams(); 6621d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 6631d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell if (!isDrawerView(child) || (peekingOnly && !lp.isPeeking)) { 6641d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell continue; 6651d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 6661d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 6671d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final int childWidth = child.getWidth(); 6681d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 6691d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell if (checkDrawerViewGravity(child, Gravity.LEFT)) { 6701d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell needsInvalidate |= mLeftDragger.smoothSlideViewTo(child, 6711d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell -childWidth, child.getTop()); 6721d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } else { 6731d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell needsInvalidate |= mRightDragger.smoothSlideViewTo(child, 6741d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell getWidth(), child.getTop()); 6751d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 6761d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 6771d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell lp.isPeeking = false; 6781d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 6791d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 6801d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell if (needsInvalidate) { 6811d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell invalidate(); 6821d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 6831d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 6841d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 6851d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell /** 6861d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * Open the specified drawer view by animating it into view. 6871d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * 6881d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * @param drawerView Drawer view to open 6891d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell */ 6901d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell public void openDrawer(View drawerView) { 6911d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell if (!isDrawerView(drawerView)) { 6921d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell throw new IllegalArgumentException("View " + drawerView + " is not a sliding drawer"); 6931d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 6941d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 69557902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell if (mFirstLayout) { 69657902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell final LayoutParams lp = (LayoutParams) drawerView.getLayoutParams(); 69757902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell lp.onScreen = 1.f; 69857902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell lp.knownOpen = true; 6991d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } else { 70057902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell if (checkDrawerViewGravity(drawerView, Gravity.LEFT)) { 70157902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell mLeftDragger.smoothSlideViewTo(drawerView, 0, drawerView.getTop()); 70257902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell } else { 70357902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell mRightDragger.smoothSlideViewTo(drawerView, getWidth() - drawerView.getWidth(), 70457902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell drawerView.getTop()); 70557902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell } 7061d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 7071d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell invalidate(); 7081d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 7091d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 7101d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell /** 7111d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * Open the specified drawer by animating it out of view. 7121d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * 7131d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * @param gravity Gravity.LEFT to move the left drawer or Gravity.RIGHT for the right. 7141d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * GravityCompat.START or GravityCompat.END may also be used. 7151d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell */ 7161d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell public void openDrawer(int gravity) { 7171d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final int absGravity = GravityCompat.getAbsoluteGravity(gravity, 7181d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell ViewCompat.getLayoutDirection(this)); 7191d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final View drawerView = findDrawerWithGravity(absGravity); 7201d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 7211d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell if (drawerView == null) { 7221d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell throw new IllegalArgumentException("No drawer view found with absolute gravity " + 7231d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell gravityToString(absGravity)); 7241d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 7251d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell openDrawer(drawerView); 7261d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 7271d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 7281d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell /** 7291d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * Close the specified drawer view by animating it into view. 7301d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * 7311d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * @param drawerView Drawer view to close 7321d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell */ 7331d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell public void closeDrawer(View drawerView) { 7341d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell if (!isDrawerView(drawerView)) { 7351d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell throw new IllegalArgumentException("View " + drawerView + " is not a sliding drawer"); 7361d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 7371d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 73857902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell if (mFirstLayout) { 73957902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell final LayoutParams lp = (LayoutParams) drawerView.getLayoutParams(); 74057902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell lp.onScreen = 0.f; 74157902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell lp.knownOpen = false; 7421d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } else { 74357902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell if (checkDrawerViewGravity(drawerView, Gravity.LEFT)) { 74457902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell mLeftDragger.smoothSlideViewTo(drawerView, -drawerView.getWidth(), 74557902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell drawerView.getTop()); 74657902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell } else { 74757902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell mRightDragger.smoothSlideViewTo(drawerView, getWidth(), drawerView.getTop()); 74857902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell } 7491d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 7501d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell invalidate(); 7511d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 7521d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 7531d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell /** 7541d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * Close the specified drawer by animating it out of view. 7551d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * 7561d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * @param gravity Gravity.LEFT to move the left drawer or Gravity.RIGHT for the right. 7571d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell * GravityCompat.START or GravityCompat.END may also be used. 7581d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell */ 7591d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell public void closeDrawer(int gravity) { 7601d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final int absGravity = GravityCompat.getAbsoluteGravity(gravity, 7611d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell ViewCompat.getLayoutDirection(this)); 7621d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final View drawerView = findDrawerWithGravity(absGravity); 7631d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 7641d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell if (drawerView == null) { 7651d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell throw new IllegalArgumentException("No drawer view found with absolute gravity " + 7661d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell gravityToString(absGravity)); 7671d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 7681d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell closeDrawer(drawerView); 7691d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 7701d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 771b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell /** 772b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell * Check if the given drawer view is currently in an open state. 773b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell * To be considered "open" the drawer must have settled into its fully 774b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell * visible state. To check for partial visibility use 775b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell * {@link #isDrawerVisible(android.view.View)}. 776b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell * 777b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell * @param drawer Drawer view to check 778b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell * @return true if the given drawer view is in an open state 779b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell * @see #isDrawerVisible(android.view.View) 780b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell */ 781b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell public boolean isDrawerOpen(View drawer) { 782b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell if (!isDrawerView(drawer)) { 783b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell throw new IllegalArgumentException("View " + drawer + " is not a drawer"); 784b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell } 785b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell return ((LayoutParams) drawer.getLayoutParams()).knownOpen; 786b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell } 787b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell 788b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell /** 789b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell * Check if a given drawer view is currently visible on-screen. The drawer 790b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell * may be only peeking onto the screen, fully extended, or anywhere inbetween. 791b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell * 792b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell * @param drawer Drawer view to check 793b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell * @return true if the given drawer is visible on-screen 794b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell * @see #isDrawerOpen(android.view.View) 795b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell */ 796b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell public boolean isDrawerVisible(View drawer) { 797b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell if (!isDrawerView(drawer)) { 798b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell throw new IllegalArgumentException("View " + drawer + " is not a drawer"); 799b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell } 800b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell return ((LayoutParams) drawer.getLayoutParams()).onScreen > 0; 801b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell } 802b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell 8031d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell @Override 8041d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell protected ViewGroup.LayoutParams generateDefaultLayoutParams() { 8051d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell return new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT); 8061d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 8071d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 8081d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell @Override 8091d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell protected ViewGroup.LayoutParams generateLayoutParams(ViewGroup.LayoutParams p) { 8101d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell return p instanceof LayoutParams 8111d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell ? new LayoutParams((LayoutParams) p) 8121d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell : new LayoutParams(p); 8131d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 8141d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 8151d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell @Override 8161d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell protected boolean checkLayoutParams(ViewGroup.LayoutParams p) { 8171d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell return p instanceof LayoutParams && super.checkLayoutParams(p); 8181d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 8191d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 8201d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell @Override 8211d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell public ViewGroup.LayoutParams generateLayoutParams(AttributeSet attrs) { 8221d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell return new LayoutParams(getContext(), attrs); 8231d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 8241d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 825791f31bbba40b8b51694a1b2cdc804f360786ed1Adam Powell private boolean hasVisibleDrawer() { 826791f31bbba40b8b51694a1b2cdc804f360786ed1Adam Powell final int childCount = getChildCount(); 827791f31bbba40b8b51694a1b2cdc804f360786ed1Adam Powell for (int i = 0; i < childCount; i++) { 828791f31bbba40b8b51694a1b2cdc804f360786ed1Adam Powell final View child = getChildAt(i); 829791f31bbba40b8b51694a1b2cdc804f360786ed1Adam Powell if (isDrawerView(child) && isDrawerVisible(child)) { 830791f31bbba40b8b51694a1b2cdc804f360786ed1Adam Powell return true; 831791f31bbba40b8b51694a1b2cdc804f360786ed1Adam Powell } 832791f31bbba40b8b51694a1b2cdc804f360786ed1Adam Powell } 833791f31bbba40b8b51694a1b2cdc804f360786ed1Adam Powell return false; 834791f31bbba40b8b51694a1b2cdc804f360786ed1Adam Powell } 835791f31bbba40b8b51694a1b2cdc804f360786ed1Adam Powell 836791f31bbba40b8b51694a1b2cdc804f360786ed1Adam Powell @Override 837791f31bbba40b8b51694a1b2cdc804f360786ed1Adam Powell public boolean onKeyDown(int keyCode, KeyEvent event) { 838791f31bbba40b8b51694a1b2cdc804f360786ed1Adam Powell if (keyCode == KeyEvent.KEYCODE_BACK && hasVisibleDrawer()) { 839791f31bbba40b8b51694a1b2cdc804f360786ed1Adam Powell KeyEventCompat.startTracking(event); 840791f31bbba40b8b51694a1b2cdc804f360786ed1Adam Powell return true; 841791f31bbba40b8b51694a1b2cdc804f360786ed1Adam Powell } 842791f31bbba40b8b51694a1b2cdc804f360786ed1Adam Powell return super.onKeyDown(keyCode, event); 843791f31bbba40b8b51694a1b2cdc804f360786ed1Adam Powell } 844791f31bbba40b8b51694a1b2cdc804f360786ed1Adam Powell 845791f31bbba40b8b51694a1b2cdc804f360786ed1Adam Powell @Override 846791f31bbba40b8b51694a1b2cdc804f360786ed1Adam Powell public boolean onKeyUp(int keyCode, KeyEvent event) { 847791f31bbba40b8b51694a1b2cdc804f360786ed1Adam Powell if (keyCode == KeyEvent.KEYCODE_BACK && hasVisibleDrawer()) { 848791f31bbba40b8b51694a1b2cdc804f360786ed1Adam Powell closeDrawers(); 849791f31bbba40b8b51694a1b2cdc804f360786ed1Adam Powell return true; 850791f31bbba40b8b51694a1b2cdc804f360786ed1Adam Powell } 851791f31bbba40b8b51694a1b2cdc804f360786ed1Adam Powell return super.onKeyUp(keyCode, event); 852791f31bbba40b8b51694a1b2cdc804f360786ed1Adam Powell } 853791f31bbba40b8b51694a1b2cdc804f360786ed1Adam Powell 85457902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell @Override 85557902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell protected void onRestoreInstanceState(Parcelable state) { 85657902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell final SavedState ss = (SavedState) state; 85757902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell super.onRestoreInstanceState(ss.getSuperState()); 85857902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell 85957902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell if (ss.openDrawerGravity != Gravity.NO_GRAVITY) { 86057902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell final View toOpen = findDrawerWithGravity(ss.openDrawerGravity); 86157902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell if (toOpen != null) { 86257902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell openDrawer(toOpen); 86357902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell } 86457902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell } 86557902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell } 86657902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell 86757902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell @Override 86857902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell protected Parcelable onSaveInstanceState() { 86957902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell final Parcelable superState = super.onSaveInstanceState(); 87057902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell 87157902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell final SavedState ss = new SavedState(superState); 87257902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell 87357902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell final int childCount = getChildCount(); 87457902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell for (int i = 0; i < childCount; i++) { 87557902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell final View child = getChildAt(i); 87657902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell if (!isDrawerView(child)) { 87757902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell continue; 87857902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell } 87957902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell 88057902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell final LayoutParams lp = (LayoutParams) child.getLayoutParams(); 88157902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell if (lp.knownOpen) { 88257902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell ss.openDrawerGravity = lp.gravity; 88357902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell // Only one drawer can be open at a time. 88457902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell break; 88557902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell } 88657902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell } 88757902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell 88857902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell return ss; 88957902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell } 89057902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell 89157902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell /** 89257902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell * State persisted across instances 89357902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell */ 89457902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell protected static class SavedState extends BaseSavedState { 89557902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell int openDrawerGravity = Gravity.NO_GRAVITY; 89657902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell 89757902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell public SavedState(Parcel in) { 89857902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell super(in); 89957902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell openDrawerGravity = in.readInt(); 90057902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell } 90157902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell 90257902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell public SavedState(Parcelable superState) { 90357902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell super(superState); 90457902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell } 90557902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell 90657902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell @Override 90757902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell public void writeToParcel(Parcel dest, int flags) { 90857902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell super.writeToParcel(dest, flags); 90957902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell dest.writeInt(openDrawerGravity); 91057902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell } 91157902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell 91257902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell public static final Parcelable.Creator<SavedState> CREATOR = 91357902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell new Parcelable.Creator<SavedState>() { 91457902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell @Override 91557902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell public SavedState createFromParcel(Parcel source) { 91657902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell return new SavedState(source); 91757902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell } 91857902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell 91957902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell @Override 92057902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell public SavedState[] newArray(int size) { 92157902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell return new SavedState[size]; 92257902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell } 92357902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell }; 92457902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell } 92557902cff6c54c245feea589b06d12dba8f1a2a24Adam Powell 9261d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell private class ViewDragCallback extends ViewDragHelper.Callback { 9271d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 9281d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell private final int mGravity; 9291d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell private ViewDragHelper mDragger; 9301d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 9311d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell public ViewDragCallback(int gravity) { 9321d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell mGravity = gravity; 9331d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 9341d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 9351d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell public void setDragger(ViewDragHelper dragger) { 9361d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell mDragger = dragger; 9371d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 9381d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 9391d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell @Override 9401d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell public boolean tryCaptureView(View child, int pointerId) { 9411d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell // Only capture views where the gravity matches what we're looking for. 9421d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell // This lets us use two ViewDragHelpers, one for each side drawer. 9431d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell return isDrawerView(child) && checkDrawerViewGravity(child, mGravity); 9441d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 9451d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 9461d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell @Override 9471d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell public void onViewDragStateChanged(int state) { 948b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell updateDrawerState(mGravity, state, mDragger.getCapturedView()); 9491d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 9501d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 9511d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell @Override 9521d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell public void onViewPositionChanged(View changedView, int left, int top, int dx, int dy) { 9531d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell float offset; 9541d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final int childWidth = changedView.getWidth(); 9551d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 9561d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell // This reverses the positioning shown in onLayout. 9571d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell if (checkDrawerViewGravity(changedView, Gravity.LEFT)) { 9581d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell offset = (float) (childWidth + left) / childWidth; 9591d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } else { 9601d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final int width = getWidth(); 9611d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell offset = (float) (width - left) / childWidth; 9621d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 9631d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell setDrawerViewOffset(changedView, offset); 964b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell changedView.setVisibility(offset == 0 ? INVISIBLE : VISIBLE); 9651d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell invalidate(); 9661d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 9671d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 9681d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell @Override 9691d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell public void onViewCaptured(View capturedChild, int activePointerId) { 9701d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final LayoutParams lp = (LayoutParams) capturedChild.getLayoutParams(); 9711d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell lp.isPeeking = false; 9721d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 9731d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell closeOtherDrawer(); 9741d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 9751d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 9761d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell private void closeOtherDrawer() { 9771d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final int otherGrav = mGravity == Gravity.LEFT ? Gravity.RIGHT : Gravity.LEFT; 9781d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final View toClose = findDrawerWithGravity(otherGrav); 9791d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell if (toClose != null) { 9801d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell closeDrawer(toClose); 9811d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 9821d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 9831d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 9841d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell @Override 9851d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell public void onViewReleased(View releasedChild, float xvel, float yvel) { 9861d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell // Offset is how open the drawer is, therefore left/right values 9871d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell // are reversed from one another. 9881d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final float offset = getDrawerViewOffset(releasedChild); 9891d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final int childWidth = releasedChild.getWidth(); 9901d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 9911d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell int left; 9921d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell if (checkDrawerViewGravity(releasedChild, Gravity.LEFT)) { 9931d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell left = xvel > 0 || xvel == 0 && offset > 0.5f ? 0 : -childWidth; 9941d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } else { 9951d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final int width = getWidth(); 9961d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell left = xvel < 0 || xvel == 0 && offset < 0.5f ? width - childWidth : width; 9971d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 9981d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 9991d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell mDragger.settleCapturedViewAt(left, releasedChild.getTop()); 10001d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell invalidate(); 10011d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 10021d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 10031d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell @Override 10041d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell public void onEdgeTouched(int edgeFlags, int pointerId) { 10051d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final View toCapture; 10061d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final int childLeft; 1007b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell final boolean leftEdge = 1008b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell (edgeFlags & ViewDragHelper.EDGE_LEFT) == ViewDragHelper.EDGE_LEFT; 1009b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell if (leftEdge) { 10101d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell toCapture = findDrawerWithGravity(Gravity.LEFT); 10111d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell childLeft = -toCapture.getWidth() + mDrawerPeekDistance; 10121d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } else { 10131d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell toCapture = findDrawerWithGravity(Gravity.RIGHT); 10141d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell childLeft = getWidth() - mDrawerPeekDistance; 10151d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 10161d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 1017b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell // Only peek if it would mean making the drawer more visible 1018b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell if (toCapture != null && ((leftEdge && toCapture.getLeft() < childLeft) || 1019b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell (!leftEdge && toCapture.getLeft() > childLeft))) { 1020b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell final LayoutParams lp = (LayoutParams) toCapture.getLayoutParams(); 10211d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell mDragger.smoothSlideViewTo(toCapture, childLeft, toCapture.getTop()); 1022b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell lp.isPeeking = true; 10231d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell invalidate(); 10241d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 10251d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell closeOtherDrawer(); 10261d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 10271d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 10281d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 10291d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell @Override 10301d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell public void onEdgeDragStarted(int edgeFlags, int pointerId) { 10311d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final View toCapture; 10321d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell if ((edgeFlags & ViewDragHelper.EDGE_LEFT) == ViewDragHelper.EDGE_LEFT) { 10331d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell toCapture = findDrawerWithGravity(Gravity.LEFT); 10341d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } else { 10351d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell toCapture = findDrawerWithGravity(Gravity.RIGHT); 10361d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 10371d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 10381d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell if (toCapture != null) { 10391d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell mDragger.captureChildView(toCapture, pointerId); 10401d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 10411d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 10421d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 10431d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell @Override 10441d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell public int getViewHorizontalDragRange(View child) { 10451d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell return child.getWidth(); 10461d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 10471d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 10481d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell @Override 10491d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell public int clampViewPositionHorizontal(View child, int left, int dx) { 10501d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell if (checkDrawerViewGravity(child, Gravity.LEFT)) { 10511d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell return Math.max(-child.getWidth(), Math.min(left, 0)); 10521d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } else { 10531d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final int width = getWidth(); 10541d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell return Math.max(width - child.getWidth(), Math.min(left, width)); 10551d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 10561d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 10571d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 10581d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 10591d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell public static class LayoutParams extends ViewGroup.LayoutParams { 10601d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 10611d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell public int gravity = Gravity.NO_GRAVITY; 1062b562d856f6ff58b7fc421a3b0cd1e0e089b994abAdam Powell float onScreen; 10631d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell boolean isPeeking; 10641d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell boolean knownOpen; 10651d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 10661d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell public LayoutParams(Context c, AttributeSet attrs) { 10671d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell super(c, attrs); 10681d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 10691d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell final TypedArray a = c.obtainStyledAttributes(attrs, LAYOUT_ATTRS); 10701d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell this.gravity = a.getInt(0, Gravity.NO_GRAVITY); 10711d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell a.recycle(); 10721d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 10731d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 10741d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell public LayoutParams(int width, int height) { 10751d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell super(width, height); 10761d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 10771d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 10781d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell public LayoutParams(int width, int height, int gravity) { 10791d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell this(width, height); 10801d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell this.gravity = gravity; 10811d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 10821d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 10831d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell public LayoutParams(LayoutParams source) { 10841d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell super(source); 10851d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell this.gravity = source.gravity; 10861d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 10871d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell 10881d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell public LayoutParams(ViewGroup.LayoutParams source) { 10891d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell super(source); 10901d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 10911d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell } 10921d26501f0c8e9f3577f651938a03f6b3a1a672c7Adam Powell} 1093