28 Feb 2013

Sliding menu like facebook, gmail | Sliding menu Bar in Android.

Now a days this is most important feature in android, every one want to make easy interface with minimum user interface, Android provide Side menu for easy user interface, enjoy code.



horz_sidemenu_activity_layout.xml:

<?xml version="1.0" encoding="utf-8"?>
<com.hb.example.HorizontalSideScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:layout_margin="0px"
    android:background="#00ffffff"
    android:fadingEdge="none"
    android:fadingEdgeLength="0px"
    android:padding="0px"
    android:scrollbars="none" >

    <LinearLayout
        android:id="@+id/top"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:layout_margin="0px"
        android:background="#ffffffff"
        android:orientation="horizontal"
        android:padding="0px" >
    </LinearLayout>

</com.hb.example.HorizontalSideScrollView>


mainapplication_layout.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/app"
    android:layout_width="1dp"
    android:layout_height="1dp"
    android:layout_margin="2dp"
    android:background="#ffffff"
    android:orientation="vertical"
    android:padding="2dp" >

    <LinearLayout
        android:id="@+id/tabBar"
        android:layout_width="fill_parent"
        android:layout_height="60dip"
        android:background="#F6CE1E"
        android:gravity="center_vertical"
        android:orientation="horizontal" >

        <ImageView
            android:id="@+id/BtnSlide"
            android:layout_width="40dip"
            android:layout_height="wrap_content"
            android:layout_margin="0px"
            android:background="@drawable/left"
            android:padding="0px" />

        <View
            android:layout_width="2dip"
            android:layout_height="wrap_content"
            android:layout_marginLeft="15dip"
            android:layout_marginRight="15dip"
            android:background="#000000" >
        </View>

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:paddingTop="10dip"
            android:text="Company Name"
            android:textColor="#000000"
            android:textSize="8pt" />
    </LinearLayout>

    <View
        android:layout_width="fill_parent"
        android:layout_height="2dip"
        android:background="#000000" >
    </View>

    <ListView
        android:id="@+id/list"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="#25B5F1"
        android:cacheColorHint="@android:color/transparent"
        android:divider="#FFFFFF"
        android:dividerHeight="2dip"
        android:paddingTop="10dip" >
    </ListView>

</LinearLayout>



side_menu.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/menu"
    android:layout_width="1dp"
    android:layout_height="1dp"
    android:background="#000000"
    android:orientation="vertical" >

    <LinearLayout
        android:id="@+id/tabBar"
        android:layout_width="fill_parent"
        android:layout_height="60dip"
        android:background="#F6CE1E"
        android:gravity="center"
        android:orientation="horizontal" >

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:paddingTop="10dip"
            android:text="Mobile Name"
            android:textColor="#000000"
            android:textSize="8pt" />
    </LinearLayout>

    <ListView
        android:id="@+id/list"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="#25B5F1"
        android:cacheColorHint="@android:color/transparent"
        android:divider="#FFFFFF"
        android:dividerHeight="2dip"
        android:scrollbars="none" >
    </ListView>

</LinearLayout>


HorizontalSideScrollView:
import android.content.Context;
import android.os.Handler;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver.OnGlobalLayoutListener;
import android.widget.HorizontalScrollView;

public class HorizontalSideScrollView extends HorizontalScrollView
{
      public HorizontalSideScrollView(Context context, AttributeSet attrs, int defStyle)
      {
            super(context, attrs, defStyle);
            init(context);
      }

      public HorizontalSideScrollView(Context context, AttributeSet attrs)
      {
            super(context, attrs);
            init(context);
      }

      public HorizontalSideScrollView(Context context)
      {
            super(context);
            init(context);
      }

      void init(Context context)
      {
            // remove the fading as the HSV looks better without it
            setHorizontalFadingEdgeEnabled(false);
            setVerticalFadingEdgeEnabled(false);
      }

      /**
       * @param children
       *            The child Views to add to parent.
       * @param scrollToViewIdx
       *            The index of the View to scroll to after initialisation.
       * @param sizeCallback
       *            A SizeCallback to interact with the HSV.
       */
      public void initViews(View[] children, int scrollToViewIdx, SizeCallback sizeCallback)
      {
            // A ViewGroup MUST be the only child of the HSV
            ViewGroup parent = (ViewGroup) getChildAt(0);

            // Add all the children, but add them invisible so that the layouts are calculated, but you can't see the Views
            for (int i = 0; i < children.length; i++)
            {
                  children[i].setVisibility(View.INVISIBLE);
                  parent.addView(children[i]);
            }

            // Add a layout listener to this HSV
            // This listener is responsible for arranging the child views.
            OnGlobalLayoutListener listener = new MyOnGlobalLayoutListener(parent, children, scrollToViewIdx, sizeCallback);
            getViewTreeObserver().addOnGlobalLayoutListener(listener);
      }

