How to change the sliding drawer button image on open and close

1.5k views Asked by At

I have implemented sliding drawer and working fine. But on open and close I have to change the buttonimage. Not getting from where to change and how.

Code is:

    private final int mHandleId;
    private final int mContentId;

    private View mHandle;
    private View mContent;


    private boolean mInvert;
    private boolean mVertical;
    private boolean mExpanded;
    private int mBottomOffset;
    private int mTopOffset;
    private int mHandleHeight;
    private int mHandleWidth;

    private OnDrawerOpenListener mOnDrawerOpenListener;
    private OnDrawerCloseListener mOnDrawerCloseListener;
    private OnDrawerScrollListener  mOnDrawerScrollListener;


    public static interface OnDrawerOpenListener {
        public void onDrawerOpened();
    }


    public static interface OnDrawerCloseListener {
        public void onDrawerClosed();
    }

    public static interface OnDrawerScrollListener {

        public void onScrollStarted();

        public void onScrollEnded();
    }

    public MultiDirectionSlidingDrawer( Context context, AttributeSet attrs )
    {
        this( context, attrs, 0 );
    }

    public MultiDirectionSlidingDrawer( Context context, AttributeSet attrs, int defStyle )
    {
        super( context, attrs, defStyle );
        TypedArray a = context.obtainStyledAttributes( attrs, R.styleable.MultiDirectionSlidingDrawer, defStyle, 0 );

        int orientation = a.getInt( R.styleable.MultiDirectionSlidingDrawer_direction, ORIENTATION_BTT );
        mVertical = ( orientation == ORIENTATION_BTT || orientation == ORIENTATION_TTB );
        mBottomOffset = (int)a.getDimension( R.styleable.MultiDirectionSlidingDrawer_bottomOffset, 0.0f );
        mTopOffset = (int)a.getDimension( R.styleable.MultiDirectionSlidingDrawer_topOffset, 0.0f );
        mAllowSingleTap = a.getBoolean( R.styleable.MultiDirectionSlidingDrawer_allowSingleTap, true );
        mAnimateOnClick = a.getBoolean( R.styleable.MultiDirectionSlidingDrawer_animateOnClick, true );
        mInvert = ( orientation == ORIENTATION_TTB || orientation == ORIENTATION_LTR );

        int handleId = a.getResourceId( R.styleable.MultiDirectionSlidingDrawer_handle, 0 );
        if ( handleId == 0 ) { throw new IllegalArgumentException( "The handle attribute is required and must refer "
                + "to a valid child." ); }

        int contentId = a.getResourceId( R.styleable.MultiDirectionSlidingDrawer_content, 0 );
        if ( contentId == 0 ) { throw new IllegalArgumentException( "The content attribute is required and must refer "
                + "to a valid child." ); }

        if ( handleId == contentId ) { throw new IllegalArgumentException( "The content and handle attributes must refer "
                + "to different children." ); }
        mHandleId = handleId;
        mContentId = contentId;

        final float density = getResources().getDisplayMetrics().density;
        mTapThreshold = (int)( TAP_THRESHOLD * density + 0.5f );
        mMaximumTapVelocity = (int)( MAXIMUM_TAP_VELOCITY * density + 0.5f );
        mMaximumMinorVelocity = (int)( MAXIMUM_MINOR_VELOCITY * density + 0.5f );
        mMaximumMajorVelocity = (int)( MAXIMUM_MAJOR_VELOCITY * density + 0.5f );
        mMaximumAcceleration = (int)( MAXIMUM_ACCELERATION * density + 0.5f );
        mVelocityUnits = (int)( VELOCITY_UNITS * density + 0.5f );

        if( mInvert ) {
            mMaximumAcceleration = -mMaximumAcceleration;
            mMaximumMajorVelocity = -mMaximumMajorVelocity;
            mMaximumMinorVelocity = -mMaximumMinorVelocity;
        }

        a.recycle();
        setAlwaysDrawnWithCacheEnabled( false );
    }

    @Override
    protected void onFinishInflate()
    {
        mHandle = findViewById( mHandleId );
        if ( mHandle == null ) { throw new IllegalArgumentException( "The handle attribute is must refer to an" + " existing child." ); }
        mHandle.setOnClickListener( new DrawerToggler() );

        mContent = findViewById( mContentId );
        if ( mContent == null ) { throw new IllegalArgumentException( "The content attribute is must refer to an"
                + " existing child." ); }
        mContent.setVisibility( View.GONE );
    }

    @Override
    protected void onMeasure( int widthMeasureSpec, int heightMeasureSpec )
    {
        int widthSpecMode = MeasureSpec.getMode( widthMeasureSpec );
        int widthSpecSize = MeasureSpec.getSize( widthMeasureSpec );

        int heightSpecMode = MeasureSpec.getMode( heightMeasureSpec );
        int heightSpecSize = MeasureSpec.getSize( heightMeasureSpec );

        if ( widthSpecMode == MeasureSpec.UNSPECIFIED || heightSpecMode == MeasureSpec.UNSPECIFIED ) { throw new RuntimeException(
                "SlidingDrawer cannot have UNSPECIFIED dimensions" ); }

        final View handle = mHandle;
        measureChild( handle, widthMeasureSpec, heightMeasureSpec );

        if ( mVertical ) {
            int height = heightSpecSize - handle.getMeasuredHeight() - mTopOffset;
            mContent.measure( MeasureSpec.makeMeasureSpec( widthSpecSize, MeasureSpec.EXACTLY ), MeasureSpec.makeMeasureSpec( height, MeasureSpec.EXACTLY ) );
        } else {
            int width = widthSpecSize - handle.getMeasuredWidth() - mTopOffset;
            mContent.measure( MeasureSpec.makeMeasureSpec( width, MeasureSpec.EXACTLY ), MeasureSpec.makeMeasureSpec( heightSpecSize, MeasureSpec.EXACTLY ) );
        }

        setMeasuredDimension( widthSpecSize, heightSpecSize );
    }

    @Override
    protected void dispatchDraw( Canvas canvas )
    {
        final long drawingTime = getDrawingTime();
        final View handle = mHandle;
        final boolean isVertical = mVertical;

        drawChild( canvas, handle, drawingTime );

        if ( mTracking || mAnimating ) {
            final Bitmap cache = mContent.getDrawingCache();
            if ( cache != null ) {
                if ( isVertical ) {
                    if( mInvert ) {
                        canvas.drawBitmap( cache, 0, handle.getTop() - (getBottom() - getTop()) + mHandleHeight, null );
                    } else {
                        canvas.drawBitmap( cache, 0, handle.getBottom(), null );
                    }
                } else {
                    canvas.drawBitmap( cache, mInvert ? handle.getLeft() - cache.getWidth() : handle.getRight(), 0, null );
                }
            } else {
                canvas.save();
                if( mInvert ) {
                    canvas.translate( isVertical ? 0 : handle.getLeft() - mTopOffset - mContent.getMeasuredWidth(), isVertical ? handle.getTop() - mTopOffset - mContent.getMeasuredHeight() : 0 );
                } else {
                    canvas.translate( isVertical ? 0 : handle.getLeft() - mTopOffset, isVertical ? handle.getTop() - mTopOffset : 0 );
                }
                drawChild( canvas, mContent, drawingTime );
                canvas.restore();
            }
            invalidate();
        } else if ( mExpanded ) {
            drawChild( canvas, mContent, drawingTime );
        }
    }

    public static final String  LOG_TAG = "Sliding";

    @Override
    protected void onLayout( boolean changed, int l, int t, int r, int b )
    {
        if ( mTracking ) { return; }

        final int width = r - l;
        final int height = b - t;

        final View handle = mHandle;

        int handleWidth = handle.getMeasuredWidth();
        int handleHeight = handle.getMeasuredHeight();

        Log.d( LOG_TAG, "handleHeight: " + handleHeight );

        int handleLeft;
        int handleTop;

        final View content = mContent;

        if ( mVertical ) {
            handleLeft = ( width - handleWidth ) / 2;
            if ( mInvert ) {
                Log.d( LOG_TAG, "content.layout(1)" );

            handleTop = mExpanded ? height - mBottomOffset - handleHeight : mTopOffset;
            content.layout( 0, mTopOffset, content.getMeasuredWidth(), mTopOffset + content.getMeasuredHeight() );
        } else {
            handleTop = mExpanded ? mTopOffset : height - handleHeight + mBottomOffset;
            content.layout( 0, mTopOffset + handleHeight, content.getMeasuredWidth(), mTopOffset + handleHeight + content.getMeasuredHeight() );
        }
    } else {
        handleTop = ( height - handleHeight ) / 2;
        if( mInvert ) {
            handleLeft = mExpanded ? width - mBottomOffset - handleWidth : mTopOffset;
            content.layout( mTopOffset, 0, mTopOffset + content.getMeasuredWidth(), content.getMeasuredHeight() );
        } else {
            handleLeft = mExpanded ? mTopOffset : width - handleWidth + mBottomOffset;
            content.layout( mTopOffset + handleWidth, 0, mTopOffset + handleWidth + content.getMeasuredWidth(), content.getMeasuredHeight() );
        }
    }

    handle.layout( handleLeft, handleTop, handleLeft + handleWidth, handleTop + handleHeight );
    mHandleHeight = handle.getHeight();
    mHandleWidth = handle.getWidth();
}

@Override
public boolean onInterceptTouchEvent( MotionEvent event )
{
    if ( mLocked ) { return false; }

    final int action = event.getAction();

    float x = event.getX();
    float y = event.getY();

    final Rect frame = mFrame;
    final View handle = mHandle;

    handle.getHitRect( frame );
    if ( !mTracking && !frame.contains( (int)x, (int)y ) ) { return false; }

    if ( action == MotionEvent.ACTION_DOWN ) {
        mTracking = true;

        handle.setPressed( true );
        // Must be called before prepareTracking()
        prepareContent();

        // Must be called after prepareContent()
        if ( mOnDrawerScrollListener != null ) {
            mOnDrawerScrollListener.onScrollStarted();
        }

        if ( mVertical ) {
            final int top = mHandle.getTop();
            mTouchDelta = (int)y - top;
            prepareTracking( top );
        } else {
            final int left = mHandle.getLeft();
            mTouchDelta = (int)x - left;
            prepareTracking( left );
        }
        mVelocityTracker.addMovement( event );
    }

    return true;
}

@Override
public boolean onTouchEvent( MotionEvent event )
{
    if ( mLocked ) { return true; }

    if ( mTracking ) {
        mVelocityTracker.addMovement( event );
        final int action = event.getAction();
        switch ( action ) {
            case MotionEvent.ACTION_MOVE:
                moveHandle( (int)( mVertical ? event.getY() : event.getX() ) - mTouchDelta );
                break;
            case MotionEvent.ACTION_UP:
            case MotionEvent.ACTION_CANCEL: {
                final VelocityTracker velocityTracker = mVelocityTracker;
                velocityTracker.computeCurrentVelocity( mVelocityUnits );

                float yVelocity = velocityTracker.getYVelocity();
                float xVelocity = velocityTracker.getXVelocity();
                boolean negative;

                final boolean vertical = mVertical;
                if ( vertical ) {
                    negative = yVelocity < 0;
                    if ( xVelocity < 0 ) {
                        xVelocity = -xVelocity;
                    }
                    // fix by Maciej Ciemięga.
                    if ( (!mInvert && xVelocity > mMaximumMinorVelocity) || (mInvert && xVelocity < mMaximumMinorVelocity) ) {
                        xVelocity = mMaximumMinorVelocity;
                    }
                } else {
                    negative = xVelocity < 0;
                    if ( yVelocity < 0 ) {
                        yVelocity = -yVelocity;
                    }
                    // fix by Maciej Ciemięga.
                    if ( (!mInvert && yVelocity > mMaximumMinorVelocity) || (mInvert && yVelocity < mMaximumMinorVelocity) ) {
                        yVelocity = mMaximumMinorVelocity;
                    }
                }

                float velocity = (float)Math.hypot( xVelocity, yVelocity );
                if ( negative ) {
                    velocity = -velocity;
                }

                final int handleTop = mHandle.getTop();
                final int handleLeft = mHandle.getLeft();
                final int handleBottom = mHandle.getBottom();
                final int handleRight = mHandle.getRight();

                if ( Math.abs( velocity ) < mMaximumTapVelocity ) {
                    boolean c1;
                    boolean c2;
                    boolean c3;
                    boolean c4;

                    if( mInvert ) {
                        c1 = ( mExpanded && (getBottom() - handleBottom ) < mTapThreshold + mBottomOffset );
                        c2 = ( !mExpanded && handleTop < mTopOffset + mHandleHeight - mTapThreshold );
                        c3 = ( mExpanded && (getRight() - handleRight ) < mTapThreshold + mBottomOffset );
                        c4 = ( !mExpanded && handleLeft > mTopOffset + mHandleWidth + mTapThreshold );
                    } else {
                        c1 = ( mExpanded && handleTop < mTapThreshold + mTopOffset );
                        c2 = ( !mExpanded && handleTop > mBottomOffset + getBottom() - getTop() - mHandleHeight - mTapThreshold );
                        c3 = ( mExpanded && handleLeft < mTapThreshold + mTopOffset );
                        c4 = ( !mExpanded && handleLeft > mBottomOffset + getRight() - getLeft() - mHandleWidth - mTapThreshold );
                    }

                    Log.d( LOG_TAG, "ACTION_UP: " + "c1: " + c1 + ", c2: " + c2 + ", c3: " + c3 + ", c4: " + c4 );

                    if ( vertical ? c1 || c2 : c3 || c4 ) {

                        if ( mAllowSingleTap ) {
                            playSoundEffect( SoundEffectConstants.CLICK );

                            if ( mExpanded ) {
                                animateClose( vertical ? handleTop : handleLeft );
                            } else {
                                animateOpen( vertical ? handleTop : handleLeft );
                            }
                        } else {
                            performFling( vertical ? handleTop : handleLeft, velocity, false );
                        }
                    } else {
                        performFling( vertical ? handleTop : handleLeft, velocity, false );
                    }
                } else {
                    performFling( vertical ? handleTop : handleLeft, velocity, false );
                }
            }
                break;
        }
    }

    return mTracking || mAnimating || super.onTouchEvent( event );
}

