Alê Oliveira
Alê Oliveira

Reputation: 6439

Change HorizontalScrollView's light color - OverScrollMode

At the end of the HorizontalScrollView, a light appears to show that the scroll content has ended. Is there a way to change this color? It is appearing in my phone as a yellow one. I have already set the HorizontalScrollView's background color to the one that I desire, but this "end-of-scroll" light isn't the one I want.

EDIT: I just noticed that this light appears due to the onOverScrollMode (since API level 9 - see this link). Is there a way to set OVER_SCROLL_NEVER and also keep the compatibility with the Eclair versions? Or even better: to set the color of this light (if it appears)?

Upvotes: 1

Views: 2657

Answers (3)

Jared Rummler
Jared Rummler

Reputation: 38121

You can set the EdgeEffect color using reflection. The following will work from API 14+:

public static void setEdgeGlowColor(final HorizontalScrollView hsv, final int color) {
    try {
        final Class<?> clazz = HorizontalScrollView.class;
        for (final String name : new String[] {
                "mEdgeGlowLeft", "mEdgeGlowRight"
        }) {
            final Field field = clazz.getDeclaredField(name);
            field.setAccessible(true);
            setEdgeEffectColor((EdgeEffect) field.get(hsv), color);
        }
    } catch (final Exception ignored) {
    }
}

public static void setEdgeEffectColor(final EdgeEffect edgeEffect, final int color) {
    try {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            edgeEffect.setColor(color);
            return;
        }
        final Field edgeField = EdgeEffect.class.getDeclaredField("mEdge");
        edgeField.setAccessible(true);
        final Field glowField = EdgeEffect.class.getDeclaredField("mGlow");
        glowField.setAccessible(true);
        final Drawable mEdge = (Drawable) edgeField.get(edgeEffect);
        final Drawable mGlow = (Drawable) glowField.get(edgeEffect);
        mEdge.setColorFilter(color, PorterDuff.Mode.SRC_IN);
        mGlow.setColorFilter(color, PorterDuff.Mode.SRC_IN);
        mEdge.setCallback(null); // free up any references
        mGlow.setCallback(null); // free up any references
    } catch (final Exception ignored) {
    }
}

Upvotes: 1

WindsurferOak
WindsurferOak

Reputation: 4907

Although this question has already been answered, I wanted to add a couple of more ways that you can go about setting the overScrollMode attribute.

1) Create a "layout-v10" folder and put your alternate xml layout with the overScrollMode attribute set as desired.

2) If #1 would mean copying a ton of files and duplication, you can alternatively create a style for the HorizontalScrollView.

Upvotes: 1

slund
slund

Reputation: 6397

Unfortunately there is no simple way to set the color for the OverScroll EdgeEffect.

To safely set OVER_SCROLL_NEVER and remain compatible with early SDK revs, you can introspect for the setOverScrollMode method and if found call it. (tested on 3.1 and 2.2)

    setContentView(R.layout.main);

    // find scroll view         
    HorizontalScrollView hscroll = (HorizontalScrollView)findViewById(R.id.hscroll);
    try {
        // look for setOverScrollMode method
        Method setOverScroll = hscroll.getClass().getMethod("setOverScrollMode", new Class[] { Integer.TYPE } );

        if (setOverScroll != null) {
            try {
              // if found call it (OVER_SCROLL_NEVER == 2)
              setOverScroll.invoke(hscroll, 2);
            } catch (InvocationTargetException ite) {       
            } catch (IllegalAccessException ie) {
            }               
        }
        } catch (NoSuchMethodException nsme) {          
    }

Upvotes: 2

Related Questions