【发布时间】:2016-08-30 17:38:27
【问题描述】:
我需要在 Xamarin.Forms 中使用带圆角的图像控件。但我没有找到任何可以做到的财产。如何有圆形图像?
【问题讨论】:
标签: xamarin xamarin.forms
我需要在 Xamarin.Forms 中使用带圆角的图像控件。但我没有找到任何可以做到的财产。如何有圆形图像?
【问题讨论】:
标签: xamarin xamarin.forms
我使用FFImageLoading 库CachedImage 控件对圆形图像进行圆形变换:
<ffimageloading:CachedImage
DownsampleToViewSize="true"
Aspect="AspectFill"
Source = "{Binding Image}"
LoadingPlaceholder = "{Binding DefaultImage}"
ErrorPlaceholder = "{Binding DefaultImage}">
<ffimageloading:CachedImage.Transformations>
<fftransformations:CircleTransformation />
</ffimageloading:CachedImage.Transformations>
</ffimageloading:CachedImage>
【讨论】:
您可以使用 Image Circle Control Plugin
<controls:CircleImage Source="{Binding Image}" Aspect="AspectFill">
<controls:CircleImage.WidthRequest>
<OnPlatform x:TypeArguments="x:Double"
iOS="55"
Android="55"
WinPhone="75"/>
</controls:CircleImage.WidthRequest>
<controls:CircleImage.HeightRequest>
<OnPlatform x:TypeArguments="x:Double"
iOS="55"
Android="55"
WinPhone="75"/>
</controls:CircleImage.HeightRequest>
</controls:CircleImage>
您还可以使用 Xamarin-Forms-Labs 项目中的 CircleImage。
【讨论】:
如果您需要使用自定义渲染器的解决方案(以您想要的方式调整控件),这是我的实现。
public class ImageCircle:Image
{
public ImageCircle ()
{
}
}
[assembly: ExportRenderer(typeof(ImageCircle), typeof(ImageCircleRenderer))]
namespace myNamespace.Droid
{
public class ImageCircleRenderer:ImageRenderer
{
public ImageCircleRenderer ()
{
}
protected override void OnElementChanged(ElementChangedEventArgs<Image> e)
{
base.OnElementChanged(e);
if (e.OldElement == null)
{
if ((int)Android.OS.Build.VERSION.SdkInt < 20)
SetLayerType(Android.Views.LayerType.Software, null);
}
}
protected override bool DrawChild(Canvas canvas, global::Android.Views.View child, long drawingTime)
{
try
{
var radius = Math.Min(Width, Height) / 2;
var strokeWidth = 10;
radius -= strokeWidth / 2;
//Create path to clip
var path = new Path();
path.AddCircle(Width / 2, Height / 2, radius, Path.Direction.Ccw);
canvas.Save();
canvas.ClipPath(path);
var result = base.DrawChild(canvas, child, drawingTime);
canvas.Restore();
// Create path for circle border
path = new Path();
path.AddCircle(Width / 2, Height / 2, radius, Path.Direction.Ccw);
var paint = new Paint();
paint.AntiAlias = true;
paint.StrokeWidth = 5;
paint.SetStyle(Paint.Style.Stroke);
paint.Color = global::Android.Graphics.Color.White;
canvas.DrawPath(path, paint);
//Properly dispose
paint.Dispose();
path.Dispose();
return result;
}
catch (Exception ex)
{
Console.WriteLine("Unable to create circle image: " + ex);
}
return base.DrawChild(canvas, child, drawingTime);
}
}
}
[assembly: ExportRenderer(typeof(ImageCircle), typeof(ImageCircleRenderer))]
namespace LifesTopTen.iOS
{
public class ImageCircleRenderer:ImageRenderer
{
public ImageCircleRenderer ()
{
}
private void CreateCircle()
{
try
{
double min = Math.Min(Element.Width, Element.Height);
Control.Layer.CornerRadius = (float)(min / 2.0);
Control.Layer.MasksToBounds = false;
Control.Layer.BorderColor = Color.White.ToCGColor();
Control.Layer.BorderWidth = 3;
Control.ClipsToBounds = true;
}
catch(Exception ex)
{
Console.WriteLine ("Unable to create circle image: " + ex);
}
}
protected override void OnElementChanged (ElementChangedEventArgs<Image> e)
{
base.OnElementChanged (e);
if (e.OldElement != null || Element == null)
return;
CreateCircle();
}
protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
{
base.OnElementPropertyChanged(sender, e);
if (e.PropertyName == VisualElement.HeightProperty.PropertyName ||
e.PropertyName == VisualElement.WidthProperty.PropertyName)
{
CreateCircle();
}
}
}
}
【讨论】: