Sunday 6 January 2013

Sliding Drawer in Android


"Guide to create Sliding Drawer in Android in both side,Left to right and Right to left"


Next Image


For creating sliding view in both direction


"If you want to create sliding drawer animation in right to left no need to add any view in layout you can simply use slider widget (answer here)

but in case of both sides sliding drawer you need to call the view in your layout .In this layout i have created view in com.example.example.SlidingDrawer."


Main Layout:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:background="@drawable/back">
   
    <ImageView
            android:id="@+id/image"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:src="@drawable/ic_launcher" />
   
   
    <com.example.example.SlidingDrawer
        xmlns:my="http://schemas.android.com/apk/res/com.example.example"
        android:id="@+id/drawer"
        my:direction="leftToRight"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        my:handle="@+id/handle"
        my:content="@+id/content">
        <include
            android:id="@id/content"
            layout="@layout/contentlayout" >
            </include>
        <ImageView
            android:id="@id/handle"
            android:layout_width="wrap_content"
            android:layout_height="40px"
            android:src="@drawable/ic_launcher" />
    </com.example.example.SlidingDrawer>
    <com.example.example.SlidingDrawer
        xmlns:my="http://schemas.android.com/apk/res/com.example.example"
        android:id="@+id/drawer"
        my:direction="rightToLeft"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        my:handle="@+id/handle"
        my:content="@+id/content">
        <include
            android:id="@id/content"
            layout="@layout/contentlayout" >
            </include>
        <ImageView
            android:id="@id/handle"
            android:layout_width="wrap_content"
            android:layout_height="40px"
            android:src="@drawable/ic_launcher" />
    </com.example.example.SlidingDrawer>
</RelativeLayout>

content layout:


<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:background="@drawable/back">
   
    <ImageView
            android:id="@+id/image"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:src="@drawable/ic_launcher" />
</RelativeLayout>

 Mainactivity.java

package com.example.example;

import android.app.Activity;
import android.os.Bundle;
import android.view.Window;
import com.example.example.SlidingDrawer;

public class MainActivity extends Activity {

   
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.sliding);
       
      
   
   }
}


Here comes the view:

public class SlidingDrawer extends ViewGroup {