private void animateClose( int position )
{
    prepareTracking( position );
    performFling( position, mMaximumAcceleration, true );
}

private void animateOpen( int position )
{
    prepareTracking( position );
    performFling( position, -mMaximumAcceleration, true );
}

private void performFling( int position, float velocity, boolean always )
{
    mAnimationPosition = position;
    mAnimatedVelocity = velocity;

    boolean c1;
    boolean c2;
    boolean c3;

    if ( mExpanded ) 
    {
        int bottom = mVertical ? getBottom() : getRight();
        int handleHeight = mVertical ? mHandleHeight : mHandleWidth;

        Log.d( LOG_TAG, "position: " + position + ", velocity: " + velocity + ", mMaximumMajorVelocity: " + mMaximumMajorVelocity );
        c1 = mInvert ? velocity < mMaximumMajorVelocity : velocity > mMaximumMajorVelocity;
        c2 = mInvert ? ( bottom - (position + handleHeight) ) + mBottomOffset > handleHeight : position > mTopOffset + ( mVertical ? mHandleHeight : mHandleWidth );
        c3 = mInvert ? velocity < -mMaximumMajorVelocity : velocity > -mMaximumMajorVelocity;
        Log.d( LOG_TAG, "EXPANDED. c1: " + c1 + ", c2: " + c2 + ", c3: " + c3 );
        if ( always || ( c1 || ( c2 && c3 ) ) ) {
            // We are expanded, So animate to CLOSE!
            mAnimatedAcceleration = mMaximumAcceleration;
            if( mInvert )
            {
                if ( velocity > 0 ) {
                    mAnimatedVelocity = 0;
                }
            } else {
                if ( velocity < 0 ) {
                    mAnimatedVelocity = 0;
                }
            }
        } else {
            // We are expanded, but they didn't move sufficiently to cause
            // us to retract. Animate back to the expanded position. so animate BACK to expanded!
            mAnimatedAcceleration = -mMaximumAcceleration;

            if( mInvert ) {
                if ( velocity < 0 ) {
                    mAnimatedVelocity = 0;
                }
            } else {
                if ( velocity > 0 ) {
                    mAnimatedVelocity = 0;
                }
            }
        }
    } else {

        // WE'RE COLLAPSED

        c1 = mInvert ? velocity < mMaximumMajorVelocity : velocity > mMaximumMajorVelocity;
        c2 = mInvert ? ( position < ( mVertical ? getHeight() : getWidth() ) / 2 ) : ( position > ( mVertical ? getHeight() : getWidth() ) / 2 );
        c3 = mInvert ? velocity < -mMaximumMajorVelocity : velocity > -mMaximumMajorVelocity;

        Log.d( LOG_TAG, "COLLAPSED. position: " + position + ", velocity: " + velocity + ", mMaximumMajorVelocity: " + mMaximumMajorVelocity );
        Log.d( LOG_TAG, "COLLAPSED. always: " + always + ", c1: " + c1 + ", c2: " + c2 + ", c3: " + c3 );

        if ( !always && ( c1 || ( c2 && c3 ) ) ) {
            mAnimatedAcceleration = mMaximumAcceleration;

            if( mInvert ) {
                if ( velocity > 0 ) {
                    mAnimatedVelocity = 0;
                }
            } else {
                if ( velocity < 0 ) {
                    mAnimatedVelocity = 0;
                }
            }
        } else {
            mAnimatedAcceleration = -mMaximumAcceleration;

            if( mInvert ) {
                if ( velocity < 0 ) {
                    mAnimatedVelocity = 0;
                }
            } else {
                if ( velocity > 0 ) {
                    mAnimatedVelocity = 0;
                }
            }
        }
    }

    long now = SystemClock.uptimeMillis();
    mAnimationLastTime = now;
    mCurrentAnimationTime = now + ANIMATION_FRAME_DURATION;
    mAnimating = true;
    mHandler.removeMessages( MSG_ANIMATE );
    mHandler.sendMessageAtTime( mHandler.obtainMessage( MSG_ANIMATE ), mCurrentAnimationTime );
    stopTracking();
}

private void prepareTracking( int position )
{
    mTracking = true;
    mVelocityTracker = VelocityTracker.obtain();
    boolean opening = !mExpanded;

    if ( opening ) {
        mAnimatedAcceleration = mMaximumAcceleration;
        mAnimatedVelocity = mMaximumMajorVelocity;
        if( mInvert )
            mAnimationPosition = mTopOffset;
        else
            mAnimationPosition = mBottomOffset + ( mVertical ? getHeight() - mHandleHeight : getWidth() - mHandleWidth );
        moveHandle( (int)mAnimationPosition );
        mAnimating = true;
        mHandler.removeMessages( MSG_ANIMATE );
        long now = SystemClock.uptimeMillis();
        mAnimationLastTime = now;
        mCurrentAnimationTime = now + ANIMATION_FRAME_DURATION;
        mAnimating = true;
    } else {
        if ( mAnimating ) {
            mAnimating = false;
            mHandler.removeMessages( MSG_ANIMATE );
        }
        moveHandle( position );
    }
}

private void moveHandle( int position )
{
    final View handle = mHandle;

    if ( mVertical ) {
        if ( position == EXPANDED_FULL_OPEN ) {
            if( mInvert )
                handle.offsetTopAndBottom( mBottomOffset + getBottom() - getTop() - mHandleHeight );
            else
                handle.offsetTopAndBottom( mTopOffset - handle.getTop() );
            invalidate();
        } else if ( position == COLLAPSED_FULL_CLOSED ) {
            if( mInvert ) {
                handle.offsetTopAndBottom( mTopOffset - handle.getTop() );
            } else {
                handle.offsetTopAndBottom( mBottomOffset + getBottom() - getTop() - mHandleHeight - handle.getTop() );
            }
            invalidate();
        } else 
        {
            final int top = handle.getTop();
            int deltaY = position - top;
            if ( position < mTopOffset ) {
                deltaY = mTopOffset - top;
            } else if ( deltaY > mBottomOffset + getBottom() - getTop() - mHandleHeight - top ) {
                deltaY = mBottomOffset + getBottom() - getTop() - mHandleHeight - top;
            }

            handle.offsetTopAndBottom( deltaY );

            final Rect frame = mFrame;
            final Rect region = mInvalidate;

            handle.getHitRect( frame );
            region.set( frame );

            region.union( frame.left, frame.top - deltaY, frame.right, frame.bottom - deltaY );
            region.union( 0, frame.bottom - deltaY, getWidth(), frame.bottom - deltaY + mContent.getHeight() );

            invalidate( region );
        }
    } else {
        if ( position == EXPANDED_FULL_OPEN ) {
            if( mInvert )
                handle.offsetLeftAndRight( mBottomOffset + getRight() - getLeft() - mHandleWidth );
            else
                handle.offsetLeftAndRight( mTopOffset - handle.getLeft() );
            invalidate();
        } else if ( position == COLLAPSED_FULL_CLOSED ) {
            if( mInvert )
                handle.offsetLeftAndRight( mTopOffset - handle.getLeft() );
            else
                handle.offsetLeftAndRight( mBottomOffset + getRight() - getLeft() - mHandleWidth - handle.getLeft() );
            invalidate();
        } else {
            final int left = handle.getLeft();
            int deltaX = position - left;
            if ( position < mTopOffset ) {
                deltaX = mTopOffset - left;
            } else if ( deltaX > mBottomOffset + getRight() - getLeft() - mHandleWidth - left ) {
                deltaX = mBottomOffset + getRight() - getLeft() - mHandleWidth - left;
            }
            handle.offsetLeftAndRight( deltaX );

            final Rect frame = mFrame;
            final Rect region = mInvalidate;

            handle.getHitRect( frame );
            region.set( frame );

            region.union( frame.left - deltaX, frame.top, frame.right - deltaX, frame.bottom );
            region.union( frame.right - deltaX, 0, frame.right - deltaX + mContent.getWidth(), getHeight() );

            invalidate( region );
        }
    }
}

private void prepareContent()
{
    if ( mAnimating ) { return; }

    // Something changed in the content, we need to honor the layout request
    // before creating the cached bitmap
    final View content = mContent;
    if ( content.isLayoutRequested() ) {

        if ( mVertical ) {
            final int handleHeight = mHandleHeight;
            int height = getBottom() - getTop() - handleHeight - mTopOffset;
            content.measure( MeasureSpec.makeMeasureSpec( getRight() - getLeft(), MeasureSpec.EXACTLY ), MeasureSpec.makeMeasureSpec( height, MeasureSpec.EXACTLY ) );

            Log.d( LOG_TAG, "content.layout(2)" );

            if ( mInvert ) 
                content.layout( 0, mTopOffset, content.getMeasuredWidth(), mTopOffset + content.getMeasuredHeight() );
            else 
                content.layout( 0, mTopOffset + handleHeight, content.getMeasuredWidth(), mTopOffset + handleHeight + content.getMeasuredHeight() );

        } else {

            final int handleWidth = mHandle.getWidth();
            int width = getRight() - getLeft() - handleWidth - mTopOffset;
            content.measure( MeasureSpec.makeMeasureSpec( width, MeasureSpec.EXACTLY ), MeasureSpec.makeMeasureSpec( getBottom() - getTop(), MeasureSpec.EXACTLY ) );

            if( mInvert )
                content.layout( mTopOffset, 0, mTopOffset + content.getMeasuredWidth(), content.getMeasuredHeight() );
            else
                content.layout( handleWidth + mTopOffset, 0, mTopOffset + handleWidth + content.getMeasuredWidth(), content.getMeasuredHeight() );
        }
    }
    // Try only once... we should really loop but it's not a big deal
    // if the draw was cancelled, it will only be temporary anyway
    content.getViewTreeObserver().dispatchOnPreDraw();
    content.buildDrawingCache();

    content.setVisibility( View.GONE );
}

