using System; using Android.Widget; using Android.Content; using Android.Graphics; using Android.Views; using Android.Util; using Android.Runtime; namespace Shared { //已经全面检查了代码 /// /// 位置布局 /// public class VerticalSeekBar : View { /// /// 当前视图 /// /// The android horizonetal seek bar. VerticalSeekBarAndroidFrameLayout verticalSeekBarAndroidFrameLayout { get { return AndroidView as VerticalSeekBarAndroidFrameLayout; } set { AndroidView = value; } } Android.Widget.ImageView btnBackgroundColor; /// /// 显示进度控件 /// Android.Widget.ImageView btnProgressColor; /// /// 滑块 /// Android.Widget.ImageView btnThum; /// /// 当前实例 /// public VerticalSeekBar() { verticalSeekBarAndroidFrameLayout = new VerticalSeekBarAndroidFrameLayout(Application.Activity, this); btnBackgroundColor = new Android.Widget.ImageView(Application.Activity); verticalSeekBarAndroidFrameLayout.AddView(btnBackgroundColor, new Android.Widget.FrameLayout.LayoutParams(DensityUtil.Dip2Px(1), 0, GravityFlags.CenterHorizontal)); btnProgressColor = new Android.Widget.ImageView(Application.Activity); verticalSeekBarAndroidFrameLayout.AddView(btnProgressColor, new Android.Widget.FrameLayout.LayoutParams(DensityUtil.Dip2Px(1), 0, GravityFlags.CenterHorizontal)); btnThum = new Android.Widget.ImageView(Application.Activity); verticalSeekBarAndroidFrameLayout.AddView(btnThum, new Android.Widget.FrameLayout.LayoutParams(DensityUtil.Dip2Px(24), DensityUtil.Dip2Px(24), GravityFlags.CenterHorizontal)); } internal override bool TouchEvent(MotionEvent e) { switch (e.Action) { case MotionEventActions.Down: dateTime = DateTime.Now; setButtonLoaction((int)e.GetY()); break; case MotionEventActions.Move: setButtonLoaction((int)e.GetY()); break; case MotionEventActions.Cancel: case MotionEventActions.Up: dateTime = DateTime.MinValue; setButtonLoaction((int)e.GetY()); break; } return base.TouchEvent(e); } /// /// 当前视图的高度 /// /// The height. public override int Height { get { return base.Height; } set { base.Height = value; var frameBackgroundColor = btnBackgroundColor.LayoutParameters as Android.Widget.FrameLayout.LayoutParams; frameBackgroundColor.Height = base.Height; btnBackgroundColor.LayoutParameters = frameBackgroundColor; } } DateTime dateTime; /// /// 进度变化事件 /// public Action ProgressChanged; int max = 100; /// /// 最大值 /// /// The max. public int Max { get { return max; } set { max = value; } } bool isCanScrolled = true; /// /// 是否允许滑动滑块 /// /// true if is can scrolled; otherwise, false. public bool IsCanScrolled { get { return isCanScrolled; } set { isCanScrolled = value; } } int validHeight { get { return AndroidView.Height - btnThum.Height; } } //2019-08-29 改100毫秒 public int DelayTime = 100; //防止跳动,延时显示状态 DateTime delayDateTime = DateTime.MinValue; int progress; /// /// 当前进度 /// /// The progress. public int Progress { get { return (int)(Max * (validHeight - btnThum.Top) / validHeight); } set { progress = value; if (!IsCanRefresh) { return; } //发送命令后3000毫秒内不更新状态,防止跳动 if ((DateTime.Now - delayDateTime).TotalMilliseconds < DelayTime) { return; } if (Max < progress) { progress = Max; } var frameThum = btnThum.LayoutParameters as Android.Widget.FrameLayout.LayoutParams; frameThum.TopMargin = (int)(1.0f * (Max - progress) / Max * validHeight); btnThum.LayoutParameters = frameThum; var frameProgress = btnProgressColor.LayoutParameters as Android.Widget.FrameLayout.LayoutParams; frameProgress.TopMargin = frameThum.TopMargin + frameThum.Height / 2; frameProgress.Height = AndroidView.LayoutParameters.Height - frameProgress.TopMargin; btnProgressColor.LayoutParameters = frameProgress; } } /// /// 刷新当前对象 /// public override void Refresh() { base.Refresh(); ProgressColor = progressColor; BackgroundColor = BackgroundColor; ThumbColor = thumbColor; Progress = progress; } /// /// 滑动休眠时间 /// public int SleepTime = 0; uint progressColor = 0x99000099; /// /// 进度视图颜色 /// /// The color of the progress. public uint ProgressColor { get { return progressColor; } set { progressColor = value; if (!IsCanRefresh) { return; } byte r, g, b, a; r = (byte)(progressColor / 256 / 256 % 256); g = (byte)(progressColor / 256 % 256); b = (byte)(progressColor % 256); a = (byte)(progressColor / 256 / 256 / 256 % 256); btnProgressColor.SetBackgroundColor(Android.Graphics.Color.Argb(a, r, g, b)); } } uint backgroundColor=0xFFFFFFFF; /// /// 进度视图颜色 /// /// The color of the progress. public new uint BackgroundColor { get { return backgroundColor; } set { backgroundColor = value; if (!IsCanRefresh) { return; } byte r, g, b, a; r = (byte)(backgroundColor / 256 / 256 % 256); g = (byte)(backgroundColor / 256 % 256); b = (byte)(backgroundColor % 256); a = (byte)(backgroundColor / 256 / 256 / 256 % 256); btnBackgroundColor.SetBackgroundColor(Android.Graphics.Color.Argb(a, r, g, b)); } } uint thumbColor = 0xFFFFFFFF; /// /// 滑块颜色 /// /// The color of the background. public uint ThumbColor { get { return thumbColor; } set { thumbColor = value; var gradientDrawable = new Android.Graphics.Drawables.GradientDrawable(); gradientDrawable.SetCornerRadius(DensityUtil.Dip2Px(12)); byte r, g, b, a; r = (byte)(thumbColor / 256 / 256 % 256); g = (byte)(thumbColor / 256 % 256); b = (byte)(thumbColor % 256); a = (byte)(thumbColor / 256 / 256 / 256 % 256); gradientDrawable.SetColor(Android.Graphics.Color.Argb(a, r, g, b).ToArgb()); btnThum.Background = gradientDrawable; } } int beforValue = 0; //将图片移动到点击的位置 void setButtonLoaction(int y) { if (!IsCanScrolled) { return; } delayDateTime = DateTime.Now; if (y < 0) { y = 0; } if (validHeight < y) { y = validHeight; } var frameThum = btnThum.LayoutParameters as Android.Widget.FrameLayout.LayoutParams; frameThum.TopMargin = y; btnThum.LayoutParameters = frameThum; var frameProgress = btnProgressColor.LayoutParameters as Android.Widget.FrameLayout.LayoutParams; frameProgress.TopMargin = frameThum.TopMargin + frameThum.Height / 2; frameProgress.Height = AndroidView.LayoutParameters.Height - frameProgress.TopMargin; btnProgressColor.LayoutParameters = frameProgress; if (dateTime == DateTime.MinValue) { if (ProgressChanged != null && beforValue != Progress) { dateTime = DateTime.Now; delayDateTime = DateTime.Now; ProgressChanged(this, beforValue = Progress); } } else { //变化大于500毫秒的时候才通知 if (SleepTime < (DateTime.Now - dateTime).TotalMilliseconds) { dateTime = DateTime.Now; delayDateTime = DateTime.Now; if (ProgressChanged != null && beforValue != Progress) { ProgressChanged(this, beforValue = Progress); } } } } /// /// 需要重写的视图 /// class VerticalSeekBarAndroidFrameLayout : Android.Widget.FrameLayout { View _view; public VerticalSeekBarAndroidFrameLayout(Context context, View view) : base(context) { _view = view; Touch += (sender, e) => { if (_view != null) { _view.TouchEvent(e.Event); } }; } /// /// 所有事件本视图全部消化,不通知给子视图 /// /// true事件已经处理false需要父视图处理 /// Ev. public override bool OnInterceptTouchEvent(MotionEvent ev) { //不需要子视图处理事件,所有的事件自己处理 return true; } float startPointX; /// /// 执行OnInterceptTouchEvent和OnTouchEvent /// /// true事件已经处理false事件没有处理 /// E. public override bool DispatchTouchEvent(MotionEvent e) { switch (e.Action) { case MotionEventActions.Down: startPointX = e.RawX; requestParentDisallowInterceptTouchEvent(true); break; case MotionEventActions.Move: if (20 < Math.Abs(e.RawX - startPointX)) { requestParentDisallowInterceptTouchEvent(false); } break; case MotionEventActions.Up: case MotionEventActions.Cancel: requestParentDisallowInterceptTouchEvent(false); break; } return base.DispatchTouchEvent(e); } /// /// 设置所有父视图禁止拦截事件 /// /// 如果设置True表示不要拦截,如果设置为False表示可以拦截 void requestParentDisallowInterceptTouchEvent(bool b) { var tempParent = Parent; while (tempParent != null) { //告诉父类不要拦截这个视图的事件 tempParent.RequestDisallowInterceptTouchEvent(b); tempParent = tempParent.Parent; } } } } }