Xamarin圆形标签自定义渲染器无法正常工作

时间:2017-05-15 12:56:50

标签: c# android ios xamarin custom-renderer

我创建了一个自定义渲染器,可以像徽章一样在标签后面创建圆圈。

CircleView.cs(PCL)

public partial class CircleView : BoxView
    {
        public static readonly BindableProperty CornerRadiusProperty = BindableProperty.Create(nameof(CornerRadius), typeof(double), typeof(CircleView), 0.0);

        public double CornerRadius
        {
            get { return (double)GetValue(CornerRadiusProperty); }
            set { SetValue(CornerRadiusProperty, value); }
        }

        public CircleView()
        {
            InitializeComponent();
        }
    }

CircleViewRenderer.cs(Android)

[assembly: ExportRenderer(typeof(CircleView), typeof(CircleViewRenderer))]
namespace TestApp.Droid
{
    public class CircleViewRenderer : BoxRenderer
    {
        private float _cornerRadius;
        private RectF _bounds;
        private Path _path;
        protected override void OnElementChanged(ElementChangedEventArgs<BoxView> e)
        {
            base.OnElementChanged(e);

            if (Element == null)
            {
                return;
            }
            var element = (CircleView)Element;

            _cornerRadius = TypedValue.ApplyDimension(ComplexUnitType.Dip, (float)element.CornerRadius, Context.Resources.DisplayMetrics);

        }

        protected override void OnSizeChanged(int w, int h, int oldw, int oldh)
        {
            base.OnSizeChanged(w, h, oldw, oldh);
            if (w != oldw && h != oldh)
            {
                _bounds = new RectF(0, 0, w, h);
            }

            _path = new Path();
            _path.Reset();
            _path.AddRoundRect(_bounds, _cornerRadius, _cornerRadius, Path.Direction.Cw);
            _path.Close();
        }

        public override void Draw(Canvas canvas)
        {
            canvas.Save();
            canvas.ClipPath(_path);
            base.Draw(canvas);
            canvas.Restore();
        }
    }
}

CircleViewRenderer.cs(iOS)

[assembly: ExportRenderer(typeof(CircleView), typeof(CircleViewRenderer))]
namespace TestApp.iOS
{
    public class CircleViewRenderer : BoxRenderer
    {
        protected override void OnElementChanged(ElementChangedEventArgs<BoxView> e)
        {
            base.OnElementChanged(e);

            if (Element == null)
                return;

            Layer.MasksToBounds = true;
            Layer.CornerRadius = (float)((CircleView)Element).CornerRadius / 2.0f;
        }

    }
}

在Xaml中,我试过这样:

<Grid>
<customRenderer:CircleView x:Name="BadgeCircle" HeightRequest="16" WidthRequest="16" CornerRadius="16" VerticalOptions="Center" HorizontalOptions="Center" /><Label x:Name="BadgeLabel" TextColor="White" VerticalOptions="Center" HorizontalOptions="Center" VerticalTextAlignment="Center" HorizontalTextAlignment="Center" FontSize="10"/>
</Grid>

但它没有显示任何东西。初始化错误显示在CircleView上,所以我评论了InitializeComponent(); 我在这里缺少什么?

2 个答案:

答案 0 :(得分:0)

我认为你可以使用Frame。它应该有CornerRadius属性。

否则我用这个

XFShapeView

这就是你如何使用它

var box = new ShapeView
{
    ShapeType = ShapeType.Box,
    HeightRequest = 75,
    WidthRequest = 75,
    Color = Color.Navy,
    HorizontalOptions = LayoutOptions.Center,
    CornerRadius = 5,
    BorderColor = Color.Red,
    BorderWidth = 1f,
    Content = new Label
    {
        Text = "Touch me!",
        FontSize = Device.GetNamedSize(NamedSize.Micro, typeof (Label)),
        TextColor = Color.White,
        HorizontalOptions = LayoutOptions.Fill,
        VerticalOptions = LayoutOptions.Fill,
        VerticalTextAlignment = TextAlignment.Center,
        HorizontalTextAlignment = TextAlignment.Center,
    },
};

ShapeType可以是

public enum ShapeType
    {
        /// <summary>
        /// A 4-sides shape (square/rectangle) - can have rounded corners
        /// </summary>
        Box,
        /// <summary>
        /// A circle shape with a radius equals to the minimum value between height &amp; width
        /// </summary>
        Circle,
        /// <summary>
        /// A star shape for which you can define the number of points and the radius ratio
        /// </summary>
        Star,
        /// <summary>
        /// A triangle shape - the appearance depends on the height/width ratio
        /// </summary>
        Triangle,
        /// <summary>
        /// An oval shape - the appearance depends on the height/width ratio
        /// </summary>
        Oval,
        /// <summary>
        /// A diamond shape - 4-sides - the same you can find in a card deck - the appearance depends on the height/width ratio
        /// </summary>
        Diamond,
        /// <summary>
        /// A heart shape - the appearance depends on the minimum value between height &amp; width
        /// </summary>
        Heart,
        /// <summary>
        /// A progress circle shape acting like a progress bar with a radius equals to the minimum value between height &amp; width
        /// </summary>
        ProgressCircle,
        /// <summary>
        /// A custom path shape defined by a list of points
        /// </summary>
        Path

答案 1 :(得分:0)

enter image description here 从我的xamarin项目中删除

工作示例:

<Frame
    CornerRadius="15"
    Padding="0"
    BackgroundColor="AntiqueWhite"
    Margin="15,10,15,10" 
    HasShadow="False"
>
    <Label Margin="5" 
        HorizontalOptions="Center" 
        BackgroundColor="Transparent" 
        Text="My rounded label" />
</Frame>

需要注意的是框架的CornerRadius以及标签本身的边距和透明背景。 “标签”的宽度可以设置为此处,也可以使用您选择的容器进行管理。我不想用更多代码使答案复杂化。

HTH