    public static final int   Orientationright      = 0;
    public static final int   Orientationbottom  = 1;
    public static final int   Orientationleft        = 2;
    public static final int   Orientationtop        = 3;

// Based on your requirement you can add the orientation 


 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 SlidingDrawer( Context context, AttributeSet attrs )
    {
        this( context, attrs, 0 );
    }
   
   
    public SlidingDrawer( Context context, AttributeSet attrs, int defStyle )
    {
        super( context, attrs, defStyle );
        TypedArray a = context.obtainStyledAttributes( attrs, R.styleable.SlidingDrawer, defStyle, 0 );
      
        int orientation = a.getInt( R.styleable.SlidingDrawer_direction, Orientationbottom );
        moveVertical = ( orientation == Orientationbottom || orientation == Orientationtop );
        Bottom_Offset = (int)a.getDimension( R.styleable.SlidingDrawer_bottom_Offset, 0.0f );
        Top_Offset = (int)a.getDimension( R.styleable.SlidingDrawer_top_Offset, 0.0f );
        Onsingletap = a.getBoolean( R.styleable.SlidingDrawer_allowSingleTap, true );
        animateclick = a.getBoolean( R.styleable.SlidingDrawer_animateOnClick, true );
        invert = ( orientation == Orientationtop || orientation == Orientationleft );
      
        int handleId = a.getResourceId( R.styleable.SlidingDrawer_handle, 0 );
        if ( handleId == 0 ) { throw new IllegalArgumentException( "Exception "
                + "a valid child." ); }
      
        int contentId = a.getResourceId( R.styleable.SlidingDrawer_content, 0 );
        if ( contentId == 0 ) { throw new IllegalArgumentException( "The content attribute required  "
                + " valid child." ); }
      
        if ( handleId == contentId ) { throw new IllegalArgumentException( "The content and handle attributes refer "
                + " different children." ); }
        mHandleId = handleId;
        mContentId = contentId;
      
        final float density = getResources().getDisplayMetrics().density;
        mTapThreshold = (int)( tap_threshold * density + 0.5f );
        Maxtapvelocity = (int)( Max_velocity * density + 0.5f );
        minorvelocity = (int)( Min_velocity * density + 0.5f );
        majorvelocity = (int)( Maj_velocity * density + 0.5f );
        maxacceleration = (int)( Max_acceleration * density + 0.5f );
        velocityunits = (int)( velocityunit * density + 0.5f );
      
        if( invert ) {
            maxacceleration = -maxacceleration;
            majorvelocity = -majorvelocity;
            minorvelocity = -minorvelocity;
        }
      
        a.recycle();
        setAlwaysDrawnWithCacheEnabled( false );
    }
    .....
protected void onLayout( boolean changed, int l, int t, int r, int b )
    {
      final View handle = mHandle;
       
        int handleWidth = handle.getMeasuredWidth();
        int handleHeight = handle.getMeasuredHeight();
       
    final View content = mContent;
       
        if ( moveVertical ) {
            handleLeft = ( width - handleWidth ) / 2;
            if ( invert ) {
              
                handleTop = mExpanded ? height - Bottom_Offset - handleHeight : Top_Offset;
                content.layout( 0, Top_Offset, content.getMeasuredWidth(), Top_Offset + content.getMeasuredHeight() );
            } else {
                handleTop = mExpanded ? Top_Offset : height - handleHeight + Bottom_Offset;
                content.layout( 0, Top_Offset + handleHeight, content.getMeasuredWidth(), Top_Offset + handleHeight + content.getMeasuredHeight() );
            }
        } else {
            handleTop = ( height - handleHeight ) / 2;
            if( invert ) {
                handleLeft = mExpanded ? width - Bottom_Offset - handleWidth : Top_Offset;
                content.layout( Top_Offset, 0, Top_Offset + content.getMeasuredWidth(), content.getMeasuredHeight() );
            } else {
                handleLeft = mExpanded ? Top_Offset : width - handleWidth + Bottom_Offset;
                content.layout( Top_Offset + handleWidth, 0, Top_Offset + handleWidth + content.getMeasuredWidth(), content.getMeasuredHeight() );
            }
        }
       
        handle.layout( handleLeft, handleTop, handleLeft + handleWidth, handleTop + handleHeight );
        mHandleHeight = handle.getHeight();
        mHandleWidth = handle.getWidth();
    }
  
 ....Use can use Touchevent:

public boolean onTouchEvent( MotionEvent event )
    {
    switch ( action ) {
                case MotionEvent.ACTION_MOVE:
                    moveHandle( (int)( moveVertical ? event.getY() : event.getX() ) - mTouchDelta );
                    break;
                case MotionEvent.ACTION_UP:
                case MotionEvent.ACTION_CANCEL: {
                    final VelocityTracker velocityTracker = mVelocityTracker;
                    velocityTracker.computeCurrentVelocity( velocityunits );
                   
                    float yVelocity = velocityTracker.getYVelocity();
                    float xVelocity = velocityTracker.getXVelocity();
                    boolean negative;
.....
.....
}
 For Animate open and close:

private void animateClose( int position )
    {
        prepareTracking( position );
        performFling( position, maxacceleration, true );
    }
   
    private void animateOpen( int position )
    {
        prepareTracking( position );
        performFling( position, -maxacceleration, true );
    }
   
    private void performFling( int position, float velocity, boolean always )
    {
        AnimationPosition = position;
        AnimatedVelocity = velocity;
        ..
.....
...
....}
       
    For more information you can try this SlidingDrawer






5 comments:

Unknown said...

i want to download this example can u please provide this example thanks in advance... :)

Adrian said...

Hi :) I'm working at the same problem and if you can send or provide code of SlidingDrawer class it would be great.

krunal said...

i want only from drawer moves left to right...please help me

Janmejoy said...

Yes you change the direction Also..Kindly go through the code..

Anonymous said...

What is stylable in this code? I get error for it.