利川市网站建设,Wordpress加入天气,十大软件app排行榜下载免费,营业执照网上年检入口文章目录 关于图形绘制创建自定义控件使用控件创建专辑封面项目地址 我们将绘制一个圆形的音乐播放控件#xff0c;它包含一个圆形的进度条、专辑页面和播放按钮。 关于图形绘制
使用MAUI的绘制功能#xff0c;需要Microsoft.Maui.Graphics库。
Microsoft.Maui.Graphics 是… 文章目录 关于图形绘制创建自定义控件使用控件创建专辑封面项目地址 我们将绘制一个圆形的音乐播放控件它包含一个圆形的进度条、专辑页面和播放按钮。 关于图形绘制
使用MAUI的绘制功能需要Microsoft.Maui.Graphics库。
Microsoft.Maui.Graphics 是一个实验性的跨平台图形库它可以在 .NET MAUI 中使用。它提供了一组基本的图形元素如矩形、圆形、线条、路径、文本和图像。它还提供了一组基本的图形操作如填充、描边、裁剪、变换和渐变。Microsoft.Maui.Graphics在不同的目标平台上使用一致的API访问本机图形功能而底层实现使用了不同的图形渲染引擎。其中通用性较好的是SkiaSharp图形库支持几乎所有的操作系统在不同平台上的表现也近乎一致。
创建自定义控件
在项目中添加SkiaSharp绘制功能的引用Microsoft.Maui.Graphics.Skia以及SkiaSharp.Views.Maui.Controls。
ItemGroupPackageReference IncludeMicrosoft.Maui.Graphics.Skia Version7.0.59 /PackageReference IncludeSkiaSharp.Views.Maui.Controls Version2.88.3 /
/ItemGroup创建CircleSlider.xaml文件添加如下内容
?xml version1.0 encodingUTF-8?
ContentView xmlnshttp://schemas.microsoft.com/dotnet/2021/maui xmlns:xhttp://schemas.microsoft.com/winfx/2009/xamlxmlns:formsclr-namespace:SkiaSharp.Views.Maui.Controls;assemblySkiaSharp.Views.Maui.Controlsx:ClassMatoMusic.Controls.CircleSliderContentView.Contentforms:SKCanvasView x:NamecanvasViewPaintSurfaceOnCanvasViewPaintSurface //ContentView.Content
/ContentViewSKCanvasView是SkiaSharp.Views.Maui.Controls封装的View控件。
打开CircleSlider.xaml.cs文件
控件将包含以下可绑定属性
Maximum最大值Minimum最小值Value当前值TintColor进度条颜色ContainerColor进度条背景颜色BorderWidth进度条宽度
定义两个SKPaint画笔属性OutlinePaint用于绘制进度条背景ArcPaint用于绘制进度条本身。他们的描边宽度StrokeWidth则是圆形进度条的宽度。 两个画笔的初始值样式为SKPaintStyle.Stroke描边宽度为BorderWidth的值。
private SKPaint _outlinePaint;public SKPaint OutlinePaint
{get{if (_outlinePaint null){SKPaint outlinePaint new SKPaint{Style SKPaintStyle.Stroke,StrokeWidth BorderWidth,};_outlinePaint outlinePaint;}return_outlinePaint;}set { _outlinePaint value; }
}private SKPaint _arcPaint;public SKPaint ArcPaint
{get{if (_arcPaint null){SKPaint arcPaint new SKPaint{Style SKPaintStyle.Stroke,StrokeWidth BorderWidth,};_arcPaint arcPaint;}return _arcPaint;}set { _arcPaint value; }
}
SetStrokeWidth用于设置描边宽度并产生一个动效 在BorderWidth发生变更的时候会出现一个动效。宽度会缓慢地变化至新的值。刷新率为10ms一次每次变化的值为1。 private float _borderWidth;public float BorderWidth
{get { return _borderWidth; }set{var old_borderWidth _borderWidth;var span value - old_borderWidth;SetStrokeWidth(span, old_borderWidth);_borderWidth value;this.ArcPaint.StrokeWidth _borderWidth;this.OutlinePaint.StrokeWidth _borderWidth;}
}private async void SetStrokeWidth(float span, float old_borderWidth)
{if (span 0){for (int i 0; i span; i){await Task.Delay(10);this.ArcPaint.StrokeWidth old_borderWidth i;this.OutlinePaint.StrokeWidth old_borderWidth i;RefreshMainRectPadding();}}else{for (int i 0; i span; i--){await Task.Delay(10);this.ArcPaint.StrokeWidth old_borderWidth i;this.OutlinePaint.StrokeWidth old_borderWidth i;RefreshMainRectPadding();}}}于此同时因为描边宽度变化了需要对Padding进行补偿。调用RefreshMainRectPadding方法计算一个新的Padding值BoderWidth缩小时Padding也随之增大。
private void RefreshMainRectPadding()
{this._mainRectPadding this.BorderWidth / 2;
}在视觉上进度条宽度从内向外扩张变细。 若设为原宽度减去计算值从视觉上是从外向内收缩变细。
private void RefreshMainRectPadding()
{this._mainRectPadding 15 - this.BorderWidth / 2;
}接下来写订阅了CanvaseView的PaintSurface事件的方法OnCanvasViewPaintSurface。在这个方法中我们将编写圆形进度条的绘制逻辑。
PaintSurface事件在绘制图形时触发。程序运行时会实时触发这个方法它的参数SKPaintSurfaceEventArgs事件附带的对象具有两个属性
Info类型SKImageInfoSurface类型SKSurface
SKImageInfo对象包含如宽度和高度等有关绘图区域的信息对象SKSurface为绘制本身我们需要利用SKImageInfo宽度和高度等信息结合业务数据在SKSurface绘制出我们想要的图形。
清空上一次绘制的图形调用SKSurface.Canvas获取Canvas对象调用Canvas.Clear方法清空上一次绘制的图形。
canvas.Clear();rect是一个SKRect对象进度条本身是圆形我们需要一个正方形的区域来控制圆形区域。
sweepAngle是当前进度对应的角度首先计算出总进度值通过计算当前进度对应总进度的比值换算成角度将这一角度赋值给sweepAngle。
startAngle是进度条的起始角度我们将其设置为-90度即从正上方开始绘制。 SKRect rect new SKRect(_mainRectPadding, _mainRectPadding, info.Width - _mainRectPadding, info.Height - _mainRectPadding);
float startAngle -90;
float sweepAngle (float)((Value / SumValue) * 360);调用Canvas.DrawOval使用OutlinePaint画笔绘制进度条背景它是一个圆形
canvas.DrawOval(rect, OutlinePaint);创建绘制路径path调用AddArc方法将rect对象和起始角度和终止角度传入即可绘制出弧形。
using (SKPath path new SKPath())
{path.AddArc(rect, startAngle, sweepAngle);canvas.DrawPath(path, ArcPaint);
}绘制部分的完整代码如下
private void OnCanvasViewPaintSurface(object sender, SKPaintSurfaceEventArgs args)
{var SumValue Maximum - Minimum;SKImageInfo info args.Info;SKSurface surface args.Surface;SKCanvas canvas surface.Canvas;canvas.Clear();SKRect rect new SKRect(_mainRectPadding, _mainRectPadding, info.Width - _mainRectPadding, info.Height - _mainRectPadding);float startAngle -90;float sweepAngle (float)((Value / SumValue) * 360);canvas.DrawOval(rect, OutlinePaint);using (SKPath path new SKPath()){path.AddArc(rect, startAngle, sweepAngle);canvas.DrawPath(path, ArcPaint);}
}
使用控件
在MainPage.xaml中添加一个CircleSlider控件, 设置的Maximum是当前曲目的时长Value是当前曲目的进度
controls:CircleSlider HeightRequest250WidthRequest250x:NameMainCircleSliderMaximum{Binding Duration}Minimum0.0TintColor#FFFFFFContainerColor#4CFFFFFFIsEnabled{Binding Canplay}ValueChangedOnValueChangedValue{Binding CurrentTime,ModeTwoWay}
/controls:CircleSlider创建专辑封面
使用MAUI的VisualElement中的Clip属性创建Clip裁剪可以传入一个Geometry对象这里我们使用RoundRectangleGeometry将它的CornerRadius属性设置为图片宽度的一半即可实现圆形图片。
Image HeightRequest250WidthRequest250Margin7.5Source{Binding CurrentMusic.AlbumArt}VerticalOptionsCenterAndExpandHorizontalOptionsCenterAndExpandAspectAspectFillImage.ClipRoundRectangleGeometry CornerRadius125 Rect0,0,250,250 //Image.Clip
/Image设置一个半透明背景的播放状态指示器当IsPlaying为False时将显示一个播放按钮
Grid IsVisible{Binding IsPlaying, Converter{StaticResource True2FalseConverter}}BoxView HeightRequest250WidthRequest250Margin7.5Color#60000000VerticalOptionsCenterAndExpandHorizontalOptionsCenterAndExpandCornerRadius250 /BoxViewLabel x:NamePauseLabel HorizontalOptionsCenterAndExpandFontSize58 TextColor{Binding Canplay,Converter{StaticResource Bool2StringConverter},ConverterParameterWhite|#434343}FontFamilyFontAwesomeMargin0/Label
/Grid创建PanContainer对象用于实现拖动效果设置AutoAdsorption属性为True即可实现拖动后自动吸附效果。
关于PanContainer请查看上期的文章平移手势交互
用一个Grid将专辑封面CircleSlider以及播放状态指示器包裹起来。完整代码如下 controls1:PanContainer BackgroundColorTransparentx:NameDefaultPanContainerOnTappedDefaultPanContainer_OnOnTappedAutoAdsorptionTrueOnfinishedChoiseDefaultPanContainer_OnOnfinishedChoiseGrid PropertyChangedBindableObject_OnPropertyChangedVerticalOptionsStartHorizontalOptionsStartImage HeightRequest250WidthRequest250Margin7.5Source{Binding CurrentMusic.AlbumArt}VerticalOptionsCenterAndExpandHorizontalOptionsCenterAndExpandAspectAspectFillImage.ClipRoundRectangleGeometry CornerRadius125 Rect0,0,250,250 //Image.Clip/Imagecontrols:CircleSlider.../controls:CircleSliderGrid IsVisible{Binding IsPlaying, Converter{StaticResource True2FalseConverter}}BoxView HeightRequest250WidthRequest250Margin7.5Color#60000000VerticalOptionsCenterAndExpandHorizontalOptionsCenterAndExpandCornerRadius250 /BoxViewLabel x:NamePauseLabel HorizontalOptionsCenterAndExpandFontSize58 TextColor{Binding Canplay,Converter{StaticResource Bool2StringConverter},ConverterParameterWhite|#434343}FontFamilyFontAwesomeMargin0/Label/Grid/Grid
/controls1:PanContainer 以上就是这个项目的全部内容感谢阅读
项目地址
Github:maui-samples