滑动菜单SlidingMenu实例

设计原理在你的UI布局有限的情况下,放不下太多的控件的时候,可以考虑用这个滑动式菜单。

效果图:

        

效果1

 

 

效果2

 

 HorzScrollWithImageMenu.java

  1. package grimbo.android.demo.slidingmenu;  
  2.   
  3. import android.app.Activity;  
  4. import android.os.Bundle;  
  5. import android.os.Handler;  
  6. import android.view.LayoutInflater;  
  7. import android.view.View;  
  8. import android.view.ViewGroup;  
  9. import android.widget.Button;  
  10. import android.widget.ListView;  
  11. import android.widget.TextView;  
  12.   
  13. public class HorzScrollWithImageMenu extends Activity {  
  14.     MyHorizontalScrollView scrollView;  
  15.     View menu;  
  16.     View app;  
  17.     Button btnSlide;  
  18.     boolean menuOut = false;  
  19.     Handler handler = new Handler();  
  20.     int btnWidth;  
  21.   
  22.     @Override  
  23.     public void onCreate(Bundle savedInstanceState) {  
  24.         super.onCreate(savedInstanceState);  
  25.   
  26.         LayoutInflater inflater = LayoutInflater.from(this);  
  27.         setContentView(inflater.inflate(R.layout.horz_scroll_with_image_menu,  
  28.                 null));  
  29.   
  30.         scrollView = (MyHorizontalScrollView) findViewById(R.id.myScrollView);  
  31.         menu = findViewById(R.id.menu);  
  32.         app = inflater.inflate(R.layout.horz_scroll_app, null);  
  33.         ViewGroup tabBar = (ViewGroup) app.findViewById(R.id.tabBar);  
  34.   
  35.         ListView listView = (ListView) app.findViewById(R.id.list);  
  36.         ViewUtils.initListView(this, listView, "Item "30,  
  37.                 android.R.layout.simple_list_item_1);  
  38.   
  39.         btnSlide = (Button) tabBar.findViewById(R.id.BtnSlide);  
  40.         btnSlide.setOnClickListener(new HorzScrollWithListMenu.ClickListenerForScrolling(  
  41.                 scrollView, menu));  
  42.   
  43.         // Create a transparent view that pushes the other views in the HSV to  
  44.         // the right.  
  45.         // This transparent view allows the menu to be shown when the HSV is  
  46.         // scrolled.  
  47.         View transparent = new TextView(this);  
  48.         transparent.setBackgroundColor(android.R.color.transparent);  
  49.   
  50.         final View[] children = new View[] { transparent, app };  
  51.   
  52.         // Scroll to app (view[1]) when layout finished.  
  53.         int scrollToViewIdx = 1;  
  54.         scrollView.initViews(children, scrollToViewIdx,  
  55.                 new HorzScrollWithListMenu.SizeCallbackForMenu(btnSlide));  
  56.     }  
  57. }  
package grimbo.android.demo.slidingmenu;

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.ListView;
import android.widget.TextView;

public class HorzScrollWithImageMenu extends Activity {
	MyHorizontalScrollView scrollView;
	View menu;
	View app;
	Button btnSlide;
	boolean menuOut = false;
	Handler handler = new Handler();
	int btnWidth;

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

		LayoutInflater inflater = LayoutInflater.from(this);
		setContentView(inflater.inflate(R.layout.horz_scroll_with_image_menu,
				null));

		scrollView = (MyHorizontalScrollView) findViewById(R.id.myScrollView);
		menu = findViewById(R.id.menu);
		app = inflater.inflate(R.layout.horz_scroll_app, null);
		ViewGroup tabBar = (ViewGroup) app.findViewById(R.id.tabBar);

		ListView listView = (ListView) app.findViewById(R.id.list);
		ViewUtils.initListView(this, listView, "Item ", 30,
				android.R.layout.simple_list_item_1);

		btnSlide = (Button) tabBar.findViewById(R.id.BtnSlide);
		btnSlide.setOnClickListener(new HorzScrollWithListMenu.ClickListenerForScrolling(
				scrollView, menu));

