MAUI中如何实现构建跨平台原生控件,实现全平台兼容性?

2026-03-30 10:361阅读0评论SEO问题
  • 内容介绍
  • 文章标签
  • 相关推荐

本文共计977个文字,预计阅读时间需要4分钟。

MAUI中如何实现构建跨平台原生控件,实现全平台兼容性?

简介:MAUI中使用Handler体系处理不同平台的原生控件实现,即对应应用、如需创建控件,仅需创建基于不同平台的Handler即可。下面主要讲解如何通过创建Handler(事件处理流程)来实现。

简介

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, 如下所示:

MAUI中如何实现构建跨平台原生控件,实现全平台兼容性?

接着继承于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="schemas.microsoft.com/dotnet/2021/maui" xmlns:x="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中实现构建跨平台原生控件的文章就介绍到这了。希望对大家的学习有所帮助,也希望大家多多支持自由互联。

本文共计977个文字,预计阅读时间需要4分钟。

MAUI中如何实现构建跨平台原生控件,实现全平台兼容性?

简介:MAUI中使用Handler体系处理不同平台的原生控件实现,即对应应用、如需创建控件,仅需创建基于不同平台的Handler即可。下面主要讲解如何通过创建Handler(事件处理流程)来实现。

简介

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, 如下所示:

MAUI中如何实现构建跨平台原生控件,实现全平台兼容性?

接着继承于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="schemas.microsoft.com/dotnet/2021/maui" xmlns:x="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中实现构建跨平台原生控件的文章就介绍到这了。希望对大家的学习有所帮助,也希望大家多多支持自由互联。