private void stopTracking()
{
    mHandle.setPressed( false );
    mTracking = false;

    if ( mOnDrawerScrollListener != null ) {
        mOnDrawerScrollListener.onScrollEnded();
    }

    if ( mVelocityTracker != null ) {
        mVelocityTracker.recycle();
        mVelocityTracker = null;
    }
}

private void doAnimation()
{
    if ( mAnimating ) {
        incrementAnimation();

        if( mInvert )
        {
            if ( mAnimationPosition < mTopOffset ) {
                mAnimating = false;
                closeDrawer();
            } else if ( mAnimationPosition >= mTopOffset + ( mVertical ? getHeight() : getWidth() ) - 1 ) {
                mAnimating = false;
                openDrawer();
            } else {
                moveHandle( (int)mAnimationPosition );
                mCurrentAnimationTime += ANIMATION_FRAME_DURATION;
                mHandler.sendMessageAtTime( mHandler.obtainMessage( MSG_ANIMATE ), mCurrentAnimationTime );
            }               
        } else {
            if ( mAnimationPosition >= mBottomOffset + ( mVertical ? getHeight() : getWidth() ) - 1 ) {
                mAnimating = false;
                closeDrawer();
            } else if ( mAnimationPosition < mTopOffset ) {
                mAnimating = false;
                openDrawer();
            } else {
                moveHandle( (int)mAnimationPosition );
                mCurrentAnimationTime += ANIMATION_FRAME_DURATION;
                mHandler.sendMessageAtTime( mHandler.obtainMessage( MSG_ANIMATE ), mCurrentAnimationTime );
            }
        }
    }
}