		// Create a transparent view that pushes the other views in the HSV to
		// the right.
		// This transparent view allows the menu to be shown when the HSV is
		// scrolled.
		View transparent = new TextView(this);
		transparent.setBackgroundColor(android.R.color.transparent);

		final View[] children = new View[] { transparent, app };

		// Scroll to app (view[1]) when layout finished.
		int scrollToViewIdx = 1;
		scrollView.initViews(children, scrollToViewIdx,
				new HorzScrollWithListMenu.SizeCallbackForMenu(btnSlide));
	}
}


 

HorzScrollWithListMenu.java

  1. package grimbo.android.demo.slidingmenu;  
  2.   
  3. import grimbo.android.demo.slidingmenu.MyHorizontalScrollView.SizeCallback;  
  4.   
  5. import java.security.Guard;  
  6. import java.util.Date;  
  7.   
  8. import android.app.Activity;  
  9. import android.content.Context;  
  10. import android.os.Bundle;  
  11. import android.os.Handler;  
  12. import android.view.GestureDetector.OnGestureListener;  
  13. import android.view.LayoutInflater;  
  14. import android.view.MotionEvent;  
  15. import android.view.View;  
  16. import android.view.View.OnClickListener;  
  17. import android.view.ViewGroup;  
  18. import android.widget.HorizontalScrollView;  
  19. import android.widget.ImageView;  
  20. import android.widget.ListView;  
  21. import android.widget.Toast;  
  22.   
  23. /** 
  24.  * This demo uses a custom HorizontalScrollView that ignores touch events, and therefore does NOT allow manual scrolling. 
  25.  *  
  26.  * The only scrolling allowed is scrolling in code triggered by the menu button. 
  27.  *  
  28.  * When the button is pressed, both the menu and the app will scroll. So the menu isn't revealed from beneath the app, it 
  29.  * adjoins the app and moves with the app. 
  30.  */  
  31. public class HorzScrollWithListMenu extends Activity implements OnGestureListener{  
  32.     MyHorizontalScrollView scrollView;  
  33.     View menu;  
  34.     View app;  
  35.     ImageView btnSlide;  
  36.     boolean menuOut = false;  
  37.     Handler handler = new Handler();  
  38.     int btnWidth;  
  39.   
  40.     @Override  
  41.     public void onCreate(Bundle savedInstanceState) {  
  42.         super.onCreate(savedInstanceState);  
  43.   
  44.         LayoutInflater inflater = LayoutInflater.from(this);  
  45.         scrollView = (MyHorizontalScrollView) inflater.inflate(R.layout.horz_scroll_with_list_menu, null);  
  46.         setContentView(scrollView);  
  47.   
  48.         menu = inflater.inflate(R.layout.horz_scroll_menu, null);  
  49.         app = inflater.inflate(R.layout.horz_scroll_app, null);  
  50.         ViewGroup tabBar = (ViewGroup) app.findViewById(R.id.tabBar);  
  51.   
  52.         ListView listView = (ListView) app.findViewById(R.id.list);  
  53.         ViewUtils.initListView(this, listView, "Item "30, android.R.layout.simple_list_item_1);  
  54.   
  55.         listView = (ListView) menu.findViewById(R.id.list);  
  56.         ViewUtils.initListView(this, listView, "Menu "30, android.R.layout.simple_list_item_1);  
  57.   
  58.         btnSlide = (ImageView) tabBar.findViewById(R.id.BtnSlide);  
  59.         btnSlide.setOnClickListener(new ClickListenerForScrolling(scrollView, menu));  
  60.   
  61.         final View[] children = new View[] { menu, app };  
  62.   
  63.         // Scroll to app (view[1]) when layout finished.  
  64.         int scrollToViewIdx = 1;  
  65.         scrollView.initViews(children, scrollToViewIdx, new SizeCallbackForMenu(btnSlide));  
  66.     }  
  67.   
  68.     /** 
  69.      * Helper for examples with a HSV that should be scrolled by a menu View's width. 
  70.      */  
  71.     static class ClickListenerForScrolling implements OnClickListener {  
  72.         HorizontalScrollView scrollView;  
  73.         View menu;  
  74.         /** 
  75.          * Menu must NOT be out/shown to start with. 
  76.          */  
  77.         boolean menuOut = false;  
  78.   
  79.         public ClickListenerForScrolling(HorizontalScrollView scrollView, View menu) {  
  80.             super();  
  81.             this.scrollView = scrollView;  
  82.             this.menu = menu;  
  83.         }  
  84.   
  85.         @Override  
  86.         public void onClick(View v) {  
  87.             Context context = menu.getContext();  
  88.   
  89.             int menuWidth = menu.getMeasuredWidth();  
  90.   
  91.             // Ensure menu is visible  
  92.             menu.setVisibility(View.VISIBLE);  
  93.   
  94.             if (!menuOut) {  
  95.                 // Scroll to 0 to reveal menu  
  96.                 int left = 0;  
  97.                 scrollView.smoothScrollTo(left, 0);  
  98.             } else {  
  99.                 // Scroll to menuWidth so menu isn't on screen.  
  100.                 int left = menuWidth;  
  101.                 scrollView.smoothScrollTo(left, 0);  
  102.             }  
  103.             menuOut = !menuOut;  
  104.         }  
  105.     }  
  106.   
  107.     /** 
  108.      * Helper that remembers the width of the 'slide' button, so that the 'slide' button remains in view, even when the menu is 
  109.      * showing. 
  110.      */  
  111.     static class SizeCallbackForMenu implements SizeCallback {  
  112.         int btnWidth;  
  113.         View btnSlide;  
  114.   
  115.         public SizeCallbackForMenu(View btnSlide) {  
  116.             super();  
  117.             this.btnSlide = btnSlide;  
  118.         }  
  119.   
  120.         @Override  
  121.         public void onGlobalLayout() {  
  122.             btnWidth = btnSlide.getMeasuredWidth();  
  123.             System.out.println("btnWidth=" + btnWidth);  
  124.         }  
  125.   
  126.         @Override  
  127.         public void getViewSize(int idx, int w, int h, int[] dims) {  
  128.             dims[0] = w;  
  129.             dims[1] = h;  
  130.             final int menuIdx = 0;  
  131.             if (idx == menuIdx) {  
  132.                 dims[0] = w - btnWidth;  
  133.             }  
  134.         }  
  135.     }  
  136.   
  137.     @Override  
  138.     public boolean onDown(MotionEvent e) {  
  139.         // TODO Auto-generated method stub  
  140.         return false;  
  141.     }  
  142.   
  143.     @Override  
  144.     public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,  
  145.             float velocityY) {  
  146.         // TODO Auto-generated method stub  
  147.         return false;  
  148.     }  
  149.   
  150.     @Override  
  151.     public void onLongPress(MotionEvent e) {  
  152.         // TODO Auto-generated method stub  
  153.           
  154.     }  
  155.   
  156.     @Override  
  157.     public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX,  
  158.             float distanceY) {  
  159.         // TODO Auto-generated method stub  
  160.         return false;  
  161.     }  
  162.   
  163.     @Override  
  164.     public void onShowPress(MotionEvent e) {  
  165.         // TODO Auto-generated method stub  
  166.           
  167.     }  
  168.   
  169.     @Override  
  170.     public boolean onSingleTapUp(MotionEvent e) {  
  171.         // TODO Auto-generated method stub  
  172.         return false;  
  173.     }  
  174. }  
