【问题标题】:Frame OutlineColor not work in only Android, Xamarin FormsFrame OutlineColor 仅适用于 Android、Xamarin 表单
【发布时间】:2017-11-25 10:08:44
【问题描述】:

我正在 Xamarin Forms 中开发应用程序,我遇到了一个很久以前就应该修复的错误。 我尝试为框架设置轮廓,它在 ios 上运行良好,但在 android 上不起作用。

这是我的 Frame 的 xaml。

<Frame
    HasShadow="true"
    CornerRadius="10"
    OutlineColor="Red"
    BackgroundColor="White">
    <StackLayout 
        Orientation="Horizontal">
        <Label
        Text="TEST"
        VerticalOptions="Center"/>
        <Label
        Text="For OUTLINE"
        VerticalOptions="Center"/>
    </StackLayout>
</Frame>

感谢您的帮助!

【问题讨论】:

    标签: android xamarin.forms frame


    【解决方案1】:

    这不适用于安卓。错误报告here

    解决方案 1:

    您应该为 Android 平台的Frame 创建一个Renderer,如下所示:

    using System;
    using Android.Graphics.Drawables;
    using Xamarin.Forms;
    using Xamarin.Forms.Platform.Android;
    using XFormsUI.Droid;
    
    [assembly: ExportRenderer(typeof(Frame), typeof(RoundBorderFrameRenderer))]
    namespace XFormsUI.Droid
    {
        public class RoundBorderFrameRenderer : FrameRenderer
        {
            protected override void OnElementChanged(ElementChangedEventArgs<Frame> e)
            {
                base.OnElementChanged(e);
    
                if (e.NewElement != null && e.OldElement == null)
                {
                    SetBackgroundResource(Resource.Drawable.round_border_frame);
    
                    //Write following lines if you want to bring the XAML Frame Elements's background Color into Native. Otherwise, Frame's BackgroundColor will not be effective.
                    GradientDrawable drawable = (GradientDrawable)Background;
                    string FrameBackgroundColorHex = String.Format("#{0:X2}{1:X2}{2:X2}", (int)(e.NewElement.BackgroundColor.R * 255), (int)(e.NewElement.BackgroundColor.G * 255), (int)(e.NewElement.BackgroundColor.B * 255));
                    drawable.SetColor(Android.Graphics.Color.ParseColor(FrameBackgroundColorHex));
                }
            }
        }
    }
    

    这也需要xml (round_border_frame.xml) 选择器文件。将此文件放入您的 Drawable 文件夹中。

    <?xml version="1.0" encoding="UTF-8"?>
    <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
        <!--We need to give Frame's 'BorderColor Here-->
        <stroke android:width="1dp" android:color="#FF0000" />
        <corners android:radius="10dp" />
    </shape>
    

    解决方案 2:

    在没有选择器 xml 文件的情况下使用 RendererSource.

    using System;
    using Android.Graphics;
    using Xamarin.Forms;
    using Xamarin.Forms.Platform.Android;
    using XFormsUI.Droid;
    
    [assembly: ExportRenderer(typeof(Frame), typeof(RoundBorderFrameRenderer))]
    namespace XFormsUI.Droid
    {
        public class RoundBorderFrameRenderer : FrameRenderer
        {
            public override void Draw(Canvas canvas)
            {
                base.Draw(canvas);
    
                using (var paint = new Paint { AntiAlias = true })
                using (var path = new Path())
                using (Path.Direction direction = Path.Direction.Cw)
                using (Paint.Style style = Paint.Style.Stroke)
                using (var rect = new RectF(0, 0, canvas.Width, canvas.Height))
                {
                    float px = Forms.Context.ToPixels(Element != null ? Element.CornerRadius : 10); //Default Corner Radius = 10
                    float py = Forms.Context.ToPixels(Element != null ? Element.CornerRadius : 10); //Default Corner Radius = 10
                    path.AddRoundRect(rect, px, py, direction);
    
                    //Set the Width of the Border here
                    paint.StrokeWidth = 1f;
                    paint.SetStyle(style);
    
                    //Take OutLineColor from XAML Frame element and set it natively here.
                    string FrameBorderColorHex = String.Format("#{0:X2}{1:X2}{2:X2}", (int)(Element.OutlineColor.R * 255), (int)(Element.OutlineColor.G * 255), (int)(Element.OutlineColor.B * 255));
                    paint.Color = Android.Graphics.Color.ParseColor(FrameBorderColorHex);
                    canvas.DrawPath(path, paint);
                }
            }
        }
    }
    

    解决方案 3:

    但这不是最好的解决方案,但它是一种解决方法: 将您的外部 Frame 包裹在另一个具有 PaddingFrame 中,并将其 BackgroundColor 设置为您的边框颜色。

    注意:我还没有在 iOS 上检查过这个。

    <Frame BackgroundColor="Red" CornerRadius="10" Padding="1,1,1,1">
        <Frame CornerRadius="10" BackgroundColor="White">
            <StackLayout Orientation="Horizontal">
                <Label Text="TEST" VerticalOptions="Center" />
                <Label Text="For OUTLINE" VerticalOptions="Center" />
            </StackLayout>
        </Frame>
    </Frame>
    

    人们正在thread 上讨论这个问题。

    希望这会有所帮助!

    【讨论】:

    • 你好,我尝试了解决方案 2 绑定 OutlineColor 但似乎 StrokeWidth 什么都不做。我不能得到更大的中风。你知道为什么吗?
    • 另一个框架内的框架对我有用。感谢您的解决方案。希望 Xamarin 团队能尽快在 android 上解决这个问题。
    【解决方案2】:

    我被这个问题困了半天..

    我的解决方案:

     using System;
     using Android.Content;
     using MyGlobe.Droid.Renderers;
     using Xamarin.Forms;
     using Xamarin.Forms.Platform.Android;
     using Android.Graphics;
     using Android.Graphics.Drawables;
    
     [assembly: ExportRenderer(typeof(Frame),typeof(MyGlobe.Droid.Renderers.BorderFrameRenderer))]
     namespace Yours.Droid.Renderers
     {
     public class BorderFrameRenderer : FrameRenderer
     {
        public override void Draw(Canvas canvas)
        {
            base.Draw(canvas);
            using (var strokePaint = new Paint())
            using (var rect = new RectF(0, 0, canvas.Width, canvas.Height))
            {
                string FrameBorderColorHex = String.Format("#{3:X2}{0:X2}{1:X2}{2:X2}", (int)(Element.OutlineColor.R * 255), (int)(Element.OutlineColor.G * 255), (int)(Element.OutlineColor.B * 255), (int)(Element.OutlineColor.A * 255));
    
                // stroke
                strokePaint.SetStyle(Paint.Style.Stroke);
                strokePaint.Color = Android.Graphics.Color.ParseColor(FrameBorderColorHex);
                strokePaint.StrokeWidth = 5;
    
                var radius = 10;
    
                canvas.DrawRoundRect(rect, radius, radius, strokePaint);  // stroke
            }
        }
    
        public BorderFrameRenderer(Context context) : base(context)
        {
        }
    
        protected override void OnElementChanged(ElementChangedEventArgs<Frame> e)
        {
            base.OnElementChanged(e);
        }
    }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-03-14
      • 2019-12-06
      • 1970-01-01
      • 2017-12-21
      • 2017-06-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多