private void incrementAnimation()
{
    long now = SystemClock.uptimeMillis();
    float t = ( now - mAnimationLastTime ) / 1000.0f; // ms -> s
    final float position = mAnimationPosition;
    final float v = mAnimatedVelocity; // px/s
    final float a = mInvert ? mAnimatedAcceleration : mAnimatedAcceleration; // px/s/s
    mAnimationPosition = position + ( v * t ) + ( 0.5f * a * t * t ); // px
    mAnimatedVelocity = v + ( a * t ); // px/s
    mAnimationLastTime = now; // ms
}

/**
 * Toggles the drawer open and close. Takes effect immediately.
 * 
 * @see #open()
 * @see #close()
 * @see #animateClose()
 * @see #animateOpen()
 * @see #animateToggle()
 */
public void toggle()
{
    if ( !mExpanded ) {
        openDrawer();
    } else {
        closeDrawer();
    }
    invalidate();
    requestLayout();
}

/**
 * Toggles the drawer open and close with an animation.
 * 
 * @see #open()
 * @see #close()
 * @see #animateClose()
 * @see #animateOpen()
 * @see #toggle()
 */
public void animateToggle()
{
    if ( !mExpanded ) {
        animateOpen();
    } else {
        animateClose();
    }
}

/**
 * Opens the drawer immediately.
 * 
 * @see #toggle()
 * @see #close()
 * @see #animateOpen()
 */
public void open()
{
    openDrawer();
    invalidate();
    requestLayout();

    sendAccessibilityEvent( AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED );
}

public void close()
{
    closeDrawer();
    invalidate();
    requestLayout();
}


public void animateClose()
{
    prepareContent();
    final OnDrawerScrollListener scrollListener = mOnDrawerScrollListener;
    if ( scrollListener != null ) {
        scrollListener.onScrollStarted();
    }
    animateClose( mVertical ? mHandle.getTop() : mHandle.getLeft() );

    if ( scrollListener != null ) {
        scrollListener.onScrollEnded();
    }
}


public void animateOpen()
{
    prepareContent();
    final OnDrawerScrollListener scrollListener = mOnDrawerScrollListener;
    if ( scrollListener != null ) {
        scrollListener.onScrollStarted();
    }
    animateOpen( mVertical ? mHandle.getTop() : mHandle.getLeft() );

    sendAccessibilityEvent( AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED );

    if ( scrollListener != null ) {
        scrollListener.onScrollEnded();
    }
}

private void closeDrawer()
{
    moveHandle( COLLAPSED_FULL_CLOSED );
    mContent.setVisibility( View.GONE );
    mContent.destroyDrawingCache();

    if ( !mExpanded ) { return; }

    mExpanded = false;
    if ( mOnDrawerCloseListener != null ) {
        mOnDrawerCloseListener.onDrawerClosed();
    }
}

private void openDrawer()
{
    moveHandle( EXPANDED_FULL_OPEN );
    mContent.setVisibility( View.VISIBLE );

    if ( mExpanded ) { return; }

    mExpanded = true;

    if ( mOnDrawerOpenListener != null ) {
        mOnDrawerOpenListener.onDrawerOpened();
    }
}

public void setOnDrawerOpenListener( OnDrawerOpenListener onDrawerOpenListener )
{
    mOnDrawerOpenListener = onDrawerOpenListener;
}


public void setOnDrawerCloseListener( OnDrawerCloseListener onDrawerCloseListener )
{
    mOnDrawerCloseListener = onDrawerCloseListener;
}


public void setOnDrawerScrollListener( OnDrawerScrollListener onDrawerScrollListener )
{
    mOnDrawerScrollListener = onDrawerScrollListener;
}

public View getHandle()
{
    return mHandle;
}


public View getContent()
{
    return mContent;
}

