OverlappingPaneLayout.java revision 40ed60dab29e90e28f95a0d8a9c612fed7a253ce
1e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee/* 2e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee * Copyright (C) 2012 The Android Open Source Project 3e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee * 4e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee * Licensed under the Apache License, Version 2.0 (the "License"); 5e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee * you may not use this file except in compliance with the License. 6e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee * You may obtain a copy of the License at 7e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee * 8e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee * http://www.apache.org/licenses/LICENSE-2.0 9e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee * 10e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee * Unless required by applicable law or agreed to in writing, software 11e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee * distributed under the License is distributed on an "AS IS" BASIS, 12e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee * See the License for the specific language governing permissions and 14e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee * limitations under the License. 15e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee */ 16e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 17e709fd21eda44df07327f649e4e6a257918555a9Yorke Leepackage com.android.dialer.widget; 18e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 19e709fd21eda44df07327f649e4e6a257918555a9Yorke Leeimport android.content.Context; 20e709fd21eda44df07327f649e4e6a257918555a9Yorke Leeimport android.content.res.TypedArray; 21e709fd21eda44df07327f649e4e6a257918555a9Yorke Leeimport android.graphics.Canvas; 22e709fd21eda44df07327f649e4e6a257918555a9Yorke Leeimport android.graphics.PixelFormat; 23e709fd21eda44df07327f649e4e6a257918555a9Yorke Leeimport android.graphics.Rect; 24e709fd21eda44df07327f649e4e6a257918555a9Yorke Leeimport android.graphics.drawable.Drawable; 25e709fd21eda44df07327f649e4e6a257918555a9Yorke Leeimport android.os.Build; 26e709fd21eda44df07327f649e4e6a257918555a9Yorke Leeimport android.os.Parcel; 27e709fd21eda44df07327f649e4e6a257918555a9Yorke Leeimport android.os.Parcelable; 28e709fd21eda44df07327f649e4e6a257918555a9Yorke Leeimport android.support.v4.view.AccessibilityDelegateCompat; 29e709fd21eda44df07327f649e4e6a257918555a9Yorke Leeimport android.support.v4.view.MotionEventCompat; 30e709fd21eda44df07327f649e4e6a257918555a9Yorke Leeimport android.support.v4.view.ViewCompat; 31e709fd21eda44df07327f649e4e6a257918555a9Yorke Leeimport android.support.v4.view.accessibility.AccessibilityNodeInfoCompat; 32e709fd21eda44df07327f649e4e6a257918555a9Yorke Leeimport android.util.AttributeSet; 33e709fd21eda44df07327f649e4e6a257918555a9Yorke Leeimport android.util.Log; 34e709fd21eda44df07327f649e4e6a257918555a9Yorke Leeimport android.view.MotionEvent; 35e709fd21eda44df07327f649e4e6a257918555a9Yorke Leeimport android.view.View; 36e709fd21eda44df07327f649e4e6a257918555a9Yorke Leeimport android.view.ViewGroup; 37e709fd21eda44df07327f649e4e6a257918555a9Yorke Leeimport android.view.ViewParent; 38e709fd21eda44df07327f649e4e6a257918555a9Yorke Leeimport android.view.accessibility.AccessibilityEvent; 39e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 40e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee/** 41e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee * A custom layout that aligns its child views vertically as two panes, and allows for the bottom 42e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee * pane to be dragged upwards to overlap and hide the top pane. This layout is adapted from 43e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee * {@link android.support.v4.widget.SlidingPaneLayout}. 44e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee */ 45e709fd21eda44df07327f649e4e6a257918555a9Yorke Leepublic class OverlappingPaneLayout extends ViewGroup { 46e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee private static final String TAG = "SlidingPaneLayout"; 475c7e73087ccb1615c6e460beb6c9734e665c527fYorke Lee private static final boolean DEBUG = false; 48e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 49e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee /** 50e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee * Default size of the overhang for a pane in the open state. 51e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee * At least this much of a sliding pane will remain visible. 52e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee * This indicates that there is more content available and provides 53e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee * a "physical" edge to grab to pull it closed. 54e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee */ 55e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee private static final int DEFAULT_OVERHANG_SIZE = 32; // dp; 56e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 57e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee /** 58e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee * If no fade color is given by default it will fade to 80% gray. 59e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee */ 60e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee private static final int DEFAULT_FADE_COLOR = 0xcccccccc; 61e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 62e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee /** 63e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee * Minimum velocity that will be detected as a fling 64e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee */ 65e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee private static final int MIN_FLING_VELOCITY = 400; // dips per second 66e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 67e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee /** 68e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee * The size of the overhang in pixels. 69e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee * This is the minimum section of the sliding panel that will 70e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee * be visible in the open state to allow for a closing drag. 71e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee */ 72e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee private final int mOverhangSize; 73e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 74e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee /** 75e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee * True if a panel can slide with the current measurements 76e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee */ 77e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee private boolean mCanSlide; 78e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 79e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee /** 80e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee * The child view that can slide, if any. 81e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee */ 82e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee private View mSlideableView; 83e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 84e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee /** 85e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee * The view that can be used to start the drag with. 86e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee */ 87e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee private View mCapturableView; 88e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 89e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee /** 90e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee * How far the panel is offset from its closed position. 91e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee * range [0, 1] where 0 = closed, 1 = open. 92e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee */ 93e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee private float mSlideOffset; 94e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 95e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee /** 965c7e73087ccb1615c6e460beb6c9734e665c527fYorke Lee * How far the panel is offset from its closed position, in pixels. 975c7e73087ccb1615c6e460beb6c9734e665c527fYorke Lee * range [0, {@link #mSlideRange}] where 0 is completely closed. 985c7e73087ccb1615c6e460beb6c9734e665c527fYorke Lee */ 995c7e73087ccb1615c6e460beb6c9734e665c527fYorke Lee private int mSlideOffsetPx; 1005c7e73087ccb1615c6e460beb6c9734e665c527fYorke Lee 1015c7e73087ccb1615c6e460beb6c9734e665c527fYorke Lee /** 102e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee * How far in pixels the slideable panel may move. 103e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee */ 104e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee private int mSlideRange; 105e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 106e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee /** 107e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee * A panel view is locked into internal scrolling or another condition that 108e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee * is preventing a drag. 109e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee */ 110e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee private boolean mIsUnableToDrag; 111e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 112bd180af7f0b73b0dd79a7117fb0c14370ef4d12eYorke Lee /** 113bd180af7f0b73b0dd79a7117fb0c14370ef4d12eYorke Lee * Tracks whether or not a child view is in the process of a nested scroll. 114bd180af7f0b73b0dd79a7117fb0c14370ef4d12eYorke Lee */ 115bd180af7f0b73b0dd79a7117fb0c14370ef4d12eYorke Lee private boolean mIsInNestedScroll; 116bd180af7f0b73b0dd79a7117fb0c14370ef4d12eYorke Lee 1175c7e73087ccb1615c6e460beb6c9734e665c527fYorke Lee /** 1185c7e73087ccb1615c6e460beb6c9734e665c527fYorke Lee * Indicates that the layout is currently in the process of a nested pre-scroll operation where 11940ed60dab29e90e28f95a0d8a9c612fed7a253ceYorke Lee * the child scrolling view is being dragged downwards, and still has the ability to consume 12040ed60dab29e90e28f95a0d8a9c612fed7a253ceYorke Lee * scroll events itself. If so, we should open the pane up to the maximum offset defined in 12140ed60dab29e90e28f95a0d8a9c612fed7a253ceYorke Lee * {@link #mIntermediateOffset}, and no further, so that the child view can continue performing 12240ed60dab29e90e28f95a0d8a9c612fed7a253ceYorke Lee * its own scroll. 1235c7e73087ccb1615c6e460beb6c9734e665c527fYorke Lee */ 12440ed60dab29e90e28f95a0d8a9c612fed7a253ceYorke Lee private boolean mInNestedPreScrollDownwards = false; 12540ed60dab29e90e28f95a0d8a9c612fed7a253ceYorke Lee 12640ed60dab29e90e28f95a0d8a9c612fed7a253ceYorke Lee /** 12740ed60dab29e90e28f95a0d8a9c612fed7a253ceYorke Lee * Indicates whether or not a nested scrolling child is able to scroll internally at this point 12840ed60dab29e90e28f95a0d8a9c612fed7a253ceYorke Lee * in time. 12940ed60dab29e90e28f95a0d8a9c612fed7a253ceYorke Lee */ 13040ed60dab29e90e28f95a0d8a9c612fed7a253ceYorke Lee private boolean mChildCannotConsumeScroll; 1315c7e73087ccb1615c6e460beb6c9734e665c527fYorke Lee 1325c7e73087ccb1615c6e460beb6c9734e665c527fYorke Lee /** 1335c7e73087ccb1615c6e460beb6c9734e665c527fYorke Lee * Stores an offset used to represent a point somewhere in between the panel's fully closed 1345c7e73087ccb1615c6e460beb6c9734e665c527fYorke Lee * state and fully opened state where the panel can be temporarily pinned or opened up to 1355c7e73087ccb1615c6e460beb6c9734e665c527fYorke Lee * during scrolling. 1365c7e73087ccb1615c6e460beb6c9734e665c527fYorke Lee */ 1375c7e73087ccb1615c6e460beb6c9734e665c527fYorke Lee private int mIntermediateOffset = 0; 1385c7e73087ccb1615c6e460beb6c9734e665c527fYorke Lee 139e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee private float mInitialMotionX; 140e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee private float mInitialMotionY; 141e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 142e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee private PanelSlideListener mPanelSlideListener; 143e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 144e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee private final ViewDragHelper mDragHelper; 145e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 146e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee /** 147e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee * Stores whether or not the pane was open the last time it was slideable. 148e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee * If open/close operations are invoked this state is modified. Used by 149e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee * instance state save/restore. 150e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee */ 151e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee private boolean mPreservedOpenState; 152e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee private boolean mFirstLayout = true; 153e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 154e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee private final Rect mTmpRect = new Rect(); 155e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 156e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee /** 157e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee * Listener for monitoring events about sliding panes. 158e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee */ 159e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee public interface PanelSlideListener { 160e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee /** 161e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee * Called when a sliding pane's position changes. 162e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee * @param panel The child view that was moved 163e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee * @param slideOffset The new offset of this sliding pane within its range, from 0-1 164e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee */ 165e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee public void onPanelSlide(View panel, float slideOffset); 166e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee /** 167e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee * Called when a sliding pane becomes slid completely open. The pane may or may not 168e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee * be interactive at this point depending on how much of the pane is visible. 169e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee * @param panel The child view that was slid to an open position, revealing other panes 170e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee */ 171e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee public void onPanelOpened(View panel); 172e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 173e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee /** 174e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee * Called when a sliding pane becomes slid completely closed. The pane is now guaranteed 175e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee * to be interactive. It may now obscure other views in the layout. 176e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee * @param panel The child view that was slid to a closed position 177e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee */ 178e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee public void onPanelClosed(View panel); 179e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee } 180e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 181e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee public OverlappingPaneLayout(Context context) { 182e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee this(context, null); 183e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee } 184e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 185e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee public OverlappingPaneLayout(Context context, AttributeSet attrs) { 186e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee this(context, attrs, 0); 187e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee } 188e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 189e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee public OverlappingPaneLayout(Context context, AttributeSet attrs, int defStyle) { 190e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee super(context, attrs, defStyle); 191e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 192e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee final float density = context.getResources().getDisplayMetrics().density; 193e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee mOverhangSize = (int) (DEFAULT_OVERHANG_SIZE * density + 0.5f); 194e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 195e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee setWillNotDraw(false); 196e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 197e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee ViewCompat.setAccessibilityDelegate(this, new AccessibilityDelegate()); 198e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee ViewCompat.setImportantForAccessibility(this, ViewCompat.IMPORTANT_FOR_ACCESSIBILITY_YES); 199e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 200e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee mDragHelper = ViewDragHelper.create(this, 0.5f, new DragHelperCallback()); 201e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee mDragHelper.setMinVelocity(MIN_FLING_VELOCITY * density); 202e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee } 203e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 204e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee /** 2055c7e73087ccb1615c6e460beb6c9734e665c527fYorke Lee * Set an offset, somewhere in between the panel's fully closed state and fully opened state, 2065c7e73087ccb1615c6e460beb6c9734e665c527fYorke Lee * where the panel can be temporarily pinned or opened up to. 2075c7e73087ccb1615c6e460beb6c9734e665c527fYorke Lee * 2085c7e73087ccb1615c6e460beb6c9734e665c527fYorke Lee * @param offset Offset in pixels 2095c7e73087ccb1615c6e460beb6c9734e665c527fYorke Lee */ 2105c7e73087ccb1615c6e460beb6c9734e665c527fYorke Lee public void setIntermediatePinnedOffset(int offset) { 2115c7e73087ccb1615c6e460beb6c9734e665c527fYorke Lee mIntermediateOffset = offset; 2125c7e73087ccb1615c6e460beb6c9734e665c527fYorke Lee } 2135c7e73087ccb1615c6e460beb6c9734e665c527fYorke Lee 2145c7e73087ccb1615c6e460beb6c9734e665c527fYorke Lee /** 215e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee * Set the view that can be used to start dragging the sliding pane. 216e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee */ 217e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee public void setCapturableView(View capturableView) { 218e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee mCapturableView = capturableView; 219e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee } 220e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 221e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee public void setPanelSlideListener(PanelSlideListener listener) { 222e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee mPanelSlideListener = listener; 223e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee } 224e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 225e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee void dispatchOnPanelSlide(View panel) { 226e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee if (mPanelSlideListener != null) { 227e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee mPanelSlideListener.onPanelSlide(panel, mSlideOffset); 228e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee } 229e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee } 230e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 231e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee void dispatchOnPanelOpened(View panel) { 232e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee if (mPanelSlideListener != null) { 233e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee mPanelSlideListener.onPanelOpened(panel); 234e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee } 235e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED); 236e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee } 237e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 238e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee void dispatchOnPanelClosed(View panel) { 239e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee if (mPanelSlideListener != null) { 240e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee mPanelSlideListener.onPanelClosed(panel); 241e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee } 242e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED); 243e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee } 244e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 245e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee void updateObscuredViewsVisibility(View panel) { 246e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee final int startBound = getPaddingTop(); 247e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee final int endBound = getHeight() - getPaddingBottom(); 248e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 249e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee final int leftBound = getPaddingLeft(); 250e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee final int rightBound = getWidth() - getPaddingRight(); 251e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee final int left; 252e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee final int right; 253e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee final int top; 254e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee final int bottom; 255e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee if (panel != null && viewIsOpaque(panel)) { 256e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee left = panel.getLeft(); 257e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee right = panel.getRight(); 258e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee top = panel.getTop(); 259e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee bottom = panel.getBottom(); 260e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee } else { 261e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee left = right = top = bottom = 0; 262e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee } 263e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 264e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee for (int i = 0, childCount = getChildCount(); i < childCount; i++) { 265e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee final View child = getChildAt(i); 266e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 267e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee if (child == panel) { 268e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee // There are still more children above the panel but they won't be affected. 269e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee break; 270e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee } 271e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 272e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee final int clampedChildLeft = Math.max(leftBound, child.getLeft()); 273e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee final int clampedChildRight = Math.min(rightBound, child.getRight()); 274e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee final int clampedChildTop = Math.max(startBound, child.getTop()); 275e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee final int clampedChildBottom = Math.min(endBound, child.getBottom()); 276e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 277e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee final int vis; 278e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee if (clampedChildLeft >= left && clampedChildTop >= top && 279e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee clampedChildRight <= right && clampedChildBottom <= bottom) { 280e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee vis = INVISIBLE; 281e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee } else { 282e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee vis = VISIBLE; 283e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee } 284e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee child.setVisibility(vis); 285e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee } 286e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee } 287e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 288e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee void setAllChildrenVisible() { 289e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee for (int i = 0, childCount = getChildCount(); i < childCount; i++) { 290e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee final View child = getChildAt(i); 291e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee if (child.getVisibility() == INVISIBLE) { 292e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee child.setVisibility(VISIBLE); 293e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee } 294e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee } 295e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee } 296e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 297e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee private static boolean viewIsOpaque(View v) { 298e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee if (ViewCompat.isOpaque(v)) return true; 299e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 300e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee final Drawable bg = v.getBackground(); 301e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee if (bg != null) { 302e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee return bg.getOpacity() == PixelFormat.OPAQUE; 303e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee } 304e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee return false; 305e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee } 306e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 307e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee @Override 308e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee protected void onAttachedToWindow() { 309e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee super.onAttachedToWindow(); 310e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee mFirstLayout = true; 311e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee } 312e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 313e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee @Override 314e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee protected void onDetachedFromWindow() { 315e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee super.onDetachedFromWindow(); 316e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee mFirstLayout = true; 317e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee } 318e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 319e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee @Override 320e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 321e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 322e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee int widthMode = MeasureSpec.getMode(widthMeasureSpec); 323e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee int widthSize = MeasureSpec.getSize(widthMeasureSpec); 324e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee int heightMode = MeasureSpec.getMode(heightMeasureSpec); 325e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee int heightSize = MeasureSpec.getSize(heightMeasureSpec); 326e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 327e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee if (widthMode != MeasureSpec.EXACTLY) { 328e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee if (isInEditMode()) { 329e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee // Don't crash the layout editor. Consume all of the space if specified 330e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee // or pick a magic number from thin air otherwise. 331e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee // TODO Better communication with tools of this bogus state. 332e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee // It will crash on a real device. 333e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee if (widthMode == MeasureSpec.AT_MOST) { 334e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee widthMode = MeasureSpec.EXACTLY; 335e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee } else if (widthMode == MeasureSpec.UNSPECIFIED) { 336e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee widthMode = MeasureSpec.EXACTLY; 337e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee widthSize = 300; 338e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee } 339e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee } else { 340e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee throw new IllegalStateException("Width must have an exact value or MATCH_PARENT"); 341e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee } 342e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee } else if (heightMode == MeasureSpec.UNSPECIFIED) { 343e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee if (isInEditMode()) { 344e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee // Don't crash the layout editor. Pick a magic number from thin air instead. 345e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee // TODO Better communication with tools of this bogus state. 346e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee // It will crash on a real device. 347e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee if (heightMode == MeasureSpec.UNSPECIFIED) { 348e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee heightMode = MeasureSpec.AT_MOST; 349e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee heightSize = 300; 350e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee } 351e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee } else { 352e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee throw new IllegalStateException("Height must not be UNSPECIFIED"); 353e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee } 354e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee } 355e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 356e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee int layoutWidth = 0; 357e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee int maxLayoutWidth = -1; 358e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee switch (widthMode) { 359e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee case MeasureSpec.EXACTLY: 360e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee layoutWidth = maxLayoutWidth = widthSize - getPaddingLeft() - getPaddingRight(); 361e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee break; 362e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee case MeasureSpec.AT_MOST: 363e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee maxLayoutWidth = widthSize - getPaddingLeft() - getPaddingRight(); 364e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee break; 365e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee } 366e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 367e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee float weightSum = 0; 368e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee boolean canSlide = false; 369e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee final int heightAvailable = heightSize - getPaddingTop() - getPaddingBottom(); 370e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee int heightRemaining = heightAvailable; 371e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee final int childCount = getChildCount(); 372e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 373e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee if (childCount > 2) { 374e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee Log.e(TAG, "onMeasure: More than two child views are not supported."); 375e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee } 376e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 377e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee // We'll find the current one below. 378e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee mSlideableView = null; 379e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 380e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee // First pass. Measure based on child LayoutParams width/height. 381e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee // Weight will incur a second pass. 382e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee for (int i = 0; i < childCount; i++) { 383e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee final View child = getChildAt(i); 384e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee final LayoutParams lp = (LayoutParams) child.getLayoutParams(); 385e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 386e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee if (child.getVisibility() == GONE) { 387e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee continue; 388e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee } 389e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 390e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee if (lp.weight > 0) { 391e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee weightSum += lp.weight; 392e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 393e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee // If we have no height, weight is the only contributor to the final size. 394e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee // Measure this view on the weight pass only. 395e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee if (lp.height == 0) continue; 396e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee } 397e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 398e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee int childHeightSpec; 399e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee final int verticalMargin = lp.topMargin + lp.bottomMargin; 400e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee if (lp.height == LayoutParams.WRAP_CONTENT) { 401e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee childHeightSpec = MeasureSpec.makeMeasureSpec(heightAvailable - verticalMargin, 402e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee MeasureSpec.AT_MOST); 403e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee } else if (lp.height == LayoutParams.MATCH_PARENT) { 404e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee childHeightSpec = MeasureSpec.makeMeasureSpec(heightAvailable - verticalMargin, 405e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee MeasureSpec.EXACTLY); 406e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee } else { 407e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee childHeightSpec = MeasureSpec.makeMeasureSpec(lp.height, MeasureSpec.EXACTLY); 408e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee } 409e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 410e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee int childWidthSpec; 411e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee if (lp.width == LayoutParams.WRAP_CONTENT) { 412e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee childWidthSpec = MeasureSpec.makeMeasureSpec(maxLayoutWidth, MeasureSpec.AT_MOST); 413e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee } else if (lp.width == LayoutParams.MATCH_PARENT) { 414e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee childWidthSpec = MeasureSpec.makeMeasureSpec(maxLayoutWidth, MeasureSpec.EXACTLY); 415e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee } else { 416e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee childWidthSpec = MeasureSpec.makeMeasureSpec(lp.width, MeasureSpec.EXACTLY); 417e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee } 418e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 419e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee child.measure(childWidthSpec, childHeightSpec); 420e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee final int childWidth = child.getMeasuredWidth(); 421e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee final int childHeight = child.getMeasuredHeight(); 422e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 423e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee if (widthMode == MeasureSpec.AT_MOST && childWidth > layoutWidth) { 424e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee layoutWidth = Math.min(childWidth, maxLayoutWidth); 425e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee } 426e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 427e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee heightRemaining -= childHeight; 428e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee canSlide |= lp.slideable = heightRemaining < 0; 429e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee if (lp.slideable) { 430e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee mSlideableView = child; 431e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee } 432e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee } 433e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 434e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee // Resolve weight and make sure non-sliding panels are smaller than the full screen. 435e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee if (canSlide || weightSum > 0) { 436e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee final int fixedPanelHeightLimit = heightAvailable - mOverhangSize; 437e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 438e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee for (int i = 0; i < childCount; i++) { 439e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee final View child = getChildAt(i); 440e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 441e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee if (child.getVisibility() == GONE) { 442e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee continue; 443e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee } 444e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 445e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee final LayoutParams lp = (LayoutParams) child.getLayoutParams(); 446e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 447e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee if (child.getVisibility() == GONE) { 448e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee continue; 449e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee } 450e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 451e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee final boolean skippedFirstPass = lp.height == 0 && lp.weight > 0; 452e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee final int measuredHeight = skippedFirstPass ? 0 : child.getMeasuredHeight(); 453e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee if (canSlide && child != mSlideableView) { 454e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee if (lp.height < 0 && (measuredHeight > fixedPanelHeightLimit || lp.weight > 0)) { 455e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee // Fixed panels in a sliding configuration should 456e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee // be clamped to the fixed panel limit. 457e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee final int childWidthSpec; 458e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee if (skippedFirstPass) { 459e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee // Do initial width measurement if we skipped measuring this view 460e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee // the first time around. 461e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee if (lp.width == LayoutParams.WRAP_CONTENT) { 462e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee childWidthSpec = MeasureSpec.makeMeasureSpec(maxLayoutWidth, 463e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee MeasureSpec.AT_MOST); 464e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee } else if (lp.height == LayoutParams.MATCH_PARENT) { 465e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee childWidthSpec = MeasureSpec.makeMeasureSpec(maxLayoutWidth, 466e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee MeasureSpec.EXACTLY); 467e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee } else { 468e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee childWidthSpec = MeasureSpec.makeMeasureSpec(lp.width, 469e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee MeasureSpec.EXACTLY); 470e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee } 471e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee } else { 472e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee childWidthSpec = MeasureSpec.makeMeasureSpec( 473e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee child.getMeasuredWidth(), MeasureSpec.EXACTLY); 474e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee } 475e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee final int childHeightSpec = MeasureSpec.makeMeasureSpec( 476e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee fixedPanelHeightLimit, MeasureSpec.EXACTLY); 477e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee child.measure(childWidthSpec, childHeightSpec); 478e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee } 479e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee } else if (lp.weight > 0) { 480e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee int childWidthSpec; 481e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee if (lp.height == 0) { 482e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee // This was skipped the first time; figure out a real width spec. 483e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee if (lp.width == LayoutParams.WRAP_CONTENT) { 484e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee childWidthSpec = MeasureSpec.makeMeasureSpec(maxLayoutWidth, 485e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee MeasureSpec.AT_MOST); 486e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee } else if (lp.width == LayoutParams.MATCH_PARENT) { 487e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee childWidthSpec = MeasureSpec.makeMeasureSpec(maxLayoutWidth, 488e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee MeasureSpec.EXACTLY); 489e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee } else { 490e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee childWidthSpec = MeasureSpec.makeMeasureSpec(lp.width, 491e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee MeasureSpec.EXACTLY); 492e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee } 493e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee } else { 494e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee childWidthSpec = MeasureSpec.makeMeasureSpec( 495e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee child.getMeasuredWidth(), MeasureSpec.EXACTLY); 496e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee } 497e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 498e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee if (canSlide) { 499e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee // Consume available space 500e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee final int verticalMargin = lp.topMargin + lp.bottomMargin; 501e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee final int newHeight = heightAvailable - verticalMargin; 502e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee final int childHeightSpec = MeasureSpec.makeMeasureSpec( 503e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee newHeight, MeasureSpec.EXACTLY); 504e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee if (measuredHeight != newHeight) { 505e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee child.measure(childWidthSpec, childHeightSpec); 506e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee } 507e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee } else { 508e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee // Distribute the extra width proportionally similar to LinearLayout 509e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee final int heightToDistribute = Math.max(0, heightRemaining); 510e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee final int addedHeight = (int) (lp.weight * heightToDistribute / weightSum); 511e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee final int childHeightSpec = MeasureSpec.makeMeasureSpec( 512e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee measuredHeight + addedHeight, MeasureSpec.EXACTLY); 513e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee child.measure(childWidthSpec, childHeightSpec); 514e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee } 515e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee } 516e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee } 517e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee } 518e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 519e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee final int measuredHeight = heightSize; 520e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee final int measuredWidth = layoutWidth + getPaddingLeft() + getPaddingRight(); 521e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 522e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee setMeasuredDimension(measuredWidth, measuredHeight); 523e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee mCanSlide = canSlide; 524e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 525e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee if (mDragHelper.getViewDragState() != ViewDragHelper.STATE_IDLE && !canSlide) { 526e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee // Cancel scrolling in progress, it's no longer relevant. 527e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee mDragHelper.abort(); 528e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee } 529e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee } 530e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 531e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee @Override 532e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee protected void onLayout(boolean changed, int l, int t, int r, int b) { 533e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee mDragHelper.setEdgeTrackingEnabled(ViewDragHelper.EDGE_TOP); 534e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 535e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee final int height = b - t; 536e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee final int paddingTop = getPaddingTop(); 537e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee final int paddingBottom = getPaddingBottom(); 538e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee final int paddingLeft = getPaddingLeft(); 539e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 540e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee final int childCount = getChildCount(); 541e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee int yStart = paddingTop; 542e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee int nextYStart = yStart; 543e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 544e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee if (mFirstLayout) { 545e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee mSlideOffset = mCanSlide && mPreservedOpenState ? 1.f : 0.f; 546e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee } 547e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 548e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee for (int i = 0; i < childCount; i++) { 549e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee final View child = getChildAt(i); 550e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 551e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee if (child.getVisibility() == GONE) { 552e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee continue; 553e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee } 554e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 555e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee final LayoutParams lp = (LayoutParams) child.getLayoutParams(); 556e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 557e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee final int childHeight = child.getMeasuredHeight(); 558e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 559e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee if (lp.slideable) { 560e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee final int margin = lp.topMargin + lp.bottomMargin; 561e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee final int range = Math.min(nextYStart, 562e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee height - paddingBottom - mOverhangSize) - yStart - margin; 563e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee mSlideRange = range; 564e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee final int lpMargin = lp.topMargin; 565e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee final int pos = (int) (range * mSlideOffset); 566e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee yStart += pos + lpMargin; 5675c7e73087ccb1615c6e460beb6c9734e665c527fYorke Lee updateSlideOffset(pos); 568e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee } else { 569e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee yStart = nextYStart; 570e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee } 571e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 572e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee final int childTop = yStart; 573e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee final int childBottom = childTop + childHeight; 574e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee final int childLeft = paddingLeft; 575e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee final int childRight = childLeft + child.getMeasuredWidth(); 576e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 577e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee child.layout(childLeft, childTop, childRight, childBottom); 578e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 579e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee nextYStart += child.getHeight(); 580e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee } 581e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 582e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee if (mFirstLayout) { 583e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee updateObscuredViewsVisibility(mSlideableView); 584e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee } 585e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 586e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee mFirstLayout = false; 587e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee } 588e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 589e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee @Override 590e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee protected void onSizeChanged(int w, int h, int oldw, int oldh) { 591e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee super.onSizeChanged(w, h, oldw, oldh); 592e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee // Recalculate sliding panes and their details 593e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee if (h != oldh) { 594e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee mFirstLayout = true; 595e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee } 596e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee } 597e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 598e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee @Override 599e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee public void requestChildFocus(View child, View focused) { 600e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee super.requestChildFocus(child, focused); 601e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee if (!isInTouchMode() && !mCanSlide) { 602e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee mPreservedOpenState = child == mSlideableView; 603e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee } 604e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee } 605e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 606e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee @Override 607e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee public boolean onInterceptTouchEvent(MotionEvent ev) { 608e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee final int action = MotionEventCompat.getActionMasked(ev); 609e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 610e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee // Preserve the open state based on the last view that was touched. 611e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee if (!mCanSlide && action == MotionEvent.ACTION_DOWN && getChildCount() > 1) { 612e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee // After the first things will be slideable. 613e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee final View secondChild = getChildAt(1); 614e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee if (secondChild != null) { 615e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee mPreservedOpenState = !mDragHelper.isViewUnder(secondChild, 616e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee (int) ev.getX(), (int) ev.getY()); 617e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee } 618e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee } 619e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 620e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee if (!mCanSlide || (mIsUnableToDrag && action != MotionEvent.ACTION_DOWN)) { 621bd180af7f0b73b0dd79a7117fb0c14370ef4d12eYorke Lee if (!mIsInNestedScroll) { 622bd180af7f0b73b0dd79a7117fb0c14370ef4d12eYorke Lee mDragHelper.cancel(); 623bd180af7f0b73b0dd79a7117fb0c14370ef4d12eYorke Lee } 624e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee return super.onInterceptTouchEvent(ev); 625e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee } 626e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 627e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee if (action == MotionEvent.ACTION_CANCEL || action == MotionEvent.ACTION_UP) { 628bd180af7f0b73b0dd79a7117fb0c14370ef4d12eYorke Lee if (!mIsInNestedScroll) { 629bd180af7f0b73b0dd79a7117fb0c14370ef4d12eYorke Lee mDragHelper.cancel(); 630bd180af7f0b73b0dd79a7117fb0c14370ef4d12eYorke Lee } 631e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee return false; 632e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee } 633e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 634e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee switch (action) { 635e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee case MotionEvent.ACTION_DOWN: { 636e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee mIsUnableToDrag = false; 637e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee final float x = ev.getX(); 638e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee final float y = ev.getY(); 639e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee mInitialMotionX = x; 640e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee mInitialMotionY = y; 641e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 642e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee break; 643e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee } 644e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 645e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee case MotionEvent.ACTION_MOVE: { 646e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee final float x = ev.getX(); 647e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee final float y = ev.getY(); 648e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee final float adx = Math.abs(x - mInitialMotionX); 649e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee final float ady = Math.abs(y - mInitialMotionY); 650e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee final int slop = mDragHelper.getTouchSlop(); 651e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee if (ady > slop && adx > ady || !isCapturableViewUnder((int) x, (int) y)) { 652bd180af7f0b73b0dd79a7117fb0c14370ef4d12eYorke Lee if (!mIsInNestedScroll) { 653bd180af7f0b73b0dd79a7117fb0c14370ef4d12eYorke Lee mDragHelper.cancel(); 654bd180af7f0b73b0dd79a7117fb0c14370ef4d12eYorke Lee } 655e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee mIsUnableToDrag = true; 656e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee return false; 657e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee } 658e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee } 659e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee } 660e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 661e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee final boolean interceptForDrag = mDragHelper.shouldInterceptTouchEvent(ev); 662e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 66310812203e52353f666cbb3ef02e423711dd64758Yorke Lee return interceptForDrag; 664e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee } 665e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 666e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee @Override 667e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee public boolean onTouchEvent(MotionEvent ev) { 668e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee if (!mCanSlide) { 669e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee return super.onTouchEvent(ev); 670e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee } 671e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 672e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee mDragHelper.processTouchEvent(ev); 673e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 674e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee final int action = ev.getAction(); 675e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee boolean wantTouchEvents = true; 676e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 677e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee switch (action & MotionEventCompat.ACTION_MASK) { 678e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee case MotionEvent.ACTION_DOWN: { 679e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee final float x = ev.getX(); 680e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee final float y = ev.getY(); 681e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee mInitialMotionX = x; 682e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee mInitialMotionY = y; 683e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee break; 684e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee } 685e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee } 686e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 687e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee return wantTouchEvents; 688e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee } 689e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 690e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee private boolean closePane(View pane, int initialVelocity) { 691e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee if (mFirstLayout || smoothSlideTo(0.f, initialVelocity)) { 692e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee mPreservedOpenState = false; 693e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee return true; 694e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee } 695e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee return false; 696e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee } 697e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 698e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee private boolean openPane(View pane, int initialVelocity) { 699e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee if (mFirstLayout || smoothSlideTo(1.f, initialVelocity)) { 700e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee mPreservedOpenState = true; 701e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee return true; 702e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee } 703e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee return false; 704e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee } 705e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 7065c7e73087ccb1615c6e460beb6c9734e665c527fYorke Lee private void updateSlideOffset(int offsetPx) { 7075c7e73087ccb1615c6e460beb6c9734e665c527fYorke Lee mSlideOffsetPx = offsetPx; 7085c7e73087ccb1615c6e460beb6c9734e665c527fYorke Lee mSlideOffset = (float) mSlideOffsetPx / mSlideRange; 7095c7e73087ccb1615c6e460beb6c9734e665c527fYorke Lee } 7105c7e73087ccb1615c6e460beb6c9734e665c527fYorke Lee 711e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee /** 712e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee * Open the sliding pane if it is currently slideable. If first layout 713e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee * has already completed this will animate. 714e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee * 715e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee * @return true if the pane was slideable and is now open/in the process of opening 716e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee */ 717e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee public boolean openPane() { 718e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee return openPane(mSlideableView, 0); 719e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee } 720e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 721e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee /** 722e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee * Close the sliding pane if it is currently slideable. If first layout 723e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee * has already completed this will animate. 724e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee * 725e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee * @return true if the pane was slideable and is now closed/in the process of closing 726e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee */ 727e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee public boolean closePane() { 728e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee return closePane(mSlideableView, 0); 729e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee } 730e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 731e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee /** 7325c7e73087ccb1615c6e460beb6c9734e665c527fYorke Lee * Check if the layout is open. It can be open either because the slider 733e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee * itself is open revealing the left pane, or if all content fits without sliding. 734e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee * 7355c7e73087ccb1615c6e460beb6c9734e665c527fYorke Lee * @return true if sliding panels are open 736e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee */ 737e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee public boolean isOpen() { 7385c7e73087ccb1615c6e460beb6c9734e665c527fYorke Lee return !mCanSlide || mSlideOffset > 0; 739e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee } 740e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 741e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee /** 742e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee * Check if the content in this layout cannot fully fit side by side and therefore 743e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee * the content pane can be slid back and forth. 744e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee * 745e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee * @return true if content in this layout can be slid open and closed 746e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee */ 747e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee public boolean isSlideable() { 748e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee return mCanSlide; 749e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee } 750e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 751e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee private void onPanelDragged(int newTop) { 752e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee if (mSlideableView == null) { 753e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee // This can happen if we're aborting motion during layout because everything now fits. 754e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee mSlideOffset = 0; 755e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee return; 756e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee } 757e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee final LayoutParams lp = (LayoutParams) mSlideableView.getLayoutParams(); 758e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 759e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee final int lpMargin = lp.topMargin; 760e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee final int topBound = getPaddingTop() + lpMargin; 761e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 7625c7e73087ccb1615c6e460beb6c9734e665c527fYorke Lee updateSlideOffset(newTop - topBound); 763e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 764e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee dispatchOnPanelSlide(mSlideableView); 765e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee } 766e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 767e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee @Override 768e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee protected boolean drawChild(Canvas canvas, View child, long drawingTime) { 769e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee final LayoutParams lp = (LayoutParams) child.getLayoutParams(); 770e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee boolean result; 771e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee final int save = canvas.save(Canvas.CLIP_SAVE_FLAG); 772e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 773e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee if (mCanSlide && !lp.slideable && mSlideableView != null) { 774e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee // Clip against the slider; no sense drawing what will immediately be covered. 775e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee canvas.getClipBounds(mTmpRect); 776e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 777e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee mTmpRect.bottom = Math.min(mTmpRect.bottom, mSlideableView.getTop()); 778e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee canvas.clipRect(mTmpRect); 779e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee } 780e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 781e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee if (Build.VERSION.SDK_INT >= 11) { // HC 782e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee result = super.drawChild(canvas, child, drawingTime); 783e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee } else { 78410812203e52353f666cbb3ef02e423711dd64758Yorke Lee if (child.isDrawingCacheEnabled()) { 78510812203e52353f666cbb3ef02e423711dd64758Yorke Lee child.setDrawingCacheEnabled(false); 786e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee } 78710812203e52353f666cbb3ef02e423711dd64758Yorke Lee result = super.drawChild(canvas, child, drawingTime); 788e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee } 789e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 790e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee canvas.restoreToCount(save); 791e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 792e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee return result; 793e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee } 794e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 795e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee /** 796e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee * Smoothly animate mDraggingPane to the target X position within its range. 797e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee * 798e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee * @param slideOffset position to animate to 799e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee * @param velocity initial velocity in case of fling, or 0. 800e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee */ 801e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee boolean smoothSlideTo(float slideOffset, int velocity) { 802e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee if (!mCanSlide) { 803e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee // Nothing to do. 804e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee return false; 805e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee } 806e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 807e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee final LayoutParams lp = (LayoutParams) mSlideableView.getLayoutParams(); 808e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 809e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee int y; 810e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee int topBound = getPaddingTop() + lp.topMargin; 811e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee y = (int) (topBound + slideOffset * mSlideRange); 812e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 813e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee if (mDragHelper.smoothSlideViewTo(mSlideableView, mSlideableView.getLeft(), y)) { 814e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee setAllChildrenVisible(); 815e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee ViewCompat.postInvalidateOnAnimation(this); 816e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee return true; 817e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee } 818e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee return false; 819e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee } 820e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 821e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee @Override 822e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee public void computeScroll() { 823e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee if (mDragHelper.continueSettling(true)) { 824e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee if (!mCanSlide) { 825e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee mDragHelper.abort(); 826e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee return; 827e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee } 828e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 829e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee ViewCompat.postInvalidateOnAnimation(this); 830e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee } 831e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee } 832e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 833e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee private boolean isCapturableViewUnder(int x, int y) { 834e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee View capturableView = mCapturableView != null ? mCapturableView : mSlideableView; 835e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee if (capturableView == null) { 836e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee return false; 837e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee } 838e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee int[] viewLocation = new int[2]; 839e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee capturableView.getLocationOnScreen(viewLocation); 840e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee int[] parentLocation = new int[2]; 841e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee this.getLocationOnScreen(parentLocation); 842e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee int screenX = parentLocation[0] + x; 843e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee int screenY = parentLocation[1] + y; 844e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee return screenX >= viewLocation[0] 845e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee && screenX < viewLocation[0] + capturableView.getWidth() 846e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee && screenY >= viewLocation[1] 847e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee && screenY < viewLocation[1] + capturableView.getHeight(); 848e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee } 849e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 850e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee @Override 851e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee protected ViewGroup.LayoutParams generateDefaultLayoutParams() { 852e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee return new LayoutParams(); 853e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee } 854e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 855e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee @Override 856e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee protected ViewGroup.LayoutParams generateLayoutParams(ViewGroup.LayoutParams p) { 857e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee return p instanceof MarginLayoutParams 858e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee ? new LayoutParams((MarginLayoutParams) p) 859e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee : new LayoutParams(p); 860e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee } 861e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 862e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee @Override 863e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee protected boolean checkLayoutParams(ViewGroup.LayoutParams p) { 864e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee return p instanceof LayoutParams && super.checkLayoutParams(p); 865e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee } 866e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 867e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee @Override 868e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee public ViewGroup.LayoutParams generateLayoutParams(AttributeSet attrs) { 869e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee return new LayoutParams(getContext(), attrs); 870e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee } 871e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 872e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee @Override 873e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee protected Parcelable onSaveInstanceState() { 874e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee Parcelable superState = super.onSaveInstanceState(); 875e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 876e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee SavedState ss = new SavedState(superState); 877e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee ss.isOpen = isSlideable() ? isOpen() : mPreservedOpenState; 878e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 879e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee return ss; 880e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee } 881e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 882e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee @Override 883e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee protected void onRestoreInstanceState(Parcelable state) { 884e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee SavedState ss = (SavedState) state; 885e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee super.onRestoreInstanceState(ss.getSuperState()); 886e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 887e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee if (ss.isOpen) { 888e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee openPane(); 889e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee } else { 890e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee closePane(); 891e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee } 892e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee mPreservedOpenState = ss.isOpen; 893e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee } 894e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 895bd180af7f0b73b0dd79a7117fb0c14370ef4d12eYorke Lee @Override 896bd180af7f0b73b0dd79a7117fb0c14370ef4d12eYorke Lee public boolean onStartNestedScroll(View child, View target, int nestedScrollAxes) { 897bd180af7f0b73b0dd79a7117fb0c14370ef4d12eYorke Lee final boolean startNestedScroll = (nestedScrollAxes & SCROLL_AXIS_VERTICAL) != 0; 898bd180af7f0b73b0dd79a7117fb0c14370ef4d12eYorke Lee if (startNestedScroll) { 899bd180af7f0b73b0dd79a7117fb0c14370ef4d12eYorke Lee mIsInNestedScroll = true; 90040ed60dab29e90e28f95a0d8a9c612fed7a253ceYorke Lee mChildCannotConsumeScroll = true; 901bd180af7f0b73b0dd79a7117fb0c14370ef4d12eYorke Lee mDragHelper.startNestedScroll(mSlideableView); 902bd180af7f0b73b0dd79a7117fb0c14370ef4d12eYorke Lee } 9035c7e73087ccb1615c6e460beb6c9734e665c527fYorke Lee if (DEBUG) { 9045c7e73087ccb1615c6e460beb6c9734e665c527fYorke Lee Log.d(TAG, "onStartNestedScroll: " + startNestedScroll); 9055c7e73087ccb1615c6e460beb6c9734e665c527fYorke Lee } 906bd180af7f0b73b0dd79a7117fb0c14370ef4d12eYorke Lee return startNestedScroll; 907bd180af7f0b73b0dd79a7117fb0c14370ef4d12eYorke Lee } 908bd180af7f0b73b0dd79a7117fb0c14370ef4d12eYorke Lee 909bd180af7f0b73b0dd79a7117fb0c14370ef4d12eYorke Lee @Override 910bd180af7f0b73b0dd79a7117fb0c14370ef4d12eYorke Lee public void onNestedPreScroll(View target, int dx, int dy, int[] consumed) { 9115c7e73087ccb1615c6e460beb6c9734e665c527fYorke Lee if (dy == 0) { 9125c7e73087ccb1615c6e460beb6c9734e665c527fYorke Lee // Nothing to do 9135c7e73087ccb1615c6e460beb6c9734e665c527fYorke Lee return; 9145c7e73087ccb1615c6e460beb6c9734e665c527fYorke Lee } 9155c7e73087ccb1615c6e460beb6c9734e665c527fYorke Lee if (DEBUG) { 9165c7e73087ccb1615c6e460beb6c9734e665c527fYorke Lee Log.d(TAG, "onNestedPreScroll: " + dy); 9175c7e73087ccb1615c6e460beb6c9734e665c527fYorke Lee } 91840ed60dab29e90e28f95a0d8a9c612fed7a253ceYorke Lee mInNestedPreScrollDownwards = 91940ed60dab29e90e28f95a0d8a9c612fed7a253ceYorke Lee mChildCannotConsumeScroll && dy > 0 && mSlideOffsetPx <= mIntermediateOffset; 920bd180af7f0b73b0dd79a7117fb0c14370ef4d12eYorke Lee mDragHelper.processNestedScroll(mSlideableView, 0, dy, consumed); 921bd180af7f0b73b0dd79a7117fb0c14370ef4d12eYorke Lee } 922bd180af7f0b73b0dd79a7117fb0c14370ef4d12eYorke Lee 923bd180af7f0b73b0dd79a7117fb0c14370ef4d12eYorke Lee @Override 9245c7e73087ccb1615c6e460beb6c9734e665c527fYorke Lee public void onNestedScroll(View target, int dxConsumed, int dyConsumed, int dxUnconsumed, 9255c7e73087ccb1615c6e460beb6c9734e665c527fYorke Lee int dyUnconsumed) { 9265c7e73087ccb1615c6e460beb6c9734e665c527fYorke Lee if (DEBUG) { 9275c7e73087ccb1615c6e460beb6c9734e665c527fYorke Lee Log.d(TAG, "onNestedScroll: " + dyUnconsumed); 9285c7e73087ccb1615c6e460beb6c9734e665c527fYorke Lee } 92940ed60dab29e90e28f95a0d8a9c612fed7a253ceYorke Lee mChildCannotConsumeScroll = false; 9305c7e73087ccb1615c6e460beb6c9734e665c527fYorke Lee mInNestedPreScrollDownwards = false; 9315c7e73087ccb1615c6e460beb6c9734e665c527fYorke Lee // We need to flip dyUnconsumed here, because its magnitude is reversed. b/14585990 9325c7e73087ccb1615c6e460beb6c9734e665c527fYorke Lee mDragHelper.processNestedScroll(mSlideableView, 0, -dyUnconsumed, null); 9335c7e73087ccb1615c6e460beb6c9734e665c527fYorke Lee } 9345c7e73087ccb1615c6e460beb6c9734e665c527fYorke Lee 9355c7e73087ccb1615c6e460beb6c9734e665c527fYorke Lee @Override 936bd180af7f0b73b0dd79a7117fb0c14370ef4d12eYorke Lee public void onStopNestedScroll(View child) { 9375c7e73087ccb1615c6e460beb6c9734e665c527fYorke Lee if (DEBUG) { 9385c7e73087ccb1615c6e460beb6c9734e665c527fYorke Lee Log.d(TAG, "onStopNestedScroll"); 9395c7e73087ccb1615c6e460beb6c9734e665c527fYorke Lee } 9405c7e73087ccb1615c6e460beb6c9734e665c527fYorke Lee if (mIsInNestedScroll) { 9415c7e73087ccb1615c6e460beb6c9734e665c527fYorke Lee mDragHelper.stopNestedScroll(mSlideableView); 9425c7e73087ccb1615c6e460beb6c9734e665c527fYorke Lee } 943bd180af7f0b73b0dd79a7117fb0c14370ef4d12eYorke Lee mIsInNestedScroll = false; 944bd180af7f0b73b0dd79a7117fb0c14370ef4d12eYorke Lee } 945bd180af7f0b73b0dd79a7117fb0c14370ef4d12eYorke Lee 946e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee private class DragHelperCallback extends ViewDragHelper.Callback { 947e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 948e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee @Override 949e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee public boolean tryCaptureView(View child, int pointerId) { 950e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee if (mIsUnableToDrag) { 951e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee return false; 952e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee } 953e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 954e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee return ((LayoutParams) child.getLayoutParams()).slideable; 955e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee } 956e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 957e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee @Override 958e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee public void onViewDragStateChanged(int state) { 959e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee if (mDragHelper.getViewDragState() == ViewDragHelper.STATE_IDLE) { 960e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee if (mSlideOffset == 0) { 961e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee updateObscuredViewsVisibility(mSlideableView); 962e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee dispatchOnPanelClosed(mSlideableView); 963e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee mPreservedOpenState = false; 964e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee } else { 965e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee dispatchOnPanelOpened(mSlideableView); 966e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee mPreservedOpenState = true; 967e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee } 968e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee } 969e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee } 970e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 971e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee @Override 972e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee public void onViewCaptured(View capturedChild, int activePointerId) { 973e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee // Make all child views visible in preparation for sliding things around 974e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee setAllChildrenVisible(); 975e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee } 976e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 977e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee @Override 978e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee public void onViewPositionChanged(View changedView, int left, int top, int dx, int dy) { 979e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee onPanelDragged(top); 980e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee invalidate(); 981e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee } 982e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 983e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee @Override 984e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee public void onViewReleased(View releasedChild, float xvel, float yvel) { 985e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee final LayoutParams lp = (LayoutParams) releasedChild.getLayoutParams(); 986e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 987e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee int top = getPaddingTop() + lp.topMargin; 9885c7e73087ccb1615c6e460beb6c9734e665c527fYorke Lee 9895c7e73087ccb1615c6e460beb6c9734e665c527fYorke Lee if (mInNestedPreScrollDownwards) { 9905c7e73087ccb1615c6e460beb6c9734e665c527fYorke Lee // Snap to the closest pinnable position based on the current slide offset 9915c7e73087ccb1615c6e460beb6c9734e665c527fYorke Lee // (in pixels) [0 - mIntermediateoffset - mSlideRange] 9925c7e73087ccb1615c6e460beb6c9734e665c527fYorke Lee if (yvel > 0) { 9935c7e73087ccb1615c6e460beb6c9734e665c527fYorke Lee top += mSlideRange; 9945c7e73087ccb1615c6e460beb6c9734e665c527fYorke Lee } else if (0 <= mSlideOffsetPx && mSlideOffsetPx <= mIntermediateOffset / 2) { 9955c7e73087ccb1615c6e460beb6c9734e665c527fYorke Lee // Offset is between 0 and mIntermediateOffset, but closer to 0 9965c7e73087ccb1615c6e460beb6c9734e665c527fYorke Lee // Leave top unchanged 9975c7e73087ccb1615c6e460beb6c9734e665c527fYorke Lee } else if (mIntermediateOffset / 2 <= mSlideOffsetPx 9985c7e73087ccb1615c6e460beb6c9734e665c527fYorke Lee && mSlideOffsetPx <= (mIntermediateOffset + mSlideRange) / 2) { 9995c7e73087ccb1615c6e460beb6c9734e665c527fYorke Lee // Offset is closest to mIntermediateOffset 10005c7e73087ccb1615c6e460beb6c9734e665c527fYorke Lee top += mIntermediateOffset; 10015c7e73087ccb1615c6e460beb6c9734e665c527fYorke Lee } else { 10025c7e73087ccb1615c6e460beb6c9734e665c527fYorke Lee // Offset is between mIntermediateOffset and mSlideRange, but closer to 10035c7e73087ccb1615c6e460beb6c9734e665c527fYorke Lee // mSlideRange 10045c7e73087ccb1615c6e460beb6c9734e665c527fYorke Lee top += mSlideRange; 10055c7e73087ccb1615c6e460beb6c9734e665c527fYorke Lee } 10065c7e73087ccb1615c6e460beb6c9734e665c527fYorke Lee } else if (yvel > 0 || (yvel == 0 && mSlideOffset > 0.5f)) { 1007e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee top += mSlideRange; 1008e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee } 1009e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 1010e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee mDragHelper.settleCapturedViewAt(releasedChild.getLeft(), top); 1011e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee invalidate(); 1012e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee } 1013e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 1014e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee @Override 1015e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee public int getViewVerticalDragRange(View child) { 1016e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee return mSlideRange; 1017e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee } 1018e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 1019e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee @Override 1020e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee public int clampViewPositionHorizontal(View child, int left, int dx) { 1021e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee // Make sure we never move views horizontally. 1022e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee return child.getLeft(); 1023e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee } 1024e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 1025e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee @Override 1026e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee public int clampViewPositionVertical(View child, int top, int dy) { 1027e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee final LayoutParams lp = (LayoutParams) mSlideableView.getLayoutParams(); 1028e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 1029e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee final int newTop; 1030e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee int topBound = getPaddingTop() + lp.topMargin; 10315c7e73087ccb1615c6e460beb6c9734e665c527fYorke Lee int bottomBound = topBound 10325c7e73087ccb1615c6e460beb6c9734e665c527fYorke Lee + (mInNestedPreScrollDownwards ? mIntermediateOffset : mSlideRange); 1033e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee newTop = Math.min(Math.max(top, topBound), bottomBound); 1034e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 1035e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee return newTop; 1036e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee } 1037e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 1038e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee @Override 1039e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee public void onEdgeDragStarted(int edgeFlags, int pointerId) { 1040e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee mDragHelper.captureChildView(mSlideableView, pointerId); 1041e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee } 1042e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee } 1043e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 1044e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee public static class LayoutParams extends ViewGroup.MarginLayoutParams { 1045e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee private static final int[] ATTRS = new int[] { 1046e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee android.R.attr.layout_weight 1047e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee }; 1048e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 1049e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee /** 1050e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee * The weighted proportion of how much of the leftover space 1051e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee * this child should consume after measurement. 1052e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee */ 1053e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee public float weight = 0; 1054e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 1055e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee /** 1056e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee * True if this pane is the slideable pane in the layout. 1057e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee */ 1058e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee boolean slideable; 1059e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 1060e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee public LayoutParams() { 1061e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee super(FILL_PARENT, FILL_PARENT); 1062e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee } 1063e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 1064e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee public LayoutParams(int width, int height) { 1065e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee super(width, height); 1066e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee } 1067e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 1068e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee public LayoutParams(android.view.ViewGroup.LayoutParams source) { 1069e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee super(source); 1070e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee } 1071e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 1072e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee public LayoutParams(MarginLayoutParams source) { 1073e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee super(source); 1074e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee } 1075e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 1076e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee public LayoutParams(LayoutParams source) { 1077e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee super(source); 1078e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee this.weight = source.weight; 1079e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee } 1080e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 1081e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee public LayoutParams(Context c, AttributeSet attrs) { 1082e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee super(c, attrs); 1083e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 1084e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee final TypedArray a = c.obtainStyledAttributes(attrs, ATTRS); 1085e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee this.weight = a.getFloat(0, 0); 1086e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee a.recycle(); 1087e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee } 1088e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 1089e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee } 1090e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 1091e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee static class SavedState extends BaseSavedState { 1092e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee boolean isOpen; 1093e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 1094e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee SavedState(Parcelable superState) { 1095e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee super(superState); 1096e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee } 1097e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 1098e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee private SavedState(Parcel in) { 1099e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee super(in); 1100e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee isOpen = in.readInt() != 0; 1101e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee } 1102e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 1103e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee @Override 1104e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee public void writeToParcel(Parcel out, int flags) { 1105e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee super.writeToParcel(out, flags); 1106e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee out.writeInt(isOpen ? 1 : 0); 1107e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee } 1108e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 1109e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee public static final Parcelable.Creator<SavedState> CREATOR = 1110e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee new Parcelable.Creator<SavedState>() { 1111e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee public SavedState createFromParcel(Parcel in) { 1112e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee return new SavedState(in); 1113e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee } 1114e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 1115e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee public SavedState[] newArray(int size) { 1116e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee return new SavedState[size]; 1117e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee } 1118e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee }; 1119e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee } 1120e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 1121e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee class AccessibilityDelegate extends AccessibilityDelegateCompat { 1122e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee private final Rect mTmpRect = new Rect(); 1123e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 1124e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee @Override 1125e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee public void onInitializeAccessibilityNodeInfo(View host, AccessibilityNodeInfoCompat info) { 1126e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee final AccessibilityNodeInfoCompat superNode = AccessibilityNodeInfoCompat.obtain(info); 1127e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee super.onInitializeAccessibilityNodeInfo(host, superNode); 1128e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee copyNodeInfoNoChildren(info, superNode); 1129e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee superNode.recycle(); 1130e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 1131e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee info.setClassName(OverlappingPaneLayout.class.getName()); 1132e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee info.setSource(host); 1133e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 1134e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee final ViewParent parent = ViewCompat.getParentForAccessibility(host); 1135e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee if (parent instanceof View) { 1136e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee info.setParent((View) parent); 1137e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee } 1138e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 1139e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee // This is a best-approximation of addChildrenForAccessibility() 1140e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee // that accounts for filtering. 1141e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee final int childCount = getChildCount(); 1142e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee for (int i = 0; i < childCount; i++) { 1143e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee final View child = getChildAt(i); 114410812203e52353f666cbb3ef02e423711dd64758Yorke Lee if (child.getVisibility() == View.VISIBLE) { 1145e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee // Force importance to "yes" since we can't read the value. 1146e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee ViewCompat.setImportantForAccessibility( 1147e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee child, ViewCompat.IMPORTANT_FOR_ACCESSIBILITY_YES); 1148e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee info.addChild(child); 1149e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee } 1150e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee } 1151e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee } 1152e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 1153e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee @Override 1154e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee public void onInitializeAccessibilityEvent(View host, AccessibilityEvent event) { 1155e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee super.onInitializeAccessibilityEvent(host, event); 1156e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 1157e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee event.setClassName(OverlappingPaneLayout.class.getName()); 1158e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee } 1159e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 1160e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee /** 1161e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee * This should really be in AccessibilityNodeInfoCompat, but there unfortunately 1162e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee * seem to be a few elements that are not easily cloneable using the underlying API. 1163e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee * Leave it private here as it's not general-purpose useful. 1164e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee */ 1165e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee private void copyNodeInfoNoChildren(AccessibilityNodeInfoCompat dest, 1166e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee AccessibilityNodeInfoCompat src) { 1167e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee final Rect rect = mTmpRect; 1168e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 1169e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee src.getBoundsInParent(rect); 1170e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee dest.setBoundsInParent(rect); 1171e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 1172e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee src.getBoundsInScreen(rect); 1173e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee dest.setBoundsInScreen(rect); 1174e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 1175e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee dest.setVisibleToUser(src.isVisibleToUser()); 1176e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee dest.setPackageName(src.getPackageName()); 1177e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee dest.setClassName(src.getClassName()); 1178e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee dest.setContentDescription(src.getContentDescription()); 1179e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 1180e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee dest.setEnabled(src.isEnabled()); 1181e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee dest.setClickable(src.isClickable()); 1182e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee dest.setFocusable(src.isFocusable()); 1183e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee dest.setFocused(src.isFocused()); 1184e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee dest.setAccessibilityFocused(src.isAccessibilityFocused()); 1185e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee dest.setSelected(src.isSelected()); 1186e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee dest.setLongClickable(src.isLongClickable()); 1187e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 1188e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee dest.addAction(src.getActions()); 1189e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee 1190e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee dest.setMovementGranularities(src.getMovementGranularities()); 1191e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee } 1192e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee } 1193e709fd21eda44df07327f649e4e6a257918555a9Yorke Lee} 1194