package grimbo.android.demo.slidingmenu;

import grimbo.android.demo.slidingmenu.MyHorizontalScrollView.SizeCallback;

import java.security.Guard;
import java.util.Date;

import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.os.Handler;
import android.view.GestureDetector.OnGestureListener;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.HorizontalScrollView;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.Toast;

/**
 * This demo uses a custom HorizontalScrollView that ignores touch events, and therefore does NOT allow manual scrolling.
 * 
 * The only scrolling allowed is scrolling in code triggered by the menu button.
 * 
 * When the button is pressed, both the menu and the app will scroll. So the menu isn't revealed from beneath the app, it
 * adjoins the app and moves with the app.
 */
public class HorzScrollWithListMenu extends Activity implements OnGestureListener{
    MyHorizontalScrollView scrollView;
    View menu;
    View app;
    ImageView btnSlide;
    boolean menuOut = false;
    Handler handler = new Handler();
    int btnWidth;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

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

        menu = inflater.inflate(R.layout.horz_scroll_menu, null);
        app = inflater.inflate(R.layout.horz_scroll_app, null);
        ViewGroup tabBar = (ViewGroup) app.findViewById(R.id.tabBar);

        ListView listView = (ListView) app.findViewById(R.id.list);
        ViewUtils.initListView(this, listView, "Item ", 30, android.R.layout.simple_list_item_1);

