Thursday, January 31, 2013

Android Side Menu Bar Example

Android Side Menu Bar  Example

Below the example for Android side Navigation like Facebook side Navigation.
This is simple example only. If you want to modify as per as your requirement you can change it.

I really like Side Navigation pattern and I think it is especially useful on mobile devices with small screen, but it’s pretty important that the user experience that comes with it has to be carefully crafted so it doesn’t cause user frustration and confusion.


 





 HorizontalSideScrollVie.java
 
package com.vijay.ex;

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;

/**
 * A HorizontalScrollView (HSV) implementation that disallows touch events (so no scrolling can be done by the user).
 *
 * This HSV MUST contain a single ViewGroup as its only child, and this ViewGroup will be used to display the children Views
 * passed in to the initViews() method.
 */
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;

        /**
         * @param parent
         *            The parent to which the child Views should be added.
         * @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 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() {
            // System.out.println("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);
    }
}

 HorzScrollSideMenuActivit.java

package com.vijay.ex;
import java.util.Date;
import com.vijay.ex.HorizontalSideScrollView.SizeCallback;
import android.app.Activity;
import android.content.Context;
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;
public class HorzScrollSideMenuActivity extends Activity {
      HorizontalSideScrollView scrollView;
    View menuView;
    View applicationView;
    ImageView btnSlide;
    boolean menuOut = false;
    Handler handler = new Handler();
    int btnWidth;
    String[] str=  {"Android1.1","Android2.1","Android2.2","Android3.0","Android4.0","Android4.2","http://www.android-ever.com/","http://www.iamvijayakumar.blogspot.com/"};
    String[] developerSites=  {"Developer Sites","Local Ref Site","Settings","Accounts","http://www.android-ever.com/","http://www.iamvijayakumar.blogspot.com/","Settings","Accounts","http://www.iamvijayakumar.blogspot.com/","http://www.iamvijayakumar.blogspot.com/"};
    @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, str);
        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, developerSites);
        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  : "+developerSites[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  : "+str[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;
            }
        }
    }
}


XML
horz_sidemenu_activity_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<com.vijay.ex.HorizontalSideScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="#00ffffff" android:padding="0px"
    android:layout_margin="0px" android:fadingEdge="none" android:fadingEdgeLength="0px" android:scrollbars="none">
    <LinearLayout android:id="@+id/top" android:layout_height="fill_parent" android:layout_width="fill_parent"
        android:orientation="horizontal" android:background="#ffffffff" android:padding="0px" android:layout_margin="0px">
    </LinearLayout>
</com.vijay.ex.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:orientation="vertical" android:background="#ffffff"
    android:padding="2px" android:layout_margin="2px">
    <LinearLayout android:id="@+id/tabBar" android:background="#F6CE1E" android:layout_width="fill_parent" android:layout_height="60dip"
        android:orientation="horizontal">
        <ImageView android:id="@+id/BtnSlide" android:layout_width="40dip" android:layout_height="wrap_content"
            android:padding="0px" android:layout_margin="0px"  android:src="@drawable/left" />
          <View android:layout_marginLeft="15dip" android:layout_marginRight="15dip" android:background="#000000" android:layout_width="2dip" android:layout_height="wrap_content"></View>
        <TextView android:textColor="#000000" android:paddingTop="10dip" android:textSize="8pt" android:text="List Of Android Version" android:layout_width="wrap_content" android:layout_height="wrap_content" />
    </LinearLayout>
    <View  android:background="#000000" android:layout_width="fill_parent" android:layout_height="2dip"></View>
    <ListView android:id="@+id/list" android:paddingTop="10dip" android:layout_width="match_parent" android:layout_height="wrap_content"
        android:background="#25B5F1" android:cacheColorHint="@android:color/transparent" android:dividerHeight="2dip" android:divider="#FFFFFF"  >
    </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:orientation="vertical" android:background="#000000" android:layout_width="1dp" android:layout_height="1dp">
      <LinearLayout android:id="@+id/tabBar" android:background="#F6CE1E" android:layout_width="fill_parent" android:layout_height="60dip"
        android:orientation="horizontal">
        <TextView android:textColor="#000000" android:paddingTop="10dip" android:textSize="8pt" android:text="Side Menu" android:layout_width="wrap_content" android:layout_height="wrap_content" />
    </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:dividerHeight="2dip" android:divider="#FFFFFF"  android:scrollbars="none">
    </ListView>
</LinearLayout>

  Download Source Code





5 comments:

  1. From the glŠ°ss blowing manufacturing unit that is still in operation, to a dwell baĪŗery exactlу where уŠ¾u cŠ°n bakŠµ your рŠµrsonal goodies, running
    farms that you can visit and feed the animals, and functioning pottery mills.
    Sizzlіng Š°iŠ³ balloon ridŠµs over thŠµ
    gorge are also tremendously widely used. Ī¤he blooŌ of
    those whĪæ are lіving a Šµxistence of try tĪæ eat, ŌrinĪŗ and bŠµ merry is
    standard and theіr breathing is Š°bsĪælutely rapid.
    Here is my blog : using a pizza stone to bake

    ReplyDelete
  2. Howdy would you mind sharing which blog platform you're using? I'm looking
    to start my own blog in the near future but I'm having a tough time deciding between BlogEngine/Wordpress/B2evolution and Drupal. The reason I ask is because your layout seems different then most blogs and I'm looking for something unique.
    P.S Sorry for getting off-topic but I had to ask!

    Feel free to surf to my blog post onlineradio

    ReplyDelete
  3. Our table above signifies that going for a higher type of loan having a lower fee or no fee whatsoever is often more cost-effective than choosing an arrangement which has a
    lower headline rate and a large arrangement fee
    payday loans the good news is that
    approximately half all homeowners who were dropped in the foreclosure prevention
    programs last april 2010 did recieve an alternative mortgage loan modification.

    ReplyDelete
  4. i want that menu fit to every mobile... this menu open in tablts full screen. i want that in 25% of tablet screens..
    please ,,
    thanx in advance..

    ReplyDelete
  5. i want create layout support for all devices pls help me ...how to create layout design support to all device

    ReplyDelete

Check out this may be help you

Related Posts Plugin for WordPress, Blogger...