using System; using Android.Content; using Android.Views; using Android.Util; using Android.Runtime; using Android.Widget; using Android.OS; using Android.Views.Animations; namespace Shared { //已经全面检查了代码 /// /// 在滑动事件下,可显示隐藏些自定义视图 /// public class RowLayout : ViewGroup { AndroidRowLayout androidRowLayout; ///// ///// OpenLeftMenuAction ///// //public Action OpenLeftMenuAction; ///// ///// OpenRightMenuAction ///// //public Action OpenRightMenuAction; public Action OpenMenuAction; uint lineColor = 0x62818181; /// /// 背景颜色 /// /// The color of the background. public virtual uint LineColor { get { return lineColor; } set { lineColor = value; byte r, g, b, a; r = (byte)(lineColor / 256 / 256 % 256); g = (byte)(lineColor / 256 % 256); b = (byte)(lineColor % 256); a = (byte)(lineColor / 256 / 256 / 256 % 256); lineLinearLayout.SetBackgroundColor(Android.Graphics.Color.Argb(a, r, g, b)); } } /// /// 宽度设置或读取 /// /// The width. public override int Width { get { return base.Width; } set { base.Width = value; if (!IsCanRefresh) { return; } var layoutParameters = androidRowLayout.LayoutParameters; layoutParameters.Width = Width; androidRowLayout.LayoutParameters = layoutParameters; } } /// /// 视图高度 /// /// The height. public override int Height { get { return base.Height; } set { base.Height = value; if (!IsCanRefresh) { return; } var layoutParameters = androidRowLayout.LayoutParameters; layoutParameters.Height = Height; androidRowLayout.LayoutParameters = layoutParameters; } } Android.Widget.LinearLayout leftLinarLayout; Android.Widget.LinearLayout rightLinarLayout; Android.Widget.LinearLayout lineLinearLayout; /// /// 在滑动事件下,可显示隐藏些自定义视图 /// public RowLayout() { viewGroup = new Android.Widget.FrameLayout(Application.Activity); androidRowLayout = new AndroidRowLayout(Application.Activity, this) { }; androidRowLayout.RightToLeftAction += () => { HideOtherRowLayout(); OpenRightMenu(); }; androidRowLayout.LeftToRightAction += () => { HideOtherRowLayout(); OpenLeftMenu(); }; realViewGroup = androidRowLayout; leftLinarLayout = new Android.Widget.LinearLayout(Application.Activity) { Orientation = Android.Widget.Orientation.Horizontal, Alpha = 0.0f }; rightLinarLayout = new Android.Widget.LinearLayout(Application.Activity) { Orientation = Android.Widget.Orientation.Horizontal, Alpha = 0.0f }; lineLinearLayout = new Android.Widget.LinearLayout(Application.Activity); LineColor = lineColor; viewGroup.AddView(leftLinarLayout, new Android.Views.ViewGroup.LayoutParams(Android.Views.ViewGroup.LayoutParams.WrapContent, Android.Views.ViewGroup.LayoutParams.MatchParent)); viewGroup.AddView(rightLinarLayout, new Android.Views.ViewGroup.LayoutParams(Android.Views.ViewGroup.LayoutParams.WrapContent, Android.Views.ViewGroup.LayoutParams.MatchParent)); viewGroup.AddView(androidRowLayout, new Android.Views.ViewGroup.LayoutParams(Android.Views.ViewGroup.LayoutParams.MatchParent, Android.Views.ViewGroup.LayoutParams.MatchParent)); viewGroup.AddView(lineLinearLayout, new Android.Widget.FrameLayout.LayoutParams(Android.Views.ViewGroup.LayoutParams.MatchParent, DensityUtil.Dip2Px(1), Android.Views.GravityFlags.Bottom)); } /// /// 是否正打开 /// //public bool IsOpening; public bool IsShowLeft; public bool IsShowRight; /// /// 关闭其他RowLayout 显示的View /// private void HideOtherRowLayout() { try { if (this.Parent != null) { foreach (View mView in Parent.viewList) { if (mView is RowLayout && mView != this) { if ((mView as RowLayout).IsShowRight || (mView as RowLayout).IsShowLeft) { (mView as RowLayout).HideMenu(); } } } } } catch { } } /// /// 关闭显示的View /// public void HideMenu() { if (IsShowLeft) { HideLeftMenu(); } if (IsShowRight) { HideRightMenu(); } } public void OpenLeftMenu() { if (IsShowRight) { HideRightMenu(); return; } if (leftLinarLayout.ChildCount == 0) return; IsShowLeft = true; Android.Widget.FrameLayout.LayoutParams lp = (Android.Widget.FrameLayout.LayoutParams)androidRowLayout.LayoutParameters; lp.LeftMargin = leftLinarLayout.LayoutParameters.Width; androidRowLayout.LayoutParameters = lp; leftLinarLayout.Alpha = 1.0f; if (leftLinarLayout.Animation == null) { leftLinarLayout.Animation = new TranslateAnimation( Dimension.RelativeToSelf, 0.1f, Dimension.RelativeToSelf, 0, Dimension.RelativeToSelf, 0, Dimension.RelativeToSelf, 0); leftLinarLayout.Animation.Duration = 200; } // Animation = leftUIView.Animation; //Animation.Reset(); //Animation.StartNow(); leftLinarLayout.Animation.Reset(); leftLinarLayout.Animation.StartNow(); OpenMenuAction?.Invoke(); // UIView.Animate (0.2f, 0.0f, UIViewAnimationOptions.BeginFromCurrentState, () => { // contentView.X = (int)leftUIView.Frame.Width; // leftUIView.Alpha = 1.0f; // }, () => { // // }); } public void HideLeftMenu() { IsShowLeft = false; Android.Widget.FrameLayout.LayoutParams lp = (Android.Widget.FrameLayout.LayoutParams)androidRowLayout.LayoutParameters; lp.LeftMargin = 0; androidRowLayout.LayoutParameters = lp; leftLinarLayout.Alpha = 0.0f; // UIView.Animate(0.2f,0.0f,UIViewAnimationOptions.BeginFromCurrentState,()=>{ // contentView.X=0; // leftUIView.Alpha=0.0f; // },()=>{ // // }); } public void OpenRightMenu() { if (IsShowLeft) { HideLeftMenu(); return; } if (rightLinarLayout.ChildCount == 0) return; IsShowRight = true; Android.Widget.FrameLayout.LayoutParams lp = (Android.Widget.FrameLayout.LayoutParams)androidRowLayout.LayoutParameters; lp.LeftMargin = -rightLinarLayout.LayoutParameters.Width; androidRowLayout.LayoutParameters = lp; rightLinarLayout.Alpha = 1.0f; if (rightLinarLayout.Animation == null) { rightLinarLayout.Animation = new TranslateAnimation( Dimension.RelativeToSelf, -0.1f, Dimension.RelativeToSelf, 0.0f, Dimension.RelativeToSelf, 0, Dimension.RelativeToSelf, 0); rightLinarLayout.Animation.Duration = 200; } //Animation = rightUIView.Animation; //Animation.Reset(); //Animation.StartNow(); rightLinarLayout.Animation.Reset(); rightLinarLayout.Animation.StartNow(); OpenMenuAction?.Invoke(); } public void HideRightMenu() { IsShowRight = false; Android.Widget.FrameLayout.LayoutParams lp = (Android.Widget.FrameLayout.LayoutParams)androidRowLayout.LayoutParameters; lp.LeftMargin = 0; androidRowLayout.LayoutParameters = lp; rightLinarLayout.Alpha = 0.0f; } public int SubViewWidth { get { return subViewWidth; } set { subViewWidth = value; } } /// /// 是否使用同样的SubViewWidth宽 /// bool isUseSameSubViewWidth = true; public bool IsUseSameSubViewWidth { get { return isUseSameSubViewWidth; } set { isUseSameSubViewWidth = value; } } /// /// 获取当前leftView的总宽 /// /// int GetAllLeftViewWidth() { int mWidth = 0; for (int i = 0; i < leftLinarLayout.ChildCount; i++) { if (leftLinarLayout.GetChildAt(i).LayoutParameters != null) { mWidth += leftLinarLayout.GetChildAt(i).LayoutParameters.Width; } } return mWidth; } /// /// 获取当前rigthView的总宽 /// /// int GetAllRightViewWidth() { int mWidth = 0; for (int i = 0; i < rightLinarLayout.ChildCount; i++) { if (rightLinarLayout.GetChildAt(i).LayoutParameters != null) { mWidth += rightLinarLayout.GetChildAt(i).LayoutParameters.Width; } } return mWidth; } /// /// 子视图的宽度 /// int subViewWidth = DensityUtil.Dip2Px(100); /// /// 增加左边视图 /// /// View. public void AddLeftView(View view) { var mSubViewWidth = isUseSameSubViewWidth ? SubViewWidth : view.Width; if (isUseSameSubViewWidth) { leftLinarLayout.AddView(view.AndroidView, new Android.Views.ViewGroup.LayoutParams(mSubViewWidth, androidRowLayout.LayoutParameters.Height)); } else { var mLayoutParams = new LinearLayout.LayoutParams(mSubViewWidth, androidRowLayout.LayoutParameters.Height); mLayoutParams.Gravity = GravityFlags.CenterHorizontal; leftLinarLayout.AddView(view.AndroidView, mLayoutParams); } leftLinarLayout.LayoutParameters.Width = GetAllLeftViewWidth(); view.Parent = this; view.Width = mSubViewWidth; view.Height = androidRowLayout.LayoutParameters.Height; } /// /// 增加右边视图 /// /// View. public void AddRightView(View view) { var mSubViewWidth = isUseSameSubViewWidth ? SubViewWidth : view.Width; if (isUseSameSubViewWidth) { rightLinarLayout.AddView(view.AndroidView, new Android.Views.ViewGroup.LayoutParams(mSubViewWidth, androidRowLayout.LayoutParameters.Height)); } else { var mLayoutParams = new LinearLayout.LayoutParams(mSubViewWidth, androidRowLayout.LayoutParameters.Height); mLayoutParams.Gravity = GravityFlags.CenterHorizontal; rightLinarLayout.AddView(view.AndroidView, mLayoutParams); } rightLinarLayout.LayoutParameters.Width = GetAllRightViewWidth(); ((Android.Widget.FrameLayout.LayoutParams)rightLinarLayout.LayoutParameters).LeftMargin = androidRowLayout.LayoutParameters.Width - rightLinarLayout.LayoutParameters.Width; view.Parent = this; view.Width = mSubViewWidth; view.Height = androidRowLayout.LayoutParameters.Height; } class AndroidRowLayout : Android.Widget.FrameLayout { View _view; int mTouchSlop { get { var configuration = ViewConfiguration.Get(Context); //最小的滑动距离 return configuration.ScaledTouchSlop; } } public AndroidRowLayout(Context context, View view) : base(context) { _view = view; } float mLastX, mLastY; //internal bool isShowLeft; //internal bool isShowRight; public Action RightToLeftAction; public Action LeftToRightAction; bool isActioned; bool action(MotionEvent e) { switch (e.Action) { case MotionEventActions.Down: //记录点击的最新X坐标 mLastX = e.RawX; mLastY = e.RawY; Parent?.RequestDisallowInterceptTouchEvent(true); break; case MotionEventActions.Move: var x = e.RawX; var y = e.RawY; var deltaX = x - mLastX; var deltaY = y - mLastY; if (Math.Abs(deltaY) < Math.Abs(deltaX)) { if (!isActioned) { //RightToLeftAction if (deltaX < -mTouchSlop) { isActioned = true; //parentDelay(true); //Shared.HDLUtils.WriteLine("RowLayout:DispatchTouchEvent:RightToLeft"); RightToLeftAction?.Invoke(); } //LeftToRightAction if (mTouchSlop < deltaX) { isActioned = true; //parentDelay(true); //Shared.HDLUtils.WriteLine("RowLayout:DispatchTouchEvent:LeftToRight"); LeftToRightAction?.Invoke(); } } return true; } else { //上下滑动时,允许父控件的拦截 if (4 < Math.Abs(deltaY)) { Parent?.RequestDisallowInterceptTouchEvent(false); } } break; } return false; } /// /// 执行OnInterceptTouchEvent和OnTouchEvent /// /// true事件已经处理false事件没有处理 /// E. public override bool DispatchTouchEvent(MotionEvent e) { //Shared.HDLUtils.WriteLine($"{GetType()} Height->{Height} Width->{Width} DispatchTouchEvent->{e.Action}"); if (e.Action == MotionEventActions.Down) { isActioned = false; //还原允许拦截事件 RequestDisallowInterceptTouchEvent(false); } return base.DispatchTouchEvent(e); } public override bool OnInterceptTouchEvent(MotionEvent e) { //Shared.HDLUtils.WriteLine($"{GetType()} Height->{Height} Width->{Width} OnInterceptTouchEvent->{e.Action}"); if (disallowIntercept) { return false; } if (action(e)) { return true; } return base.OnInterceptTouchEvent(e); } /// /// 重写点击事件 /// /// true, if touch event was oned, false otherwise. /// E. public override bool OnTouchEvent(MotionEvent e) { //Shared.HDLUtils.WriteLine($"{GetType()} Height->{Height} Width->{Width} OnTouchEvent->{e.Action}"); if (!isActioned) { _view.TouchEvent(e); } action(e); return true; } bool disallowIntercept; public override void RequestDisallowInterceptTouchEvent(bool disallowIntercept) { this.disallowIntercept = disallowIntercept; //Shared.HDLUtils.WriteLine($"{GetType()} Height->{Height} RequestDisallowInterceptTouchEvent->{disallowIntercept}"); base.RequestDisallowInterceptTouchEvent(disallowIntercept); Parent?.RequestDisallowInterceptTouchEvent(disallowIntercept); } } } }