        listView = (ListView) menu.findViewById(R.id.list);
        ViewUtils.initListView(this, listView, "Menu ", 30, android.R.layout.simple_list_item_1);

        btnSlide = (ImageView) tabBar.findViewById(R.id.BtnSlide);
        btnSlide.setOnClickListener(new ClickListenerForScrolling(scrollView, menu));

        final View[] children = new View[] { menu, app };

        // Scroll to app (view[1]) when layout finished.
        int scrollToViewIdx = 1;
        scrollView.initViews(children, scrollToViewIdx, new SizeCallbackForMenu(btnSlide));
    }

    /**
     * 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) {
            Context context = menu.getContext();

            int menuWidth = menu.getMeasuredWidth();

            // Ensure menu is visible
            menu.setVisibility(View.VISIBLE);

            if (!menuOut) {
                // Scroll to 0 to reveal menu
                int left = 0;
                scrollView.smoothScrollTo(left, 0);
            } else {
                // Scroll to menuWidth so menu isn't on screen.
                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();
            System.out.println("btnWidth=" + btnWidth);
        }

        @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;
            }
        }
    }

	@Override
	public boolean onDown(MotionEvent e) {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
			float velocityY) {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public void onLongPress(MotionEvent e) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX,
			float distanceY) {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public void onShowPress(MotionEvent e) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public boolean onSingleTapUp(MotionEvent e) {
		// TODO Auto-generated method stub
		return false;
	}
}


 

MyHorizontalScrollView.java

  1. package grimbo.android.demo.slidingmenu;  
  2.   
  3. import android.content.Context;  
  4. import android.os.Handler;  
  5. import android.util.AttributeSet;  
  6. import android.view.MotionEvent;  
  7. import android.view.View;  
  8. import android.view.ViewGroup;  
  9. import android.view.ViewTreeObserver.OnGlobalLayoutListener;  
  10. import android.widget.HorizontalScrollView;  
  11.   
  12. /** 
  13.  * A HorizontalScrollView (HSV) implementation that disallows touch events (so 
  14.  * no scrolling can be done by the user). 
  15.  *  
  16.  * This HSV MUST contain a single ViewGroup as its only child, and this 
  17.  * ViewGroup will be used to display the children Views passed in to the 
  18.  * initViews() method. 
  19.  */  
  20. public class MyHorizontalScrollView extends HorizontalScrollView {  
  21.     public MyHorizontalScrollView(Context context, AttributeSet attrs,  
  22.             int defStyle) {  
  23.         super(context, attrs, defStyle);  
  24.         init(context);  
  25.     }  
  26.   
  27.     public MyHorizontalScrollView(Context context, AttributeSet attrs) {  
  28.         super(context, attrs);  
  29.         init(context);  
  30.     }  
  31.   
  32.     public MyHorizontalScrollView(Context context) {  
  33.         super(context);  
  34.         init(context);  
  35.     }  
  36.   
  37.     void init(Context context) {  
  38.         // remove the fading as the HSV looks better without it  
  39.         setHorizontalFadingEdgeEnabled(false);  
  40.         setVerticalFadingEdgeEnabled(false);  
  41.     }  
  42.   
  43.     /** 
  44.      * @param children 
  45.      *            The child Views to add to parent. 
  46.      * @param scrollToViewIdx 
  47.      *            The index of the View to scroll to after initialisation. 
  48.      * @param sizeCallback 
  49.      *            A SizeCallback to interact with the HSV. 
  50.      */  
  51.     public void initViews(View[] children, int scrollToViewIdx,  
  52.             SizeCallback sizeCallback) {  
  53.         // A ViewGroup MUST be the only child of the HSV  
  54.         ViewGroup parent = (ViewGroup) getChildAt(0);  
  55.   
  56.         // Add all the children, but add them invisible so that the layouts are  
  57.         // calculated, but you can't see the Views  
  58.         for (int i = 0; i < children.length; i++) {  
  59.             children[i].setVisibility(View.INVISIBLE);  
  60.             parent.addView(children[i]);  
  61.         }  
  62.   
  63.         // Add a layout listener to this HSV  
  64.         // This listener is responsible for arranging the child views.  
  65.         OnGlobalLayoutListener listener = new MyOnGlobalLayoutListener(parent,  
  66.                 children, scrollToViewIdx, sizeCallback);  
  67.         getViewTreeObserver().addOnGlobalLayoutListener(listener);  
  68.     }  
  69.   
  70.     @Override  
  71.     public boolean onTouchEvent(MotionEvent ev) {  
  72.         // Do not allow touch events.  
  73.         return false;  
  74.     }  
  75.   
  76.     @Override  
  77.     public boolean onInterceptTouchEvent(MotionEvent ev) {  
  78.         // Do not allow touch events.  
  79.         return false;  
  80.     }  
  81.   
  82.     /** 
  83.      * An OnGlobalLayoutListener impl that passes on the call to onGlobalLayout 
  84.      * to a SizeCallback, before removing all the Views in the HSV and adding 
  85.      * them again with calculated widths and heights. 
  86.      */  
  87.     class MyOnGlobalLayoutListener implements OnGlobalLayoutListener {  
  88.         ViewGroup parent;  
  89.         View[] children;  
  90.         int scrollToViewIdx;  
  91.         int scrollToViewPos = 0;  
  92.         SizeCallback sizeCallback;  
  93.   
  94.         /** 
  95.          * @param parent 
  96.          *            The parent to which the child Views should be added. 
  97.          * @param children 
  98.          *            The child Views to add to parent. 
  99.          * @param scrollToViewIdx 
  100.          *            The index of the View to scroll to after initialisation. 
  101.          * @param sizeCallback 
  102.          *            A SizeCallback to interact with the HSV. 
  103.          */  
  104.         public MyOnGlobalLayoutListener(ViewGroup parent, View[] children,  
  105.                 int scrollToViewIdx, SizeCallback sizeCallback) {  
  106.             this.parent = parent;  
  107.             this.children = children;  
  108.             this.scrollToViewIdx = scrollToViewIdx;  
  109.             this.sizeCallback = sizeCallback;  
  110.         }  
  111.   
  112.         @Override  
  113.         public void onGlobalLayout() {  
  114.             // System.out.println("onGlobalLayout");  
  115.   
  116.             final HorizontalScrollView me = MyHorizontalScrollView.this;  
  117.   
  118.             // The listener will remove itself as a layout listener to the HSV  
  119.             me.getViewTreeObserver().removeGlobalOnLayoutListener(this);  
  120.   
  121.             // Allow the SizeCallback to 'see' the Views before we remove them  
  122.             // and re-add them.  
  123.             // This lets the SizeCallback prepare View sizes, ahead of calls to  
  124.             // SizeCallback.getViewSize().  
  125.             sizeCallback.onGlobalLayout();  
  126.   
  127.             parent.removeViewsInLayout(0, children.length);  
  128.   
  129.             final int w = me.getMeasuredWidth();  
  130.             final int h = me.getMeasuredHeight();  
  131.   
  132.             // System.out.println("w=" + w + ", h=" + h);  
  133.   
  134.             // Add each view in turn, and apply the width and height returned by  
  135.             // the SizeCallback.  
  136.             int[] dims = new int[2];  
  137.             scrollToViewPos = 0;  
  138.             for (int i = 0; i < children.length; i++) {  
  139.                 sizeCallback.getViewSize(i, w, h, dims);  
  140.                 // System.out.println("addView w=" + dims[0] + ", h=" +  
  141.                 // dims[1]);  
  142.                 children[i].setVisibility(View.VISIBLE);  
  143.                 parent.addView(children[i], dims[0], dims[1]);  
  144.                 if (i < scrollToViewIdx) {  
  145.                     scrollToViewPos += dims[0];  
  146.                 }  
  147.             }  
  148.   
  149.             // For some reason we need to post this action, rather than call  
  150.             // immediately.  
  151.             // If we try immediately, it will not scroll.  
  152.             new Handler().post(new Runnable() {  
  153.                 @Override  
  154.                 public void run() {  
  155.                     me.scrollBy(scrollToViewPos, 0);  
  156.                 }  
  157.             });  
  158.         }  
  159.     }  
  160.   
  161.     /** 
  162.      * Callback interface to interact with the HSV. 
  163.      */  
  164.     public interface SizeCallback {  
  165.         /** 
  166.          * Used to allow clients to measure Views before re-adding them. 
  167.          */  
  168.         public void onGlobalLayout();  
  169.   
  170.         /** 
  171.          * Used by clients to specify the View dimensions. 
  172.          *  
  173.          * @param idx 
  174.          *            Index of the View. 
  175.          * @param w 
  176.          *            Width of the parent View. 
  177.          * @param h 
  178.          *            Height of the parent View. 
  179.          * @param dims 
  180.          *            dims[0] should be set to View width. dims[1] should be set 
  181.          *            to View height. 
  182.          */  
  183.         public void getViewSize(int idx, int w, int h, int[] dims);  
  184.     }  
  185. }  
