2

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

2 Answers2

0

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)

Wendy Zang - MSFT
  • 10,509
  • 1
  • 7
  • 17
  • I am testing for another way and would feedback ASAP. – Wendy Zang - MSFT Nov 29 '21 at 09:52
  • Thanks so much for the alert. Unfortunately, even after changing to setVerticalScrollbarThumbDrawable, the same error still occurs https://i.imgur.com/zxPGsbo.png. My project Xamarin.Android targets Android 11 (API 30). You have an executable project or example. Thanks so much for the effort. –  Nov 29 '21 at 18:58
0
    protected override void OnElementChanged(VisualElementChangedEventArgs e)
    {
        base.OnElementChanged(e);
        this.VerticalScrollbarThumbDrawable = Context.GetDrawable(Resource.Drawable.scrollbar_style);
    }
Any Thing
  • 11
  • 1