Xamarin 圆形标签自定义渲染器不起作用

Posted

技术标签:

【中文标题】Xamarin 圆形标签自定义渲染器不起作用【英文标题】:Xamarin Round Label Custom renderer not working 【发布时间】:2017-05-15 12:56:49 【问题描述】:

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

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(); 我在这里错过了什么?

【问题讨论】:

您能否尝试取消注释InitializeComponent() 并构建项目? 它不工作并给出错误 请尝试清除项目并重建它。如果仍然有错误,您可以分享一个基本的演示吗? 【参考方案1】:

我认为你可以使用框架。它应该有 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

【讨论】:

【参考方案2】:

从我的 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>

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

HTH

【讨论】:

以上是关于Xamarin 圆形标签自定义渲染器不起作用的主要内容,如果未能解决你的问题,请参考以下文章

Phong 着色器不起作用

在父项中设置绑定时,Xamarin.Forms 绑定到自定义控件不起作用

@shared_task 装饰器不起作用

ListView 内的 ImageButton onclick 列表器不起作用。应用点击后崩溃

动态 Jquery 选择器不起作用

AngularJS、SweetAlert.js 在自定义指令中不起作用