      @Override
      public boolean onTouchEvent(MotionEvent ev)
      {
            // Do not allow touch events.
            return false;
      }

      @Override
      public boolean onInterceptTouchEvent(MotionEvent ev)
      {
            // Do not allow touch events.
            return false;
      }

      /**
       * An OnGlobalLayoutListener impl that passes on the call to onGlobalLayout to a SizeCallback, before removing all the Views
       * in the HSV and adding them again with calculated widths and heights.
       */
      class MyOnGlobalLayoutListener implements OnGlobalLayoutListener
      {
            ViewGroup parent;
            View[] children;
            int scrollToViewIdx;
            int scrollToViewPos = 0;
            SizeCallback sizeCallback;

            public MyOnGlobalLayoutListener(ViewGroup parent, View[] children, int scrollToViewIdx, SizeCallback sizeCallback)
            {
                  this.parent = parent;
                  this.children = children;
                  this.scrollToViewIdx = scrollToViewIdx;
                  this.sizeCallback = sizeCallback;
            }

            @Override
            public void onGlobalLayout()
            {    

                  final HorizontalSideScrollView me = HorizontalSideScrollView.this;

                  // The listener will remove itself as a layout listener to the HSV
                  me.getViewTreeObserver().removeGlobalOnLayoutListener(this);

                  // Allow the SizeCallback to 'see' the Views before we remove them and re-add them.
                  // This lets the SizeCallback prepare View sizes, ahead of calls to SizeCallback.getViewSize().
                  sizeCallback.onGlobalLayout();

                  parent.removeViewsInLayout(0, children.length);

                  final int w = me.getMeasuredWidth();
                  final int h = me.getMeasuredHeight();

                  // System.out.println("w=" + w + ", h=" + h);

                  // Add each view in turn, and apply the width and height returned by the SizeCallback.
                  int[] dims = new int[2];
                  scrollToViewPos = 0;
                  for (int i = 0; i < children.length; i++)
                  {
                        sizeCallback.getViewSize(i, w, h, dims);
                        // System.out.println("addView w=" + dims[0] + ", h=" + dims[1]);
                        children[i].setVisibility(View.VISIBLE);
                        parent.addView(children[i], dims[0], dims[1]);
                        if (i < scrollToViewIdx)
                        {
                              scrollToViewPos += dims[0];
                        }
                  }

                  // For some reason we need to post this action, rather than call immediately.
                  // If we try immediately, it will not scroll.
                  new Handler().post(new Runnable()
                  {
                        @Override
                        public void run()
                        {
                              me.scrollBy(scrollToViewPos, 0);
                        }
                  });
            }
      }

      /**
       * Callback interface to interact with the HSV.
       */
      public interface SizeCallback
      {
            /**
             * Used to allow clients to measure Views before re-adding them.
             */
            public void onGlobalLayout();

            /**
             * Used by clients to specify the View dimensions.
             *
             * @param idx
             *            Index of the View.
             * @param w
             *            Width of the parent View.
             * @param h
             *            Height of the parent View.
             * @param dims
             *            dims[0] should be set to View width. dims[1] should be set to View height.
             */
            public void getViewSize(int idx, int w, int h, int[] dims);
      }
}

HorzScrollSideMenuActivity:
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.HorizontalScrollView;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.Toast;

import com.hb.example.HorizontalSideScrollView.SizeCallback;

public class HorzScrollSideMenuActivity extends Activity
{
      HorizontalSideScrollView scrollView;
      View menuView;
      View applicationView;
      ImageView btnSlide;
      boolean menuOut = false;
      Handler handler = new Handler();
      int btnWidth;
      String[] cmpName=  {"HTC","i-Phone","Blackberry","Nokia","Samsung","Micromax","Spice","Relilence"};
      String[] mobilenm=  {"HTC-Desire X","i-Phone5","Tourch-9700","Lumia-9200","Ninja-A90","Ninja A-110"};
     
