MAUI中實現(xiàn)構(gòu)建跨平臺原生控件
簡介
MAUI中使用Handler體系來處理不同平臺的原生控件實現(xiàn), 即對應(yīng)的, 如果我們想要創(chuàng)建控件, 只需要創(chuàng)建基于不同平臺的Handler即可。
那么下面主要教大家如何通過創(chuàng)建Handler(事件處理程序)來構(gòu)建自己的控件。
開始
下面, 將通過創(chuàng)建一個進度條控件案例, 來演示如何在MAUI項目中創(chuàng)建平臺控件并且使用它。
假設(shè)控件包含基礎(chǔ)的三項功能, 進度條顏色(Foreground)、進度條當前值(Value)、進度條模式(Indeterminate)
1.第一步(聲明控件類)
首先, 創(chuàng)建MyProgressBar類, 定義對應(yīng)的依賴屬性
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)建標準處理程序)
有了控件的標準屬性定義之后, 接下來就是定義標準的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)建平臺處理程序)
在屬性映射器中, 我們可以很輕松看見對應(yīng)了三個屬性的事件處理程序, 但是目前并沒有定義它, 這意味著你需要在不同平臺下分別實現(xiàn)對應(yīng)的
三個事件處理程序, 所以很快阿, 趕緊在Platforms > Android > Controls 下定義了一個MyProgressBarHandler, 如下所示:
接著繼承于ViewHandler并且與原生安卓ProgressBar關(guān)聯(lián)。
using Android.Widget;
partial class MyProgressBarHandler :
ViewHandler<MyProgressBar, ProgressBar>
{
}重寫CreateNativeView(這是創(chuàng)建本地控件最開始的地方)
protected override ProgressBar CreateNativeView()
{
return new ProgressBar(Context, null, Android.Resource.Attribute.ProgressBarStyleHorizontal)
{
Indeterminate = true,
Max = 10000,
};
}緊接著, 實現(xiàn)三個事件處理程序方法, 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. 對應(yīng)的實現(xiàn)iOS平臺的Handler事件處理程序, 與上步驟相同, 對于事件的處理細節(jié)則對應(yīng)不同平臺的邏輯處理。
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>運行實際效果:
總結(jié)
通過利用Handler來處理不同平臺控件的行為, 與控件本身解耦并且更加容器支持更多的平臺。
到此這篇關(guān)于MAUI中實現(xiàn)構(gòu)建跨平臺原生控件的文章就介紹到這了。希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Visual?Studio?2022?MAUI?NU1105(NETSDK1005)?問題處理記錄
某一天修改了幾行代碼后,突然項目無法編譯了,提示NU1105錯誤,這篇文章主要介紹了Visual?Studio?2022?MAUI?NU1105(NETSDK1005)?處理記錄,需要的朋友可以參考下2022-12-12
深入Lumisoft.NET組件POP3郵件接收與刪除操作的使用詳解
本篇文章對Lumisoft.NET組件POP3郵件接收與刪除操作的使用進行了詳細的介紹。需要的朋友參考下2013-05-05
asp.net+sqlserver實現(xiàn)的簡單高效的權(quán)限設(shè)計示例
大部分系統(tǒng)都有權(quán)限系統(tǒng)。一般來說,它能管控人員對某個否頁面的訪問;對某些字段、控件可見或者不可見。對gridview中的數(shù)據(jù)是否可刪除、可添加、可新增等等。2010-04-04
asp.net下DataSet.WriteXml(String)與(Stream)的區(qū)別
asp.net下DataSet.WriteXml(String)與(Stream)的區(qū)別...2007-04-04



