19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2008 The Android Open Source Project 39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License. 69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at 79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and 149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License. 159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage android.widget; 189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganovimport android.R; 209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.Context; 219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.res.TypedArray; 2275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganovimport android.graphics.Bitmap; 239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.graphics.Canvas; 249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.graphics.Rect; 259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Handler; 269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Message; 2775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganovimport android.os.SystemClock; 2875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganovimport android.util.AttributeSet; 2975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganovimport android.view.MotionEvent; 3075986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganovimport android.view.SoundEffectConstants; 3175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganovimport android.view.VelocityTracker; 3275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganovimport android.view.View; 3375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganovimport android.view.ViewGroup; 3475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganovimport android.view.accessibility.AccessibilityEvent; 359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/** 379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * SlidingDrawer hides content out of the screen and allows the user to drag a handle 389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * to bring the content on screen. SlidingDrawer can be used vertically or horizontally. 399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * A special widget composed of two children views: the handle, that the users drags, 419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * and the content, attached to the handle and dragged with it. 429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * SlidingDrawer should be used as an overlay inside layouts. This means SlidingDrawer 449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * should only be used inside of a FrameLayout or a RelativeLayout for instance. The 459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * size of the SlidingDrawer defines how much space the content will occupy once slid 46980a938c1c9a6a5791a8240e5a1e6638ab28dc77Romain Guy * out so SlidingDrawer should usually use match_parent for both its dimensions. 479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Inside an XML layout, SlidingDrawer must define the id of the handle and of the 499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * content: 509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <pre class="prettyprint"> 529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <SlidingDrawer 539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * android:id="@+id/drawer" 54980a938c1c9a6a5791a8240e5a1e6638ab28dc77Romain Guy * android:layout_width="match_parent" 55980a938c1c9a6a5791a8240e5a1e6638ab28dc77Romain Guy * android:layout_height="match_parent" 569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * android:handle="@+id/handle" 589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * android:content="@+id/content"> 599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <ImageView 619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * android:id="@id/handle" 629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * android:layout_width="88dip" 639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * android:layout_height="44dip" /> 649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <GridView 669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * android:id="@id/content" 67980a938c1c9a6a5791a8240e5a1e6638ab28dc77Romain Guy * android:layout_width="match_parent" 68980a938c1c9a6a5791a8240e5a1e6638ab28dc77Romain Guy * android:layout_height="match_parent" /> 699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </SlidingDrawer> 719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </pre> 729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#SlidingDrawer_content 749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#SlidingDrawer_handle 759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#SlidingDrawer_topOffset 769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#SlidingDrawer_bottomOffset 779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#SlidingDrawer_orientation 789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#SlidingDrawer_allowSingleTap 799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#SlidingDrawer_animateOnClick 8086ca5d35139db0eccc2babcca5bf835f8c2b019fRomain Guy * 8186ca5d35139db0eccc2babcca5bf835f8c2b019fRomain Guy * @deprecated This class is not supported anymore. It is recommended you 8286ca5d35139db0eccc2babcca5bf835f8c2b019fRomain Guy * base your own implementation on the source code for the Android Open 8386ca5d35139db0eccc2babcca5bf835f8c2b019fRomain Guy * Source Project if you must use it in your application. 849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 8586ca5d35139db0eccc2babcca5bf835f8c2b019fRomain Guy@Deprecated 869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic class SlidingDrawer extends ViewGroup { 879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int ORIENTATION_HORIZONTAL = 0; 889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int ORIENTATION_VERTICAL = 1; 899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int TAP_THRESHOLD = 6; 919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final float MAXIMUM_TAP_VELOCITY = 100.0f; 929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final float MAXIMUM_MINOR_VELOCITY = 150.0f; 939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final float MAXIMUM_MAJOR_VELOCITY = 200.0f; 949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final float MAXIMUM_ACCELERATION = 2000.0f; 959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int VELOCITY_UNITS = 1000; 969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int ANIMATION_FRAME_DURATION = 1000 / 60; 979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int EXPANDED_FULL_OPEN = -10001; 999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int COLLAPSED_FULL_CLOSED = -10002; 1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final int mHandleId; 1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final int mContentId; 1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private View mHandle; 1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private View mContent; 1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final Rect mFrame = new Rect(); 1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final Rect mInvalidate = new Rect(); 1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mTracking; 1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mLocked; 1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private VelocityTracker mVelocityTracker; 1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mVertical; 1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mExpanded; 1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mBottomOffset; 1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mTopOffset; 1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mHandleHeight; 1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mHandleWidth; 1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private OnDrawerOpenListener mOnDrawerOpenListener; 1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private OnDrawerCloseListener mOnDrawerCloseListener; 1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private OnDrawerScrollListener mOnDrawerScrollListener; 1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private float mAnimatedAcceleration; 1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private float mAnimatedVelocity; 1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private float mAnimationPosition; 1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private long mAnimationLastTime; 1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private long mCurrentAnimationTime; 1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mTouchDelta; 1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mAnimating; 1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mAllowSingleTap; 1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mAnimateOnClick; 1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final int mTapThreshold; 1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final int mMaximumTapVelocity; 1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final int mMaximumMinorVelocity; 1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final int mMaximumMajorVelocity; 1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final int mMaximumAcceleration; 1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final int mVelocityUnits; 1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Callback invoked when the drawer is opened. 1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static interface OnDrawerOpenListener { 1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Invoked when the drawer becomes fully open. 1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void onDrawerOpened(); 1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Callback invoked when the drawer is closed. 1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static interface OnDrawerCloseListener { 1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Invoked when the drawer becomes fully closed. 1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void onDrawerClosed(); 1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Callback invoked when the drawer is scrolled. 1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static interface OnDrawerScrollListener { 1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Invoked when the user starts dragging/flinging the drawer's handle. 1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void onScrollStarted(); 1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Invoked when the user stops dragging/flinging the drawer's handle. 1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void onScrollEnded(); 1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Creates a new SlidingDrawer from a specified set of attributes defined in XML. 1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param context The application's environment. 1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param attrs The attributes defined in XML. 1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public SlidingDrawer(Context context, AttributeSet attrs) { 1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project this(context, attrs, 0); 1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Creates a new SlidingDrawer from a specified set of attributes defined in XML. 1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param context The application's environment. 1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param attrs The attributes defined in XML. 192617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette * @param defStyleAttr An attribute in the current theme that contains a 193617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette * reference to a style resource that supplies default values for 194617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette * the view. Can be 0 to not look for defaults. 1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 196617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette public SlidingDrawer(Context context, AttributeSet attrs, int defStyleAttr) { 197617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette this(context, attrs, defStyleAttr, 0); 198617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette } 199617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette 200617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette /** 201617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette * Creates a new SlidingDrawer from a specified set of attributes defined in XML. 202617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette * 203617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette * @param context The application's environment. 204617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette * @param attrs The attributes defined in XML. 205617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette * @param defStyleAttr An attribute in the current theme that contains a 206617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette * reference to a style resource that supplies default values for 207617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette * the view. Can be 0 to not look for defaults. 208617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette * @param defStyleRes A resource identifier of a style resource that 209617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette * supplies default values for the view, used only if 210617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette * defStyleAttr is 0 or can not be found in the theme. Can be 0 211617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette * to not look for defaults. 212617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette */ 213617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette public SlidingDrawer(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { 214617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette super(context, attrs, defStyleAttr, defStyleRes); 215617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette 216617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette final TypedArray a = context.obtainStyledAttributes( 217617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette attrs, R.styleable.SlidingDrawer, defStyleAttr, defStyleRes); 2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int orientation = a.getInt(R.styleable.SlidingDrawer_orientation, ORIENTATION_VERTICAL); 2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mVertical = orientation == ORIENTATION_VERTICAL; 2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mBottomOffset = (int) a.getDimension(R.styleable.SlidingDrawer_bottomOffset, 0.0f); 2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mTopOffset = (int) a.getDimension(R.styleable.SlidingDrawer_topOffset, 0.0f); 2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mAllowSingleTap = a.getBoolean(R.styleable.SlidingDrawer_allowSingleTap, true); 2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mAnimateOnClick = a.getBoolean(R.styleable.SlidingDrawer_animateOnClick, true); 2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int handleId = a.getResourceId(R.styleable.SlidingDrawer_handle, 0); 2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (handleId == 0) { 2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalArgumentException("The handle attribute is required and must refer " 2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + "to a valid child."); 2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int contentId = a.getResourceId(R.styleable.SlidingDrawer_content, 0); 2339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (contentId == 0) { 2348a342a3cc07162cdb5458692f04fbc677802919eRomain Guy throw new IllegalArgumentException("The content attribute is required and must refer " 2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + "to a valid child."); 2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2388a342a3cc07162cdb5458692f04fbc677802919eRomain Guy if (handleId == contentId) { 2398a342a3cc07162cdb5458692f04fbc677802919eRomain Guy throw new IllegalArgumentException("The content and handle attributes must refer " 2408a342a3cc07162cdb5458692f04fbc677802919eRomain Guy + "to different children."); 2418a342a3cc07162cdb5458692f04fbc677802919eRomain Guy } 2428a342a3cc07162cdb5458692f04fbc677802919eRomain Guy 2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mHandleId = handleId; 2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mContentId = contentId; 2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final float density = getResources().getDisplayMetrics().density; 2479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mTapThreshold = (int) (TAP_THRESHOLD * density + 0.5f); 2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mMaximumTapVelocity = (int) (MAXIMUM_TAP_VELOCITY * density + 0.5f); 2499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mMaximumMinorVelocity = (int) (MAXIMUM_MINOR_VELOCITY * density + 0.5f); 2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mMaximumMajorVelocity = (int) (MAXIMUM_MAJOR_VELOCITY * density + 0.5f); 2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mMaximumAcceleration = (int) (MAXIMUM_ACCELERATION * density + 0.5f); 2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mVelocityUnits = (int) (VELOCITY_UNITS * density + 0.5f); 2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project a.recycle(); 2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setAlwaysDrawnWithCacheEnabled(false); 2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected void onFinishInflate() { 2619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mHandle = findViewById(mHandleId); 2629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mHandle == null) { 2639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalArgumentException("The handle attribute is must refer to an" 2649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + " existing child."); 2659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mHandle.setOnClickListener(new DrawerToggler()); 2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mContent = findViewById(mContentId); 2699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mContent == null) { 2709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalArgumentException("The content attribute is must refer to an" 2719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + " existing child."); 2729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mContent.setVisibility(View.GONE); 2749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 2779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 2789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int widthSpecMode = MeasureSpec.getMode(widthMeasureSpec); 2799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int widthSpecSize = MeasureSpec.getSize(widthMeasureSpec); 2809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int heightSpecMode = MeasureSpec.getMode(heightMeasureSpec); 2829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int heightSpecSize = MeasureSpec.getSize(heightMeasureSpec); 2839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (widthSpecMode == MeasureSpec.UNSPECIFIED || heightSpecMode == MeasureSpec.UNSPECIFIED) { 2859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new RuntimeException("SlidingDrawer cannot have UNSPECIFIED dimensions"); 2869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final View handle = mHandle; 2899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project measureChild(handle, widthMeasureSpec, heightMeasureSpec); 2909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mVertical) { 2929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int height = heightSpecSize - handle.getMeasuredHeight() - mTopOffset; 2939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mContent.measure(MeasureSpec.makeMeasureSpec(widthSpecSize, MeasureSpec.EXACTLY), 2949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY)); 2959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 2969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int width = widthSpecSize - handle.getMeasuredWidth() - mTopOffset; 2979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mContent.measure(MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY), 2989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project MeasureSpec.makeMeasureSpec(heightSpecSize, MeasureSpec.EXACTLY)); 2999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setMeasuredDimension(widthSpecSize, heightSpecSize); 3029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 3059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected void dispatchDraw(Canvas canvas) { 3069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final long drawingTime = getDrawingTime(); 3079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final View handle = mHandle; 3089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final boolean isVertical = mVertical; 3099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project drawChild(canvas, handle, drawingTime); 3119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mTracking || mAnimating) { 3139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final Bitmap cache = mContent.getDrawingCache(); 3149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (cache != null) { 3159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (isVertical) { 3169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project canvas.drawBitmap(cache, 0, handle.getBottom(), null); 3179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 3189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project canvas.drawBitmap(cache, handle.getRight(), 0, null); 3199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 3219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project canvas.save(); 3229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project canvas.translate(isVertical ? 0 : handle.getLeft() - mTopOffset, 3239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project isVertical ? handle.getTop() - mTopOffset : 0); 3249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project drawChild(canvas, mContent, drawingTime); 3259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project canvas.restore(); 3269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (mExpanded) { 3289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project drawChild(canvas, mContent, drawingTime); 3299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 3339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected void onLayout(boolean changed, int l, int t, int r, int b) { 3349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mTracking) { 3359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 3369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int width = r - l; 3399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int height = b - t; 3409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final View handle = mHandle; 3429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int childWidth = handle.getMeasuredWidth(); 3449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int childHeight = handle.getMeasuredHeight(); 3459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int childLeft; 3479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int childTop; 3489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final View content = mContent; 3509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mVertical) { 3529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project childLeft = (width - childWidth) / 2; 3539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project childTop = mExpanded ? mTopOffset : height - childHeight + mBottomOffset; 3549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project content.layout(0, mTopOffset + childHeight, content.getMeasuredWidth(), 3569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mTopOffset + childHeight + content.getMeasuredHeight()); 3579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 3589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project childLeft = mExpanded ? mTopOffset : width - childWidth + mBottomOffset; 3599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project childTop = (height - childHeight) / 2; 3609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project content.layout(mTopOffset + childWidth, 0, 3629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mTopOffset + childWidth + content.getMeasuredWidth(), 3639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project content.getMeasuredHeight()); 3649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project handle.layout(childLeft, childTop, childLeft + childWidth, childTop + childHeight); 3679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mHandleHeight = handle.getHeight(); 3689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mHandleWidth = handle.getWidth(); 3699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 3729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean onInterceptTouchEvent(MotionEvent event) { 3739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mLocked) { 3749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 3759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int action = event.getAction(); 3789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float x = event.getX(); 3809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float y = event.getY(); 3819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final Rect frame = mFrame; 3839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final View handle = mHandle; 3849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project handle.getHitRect(frame); 3869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mTracking && !frame.contains((int) x, (int) y)) { 3879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 3889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (action == MotionEvent.ACTION_DOWN) { 3919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mTracking = true; 3929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project handle.setPressed(true); 3949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Must be called before prepareTracking() 3959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project prepareContent(); 3969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 397c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project // Must be called after prepareContent() 398c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project if (mOnDrawerScrollListener != null) { 399c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project mOnDrawerScrollListener.onScrollStarted(); 400c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project } 401c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project 4029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mVertical) { 4039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int top = mHandle.getTop(); 4049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mTouchDelta = (int) y - top; 4059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project prepareTracking(top); 4069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 4079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int left = mHandle.getLeft(); 4089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mTouchDelta = (int) x - left; 4099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project prepareTracking(left); 4109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mVelocityTracker.addMovement(event); 4129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 4159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 4189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean onTouchEvent(MotionEvent event) { 4199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mLocked) { 4209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 4219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mTracking) { 4249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mVelocityTracker.addMovement(event); 4259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int action = event.getAction(); 4269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project switch (action) { 4279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case MotionEvent.ACTION_MOVE: 4289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project moveHandle((int) (mVertical ? event.getY() : event.getX()) - mTouchDelta); 4299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 4309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case MotionEvent.ACTION_UP: 4319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case MotionEvent.ACTION_CANCEL: { 4329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final VelocityTracker velocityTracker = mVelocityTracker; 4339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project velocityTracker.computeCurrentVelocity(mVelocityUnits); 4349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float yVelocity = velocityTracker.getYVelocity(); 4369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float xVelocity = velocityTracker.getXVelocity(); 4379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean negative; 4389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final boolean vertical = mVertical; 4409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (vertical) { 4419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project negative = yVelocity < 0; 4429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (xVelocity < 0) { 4439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project xVelocity = -xVelocity; 4449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (xVelocity > mMaximumMinorVelocity) { 4469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project xVelocity = mMaximumMinorVelocity; 4479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 4499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project negative = xVelocity < 0; 4509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (yVelocity < 0) { 4519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project yVelocity = -yVelocity; 4529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (yVelocity > mMaximumMinorVelocity) { 4549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project yVelocity = mMaximumMinorVelocity; 4559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float velocity = (float) Math.hypot(xVelocity, yVelocity); 4599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (negative) { 4609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project velocity = -velocity; 4619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int top = mHandle.getTop(); 4649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int left = mHandle.getLeft(); 4659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (Math.abs(velocity) < mMaximumTapVelocity) { 4679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (vertical ? (mExpanded && top < mTapThreshold + mTopOffset) || 4689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (!mExpanded && top > mBottomOffset + mBottom - mTop - 4699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mHandleHeight - mTapThreshold) : 4709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (mExpanded && left < mTapThreshold + mTopOffset) || 4719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (!mExpanded && left > mBottomOffset + mRight - mLeft - 4729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mHandleWidth - mTapThreshold)) { 4739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mAllowSingleTap) { 4759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project playSoundEffect(SoundEffectConstants.CLICK); 4769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mExpanded) { 4789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project animateClose(vertical ? top : left); 4799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 4809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project animateOpen(vertical ? top : left); 4819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 482c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project } else { 483c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project performFling(vertical ? top : left, velocity, false); 4849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 4879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project performFling(vertical ? top : left, velocity, false); 4889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 4909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project performFling(vertical ? top : left, velocity, false); 4919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 4949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mTracking || mAnimating || super.onTouchEvent(event); 4989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void animateClose(int position) { 5019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project prepareTracking(position); 5029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project performFling(position, mMaximumAcceleration, true); 5039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void animateOpen(int position) { 5069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project prepareTracking(position); 5079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project performFling(position, -mMaximumAcceleration, true); 5089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void performFling(int position, float velocity, boolean always) { 5119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mAnimationPosition = position; 5129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mAnimatedVelocity = velocity; 5139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mExpanded) { 5159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (always || (velocity > mMaximumMajorVelocity || 5169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (position > mTopOffset + (mVertical ? mHandleHeight : mHandleWidth) && 5179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project velocity > -mMaximumMajorVelocity))) { 5189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // We are expanded, but they didn't move sufficiently to cause 5199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // us to retract. Animate back to the expanded position. 5209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mAnimatedAcceleration = mMaximumAcceleration; 5219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (velocity < 0) { 5229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mAnimatedVelocity = 0; 5239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 5259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // We are expanded and are now going to animate away. 5269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mAnimatedAcceleration = -mMaximumAcceleration; 5279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (velocity > 0) { 5289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mAnimatedVelocity = 0; 5299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 5329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!always && (velocity > mMaximumMajorVelocity || 5339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (position > (mVertical ? getHeight() : getWidth()) / 2 && 5349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project velocity > -mMaximumMajorVelocity))) { 5359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // We are collapsed, and they moved enough to allow us to expand. 5369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mAnimatedAcceleration = mMaximumAcceleration; 5379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (velocity < 0) { 5389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mAnimatedVelocity = 0; 5399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 5419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // We are collapsed, but they didn't move sufficiently to cause 5429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // us to retract. Animate back to the collapsed position. 5439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mAnimatedAcceleration = -mMaximumAcceleration; 5449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (velocity > 0) { 5459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mAnimatedVelocity = 0; 5469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project long now = SystemClock.uptimeMillis(); 5519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mAnimationLastTime = now; 5529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCurrentAnimationTime = now + ANIMATION_FRAME_DURATION; 5539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mAnimating = true; 554d0374c6b25c3ad8e638827bd8190553f80d9bf22John Reck removeCallbacks(mSlidingRunnable); 555d0374c6b25c3ad8e638827bd8190553f80d9bf22John Reck postDelayed(mSlidingRunnable, ANIMATION_FRAME_DURATION); 5569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project stopTracking(); 5579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void prepareTracking(int position) { 5609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mTracking = true; 5619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mVelocityTracker = VelocityTracker.obtain(); 5629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean opening = !mExpanded; 5639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (opening) { 5649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mAnimatedAcceleration = mMaximumAcceleration; 5659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mAnimatedVelocity = mMaximumMajorVelocity; 5669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mAnimationPosition = mBottomOffset + 5679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (mVertical ? getHeight() - mHandleHeight : getWidth() - mHandleWidth); 5689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project moveHandle((int) mAnimationPosition); 5699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mAnimating = true; 570d0374c6b25c3ad8e638827bd8190553f80d9bf22John Reck removeCallbacks(mSlidingRunnable); 5719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project long now = SystemClock.uptimeMillis(); 5729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mAnimationLastTime = now; 5739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCurrentAnimationTime = now + ANIMATION_FRAME_DURATION; 5749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mAnimating = true; 5759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 5769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mAnimating) { 5779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mAnimating = false; 578d0374c6b25c3ad8e638827bd8190553f80d9bf22John Reck removeCallbacks(mSlidingRunnable); 5799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project moveHandle(position); 5819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void moveHandle(int position) { 5859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final View handle = mHandle; 5869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mVertical) { 5889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (position == EXPANDED_FULL_OPEN) { 5899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project handle.offsetTopAndBottom(mTopOffset - handle.getTop()); 5909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project invalidate(); 5919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (position == COLLAPSED_FULL_CLOSED) { 5929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project handle.offsetTopAndBottom(mBottomOffset + mBottom - mTop - 5939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mHandleHeight - handle.getTop()); 5949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project invalidate(); 5959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 5969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int top = handle.getTop(); 5979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int deltaY = position - top; 5989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (position < mTopOffset) { 5999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project deltaY = mTopOffset - top; 6009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (deltaY > mBottomOffset + mBottom - mTop - mHandleHeight - top) { 6019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project deltaY = mBottomOffset + mBottom - mTop - mHandleHeight - top; 6029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project handle.offsetTopAndBottom(deltaY); 6049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final Rect frame = mFrame; 6069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final Rect region = mInvalidate; 6079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project handle.getHitRect(frame); 6099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project region.set(frame); 6109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project region.union(frame.left, frame.top - deltaY, frame.right, frame.bottom - deltaY); 6129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project region.union(0, frame.bottom - deltaY, getWidth(), 6139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project frame.bottom - deltaY + mContent.getHeight()); 6149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project invalidate(region); 6169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 6189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (position == EXPANDED_FULL_OPEN) { 6199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project handle.offsetLeftAndRight(mTopOffset - handle.getLeft()); 6209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project invalidate(); 6219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (position == COLLAPSED_FULL_CLOSED) { 6229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project handle.offsetLeftAndRight(mBottomOffset + mRight - mLeft - 6239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mHandleWidth - handle.getLeft()); 6249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project invalidate(); 6259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 6269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int left = handle.getLeft(); 6279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int deltaX = position - left; 6289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (position < mTopOffset) { 6299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project deltaX = mTopOffset - left; 6309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (deltaX > mBottomOffset + mRight - mLeft - mHandleWidth - left) { 6319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project deltaX = mBottomOffset + mRight - mLeft - mHandleWidth - left; 6329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project handle.offsetLeftAndRight(deltaX); 6349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final Rect frame = mFrame; 6369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final Rect region = mInvalidate; 6379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project handle.getHitRect(frame); 6399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project region.set(frame); 6409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project region.union(frame.left - deltaX, frame.top, frame.right - deltaX, frame.bottom); 6429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project region.union(frame.right - deltaX, 0, 6439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project frame.right - deltaX + mContent.getWidth(), getHeight()); 6449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project invalidate(region); 6469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void prepareContent() { 6519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mAnimating) { 6529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 6539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Something changed in the content, we need to honor the layout request 6569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // before creating the cached bitmap 6579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final View content = mContent; 6589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (content.isLayoutRequested()) { 6599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mVertical) { 6609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int childHeight = mHandleHeight; 6619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int height = mBottom - mTop - childHeight - mTopOffset; 6629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project content.measure(MeasureSpec.makeMeasureSpec(mRight - mLeft, MeasureSpec.EXACTLY), 6639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY)); 6649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project content.layout(0, mTopOffset + childHeight, content.getMeasuredWidth(), 6659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mTopOffset + childHeight + content.getMeasuredHeight()); 6669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 6679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int childWidth = mHandle.getWidth(); 6689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int width = mRight - mLeft - childWidth - mTopOffset; 6699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project content.measure(MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY), 6709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project MeasureSpec.makeMeasureSpec(mBottom - mTop, MeasureSpec.EXACTLY)); 6719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project content.layout(childWidth + mTopOffset, 0, 6729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mTopOffset + childWidth + content.getMeasuredWidth(), 6739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project content.getMeasuredHeight()); 6749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Try only once... we should really loop but it's not a big deal 6779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // if the draw was cancelled, it will only be temporary anyway 6789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project content.getViewTreeObserver().dispatchOnPreDraw(); 6790d9275e565551eed57297627188aa39f3897a50bRomain Guy if (!content.isHardwareAccelerated()) content.buildDrawingCache(); 6809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project content.setVisibility(View.GONE); 6829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void stopTracking() { 6859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mHandle.setPressed(false); 6869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mTracking = false; 6879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mOnDrawerScrollListener != null) { 6899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mOnDrawerScrollListener.onScrollEnded(); 6909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mVelocityTracker != null) { 6939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mVelocityTracker.recycle(); 6949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mVelocityTracker = null; 6959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void doAnimation() { 6999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mAnimating) { 7009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project incrementAnimation(); 7019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mAnimationPosition >= mBottomOffset + (mVertical ? getHeight() : getWidth()) - 1) { 7029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mAnimating = false; 7039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project closeDrawer(); 7049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (mAnimationPosition < mTopOffset) { 7059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mAnimating = false; 7069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project openDrawer(); 7079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 7089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project moveHandle((int) mAnimationPosition); 7099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCurrentAnimationTime += ANIMATION_FRAME_DURATION; 710d0374c6b25c3ad8e638827bd8190553f80d9bf22John Reck postDelayed(mSlidingRunnable, ANIMATION_FRAME_DURATION); 7119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void incrementAnimation() { 7169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project long now = SystemClock.uptimeMillis(); 7179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float t = (now - mAnimationLastTime) / 1000.0f; // ms -> s 7189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final float position = mAnimationPosition; 7199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final float v = mAnimatedVelocity; // px/s 7209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final float a = mAnimatedAcceleration; // px/s/s 7219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mAnimationPosition = position + (v * t) + (0.5f * a * t * t); // px 7229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mAnimatedVelocity = v + (a * t); // px/s 7239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mAnimationLastTime = now; // ms 7249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 7279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Toggles the drawer open and close. Takes effect immediately. 7289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 7299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #open() 7309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #close() 7319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #animateClose() 7329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #animateOpen() 7339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #animateToggle() 7349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 7359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void toggle() { 7369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mExpanded) { 7379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project openDrawer(); 7389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 7399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project closeDrawer(); 7409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project invalidate(); 7429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project requestLayout(); 7439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 7469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Toggles the drawer open and close with an animation. 7479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 7489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #open() 7499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #close() 7509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #animateClose() 7519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #animateOpen() 7529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #toggle() 7539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 7549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void animateToggle() { 7559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mExpanded) { 7569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project animateOpen(); 7579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 7589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project animateClose(); 7599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 7639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Opens the drawer immediately. 7649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 7659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #toggle() 7669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #close() 7679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #animateOpen() 7689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 7699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void open() { 7709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project openDrawer(); 7719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project invalidate(); 7729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project requestLayout(); 77375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 77475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED); 7759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 7789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Closes the drawer immediately. 7799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 7809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #toggle() 7819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #open() 7829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #animateClose() 7839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 7849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void close() { 7859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project closeDrawer(); 7869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project invalidate(); 7879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project requestLayout(); 7889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 7919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Closes the drawer with an animation. 7929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 7939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #close() 7949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #open() 7959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #animateOpen() 7969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #animateToggle() 7979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #toggle() 7989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 7999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void animateClose() { 800c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project prepareContent(); 8019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final OnDrawerScrollListener scrollListener = mOnDrawerScrollListener; 8029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (scrollListener != null) { 8039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project scrollListener.onScrollStarted(); 8049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project animateClose(mVertical ? mHandle.getTop() : mHandle.getLeft()); 80675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 8079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (scrollListener != null) { 8089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project scrollListener.onScrollEnded(); 8099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 8139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Opens the drawer with an animation. 8149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 8159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #close() 8169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #open() 8179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #animateClose() 8189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #animateToggle() 8199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #toggle() 8209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 8219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void animateOpen() { 822c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project prepareContent(); 8239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final OnDrawerScrollListener scrollListener = mOnDrawerScrollListener; 8249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (scrollListener != null) { 8259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project scrollListener.onScrollStarted(); 8269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project animateOpen(mVertical ? mHandle.getTop() : mHandle.getLeft()); 82875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 82975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED); 83075986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 8319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (scrollListener != null) { 8329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project scrollListener.onScrollEnded(); 8339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8368a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganov @Override 837a7bb6fbeab933326d58aa806d8194b7b13239d34Dianne Hackborn public CharSequence getAccessibilityClassName() { 838a7bb6fbeab933326d58aa806d8194b7b13239d34Dianne Hackborn return SlidingDrawer.class.getName(); 8398a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganov } 8408a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganov 8419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void closeDrawer() { 8429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project moveHandle(COLLAPSED_FULL_CLOSED); 8439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mContent.setVisibility(View.GONE); 8449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mContent.destroyDrawingCache(); 8459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mExpanded) { 8479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 8489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mExpanded = false; 8519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mOnDrawerCloseListener != null) { 8529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mOnDrawerCloseListener.onDrawerClosed(); 8539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void openDrawer() { 8579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project moveHandle(EXPANDED_FULL_OPEN); 8589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mContent.setVisibility(View.VISIBLE); 8599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mExpanded) { 8619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 8629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mExpanded = true; 86575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 8669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mOnDrawerOpenListener != null) { 8679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mOnDrawerOpenListener.onDrawerOpened(); 8689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 8729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Sets the listener that receives a notification when the drawer becomes open. 8739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 8749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param onDrawerOpenListener The listener to be notified when the drawer is opened. 8759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 8769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setOnDrawerOpenListener(OnDrawerOpenListener onDrawerOpenListener) { 8779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mOnDrawerOpenListener = onDrawerOpenListener; 8789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 8819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Sets the listener that receives a notification when the drawer becomes close. 8829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 8839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param onDrawerCloseListener The listener to be notified when the drawer is closed. 8849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 8859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setOnDrawerCloseListener(OnDrawerCloseListener onDrawerCloseListener) { 8869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mOnDrawerCloseListener = onDrawerCloseListener; 8879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 8909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Sets the listener that receives a notification when the drawer starts or ends 8919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * a scroll. A fling is considered as a scroll. A fling will also trigger a 8929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * drawer opened or drawer closed event. 8939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 8949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param onDrawerScrollListener The listener to be notified when scrolling 8959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * starts or stops. 8969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 8979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setOnDrawerScrollListener(OnDrawerScrollListener onDrawerScrollListener) { 8989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mOnDrawerScrollListener = onDrawerScrollListener; 8999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 9029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns the handle of the drawer. 9039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 9049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return The View reprenseting the handle of the drawer, identified by 9059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the "handle" id in XML. 9069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 9079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public View getHandle() { 9089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mHandle; 9099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 9129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns the content of the drawer. 9139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 9149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return The View reprenseting the content of the drawer, identified by 9159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the "content" id in XML. 9169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 9179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public View getContent() { 9189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mContent; 9199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 9229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unlocks the SlidingDrawer so that touch events are processed. 9239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 9249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #lock() 9259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 9269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void unlock() { 9279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLocked = false; 9289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 9319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Locks the SlidingDrawer so that touch events are ignores. 9329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 9339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #unlock() 9349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 9359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void lock() { 9369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLocked = true; 9379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 9409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Indicates whether the drawer is currently fully opened. 9419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 9429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return True if the drawer is opened, false otherwise. 9439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 9449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean isOpened() { 9459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mExpanded; 9469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 9499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Indicates whether the drawer is scrolling or flinging. 9509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 9519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return True if the drawer is scroller or flinging, false otherwise. 9529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 9539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean isMoving() { 9549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mTracking || mAnimating; 9559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private class DrawerToggler implements OnClickListener { 9589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void onClick(View v) { 9599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mLocked) { 9609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 9619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // mAllowSingleTap isn't relevant here; you're *always* 9639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // allowed to open/close the drawer by clicking with the 9649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // trackball. 9659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mAnimateOnClick) { 9679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project animateToggle(); 9689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 9699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project toggle(); 9709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 974d0374c6b25c3ad8e638827bd8190553f80d9bf22John Reck private final Runnable mSlidingRunnable = new Runnable() { 975d0374c6b25c3ad8e638827bd8190553f80d9bf22John Reck @Override 976d0374c6b25c3ad8e638827bd8190553f80d9bf22John Reck public void run() { 977d0374c6b25c3ad8e638827bd8190553f80d9bf22John Reck doAnimation(); 9789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 979d0374c6b25c3ad8e638827bd8190553f80d9bf22John Reck }; 9809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 981