      @Override
      public void onCreate(Bundle savedInstanceState)
      {
            super.onCreate(savedInstanceState);

            LayoutInflater inflater = LayoutInflater.from(this);
            scrollView = (HorizontalSideScrollView) inflater.inflate(R.layout.horz_sidemenu_activity_layout, null);
            setContentView(scrollView);

            menuView = inflater.inflate(R.layout.side_menu, null);
            applicationView = inflater.inflate(R.layout.mainapplication_layout, null);
            ViewGroup tabBar = (ViewGroup) applicationView.findViewById(R.id.tabBar);

            ListView listView = (ListView) applicationView.findViewById(R.id.list);
            ArrayAdapter< String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, cmpName);
            listView.setAdapter(adapter);
            ListView listView1 = (ListView) menuView.findViewById(R.id.list);
            ArrayAdapter< String> devSiteadapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, mobilenm);
            listView1.setAdapter(devSiteadapter);
            btnSlide = (ImageView) tabBar.findViewById(R.id.BtnSlide);
            btnSlide.setOnClickListener(new ClickListenerForScrolling(scrollView, menuView));

            final View[] children = new View[] { menuView, applicationView };
            int scrollToViewIdx = 1;
            scrollView.initViews(children, scrollToViewIdx, new SizeCallbackForMenu(btnSlide));
            listView1.setOnItemClickListener(new OnItemClickListener()
            {

                  @Override
                  public void onItemClick(AdapterView<?> arg0, View arg1, int position,
                              long arg3)
                  {
                        Toast.makeText(HorzScrollSideMenuActivity.this, "Side Menu  Clicked Item  : "+mobilenm[position], Toast.LENGTH_SHORT).show();

                  }
            });
            listView.setOnItemClickListener(new OnItemClickListener()
            {

                  @Override
                  public void onItemClick(AdapterView<?> arg0, View arg1, int position,
                              long arg3)
                  {
                        Toast.makeText(HorzScrollSideMenuActivity.this, "Clicked Item  : "+cmpName[position], Toast.LENGTH_SHORT).show();

                  }
            });
      }

      /**
       * Helper for examples with a HSV that should be scrolled by a menu View's width.
       */
      static class ClickListenerForScrolling implements OnClickListener
      {
            HorizontalScrollView scrollView;
            View menu;
            /**
             * Menu must NOT be out/shown to start with.
             */
            boolean menuOut = false;

            public ClickListenerForScrolling(HorizontalScrollView scrollView, View menu) {
                  super();
                  this.scrollView = scrollView;
                  this.menu = menu;
            }

            @Override
            public void onClick(View v)
            {
                  int menuWidth = menu.getMeasuredWidth();
                  // Ensure menu is visible
                  menu.setVisibility(View.VISIBLE);

                  if (!menuOut)
                  {
                        int left = 0;
                        scrollView.smoothScrollTo(left, 0);
                  } else
                  {
                        int left = menuWidth;
                        scrollView.smoothScrollTo(left, 0);
                  }
                  menuOut = !menuOut;
            }
      }

      /**
       * Helper that remembers the width of the 'slide' button, so that the 'slide' button remains in view, even when the menu is
       * showing.
       */
      static class SizeCallbackForMenu implements SizeCallback
      {
            int btnWidth;
            View btnSlide;

            public SizeCallbackForMenu(View btnSlide)
            {
                  super();
                  this.btnSlide = btnSlide;
            }

            @Override
            public void onGlobalLayout()
            {
                  btnWidth = btnSlide.getMeasuredWidth();
            }

            @Override
            public void getViewSize(int idx, int w, int h, int[] dims)
            {
                  dims[0] = w;
                  dims[1] = h;
                  final int menuIdx = 0;
                  if (idx == menuIdx)
                  {
                        dims[0] = w - btnWidth;
                  }
            }
      }
}

Download Sample:

More reference link:
http://www.androidhive.info/2013/11/android-sliding-menu-using-navigation-drawer/
http://v4all123.blogspot.in/2013/11/simple-sliding-menu-example-in-android.html

Implementing ActionBarSherlock Side Menu Navigation Drawer in Android

http://www.androidbegin.com/tutorial/implementing-actionbarsherlock-side-menu-navigation-drawer-in-android/

i will be happy if you will provide your feedback or follow this blog. Any suggesion and help will be appreciated.
Thank you :)