Xamarin.android 抽屉效果(SlideMenu)

话不多说,源码在此:

using System;

using Android.Content;
using Android.Views;
using Android.Widget;
using Android.Util;

namespace FirstApp.Widget
{
	class SlideMenu : HorizontalScrollView
	{
		/** 
     * 屏幕宽度 
     */
		private int mScreenWidth;
		/** 
		 * dp 
		 */
		private int mMenuRightPadding = 50;
		/** 
		 * 菜单的宽度 
		 */
		private int mMenuWidth;
		private int mHalfMenuWidth;
		private bool isOpen;
		ViewGroup menu;

		private Boolean once;
		public SlideMenu(Context context, IAttributeSet attribute) : base(context, attribute)
		{
			mScreenWidth = context.Resources.DisplayMetrics.WidthPixels;
		}

		protected override void OnMeasure(int widthMeasureSpec, int heightMeasureSpec)
		{
			if (!once)
			{
				LinearLayout wrapper = (LinearLayout)GetChildAt(0);
				menu = (ViewGroup)wrapper.GetChildAt(0);
				ViewGroup content = (ViewGroup)wrapper.GetChildAt(1);
				// dp to px  
				mMenuRightPadding = (int)TypedValue.ApplyDimension(
						ComplexUnitType.Dip, mMenuRightPadding, content
								.Resources.DisplayMetrics);

				mMenuWidth = mScreenWidth - mMenuRightPadding;
				mHalfMenuWidth = mMenuWidth / 2;
				menu.LayoutParameters.Width = mMenuWidth;
				content.LayoutParameters.Width = mScreenWidth;

			}
			base.OnMeasure(widthMeasureSpec, heightMeasureSpec);
		}


		protected override void OnLayout(bool changed, int left, int top, int right, int bottom)
		{
			base.OnLayout(changed, left, top, right, bottom);
			if (changed)
			{
				// 将菜单隐藏  
				this.ScrollTo(mMenuWidth, 0);
				once = true;
			}
		}

		public override bool OnInterceptTouchEvent(MotionEvent ev)
		{
			switch (ev.ActionMasked)
			{
				case MotionEventActions.Down:
					if (ev.RawX < 30 && !isOpen)
					{
						//ev.Action = MotionEventActions.Cancel;
						//DispatchTouchEvent(ev);
						return true;
					}
					if (isOpen)
					{
						return true;
					}
					break;
			}
			return false;
		}

		public override bool OnTouchEvent(MotionEvent ev)
		{
			MotionEventActions action = ev.ActionMasked;
			switch (action)
			{
				case MotionEventActions.Down:
					if (ev.RawX > 30 && !isOpen)
					{
						ev.Action = MotionEventActions.Cancel;
						DispatchTouchEvent(ev);
					}
					break;

				// Up时,进行判断,如果显示区域大于菜单宽度一半则完全显示,否则隐藏  
				case MotionEventActions.Up:
					int scrollX = ScrollX;
					if (isOpen)
					{
						if (scrollX > 2*mMenuWidth / 5)
						{
							this.SmoothScrollTo(mMenuWidth, 0);
							isOpen = false;
						}
						else
						{
							this.SmoothScrollTo(0, 0);
						}
						if(ev.RawX> mMenuWidth && scrollX==0)
						{
							this.SmoothScrollTo(mMenuWidth, 0);
							isOpen = false;
						}
					}
					else
					{
						if (scrollX < mMenuWidth * 3 / 5)
						{
							this.SmoothScrollTo(0, 0);
							isOpen = true;
						}
						else
						{
							this.SmoothScrollTo(mMenuWidth, 0);
						}
					}
					return true;
			}
			return base.OnTouchEvent(ev);
		}

		public bool getStatus()
		{
			return isOpen;
		}

		public void openMenu()
		{
			if (isOpen)
			{
				this.SmoothScrollTo(mMenuWidth, 0);
				isOpen = false;
			}
		}

		public void closeMenu()
		{
			if (!isOpen)
			{
				this.SmoothScrollTo(0, 0);
				isOpen = true;
			}
		}
	
	}
}

布局文件:

<?xml version="1.0" encoding="utf-8"?>
<FirstApp.Widget.SlideMenu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#ffffff"
    android:scrollbars="none">
    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="fill_parent"
        android:orientation="horizontal">
        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="fill_parent" />
        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="fill_parent"
            android:orientation="vertical">
            <EditText
                android:inputType="textPersonName"
                android:layout_width="200dp"
                android:layout_height="wrap_content"
                android:hint="username"
                android:id="@+id/editText1" />
            <EditText
                android:layout_width="200dp"
                android:layout_height="wrap_content"
                android:hint="password" />
            <Button
                android:layout_height="wrap_content"
                android:layout_width="wrap_content"
                android:text="确定"
                android:id="@+id/btn_sure" />
            <ImageView
                android:src="@android:drawable/ic_menu_gallery"
                android:layout_width="200dp"
                android:layout_height="150dp"
                android:id="@+id/imageView1" />
            <Button
                android:text="testDB"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:id="@+id/button1" />
            <FirstApp.Widget.MyIndicator
                android:layout_width="wrap_content"
                android:layout_height="40dp"
                android:background="#cccccc"
                android:id="@+id/indicor" />
            <android.support.v4.view.ViewPager
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:id="@+id/viewPager1" />
        </LinearLayout>
    </LinearLayout>
</FirstApp.Widget.SlideMenu>

注意,必须有一个组件把menu和containt包裹,这是HorizontalScrollView特性决定的。

使用时主要用openMenu()和closeMenu()方法就行了。其它自己具体设置吧。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值