Search code examples
c#xamarinxamarin.formscustom-renderer

ScrollView bar Custom Renderer Color


Trying to change the color of the ScrollView bar. I found this link here but I would prefer to write a custom renderer as I have with all my other controls:

Color of ScrollBar in ScrollView

The problem is, I can't find any property/method that has any effect on the bar color. Here is my attempt so far:

public class CustomScrollRenderer : ScrollViewRenderer
    {
        public CustomScrollRenderer(Context context) : base(context)
        {
        }

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

            this.ScrollBarSize = 50;
            this.ScrollBarDefaultDelayBeforeFade = 60000;
            
            this.SetBackgroundColor(Android.Graphics.Color.Red);
            this.SetOutlineAmbientShadowColor(Android.Graphics.Color.Red);
            this.SetOutlineSpotShadowColor(Android.Graphics.Color.Red);
            }
    }

Solution

  • In iOS , youneed to create a subclass of UIScrollView and rewrite the method LayoutSubviews

    using Foundation;
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using UIKit;
    
    using App1;
    using App1.iOS;
    using Xamarin.Forms;
    using Xamarin.Forms.Platform.iOS;
    using ObjCRuntime;
    
    [assembly:ExportRenderer(typeof(ScrollView),typeof(MyScrollViewRenderer))]
    namespace App1.iOS
    {
        public class MyScrollViewRenderer: ViewRenderer<ScrollView, UIScrollView>
        {
            protected override void OnElementChanged(ElementChangedEventArgs<ScrollView> e)
            {
                base.OnElementChanged(e);
    
                if(Control!=null)
                {
                    SetNativeControl(new MyScrollView());
                }
    
            }
        }
    
    
        public class MyScrollView : UIScrollView
        {
    
            
            public override void LayoutSubviews()
            {
    
                foreach (UIView view in Subviews)
                {
                    if (view.IsKindOfClass(new Class("UIImageView")))
                    {
                        view.BackgroundColor = UIColor.Red;
                    }
                }
    
                base.LayoutSubviews();
            }
        }
    }
    

    In Android

    Create the scrollbar_style in Resource -> drawable

    <?xml version="1.0" encoding="utf-8"?>
    <shape xmlns:android="http://schemas.android.com/apk/res/android" >
    
      <gradient
          android:angle="45"
          android:centerColor="@color/blue"
          android:endColor="@color/blue"
          android:startColor="@color/blue" />
    
      <corners android:radius="8dp" />
    </shape>
    
    using Android.App;
    using Android.Content;
    using Android.Graphics.Drawables;
    using Android.Graphics.Drawables.Shapes;
    using Android.OS;
    using Android.Runtime;
    using Android.Views;
    using Android.Widget;
    using App1.Droid;
    using Java.Lang.Reflect;
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using Xamarin.Forms;
    using Xamarin.Forms.Platform.Android;
    using static Android.Icu.Text.DateFormat;
    using Field = Java.Lang.Reflect.Field;
    
    [assembly: ExportRenderer(typeof(Xamarin.Forms.ScrollView), typeof(MyScrollViewRenderer))]
    namespace App1.Droid
    {
        class MyScrollViewRenderer : ScrollViewRenderer
        {
            public MyScrollViewRenderer(Context context) : base(context)
            {
            }
    
            protected override void OnElementChanged(VisualElementChangedEventArgs e)
            {
                base.OnElementChanged(e);
    
                Field mScrollCacheField = Java.Lang.Class.FromType(typeof(Android.Views.View)).GetDeclaredField("mScrollCache");
                mScrollCacheField.Accessible = true;
                Java.Lang.Object mScrollCache = mScrollCacheField.Get(this); // scr is your Scroll View
    
                Field scrollBarField = mScrollCache.Class.GetDeclaredField("scrollBar");
                scrollBarField.Accessible = true;
                Java.Lang.Object scrollBar = scrollBarField.Get((Java.Lang.Object)mScrollCache);
    
    
    
                Method method = scrollBar.Class.GetDeclaredMethod("setVerticalThumbDrawable", Java.Lang.Class.FromType(typeof(Drawable)));
                method.Accessible = true;
    
    
    
                // Set your drawable here.
                method.Invoke(scrollBar, Resources.GetDrawable(Resource.Drawable.scrollbar_style));
    
            }
    
        }
    }