MAUI中构建跨平台原生控件实现
Posted dotNET跨平台
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MAUI中构建跨平台原生控件实现相关的知识,希望对你有一定的参考价值。
简介
MAUI中使用Handler体系来处理不同平台的原生控件实现, 即对应的, 如果我们想要创建控件, 只需要创建基于不同平台的Handler即可。
那么下面主要教大家如何通过创建Handler(事件处理程序)来构建自己的控件。
开始
下面, 将通过创建一个进度条控件案例, 来演示如何在MAUI项目中创建平台控件并且使用它。
假设控件包含基础的三项功能, 进度条颜色(Foreground)、进度条当前值(Value)、进度条模式(Indeterminate)
1.第一步(声明控件类)
首先, 创建MyProgressBar类, 定义对应的依赖属性
internal class MyProgressBar : View
public static readonly BindableProperty ForegroundProperty =
BindableProperty.Create(nameof(Foreground),
typeof(Color),
typeof(MyProgressBar),
Colors.Transparent);
public static readonly BindableProperty ValueProperty =
BindableProperty.Create(nameof(Value),
typeof(double),
typeof(MyProgressBar),
0.0);
public static readonly BindableProperty IndeterminateProperty =
BindableProperty.Create(nameof(Indeterminate),
typeof(bool),
typeof(MyProgressBar),
false);
public Color Foreground
get return (Color)GetValue(ForegroundProperty);
set SetValue(ForegroundProperty, value);
public double Value
get return (double)GetValue(ValueProperty);
set SetValue(ValueProperty, value);
public bool Indeterminate
get return (bool)GetValue(IndeterminateProperty);
set SetValue(IndeterminateProperty, value);
2.第二步(创建标准处理程序)
有了控件的标准属性定义之后, 接下来就是定义标准的Handler处理程序, 其中包含控件属性映射器及构造函数, 如下所示:
partial class MyProgressBarHandler
public static PropertyMapper<MyProgressBar, MyProgressBarHandler> HorizontalProgressBarMapper = new
(ViewHandler.ViewMapper)
[nameof(MyProgressBar.Value)] = MapValue,
[nameof(MyProgressBar.Foreground)] = MapForeground,
[nameof(MyProgressBar.Indeterminate)]= MapIndeterminate
;
public MyProgressBarHandler(PropertyMapper mapper)
: base(mapper)
public MyProgressBarHandler() : base(HorizontalProgressBarMapper)
3.第三步(创建平台处理程序)
在属性映射器中, 我们可以很轻松看见对应了三个属性的事件处理程序, 但是目前并没有定义它, 这意味着你需要在不同平台下分别实现对应的
三个事件处理程序, 所以很快阿, 赶紧在Platforms > android > Controls 下定义了一个MyProgressBarHandler, 如下所示:
接着继承于ViewHandler并且与原生安卓ProgressBar关联。
using Android.Widget;
partial class MyProgressBarHandler :
ViewHandler<MyProgressBar, ProgressBar>
重写CreateNativeView(这是创建本地控件最开始的地方)
protected override ProgressBar CreateNativeView()
return new ProgressBar(Context, null, Android.Resource.Attribute.ProgressBarStyleHorizontal)
Indeterminate = true,
Max = 10000,
;
紧接着, 实现三个事件处理程序方法, MapValue、MapForeground、MapIndeterminate
static void MapValue(MyProgressBarHandler handler, MyProgressBar view)
var nativeView= handler?.NativeView;
nativeView.Progress = (int)(view.Value * Max);
static void MapForeground(MyProgressBarHandler handler, MyProgressBar view)
UpdateForeground(handler?.NativeView, view.Foreground);
static void UpdateForeground(ProgressBar nativeProgressBar, Color color)
if (color == null)
(nativeProgressBar.Indeterminate ? nativeProgressBar.IndeterminateDrawable :
nativeProgressBar.ProgressDrawable)?.ClearColorFilter();
else
var tintList = ColorStateList.ValueOf(color.ToNative());
if (nativeProgressBar.Indeterminate)
nativeProgressBar.IndeterminateTintList = tintList;
else
nativeProgressBar.ProgressTintList = tintList;
static void MapIndeterminate(MyProgressBarHandler handler, MyProgressBar view)
var nativeView= handler?.NativeView;
nativeView.Indeterminate = view.Indeterminate;
4. 对应的实现ios平台的Handler事件处理程序, 与上步骤相同, 对于事件的处理细节则对应不同平台的逻辑处理。
partial class MyProgressBarHandler :
ViewHandler<MyProgressBar, UIProgressView>
protected override UIProgressView CreateNativeView()
return new UIProgressView(UIProgressViewStyle.Default);
static void MapValue(MyProgressBarHandler handler, MyProgressBar view)
var nativeView = handler.NativeView;
nativeView.Progress = (float)view.Value;
static void MapForeground(MyProgressBarHandler handler, MyProgressBar view)
var nativeView = handler.NativeView;
nativeView.ProgressTintColor = view.Foreground?.ToNative();
static void MapIndeterminate(MyProgressBarHandler handler, MyProgressBar view)
//...
5.打开MauiProgram文件, 添加AddHandler
public static MauiApp CreateMauiApp()
var builder = MauiApp.CreateBuilder();
builder.UseMauiApp<App>()
.ConfigureFonts(fonts =>
fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
)
.ConfigureMauiHandlers(handler =>
handler.AddHandler(typeof(MyProgressBar), typeof(MyProgressBarHandler));
);
return builder.Build();
6.界面中,分别声明MAUI原生控件与自定义控件
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="MAUIRender.MainPage"
xmlns:my="clr-namespace:MAUIRender"
xmlns:ctor="clr-namespace:MAUIRender.Controls"
BackgroundColor="DynamicResource SecondaryColor">
<Grid>
<StackLayout>
<ProgressBar
Progress="30" ProgressColor="Red"/>
<ctor:MyProgressBar
Indeterminate="True"
Value="600" Foreground="Green" />
</StackLayout>
</Grid>
</ContentPage>
运行实际效果:
总结
通过利用Handler来处理不同平台控件的行为, 与控件本身解耦并且更加容器支持更多的平台。
以上是关于MAUI中构建跨平台原生控件实现的主要内容,如果未能解决你的问题,请参考以下文章
MAUI中Maui.Graphics.Controls绘制控件
Visual Studio 2022 正式支持 .NET MAUI 开发