/**
 * Unlocks the SlidingDrawer so that touch events are processed.
 * 
 * @see #lock()
 */
public void unlock()
{
    mLocked = false;
}

/**
 * Locks the SlidingDrawer so that touch events are ignores.
 * 
 * @see #unlock()
 */
public void lock()
{
    mLocked = true;
}

public boolean isOpened()
{
    return mExpanded;
}

/**
 * Indicates whether the drawer is scrolling or flinging.
 * 
 * @return True if the drawer is scroller or flinging, false otherwise.
 */
public boolean isMoving()
{
    return mTracking || mAnimating;
}

private class DrawerToggler implements OnClickListener {

    public void onClick( View v )
    {
        if(v.getId()==R.id.handle)
        {   
            Toast.makeText(getContext(), "handle", Toast.LENGTH_SHORT).show();
            (findViewById(R.id.handle)).setBackgroundColor(Color.BLACK);
        }
        if ( mLocked ) { return; }
        // mAllowSingleTap isn't relevant here; you're *always*
        // allowed to open/close the drawer by clicking with the
        // trackball.

        if ( mAnimateOnClick ) {
            animateToggle();
        } else {
            toggle();
        }
    }
}

private class SlidingHandler extends Handler {

    public void handleMessage( Message m )
    {
        switch ( m.what ) {
            case MSG_ANIMATE:
                doAnimation();
                break;
        }
    }
}
}
3

There are 3 answers

0
Praveen Sharma On

use a setOnDrawerOpenListener listener like as follows :-

 slidingDrawer.setOnDrawerOpenListener(new OnDrawerOpenListener() {

                @Override
                public void onDrawerOpened() {
                    Log.d("Debug","Drawer Opened");
                    //
                    iv_uporder.setImageDrawable(getResources().getDrawable(R.drawable.down));
            }
            });

            slidingDrawer.setOnDrawerCloseListener(new OnDrawerCloseListener() {

                @Override
                public void onDrawerClosed() {
                    Log.d("Debug","Drawer Closed");
                    //  
                    iv_uporder.setImageDrawable(getResources().getDrawable(R.drawable.up));

                }
            });
2
Rudi On

you can change its icon When the drawer is open:

if (mDrawerLayout.isDrawerOpen(Gravity.RIGHT)){
// change the icon
} 

else{
// change the icon
}

and you can put it in the onCreate(). and Note that this is for drawers from right to left.

Hope it helps :)

0
Josh On

I did the handle image change yesterday, my handler image is an Arrow pointing Left, or Right, depending if the SliderDrawer is pulled Out, or hidden.

Here is the solution in 3 steps: 1) IMPLEMENT Open/Close Drawer on your Activity or Class:

   public class ArticleFragment extends Fragment 
   implements   OnDrawerOpenListener, 
        OnDrawerCloseListener { 
                    .......blaaa

2) Add onDrawerOpen/Close Listeners to the overriden onActivityCreated() Method, I am working with fragments, so I had to do the parentActivity stunt...

    @Override
public void onActivityCreated(Bundle _savedInstanceName){
    super.onActivityCreated(_savedInstanceName);    

    Activity parentactivity=getActivity();
    mydrawer=(SlidingDrawer)parentactivity.findViewById(R.id.drawer);
    mydrawer.setOnDrawerOpenListener(this); 
    mydrawer.setOnDrawerCloseListener(this);
}

3) Override these two methods, to load an Arrow pointing Left to the Handle if your drawer is hidden, or an Arrow pointing Right is your drawer is expanded.:

@Override
public void onDrawerOpened() {
    Toast.makeText(getActivity(), "Drawer Opened!", Toast.LENGTH_SHORT).show();
    ImageView img;
    img=(ImageView)getActivity().findViewById(R.id.handle); //Get Handle reference
    img.setImageResource(R.drawable.arrowr);    //Load Arrow pointing right       
    }    

@Override
public void onDrawerClosed() {
    Toast.makeText(getActivity(), "Drawer Closed!", Toast.LENGTH_SHORT).show();
    ImageView img;
    img=(ImageView)getActivity().findViewById(R.id.handle); //Get Handle reference
    img.setImageResource(R.drawable.arrowl); //Load Arrow pointing right   
} 

A "Toast" to my first Stackoverflow answer!