MAUI中實(shí)現(xiàn)構(gòu)建跨平臺(tái)原生控件
簡(jiǎn)介
MAUI中使用Handler體系來(lái)處理不同平臺(tái)的原生控件實(shí)現(xiàn), 即對(duì)應(yīng)的, 如果我們想要?jiǎng)?chuàng)建控件, 只需要?jiǎng)?chuàng)建基于不同平臺(tái)的Handler即可。
那么下面主要教大家如何通過(guò)創(chuàng)建Handler(事件處理程序)來(lái)構(gòu)建自己的控件。
開(kāi)始
下面, 將通過(guò)創(chuàng)建一個(gè)進(jìn)度條控件案例, 來(lái)演示如何在MAUI項(xiàng)目中創(chuàng)建平臺(tái)控件并且使用它。
假設(shè)控件包含基礎(chǔ)的三項(xiàng)功能, 進(jìn)度條顏色(Foreground)、進(jìn)度條當(dāng)前值(Value)、進(jìn)度條模式(Indeterminate)
1.第一步(聲明控件類(lèi))
首先, 創(chuàng)建MyProgressBar類(lèi), 定義對(duì)應(yīng)的依賴(lài)屬性
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.第二步(創(chuàng)建標(biāo)準(zhǔn)處理程序)
有了控件的標(biāo)準(zhǔn)屬性定義之后, 接下來(lái)就是定義標(biāo)準(zhǔn)的Handler處理程序, 其中包含控件屬性映射器及構(gòu)造函數(shù), 如下所示:
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.第三步(創(chuàng)建平臺(tái)處理程序)
在屬性映射器中, 我們可以很輕松看見(jiàn)對(duì)應(yīng)了三個(gè)屬性的事件處理程序, 但是目前并沒(méi)有定義它, 這意味著你需要在不同平臺(tái)下分別實(shí)現(xiàn)對(duì)應(yīng)的
三個(gè)事件處理程序, 所以很快阿, 趕緊在Platforms > Android > Controls 下定義了一個(gè)MyProgressBarHandler, 如下所示:
接著繼承于ViewHandler并且與原生安卓ProgressBar關(guān)聯(lián)。
using Android.Widget; partial class MyProgressBarHandler : ViewHandler<MyProgressBar, ProgressBar> { }
重寫(xiě)CreateNativeView(這是創(chuàng)建本地控件最開(kāi)始的地方)
protected override ProgressBar CreateNativeView() { return new ProgressBar(Context, null, Android.Resource.Attribute.ProgressBarStyleHorizontal) { Indeterminate = true, Max = 10000, }; }
緊接著, 實(shí)現(xiàn)三個(gè)事件處理程序方法, 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. 對(duì)應(yīng)的實(shí)現(xiàn)iOS平臺(tái)的Handler事件處理程序, 與上步驟相同, 對(duì)于事件的處理細(xì)節(jié)則對(duì)應(yīng)不同平臺(tái)的邏輯處理。
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.打開(kāi)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>
運(yùn)行實(shí)際效果:
總結(jié)
通過(guò)利用Handler來(lái)處理不同平臺(tái)控件的行為, 與控件本身解耦并且更加容器支持更多的平臺(tái)。
到此這篇關(guān)于MAUI中實(shí)現(xiàn)構(gòu)建跨平臺(tái)原生控件的文章就介紹到這了。希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
封裝的一個(gè)asp.net驗(yàn)證碼類(lèi)
昨天在一個(gè)Q群上面群主發(fā)了一個(gè)用ASP.NET實(shí)現(xiàn)驗(yàn)證碼的demo,下載下來(lái)然后運(yùn)行正常,頁(yè)面上的img標(biāo)簽成功調(diào)用了一個(gè)一般處理程序并顯示了中文的驗(yàn)證碼圖片,雖然有點(diǎn)模糊,但是可見(jiàn)上面是四個(gè)中文,圖片背景為白色,背后有噪點(diǎn)線(xiàn),邊框黑色。2010-12-12ASP.NET下使用xml反序列化、緩存依賴(lài)實(shí)現(xiàn)個(gè)性化配置文件的實(shí)時(shí)生效
本文主要介紹了ASP.NET下使用xml反序列化、緩存依賴(lài)實(shí)現(xiàn)個(gè)性化配置文件的實(shí)時(shí)生效的方法。具有一定的參考價(jià)值,下面跟著小編一起來(lái)看下吧2017-01-01C# 動(dòng)態(tài)編譯、動(dòng)態(tài)執(zhí)行、動(dòng)態(tài)調(diào)試
前幾天看到一篇關(guān)于.net動(dòng)態(tài)編譯的文章 .NET中的動(dòng)態(tài)編譯 ,很受啟發(fā)。2009-05-05asp.net 請(qǐng)求輸入到輸出的全過(guò)程及httpHandler和httpModuler詳細(xì)介紹
看了幾篇講述httpHandler和HttpModuler的文章,雖然說(shuō)沒(méi)有完全了解底層操作,但是我也算明白了一個(gè)請(qǐng)求從進(jìn)入IIS到最后輸出都經(jīng)歷了哪些過(guò)程,感興趣的朋友可以了解下2013-01-01ASP.NET Core中使用xUnit進(jìn)行單元測(cè)試
這篇文章主要介紹了ASP.NET Core中使用xUnit進(jìn)行單元測(cè)試,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-11-11