user6473719
user6473719

Reputation:

Change the color of the ScrollBar in Xamarin.Forms

I need advice. I'm trying to change the color of the ScrollBar in Xamarin Forms. I created ScrollBarColorEffect but unfortunately it doesn't work it reports this error.

Someone would know where the mistake was.

enter image description here enter image description here

XF ScrollBarColorEffect.cs

public class ScrollBarColorEffect : RoutingEffect
{
    public ScrollBarColorEffect() : base($"MPlay.{nameof(ScrollBarColorEffect)}"){}
    
    public Color ScrollBarColor { get; set; }
}

Xamarin Android ScrollBarColorEffect.cs

[assembly: ResolutionGroupName("MPlay")]
[assembly: ExportEffect(typeof(MPlay.Droid.ScrollBarColorEffect), 
nameof(MPlay.Droid.ScrollBarColorEffect))]
namespace MPlay.Droid
{

public class ScrollBarColorEffect : PlatformEffect
{
    protected override void OnAttached()
    {
        UpdateUI();
    }

    protected override void OnDetached()
    {
    }
  
    void UpdateUI()
    {
        Xamarin.Forms.ScrollView _scrollView = Element as Xamarin.Forms.ScrollView;
        if (Element != null && Control is AndroidX.Core.Widget.NestedScrollView scrollView)
        {
            Java.Lang.Reflect.Field mScrollCacheField = Class.FromType(typeof(Android.Views.View)).GetDeclaredField("mScrollCache");
            mScrollCacheField.Accessible = true;

            var mScrollCache = mScrollCacheField.Get(scrollView);
            var scrollBarField = mScrollCache.Class.GetDeclaredField("scrollBar");
            scrollBarField.Accessible = true;
            var scrollBar = scrollBarField.Get(mScrollCache);
            if (scrollBar != null)
            {
                var method = scrollBar.Class.GetDeclaredMethod("setVerticalThumbDrawable", Class.FromType(typeof(Drawable)));
                method.Accessible = true;

                var layers = new Drawable[1];
                var shapeDrawable = new ShapeDrawable(new RectShape());
                var scrollBarColor = Color.Default;

                var effect = _scrollView.Effects.FirstOrDefault(e => e is Core.Effects.ScrollBarColorEffect) as Core.Effects.ScrollBarColorEffect;
                //var effect = (Core.Effects.ScrollBarColorEffect)Element.Effects.FirstOrDefault(e => e is Core.Effects.ScrollBarColorEffect);
                if (effect != null)
                {
                    scrollBarColor = effect.ScrollBarColor;
                }

                shapeDrawable.Paint.Color = scrollBarColor.ToAndroid();
                shapeDrawable.SetIntrinsicWidth(5);

                layers[0] = shapeDrawable;
                method.Invoke(scrollBar, layers);
            }
        }
    }
}

XAML XF

 <ScrollView>
        <ScrollView.Effects>
            <helpers:ScrollBarColorEffect ScrollBarColor="Red"/>
        </ScrollView.Effects>
 </ScrollView>

I tried to create my own render, see here: https://stackoverflow.com/a/65127686/6473719

Unfortunately, I get the same error

enter image description here

Upvotes: 2

Views: 539

Answers (2)

Any Thing
Any Thing

Reputation: 11

    protected override void OnElementChanged(VisualElementChangedEventArgs e)
    {
        base.OnElementChanged(e);
        this.VerticalScrollbarThumbDrawable = Context.GetDrawable(Resource.Drawable.scrollbar_style);
    }

Upvotes: 0

Wendy Zang - MSFT
Wendy Zang - MSFT

Reputation: 10958

The code you used should work before API 29. On Android 10(API 29), there are non-SDK interface restrictions.

The method setVerticalThumbDrawable you used is in the Non-SDK interfaces that are now blocked in Android 10.

Non-SDK interfaces that are now blocked in Android 10: https://developer.android.google.cn/about/versions/10/non-sdk-q#q-list-changes

In the Android developer, it suggest to use setVerticalScrollbarThumbDrawable instead. https://developer.android.google.cn/reference/android/view/View?hl=zh-cn#setVerticalScrollbarThumbDrawable(android.graphics.drawable.Drawable)

Upvotes: 0

Related Questions