using System;
using Android.Widget;
using Android.Content;
using Android.Views;
using Android.Util;
using Android.Runtime;
using Android.Views.Animations; using Android.Graphics.Drawables; namespace Shared
{ // 存在问题,下拉后不松开手改为上拉,会拦截MotionEventActions.Up事件,导致触发不了刷新 //VerticalRefreshScrolViewLayout 带下拉刷新 /// 
 /// 位置布局
 /// 
 public class VerticalRefreshScrolViewLayout : ViewGroup
 {
 public Action BeginHeaderRefreshingAction; //public Action beginFooterRefreshingAction; //private LinearLayout mainLayout; private MyLoadingHorizontal mHeaderLoadingView;//下拉刷新头部View //private MyLoadingHorizontal mFooterLoadingView;//上拉加载底部View /// 
 /// 构造函数
 /// 
 public VerticalRefreshScrolViewLayout()
 {
 viewGroup = new AndroidRefreshScrolView(Application.Activity, null); (viewGroup as AndroidRefreshScrolView).AlreadyToTopAction += () => { ShowHeaderLoadingView(); }; (viewGroup as AndroidRefreshScrolView).AlreadyToTopUpAction += () => { ShowHeaderAnimationBeginToRefresh(); }; mHeaderLoadingView = new MyLoadingHorizontal(Application.Activity); HideHeaderLoadingView(); realViewGroup = new AndroidLinearLayout(Application.Activity, this);
 (realViewGroup as AndroidLinearLayout).Orientation = Orientation.Vertical; viewGroup.AddView(realViewGroup); realViewGroup.AddView(mHeaderLoadingView); _isCanHeaderRefresh = true; } /// 
 /// 视图宽度
 /// 
 /// The width.
 public override int Width
 {
 get
 {
 return base.Width;
 }
 set
 {
 base.Width = value;
 if (!IsCanRefresh)
 {
 return;
 }
 var layoutParameters = realViewGroup.LayoutParameters;
 layoutParameters.Width = Width;
 realViewGroup.LayoutParameters = layoutParameters;

 }
 }

 /// 
 /// 视图高度
 /// 
 /// The height.
 public override int Height
 {
 get
 {
 return base.Height;
 }
 set
 {
 base.Height = value;
 if (!IsCanRefresh)
 {
 return;
 }
 var layoutParameters = realViewGroup.LayoutParameters;
 layoutParameters.Height = Height;
 realViewGroup.LayoutParameters = layoutParameters;
 }
 }

 /// 
 /// 是否允许滑动
 /// 
 /// true if scroll enabled; otherwise, false.
 public bool ScrollEnabled
 {
 get
 {
 return (viewGroup as AndroidScrolView).ScrollEnable;
 }
 set
 {
 (viewGroup as AndroidScrolView).ScrollEnable = value;
 }
 }

 /// 
 /// 是否正在滑动
 /// 
 /// true if decelerating; otherwise, false.
 public bool Decelerating
 {
 get
 {
 return false;
 }
 } //***************************下拉刷新*************************** private void ShowHeaderLoadingView() { if (!IsCanHeaderRefresh) return; if (IsHeaderRefreshing) return; mHeaderLoadingView.HideProgress(); SetHeaderLoadingViewText(_mHeaderReadyRefreshText); mHeaderLoadingView.Visibility = ViewStates.Visible; //(viewGroup as AndroidRefreshScrolView).showHeader(); //showHeader(); } private void ShowHeaderAnimationBeginToRefresh() { if (!IsCanHeaderRefresh) return; if (!IsHeaderRefreshing) { mHeaderLoadingView.ShowProgress(); SetHeaderLoadingViewText(_mHeaderRefreshingText); if (mHeaderLoadingView.Animation == null) { //缩放动画 mHeaderLoadingView.Animation = new ScaleAnimation( 1.0f, 1.2f, 1.0f, 1.2f, Dimension.RelativeToSelf, 0.5f, Dimension.RelativeToSelf, 0.5f); mHeaderLoadingView.Animation.Duration = 300; } mHeaderLoadingView.Animation.Reset(); mHeaderLoadingView.Animation.StartNow(); //开始刷新 IsHeaderRefreshing = true; BeginHeaderRefreshingAction?.Invoke(); } } private void SetHeaderLoadingViewText(string mes) { mHeaderLoadingView.textView.Text = mes; } private void HideHeaderLoadingView() { mHeaderLoadingView.Visibility = ViewStates.Gone; //(viewGroup as AndroidRefreshScrolView).hideHeader(); //hideHeader(); } string _mHeaderRefreshingText = "正在刷新..."; public string MHeaderRefreshingText { get
 {
 return _mHeaderRefreshingText;
 } set { _mHeaderRefreshingText = value; } } string _mHeaderReadyRefreshText = "松开立即刷新"; public string MHeaderReadyRefreshText { get
 {
 return _mHeaderReadyRefreshText;
 } set { _mHeaderReadyRefreshText = value; } } /// 
 /// 是否支持下拉刷新
 /// bool _isCanHeaderRefresh; public bool IsCanHeaderRefresh { get
 {
 return _isCanHeaderRefresh;
 } set { _isCanHeaderRefresh = value; } } /// 
 /// 是否正在下拉刷新
 /// bool _isHeaderRefreshing; public bool IsHeaderRefreshing { get
 {
 return _isHeaderRefreshing;
 } set { _isHeaderRefreshing = value; } } ///// 
 ///// 启用或者关闭下拉刷新
 ///// //public void openHeaderRefresh(bool bOpen) //{ //} /// 
 /// 头开始刷新
 /// public void BeginHeaderRefreshing() { if (!IsCanHeaderRefresh) return; if (!IsHeaderRefreshing) { ShowHeaderLoadingView(); //mHeaderLoadingView.Visibility = ViewStates.Visible; ShowHeaderAnimationBeginToRefresh(); } } /// 
 /// 头结束刷新
 /// public void EndHeaderRefreshing() { if (!IsCanHeaderRefresh) return; if (IsHeaderRefreshing) { HideHeaderLoadingView(); IsHeaderRefreshing = false; } } //public void showHeader() //{ // mHeaderLoadingView.SetPadding(0, 0, 0, 0); //} //public void hideHeader() //{ // mHeaderLoadingView.SetPadding(0, 0, 0, -100); //} ////***************************上拉加载*************************** //string _mFooterRefreshText = "正在加载..."; //public string mFooterRefreshText //{ // get // { // return _mFooterRefreshText; // } // set // { // _mFooterRefreshText = value; // } //} ///// ///// 是否支持 上拉加载 ///// //bool _isCanFooterRefresh; //public bool IsCanFooterRefresh //{ // get // { // return _isCanFooterRefresh; // } // set // { // _isCanFooterRefresh = value; // } //} ///// ///// 是否正在上拉加载 ///// //bool _isFooterRefreshing; //public bool IsFooterRefreshing //{ // get // { // return _isFooterRefreshing; // } // set // { // _isFooterRefreshing = value; // } //} ///// ///// 底部 开始上拉加载 ///// //public void beginFooterRefreshing() //{ // if (!IsCanFooterRefresh) return; // if (!IsFooterRefreshing) // { // mFooterLoadingView.Start(mHeaderRefreshText); // IsFooterRefreshing = true; // beginFooterRefreshingAction?.Invoke(); // } //} ///// ///// 底部 结束上拉加载 ///// //public void endFooterRefreshing() //{ // if (!IsCanFooterRefresh) return; // if (IsFooterRefreshing) // { // mFooterLoadingView.Hide(); // IsFooterRefreshing = false; // } //} }

 /// 
 /// 竖直方向滑动控件
 /// 
 class AndroidRefreshScrolView : Android.Widget.ScrollView
 {
 /// 
 /// 是否允许滑动
 /// 
 public bool ScrollEnable = true; public Action AlreadyToTopAction; public Action AlreadyToTopUpAction; public Action AlreadyToBottomAction; //Scroller mScroller;


 //public void showHeader() { // this.SetPadding(0, 0, 0, 0); // ////mScroller. // //mScroller.StartScroll(0, 0, 0, 0, 400); // //// trigger computeScroll // //Invalidate(); //} //public void hideHeader() //{ // this.SetPadding(0, -50, 0, 0); // ////mScroller. // //mScroller.StartScroll(0, 40, 0, -40, 400); // //// trigger computeScroll // //Invalidate(); //}


 View _view;
 /// 
 /// 构造函数
 /// 
 /// Context.
 /// View.
 public AndroidRefreshScrolView(Context context, View view)
 : base(context)
 {
 _view = view;
 VerticalScrollBarEnabled = true;
 //mScroller = new Scroller(context, new DecelerateInterpolator());
 } bool bAlreadyToTop;

 public override bool DispatchTouchEvent(MotionEvent e) { //System.Console.WriteLine($"{GetType()} Height->{Height} Width->{Width} DispatchTouchEvent->{e.Action}"); if (e.Action == MotionEventActions.Down) {
 //还原允许拦截事件 RequestDisallowInterceptTouchEvent(false);
 } return base.DispatchTouchEvent(e); } float mLastX, mLastY ;
 public override bool OnInterceptTouchEvent(MotionEvent ev)
 {
 //System.Console.WriteLine($"{GetType()} Height->{Height} Width->{Width} OnInterceptTouchEvent->{ev.Action}"); if (!ScrollEnable || disallowIntercept)
 {
 return false;
 } switch (ev.Action) {
 case MotionEventActions.Down:
 mLastX = ev.RawX;
 mLastY = ev.RawY;
 bAlreadyToTop = false; System.Console.WriteLine($"MotionEventActions.Down"); Parent?.RequestDisallowInterceptTouchEvent(true);
 break; case MotionEventActions.Up:
 
 Parent?.RequestDisallowInterceptTouchEvent(true); System.Console.WriteLine($"MotionEventActions.Up");
 if (bAlreadyToTop) { AlreadyToTopUpAction?.Invoke(); System.Console.WriteLine($"AlreadyToTopUpAction"); }
 break;
 case MotionEventActions.Move:
 var x = ev.RawX;
 var y = ev.RawY;
 var deltaX = x - mLastX;
 var deltaY = y - mLastY; System.Console.WriteLine($"MotionEventActions.Move");

 if (Math.Abs(deltaX) < Math.Abs(deltaY)) { //向下滑动,如果当前已经滑动到顶,就允许父控件的拦截事件 if (deltaY > 0 && ScrollY == 0) { bAlreadyToTop = true; AlreadyToTopAction?.Invoke(); Parent?.RequestDisallowInterceptTouchEvent(false); return false; } //向上滑动时,如果translateY等于高度时,即表明滑动到底部,可又顶层View控制滑动 var mChildH = 0; if (0 < ChildCount) { mChildH = GetChildAt(ChildCount - 1).Bottom; } var translateY = mChildH - ScrollY; if (deltaY < 0 && translateY == Height) { AlreadyToBottomAction?.Invoke(); Parent?.RequestDisallowInterceptTouchEvent(false); return false; } } else {
 //左右滑动时,允许父控件的拦截 if (4 < Math.Abs(deltaX)) { Parent?.RequestDisallowInterceptTouchEvent(false); }
 }
 break;
 }

 return base.OnInterceptTouchEvent(ev);
 }
 /// 
 /// 重写点击事件
 /// 
 /// true, if touch event was oned, false otherwise.
 /// E.
 public override bool OnTouchEvent(MotionEvent e)
 {
 //System.Console.WriteLine($"{GetType()} Height->{Height} Width->{Width} OnInterceptTouchEvent->{e.Action}");
 _view?.TouchEvent(e);
 base.OnTouchEvent(e);
 //如果返回真父控件就不需要处理了
 return true;
 }
 bool disallowIntercept;
 public override void RequestDisallowInterceptTouchEvent(bool disallowIntercept)
 {
 this.disallowIntercept = disallowIntercept;
 //System.Console.WriteLine($"{GetType()} Height->{Height} RequestDisallowInterceptTouchEvent->{disallowIntercept}");
 base.RequestDisallowInterceptTouchEvent(disallowIntercept);
 Parent?.RequestDisallowInterceptTouchEvent(disallowIntercept);
 }
 } class MyLoadingHorizontal : Android.Widget.LinearLayout { ProgressBar Progress; public Android.Widget.TextView textView; LinearLayout tempLinearLayout; public void ShowProgress() { Progress.Visibility = ViewStates.Visible; } public void HideProgress() { Progress.Visibility = ViewStates.Gone; } public MyLoadingHorizontal(Context context) : base(context) { Progress = new ProgressBar(context); //SetBackgroundColor (Android.Graphics.Color.Argb (50, 0x32, 0x32, 0x32)); SetGravity(GravityFlags.Center); tempLinearLayout = new MiddleLinearLayout(context) { Orientation = Orientation.Horizontal }; tempLinearLayout.SetGravity(GravityFlags.CenterHorizontal); LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(LayoutParams.WrapContent, Application.GetRealHeight(30)); lp.Gravity = Android.Views.GravityFlags.Center; tempLinearLayout.AddView(Progress, lp); textView = new Android.Widget.TextView(context); textView.Text = "Loading....."; textView.Gravity = GravityFlags.Center; tempLinearLayout.AddView(textView, new Android.Views.ViewGroup.LayoutParams(Android.Views.ViewGroup.LayoutParams.WrapContent, Application.GetRealHeight(40))); AddView(tempLinearLayout, new Android.Views.ViewGroup.LayoutParams(Android.Views.ViewGroup.LayoutParams.WrapContent, Android.Views.ViewGroup.LayoutParams.WrapContent)); tempLinearLayout.SetPadding(20, 20, 20, 20); } uint LoadingHorizontalBackgroundColor; /// /// 背景颜色 /// /// The color of the background. public virtual uint LodingBackgroundColor { get { return LoadingHorizontalBackgroundColor; } set { LoadingHorizontalBackgroundColor = value; if (this.GetType() != typeof(ImageView)) { if (tempLinearLayout.Background == null || tempLinearLayout.Background.GetType() != typeof(GradientDrawable)) { tempLinearLayout.Background = new Android.Graphics.Drawables.GradientDrawable(); } var gradientDrawable = (GradientDrawable)tempLinearLayout.Background; gradientDrawable.SetCornerRadius(DensityUtil.Dip2Px(6)); byte r, g, b, a; r = (byte)(LoadingHorizontalBackgroundColor / 256 / 256 % 256); g = (byte)(LoadingHorizontalBackgroundColor / 256 % 256); b = (byte)(LoadingHorizontalBackgroundColor % 256); a = (byte)(LoadingHorizontalBackgroundColor / 256 / 256 / 256 % 256); gradientDrawable.SetColor(Android.Graphics.Color.Argb(a, r, g, b).ToArgb()); } } } /// /// 点击事件 /// /// The touch event. /// E. public override bool OnTouchEvent(Android.Views.MotionEvent e) { //事件自己处理 return true; } }
}