locked
Android Custom Frame Renderer Help RRS feed

  • Question

  • User140005 posted

    Hello Community,

    I created a custom FRAME renderer that creates a gradient background. It works for iOS however in Android the gradient works but none of the child controls inside the frame display. Can someone tell me what I am doing wrong that causes the child controls to not display?

    `

    protected override void OnElementChanged( ElementChangedEventArgs<Frame> e )
        {
            base.OnElementChanged( e );
    
            if( e.OldElement != null || Element == null )
                return;
    
            Background = GetGradientDrawable();
        }
    
    private GradientDrawable GetGradientDrawable()
        {
            Xamarin.Forms.Color[] gradientColors = new Xamarin.Forms.Color[ 2 ];
            gradientColors[ 0 ] = Card.StartColor;
            gradientColors[ 1 ] = Card.EndColor;
    
            int[] androidColors = new int[ gradientColors.Length ];
            for( int i = 0; i < gradientColors.Length; i++ )
            {
                Xamarin.Forms.Color temp = gradientColors[ i ];
                androidColors[ i ] = temp.ToAndroid();
            }
    
            GradientDrawable gradient = new GradientDrawable( GradientDrawable.Orientation.LeftRight, androidColors );
            gradient.SetCornerRadii( new float[] { Element.CornerRadius, Element.CornerRadius, Element.CornerRadius, Element.CornerRadius,
                Element.CornerRadius, Element.CornerRadius, Element.CornerRadius, Element.CornerRadius } );
    
            return gradient;
        }
    

    `

    Thank you in advance for the help. Chris

    Sunday, February 25, 2018 7:37 PM

All replies

  • User198446 posted

    https://github.com/AndreiMisiukevich/GalleyFramework/blob/master/GalleyFramework.Droid/Renderers/GalleyBaseViewRenderer.cs

    Hi Check link above (My custom renderer for AbsoluteLayout) It's not framerenderer, but i think it can be useful

    BestRegards

    Sunday, February 25, 2018 11:19 PM
  • User140005 posted

    Thank you AndreiMisiukevich_, you code worked great.

    Monday, February 26, 2018 2:22 AM
  • User140005 posted

    I also found that you can do it very easy in android using a drawable xml file like this;

    <?xml version="1.0" encoding="utf-8" ?> <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle" > <corners android:radius="5dp" /> <gradient android:type="linear" android:startColor="#fff" android:endColor="#F5F5F5" android:centerX="0.2" android:centerY="0.3" android:angle="270" /> <stroke android:width="0.5dp" android:color="#D3D3D3" /> </shape>

    Then in the custom render like this;

    `

    protected override void OnElementChanged( ElementChangedEventArgs e ) { base.OnElementChanged( e );

            ViewGroup.SetBackgroundResource(Resource.Drawable.shadow_drawable);
        }
    

    `

    Monday, February 26, 2018 2:58 AM
  • User176749 posted

    @AndreiMisiukevich_ said: https://github.com/AndreiMisiukevich/GalleyFramework/blob/master/GalleyFramework.Droid/Renderers/GalleyBaseViewRenderer.cs

    Hi Check link above (My custom renderer for AbsoluteLayout) It's not framerenderer, but i think it can be useful

    BestRegards

    your link is dead. can you post your solution please?

    Sunday, May 27, 2018 10:13 PM
  • User198446 posted

    @batmaci Hi, sure

    `using Xamarin.Forms.Platform.Android; using Xamarin.Forms; using GalleyFramework.Views; using GalleyFramework.Droid.Renderers; using GalleyFramework.Extensions; using Android.Content; using Android.Runtime;

    [assembly: ExportRenderer(typeof(GalleyBaseView), typeof(GalleyBaseViewRenderer))] namespace GalleyFramework.Droid.Renderers { [Preserve(AllMembers = true)] public class GalleyBaseViewRenderer : VisualElementRenderer { public GalleyBaseViewRenderer(Context context) : base(context) { }

        protected override void OnElementChanged(ElementChangedEventArgs<GalleyBaseView> e)
        {
            base.OnElementChanged(e);
            e.OldElement.NotNull().Then(() => e.OldElement.BackgroundRedrawingInvoked -= Invalidate);
            e.NewElement.NotNull().Then(() => e.NewElement.BackgroundRedrawingInvoked += Invalidate);
        }
    
        protected override void DispatchDraw(global::Android.Graphics.Canvas canvas)
        {
            var colorFrom = Element.BackgroundGradientColorFrom;
            var colorTo = Element.BackgroundGradientColorTo;
    
            if (colorFrom.HasValue && colorTo.HasValue)
            {
                var startColor = colorFrom.GetValueOrDefault().ToAndroid();
                var endColor = colorTo.GetValueOrDefault().ToAndroid();
    
                var width = 0;
                var height = Height;
                if (Element.IsHorizontalGradientBackground)
                {
                    width = Width;
                    height = 0;
                }
    
                using (var gradient = new Android.Graphics.LinearGradient(
                    0, 0, width, height,
                    startColor,
                    endColor,
                    Android.Graphics.Shader.TileMode.Mirror))
                {
    
                    using (var paint = new Android.Graphics.Paint { Dither = true })
                    {
                        paint.SetShader(gradient);
                        canvas.DrawPaint(paint);
                    }
                }
            }
            base.DispatchDraw(canvas);
        }
    }
    

    }`

    Sunday, May 27, 2018 10:17 PM
  • User176749 posted

    @AndreiMisiukevich_ thanks for your reply. i was looking for a solution for my this question, i thought maybe your render had it. could you kindly check my question see if you can help? thanks

    https://forums.xamarin.com/discussion/127245/how-to-setonclicklistener-in-framerenderer

    Sunday, May 27, 2018 10:19 PM