Search code examples
androidandroid-xmlandroid-scrollview

Change the Color of ScrollView Programmatically


What I'm currently doing

Currently, I have changed the scrollbar in my XML file using the android:scrollbarThumbVertical property like so:

<ScrollView
    android:id="@+id/scrollView1"
    android:scrollbarThumbVertical="@drawable/scrollbar_blue"
    ... >

And scrollbar_blue refers to my scrollbar_blue.xml file, which is this:

<?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>

What I want to do

I have a colour option for my app - so when the colour is on, it should stay blue; otherwise, it should be grey.

How can I programmatically (in my activity class) change my ScrollView to use my scrollbar_grey.xml?

If you look at the Android documentation on ScrollView, there is no corresponding method to android:scrollbarThumbVertical

I'm fine with another way change the colour as well.

Here is how I create the reference to my ScrollView:

ScrollView scr = (ScrollView)findViewById(R.id.scrollView1);

Solution

  • There is a method to change it programmatically but that method is not exposed. There doesn't seem to be anything else to change it programmatically from what I have read.

    However, I did come across this one stackoverflow answer that uses reflection to do it. Please upvote the answer there if it works for you: https://stackoverflow.com/a/19819843/3286163

    The answer was for a listview but is the same for the scrollview:

    ScrollView scr = (ScrollView)findViewById(R.id.scrollView1);
    try
    {
        Field mScrollCacheField = View.class.getDeclaredField("mScrollCache");
        mScrollCacheField.setAccessible(true);
        Object mScrollCache = mScrollCacheField.get(scr); // scr is your Scroll View
    
        Field scrollBarField = mScrollCache.getClass().getDeclaredField("scrollBar");
        scrollBarField.setAccessible(true);
        Object scrollBar = scrollBarField.get(mScrollCache);
    
        Method method = scrollBar.getClass().getDeclaredMethod("setVerticalThumbDrawable", Drawable.class);
        method.setAccessible(true);
    
        // Set your drawable here.
        method.invoke(scrollBar, getResources().getDrawable(R.drawable.scrollbar_blue));
    }
    catch(Exception e)
    {
        e.printStackTrace();
    }
    

    Only thing I could find. I gave it a try myself and it worked.