package grimbo.android.demo.slidingmenu;

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 MyHorizontalScrollView extends HorizontalScrollView {
	public MyHorizontalScrollView(Context context, AttributeSet attrs,
			int defStyle) {
		super(context, attrs, defStyle);
		init(context);
	}

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

	public MyHorizontalScrollView(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 HorizontalScrollView me = MyHorizontalScrollView.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);
	}
}


 

ViewUtils.java

  1. package grimbo.android.demo.slidingmenu;  
  2.   
  3. import android.content.Context;  
  4. import android.view.View;  
  5. import android.widget.AdapterView;  
  6. import android.widget.AdapterView.OnItemClickListener;  
  7. import android.widget.ArrayAdapter;  
  8. import android.widget.ListView;  
  9. import android.widget.Toast;  
  10.   
  11. /** 
  12.  * Utility methods for Views. 
  13.  */  
  14. public class ViewUtils {  
  15.     private ViewUtils() {  
  16.     }  
  17.   
  18.     public static void setViewWidths(View view, View[] views) {  
  19.         int w = view.getWidth();  
  20.         int h = view.getHeight();  
  21.         for (int i = 0; i < views.length; i++) {  
  22.             View v = views[i];  
  23.             v.layout((i + 1) * w, 0, (i + 2) * w, h);  
  24.             printView("view[" + i + "]", v);  
  25.         }  
  26.     }  
  27.   
  28.     public static void printView(String msg, View v) {  
  29.         System.out.println(msg + "=" + v);  
  30.         if (null == v) {  
  31.             return;  
  32.         }  
  33.         System.out.print("[" + v.getLeft());  
  34.         System.out.print(", " + v.getTop());  
  35.         System.out.print(", w=" + v.getWidth());  
  36.         System.out.println(", h=" + v.getHeight() + "]");  
  37.         System.out.println("mw=" + v.getMeasuredWidth() + ", mh="  
  38.                 + v.getMeasuredHeight());  
  39.         System.out.println("scroll [" + v.getScrollX() + "," + v.getScrollY()  
  40.                 + "]");  
  41.     }  
  42.   
  43.     public static void initListView(Context context, ListView listView,  
  44.             String prefix, int numItems, int layout) {  
  45.         // By using setAdpater method in listview we an add string array in  
  46.         // list.  
  47.         String[] arr = new String[numItems];  
  48.         for (int i = 0; i < arr.length; i++) {  
  49.             arr[i] = prefix + (i + 1);  
  50.         }  
  51.         listView.setAdapter(new ArrayAdapter<String>(context, layout, arr));  
  52.         listView.setOnItemClickListener(new OnItemClickListener() {  
  53.             @Override  
  54.             public void onItemClick(AdapterView<?> parent, View view,  
  55.                     int position, long id) {  
  56.                 Context context = view.getContext();  
  57.                 String msg = "item[" + position + "]="  
  58.                         + parent.getItemAtPosition(position);  
  59.                 Toast.makeText(context, msg, 1000).show();  
  60.                 System.out.println(msg);  
  61.             }  
  62.         });  
  63.     }  
  64. }  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值