using System;
|
using Android.Widget;
|
using Android.Content;
|
using Android.Graphics;
|
using Android.Views;
|
using Android.Util;
|
using Android.Runtime;
|
|
namespace Shared
|
{
|
//已经全面检查了代码
|
/// <summary>
|
/// 位置布局
|
/// </summary>
|
public class VerticalSeekBar : View
|
{
|
/// <summary>
|
/// 当前视图
|
/// </summary>
|
/// <value>The android horizonetal seek bar.</value>
|
VerticalSeekBarAndroidFrameLayout verticalSeekBarAndroidFrameLayout
|
{
|
get
|
{
|
return AndroidView as VerticalSeekBarAndroidFrameLayout;
|
}
|
set
|
{
|
AndroidView = value;
|
}
|
}
|
Android.Widget.ImageView btnBackgroundColor;
|
/// <summary>
|
/// 显示进度控件
|
/// </summary>
|
Android.Widget.ImageView btnProgressColor;
|
/// <summary>
|
/// 滑块
|
/// </summary>
|
Android.Widget.ImageView btnThum;
|
|
|
/// <summary>
|
/// 当前实例
|
/// </summary>
|
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);
|
}
|
|
/// <summary>
|
/// 当前视图的高度
|
/// </summary>
|
/// <value>The height.</value>
|
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;
|
/// <summary>
|
/// 进度变化事件
|
/// </summary>
|
public Action<View, int> ProgressChanged;
|
|
int max = 100;
|
/// <summary>
|
/// 最大值
|
/// </summary>
|
/// <value>The max.</value>
|
public int Max
|
{
|
get
|
{
|
return max;
|
}
|
set
|
{
|
max = value;
|
}
|
}
|
bool isCanScrolled = true;
|
/// <summary>
|
/// 是否允许滑动滑块
|
/// </summary>
|
/// <value><c>true</c> if is can scrolled; otherwise, <c>false</c>.</value>
|
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;
|
/// <summary>
|
/// 当前进度
|
/// </summary>
|
/// <value>The progress.</value>
|
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;
|
}
|
}
|
|
|
|
|
/// <summary>
|
/// 刷新当前对象
|
/// </summary>
|
public override void Refresh()
|
{
|
base.Refresh();
|
ProgressColor = progressColor;
|
BackgroundColor = BackgroundColor;
|
ThumbColor = thumbColor;
|
Progress = progress;
|
}
|
|
/// <summary>
|
/// 滑动休眠时间
|
/// </summary>
|
public int SleepTime = 0;
|
|
|
uint progressColor = 0x99000099;
|
/// <summary>
|
/// 进度视图颜色
|
/// </summary>
|
/// <value>The color of the progress.</value>
|
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;
|
/// <summary>
|
/// 进度视图颜色
|
/// </summary>
|
/// <value>The color of the progress.</value>
|
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;
|
/// <summary>
|
/// 滑块颜色
|
/// </summary>
|
/// <value>The color of the background.</value>
|
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);
|
}
|
}
|
}
|
}
|
|
/// <summary>
|
/// 需要重写的视图
|
/// </summary>
|
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);
|
}
|
};
|
}
|
|
/// <summary>
|
/// 所有事件本视图全部消化,不通知给子视图
|
/// </summary>
|
/// <returns><c>true</c>事件已经处理<c>false</c>需要父视图处理</returns>
|
/// <param name="ev">Ev.</param>
|
public override bool OnInterceptTouchEvent(MotionEvent ev)
|
{
|
//不需要子视图处理事件,所有的事件自己处理
|
return true;
|
}
|
|
float startPointX;
|
/// <summary>
|
/// 执行OnInterceptTouchEvent和OnTouchEvent
|
/// </summary>
|
/// <returns><c>true</c>事件已经处理<c>false</c>事件没有处理</returns>
|
/// <param name="e">E.</param>
|
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);
|
}
|
/// <summary>
|
/// 设置所有父视图禁止拦截事件
|
/// </summary>
|
/// <param name="b">如果设置True表示不要拦截,如果设置为False表示可以拦截</param>
|
void requestParentDisallowInterceptTouchEvent(bool b)
|
{
|
var tempParent = Parent;
|
while (tempParent != null)
|
{ //告诉父类不要拦截这个视图的事件
|
tempParent.RequestDisallowInterceptTouchEvent(b);
|
tempParent = tempParent.Parent;
|
}
|
}
|
}
|
}
|
}
|