В настоящее время я вообще не могу заставить его работать, средство выбора отображается на эмуляторе. строго такой же, как и по умолчанию.
Мой пользовательский элемент управления выглядит следующим образом:
Код: Выделить всё
public partial class IconPicker : Picker
{
[AutoBindable]
private readonly ImageSource _source = null!;
[AutoBindable(DefaultValue = "1.0")]
private readonly double _strokeThickness;
[AutoBindable]
private readonly Color? _stroke;
[AutoBindable]
private readonly float _cornerRadius;
}
Код: Выделить всё
[Obsolete("This renderer is obsolete, it will be replaced in future release by corresponding handler/mapper")]
public class IconPickerRenderer(Context context) : PickerRenderer(context)
{
IconPicker? element;
protected override void OnElementChanged(ElementChangedEventArgs
e)
{
base.OnElementChanged(e);
element = (IconPicker)this.Element;
if (Control != null && this.Element != null && element.Source != null)
Control.Background = SetPickerUi(element);
}
private LayerDrawable SetPickerUi(IconPicker element)
{
GradientDrawable border = new GradientDrawable();
border.SetShape(ShapeType.Rectangle);
border.SetPadding(10, 10, 10, 10);
border.SetCornerRadius(element.CornerRadius);
border.SetColor(ColorStateList.ValueOf(element.BackgroundColor?.ToAndroid() ?? Android.Graphics.Color.Transparent));
border.SetStroke(Convert.ToInt32(element.StrokeThickness), element.Stroke?.ToAndroid() ?? Android.Graphics.Color.Black);
LayerDrawable layerDrawable = new([border, GetDrawable(element.Source).Result]);
layerDrawable.SetLayerInset(0, 20, 0, 0, 0);
return layerDrawable;
}
private async Task GetDrawable(ImageSource source)
{
Drawable drawable;
if (source is FontImageSource font)
drawable = new FontDrawable(Context!, font.Glyph, font.Color.ToAndroid(), Convert.ToInt32(font.Size), "MaterialIconsRound-Regular.otf"); // TODO: add font family and recover filename from font family
else
{
var renderer = new StreamImagesourceHandler();
Bitmap bitmapImg = await renderer.LoadImageAsync(source, Context);
drawable = new BitmapDrawable(Resources, Bitmap.CreateScaledBitmap(bitmapImg, 70, 70, true))
{
Gravity = GravityFlags.Right
};
}
return drawable;
}
}
[img]https://i. sstatic.net/LRu6YNqd.png[/img]
Текущее состояние моего рефакторинга в обработчик MAUI находится на этом этапе:
Код: Выделить всё
public partial class IconPickerHandler : PickerHandler
{
//public static readonly new PropertyMapper Mapper = new(PickerHandler.Mapper)
//{
// [nameof(IconPicker.Source)] = MapSourceChanged,
// [nameof(IconPicker.StrokeThickness)] = MapStrokeThicknessChanged,
// [nameof(IconPicker.Stroke)] = MapStrokeChanged,
// [nameof(IconPicker.CornerRadius)] = MapCornerRadiusChanged,
//};
public IconPickerHandler() : base(Mapper) { }
}
// The android one
public partial class IconPickerHandler
{
public static void MapSourceChanged(IconPickerHandler handler, IconPicker view) { Debug.WriteLine(nameof(MapSourceChanged)); }
public static void MapStrokeThicknessChanged(IconPickerHandler handler, IconPicker view)
{
Debug.WriteLine(nameof(MapStrokeThicknessChanged));
if (handler.PlatformView.Background is LayerDrawable backgroundDrawable)
{
GradientDrawable? borderDrawable = (GradientDrawable?)backgroundDrawable.GetDrawable(0);
if (borderDrawable != null)
{
borderDrawable.Thickness = Convert.ToInt32(view.StrokeThickness);
}
}
}
public static void MapStrokeChanged(IconPickerHandler handler, IconPicker view)
{
if (handler.PlatformView.Background is LayerDrawable backgroundDrawable)
{
GradientDrawable? borderDrawable = (GradientDrawable?)backgroundDrawable.GetDrawable(0);
if (borderDrawable != null)
{
borderDrawable.SetStroke(borderDrawable.Thickness, view.Stroke?.ToPlatform() ?? Android.Graphics.Color.Black);
}
}
Debug.WriteLine(nameof(MapStrokeChanged));
}
public static void MapCornerRadiusChanged(IconPickerHandler handler, IconPicker view)
{
if (handler.PlatformView.Background is LayerDrawable backgroundDrawable)
{
GradientDrawable? borderDrawable = (GradientDrawable?)backgroundDrawable.GetDrawable(0);
if (borderDrawable != null)
{
borderDrawable.SetCornerRadius(view.CornerRadius);
}
}
Debug.WriteLine(nameof(MapCornerRadiusChanged));
}
protected override void ConnectHandler(MauiPicker platformView)
{
base.ConnectHandler(platformView);
IconPicker element = (IconPicker)VirtualView;
GradientDrawable borderDrawable = new GradientDrawable();
borderDrawable.SetShape(ShapeType.Rectangle);
borderDrawable.SetPadding(10, 10, 10, 10);
borderDrawable.SetCornerRadius(element.CornerRadius);
borderDrawable.SetColor(ColorStateList.ValueOf(element.BackgroundColor?.ToPlatform() ?? Android.Graphics.Color.Transparent));
borderDrawable.SetStroke(Convert.ToInt32(element.StrokeThickness), element.Stroke?.ToPlatform() ?? Android.Graphics.Color.Black);
LayerDrawable layerDrawable = new([borderDrawable, GetImageSourceAsDrawable(element.Source).Result]);
layerDrawable.SetLayerInset(0, 20, 0, 0, 0);
platformView.Background = layerDrawable;
}
private async Task GetImageSourceAsDrawable(ImageSource source)
{
Drawable drawable;
if (source is FontImageSource fontSource)
drawable = new FontDrawable(Context, fontSource.Glyph, fontSource.Color.ToPlatform(), Convert.ToInt32(fontSource.Size), "MaterialIconsRound-Regular.otf"); // TODO: add font family and recover filename from font family
else
{
var renderer = new StreamImagesourceHandler();
Bitmap bitmapImg = await renderer.LoadImageAsync(source, Context);
drawable = new BitmapDrawable(Context.Resources, Bitmap.CreateScaledBitmap(bitmapImg, 70, 70, true))
{
Gravity = GravityFlags.Right
};
}
return drawable;
}
}
Код: Выделить всё
internal class FontDrawable : Drawable
{
private int alpha = 255;
private int size;
private string text;
private readonly TextPaint paint = new TextPaint();
public override int IntrinsicWidth => this.size;
public override int IntrinsicHeight => this.size;
public override bool IsStateful => true;
public override int Opacity => this.alpha;
public FontDrawable(Context context, string text, Android.Graphics.Color iconColor, int iconSizeDP, string font = "ionicons.ttf")
{
this.text = text;
this.paint.SetTypeface(Typeface.CreateFromAsset(context.Assets, font));
this.paint.SetStyle(Android.Graphics.Paint.Style.Fill);
this.paint.TextAlign = Android.Graphics.Paint.Align.Center;
this.paint.Color = iconColor;
this.paint.AntiAlias = true;
this.size = GetPX(context, iconSizeDP);
this.SetBounds(0, 0, this.size, this.size);
}
public override void Draw(Canvas canvas)
{
this.paint.TextSize = this.Bounds.Height();
var textBounds = new Android.Graphics.Rect();
this.paint.GetTextBounds(this.text, 0, 1, textBounds);
var textHeight = textBounds.Height();
var textBottom = this.Bounds.Top + (this.paint.TextSize - textHeight) / 2f + textHeight - textBounds.Bottom;
canvas.DrawText(this.text, this.Bounds.Right - this.Bounds.Right / 10, textBottom, this.paint);
}
public override bool SetState(int[] stateSet)
{
var oldValue = paint.Alpha;
var newValue = stateSet.Any(s => s == global::Android.Resource.Attribute.StateEnabled) ? this.alpha : this.alpha / 2;
paint.Alpha = newValue;
return oldValue != newValue;
}
private static int GetPX(Context context, int sizeDP)
{
return (int)TypedValue.ApplyDimension(ComplexUnitType.Dip, sizeDP, context.Resources.DisplayMetrics);
}
private static bool IsEnabled(int[] stateSet)
{
return stateSet.Any(s => s == global::Android.Resource.Attribute.StateEnabled);
}
public override void SetAlpha(int alpha)
{
this.alpha = alpha;
this.paint.Alpha = alpha;
}
public override void SetColorFilter(ColorFilter colorFilter)
{
this.paint.SetColorFilter(colorFilter);
}
public override void ClearColorFilter()
{
this.paint.SetColorFilter(null);
}
}
При отладке код платформы ConnectHandler выполняется правильно.< /p>
Результат выбора с обработчиком не учитывает никаких изменений и отображает базовый инструмент выбора Android:

Спасибо.
Подробнее здесь: https://stackoverflow.com/questions/790 ... dler-issue
Мобильная версия