using System; using Android.Content; using Android.Views; using Android.Views.Animations; namespace Shared { /// /// 音乐滑动视图 /// public class MusicVerticalScrolViewLayout : ViewGroup { /// /// 构造函数 /// public MusicVerticalScrolViewLayout() { viewGroup = new AndroidScrolView11(Application.Activity, this); var tempViewGroup = new Android.Widget.FrameLayout(Application.Activity); //ScrollView这样的控件需要先有个容器,而且容器高宽不能设定,而是由容器里的子控件高度决定 viewGroup.AddView(tempViewGroup); realViewGroup = new Android.Widget.FrameLayout(Application.Activity); tempViewGroup.AddView(realViewGroup); } //这个方法检查过没有问题 /// /// 添加子控件 /// /// View. public override void AddChidren(View view) { base.AddChidren(view); int height = 0; foreach(View tempView in viewList){ if(height /// 根据绝对坐标来确定当前选择了哪个控件 /// /// true, if range of view was ined, false otherwise. /// View. /// Point. bool inRangeOfView(Android.Views.View view, Android.Graphics.Point point) { var location = new int[2]; view.GetLocationOnScreen(location); int y = location[1]; if (point.Y < y || point.Y > (y + view.Height)) { return false; } return true; } bool isSameZone (Android.Views.View view) { var location = new int [2]; view.GetLocationOnScreen (location); int y = location [1]; if (y + view.Height / 2 < selectViewBeforeY || y > selectViewBeforeY + view.Height / 2) { return false; } return true; } /// /// 根据点击位置找出点击到的视图 /// /// The view of point. /// Point. /// Uiview. Android.Views.View replaceViewOfPoint(Android.Views.View view, Android.Graphics.Point point) { //第一个是背景图 for (int i = realViewGroup.ChildCount - 1; 0 <= i; i--) { var tempView = realViewGroup.GetChildAt(i); if (tempView != view) { if (inRangeOfView(tempView, point)) { return tempView; } } } return null; } /// /// /// public Action ReplaceChanged; /// /// 长按事件 /// public Action LongPressAction; /// /// 根据点击位置找出点击到的视图 /// /// 返回点击到的视图 /// 当前点击位置 Android.Views.View selectedViewByPoint(Android.Graphics.Point point) { //第一个是背景图 for (int i = realViewGroup.ChildCount - 1; 0 <= i; i--) { var tempView = realViewGroup.GetChildAt(i); { if (inRangeOfView(tempView, point)) { return tempView; } } } return null; } /// /// 当前选中按键的初始点 /// Android.Graphics.Point originPressPoint; /// /// 当前选中的视图起点 /// Android.Graphics.Point selectedViewPoint; /// /// 当前选中的视图 /// Android.Views.View selectedAndroidView; /// /// 准备交换位置的视图 /// Android.Views.View replaceAndroidView; /// /// 获取当前View的中心点 /// /// The point. /// View. Android.Graphics.Point centerPoint(Android.Views.View view) { int[] location = new int[2]; view.GetLocationOnScreen(location); int x = location[0]; int y = location[1]; x += view.Width / 2; y += view.Height / 2; return new Android.Graphics.Point(x, y); } float selectViewBeforeY; /// /// 点击开始的事件 /// /// E. internal void TouchEventDown(MotionEvent e){ //找出当前点击位置的视图 selectedAndroidView = selectedViewByPoint(new Android.Graphics.Point((int)e.RawX, (int)e.RawY)); if (selectedAndroidView == null) { return ; } selectedAndroidView.BringToFront(); var location = new int [2]; selectedAndroidView.GetLocationOnScreen (location); selectViewBeforeY = location [1]; originPressPoint = new Android.Graphics.Point((int)e.RawX, (int)e.RawY); selectedViewPoint = new Android.Graphics.Point((int)selectedAndroidView.GetX(), (int)selectedAndroidView.GetY()); isFirst = true; } /// /// 点击事件移动 /// /// E. internal void TouchEventMove(MotionEvent e) { if (selectedAndroidView == null) { return; } //selectedAndroidView.SetX(selectedViewPoint.X + e.RawX - originPressPoint.X); selectedAndroidView.SetY(selectedViewPoint.Y + e.RawY - originPressPoint.Y); //获取当前视图进入了哪个视图的区域 replaceAndroidView = replaceViewOfPoint(selectedAndroidView, centerPoint(selectedAndroidView)); if (replaceAndroidView != null) { if (!isFirst) { return; } isFirst = false; if (replaceAndroidView == null) { return; } replaceAndroidView.ClearAnimation(); /** 设置缩放动画 */ replaceAndroidView.Animation = new AlphaAnimation(1.0f, .8f); replaceAndroidView.Animation.Duration = 1000; replaceAndroidView.Animation.StartNow(); } } /// /// 点击事件弹起 /// /// E. internal void TouchEventUp(MotionEvent e) { if (selectedAndroidView == null) { return; } View selectedView = null; foreach (View view in viewList) { if (view.AndroidView == selectedAndroidView) { selectedView = view; break; } } //selectedAndroidView.SetX(selectedViewPoint.X); if(isSameZone(selectedAndroidView)) { selectedAndroidView.SetY (selectedViewPoint.Y); return; } selectedAndroidView.SetY (selectedViewPoint.Y); if (replaceAndroidView == null) { if (LongPressAction != null) { LongPressAction(selectedView); } return; } View replaceView = null; foreach (View view in viewList) { if (view.AndroidView == replaceAndroidView) { replaceView = view; break; } } if (ReplaceChanged != null) { ReplaceChanged(replaceView, selectedView); } } /// /// 给当前选择中的控件个动画缩小的效果 /// internal void scaleSelectedAndroidView() { if (selectedAndroidView == null) { return; } selectedAndroidView.ClearAnimation(); /** 设置缩放动画 */ selectedAndroidView.Animation = new AlphaAnimation(1.0f, 0.8f); selectedAndroidView.Animation.Duration = 1000; selectedAndroidView.Animation.StartNow(); } /// /// 是否第一次加载 /// bool isFirst; /// /// 竖直方向滑动控件 /// internal class AndroidScrolView11 : Android.Widget.ScrollView, GestureDetector.IOnGestureListener { MusicVerticalScrolViewLayout _view; /// /// 是否长按 /// bool isLongPress; GestureDetector mGesture; /// /// 构造函数 /// /// Context. /// View. public AndroidScrolView11(Context context, MusicVerticalScrolViewLayout view) : base(context) { _view = view; VerticalScrollBarEnabled = false; mGesture = new GestureDetector(context, this) { IsLongpressEnabled = true }; } /// /// 重写点击事件 /// /// true, if touch event was oned, false otherwise. /// E. public override bool OnTouchEvent(MotionEvent e) { //处理长按的事件 if (isLongPress) { switch (e.Action) { case MotionEventActions.Move: _view.TouchEventMove(e); break; case MotionEventActions.Up: _view.TouchEventUp(e); break; } return true; } return base.OnTouchEvent(e); } //是否是活动状态 bool isLive() { return Enabled && Visibility == ViewStates.Visible && 0 < Alpha; } public override bool OnInterceptTouchEvent(MotionEvent ev) { if (!isLive()) { return false; } mGesture.OnTouchEvent(ev); //如果是长按,就拦截事件,后面的事件是由自己的TouchEvent处理,子控件会收到取消事件,如果是快速滑动,事件也是自己处理 if (isLongPress) { return true; } //如果是滑动这里也会返回True return base.OnInterceptTouchEvent(ev); } /// /// 设置所有父视图禁止拦截事件 /// /// 如果设置True表示不要拦截,如果设置为False表示可以拦截 void requestParentDisallowInterceptTouchEvent(bool b) { var tempParent = Parent; while (tempParent != null) { //告诉父类不要拦截这个视图的事件 tempParent.RequestDisallowInterceptTouchEvent(b); tempParent = tempParent.Parent; } } public bool OnDown(MotionEvent e) { isLongPress = false; _view.TouchEventDown(e); requestParentDisallowInterceptTouchEvent(true); return false; } public bool OnFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { //迅速滑动,并松开 Shared.HDLUtils.WriteLine($"OnFling随便一划,坐标变化为X:{velocityX},Y:{velocityY}"); return false; } public void OnLongPress(MotionEvent e) { isLongPress = true; _view.scaleSelectedAndroidView(); Shared.HDLUtils.WriteLine("长按不放"); } public bool OnScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) { Shared.HDLUtils.WriteLine("OnScroll:在屏幕上滑动"); return false; } public void OnShowPress(MotionEvent e) { Shared.HDLUtils.WriteLine("OnShowPress:手指按下一段时间,还没到长按"); } public bool OnSingleTapUp(MotionEvent e) { requestParentDisallowInterceptTouchEvent(false); Shared.HDLUtils.WriteLine("OnSingleTapUp:手指弹起"); return false; } } } }