Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Custom overscroll glow/edge color for ListView?

I have a ListView, and a custom style that basically looks just like Holo, but with yellow accents instead of blue.

When I scroll to the bottom or top of the list, I get the un-fitting blue. I made custom drawables for overscroll_glow.png and overscroll_edge.png, but I don't know how to use them.

How can I get my ListView to use these drawables instead of the system ones?

Would the OverScroller class help?

like image 564
Steven Schoen Avatar asked Aug 24 '12 01:08

Steven Schoen


5 Answers

You can use a reflection-like solution to hack your way to changing this glow color:

int glowDrawableId = context.getResources().getIdentifier("overscroll_glow", "drawable", "android");
Drawable androidGlow = context.getResources().getDrawable(glowDrawableId);
androidGlow.setColorFilter(brandColor, PorterDuff.Mode.MULTIPLY);

I encountered the same problem, and it seems like a good solution, at least until Google adds an API for changing the color (or branding the color): http://evendanan.net/android/branding/2013/12/09/branding-edge-effect/

like image 83
Menny Avatar answered Nov 20 '22 21:11

Menny


Just use this library. I've only had a problem with wrapping context on a popup menu in landscape on a device that doesn't have overscroll (HTC One X/Sense 4.5). Works like a charm!

https://github.com/AndroidAlliance/EdgeEffectOverride

like image 45
MinceMan Avatar answered Nov 20 '22 22:11

MinceMan


tried this? setOverscrollFooter(Drawable)?

Update 1:

Oops. Nevermind. You've probably already seen this discussion.

The glow behavior is wrapped in the EdgeEffect class. You could disable the default edge effects by calling setOverScrollMode(OVER_SCROLL_NEVER) on your ListView and then rolling your own EdgeEffect class (the details of which are beyond me at this point).

Update 2:

Ouch. The calls on the EdgeEffect object created within AbsListView are buried deep within the scrolling logic. Could be tough. An easy fix would be a feature request to the Android team for a setEdgeEffect(EdgeEffect) method in AbsListView...

like image 4
heycosmo Avatar answered Nov 20 '22 21:11

heycosmo


Here you are the solution:

public static void ChangeEdgeEffect(Context cxt, View list, int color){

    if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {

        EdgeEffect edgeEffectTop = new EdgeEffect(cxt);
        edgeEffectTop.setColor(color);
        EdgeEffect edgeEffectBottom = new EdgeEffect(cxt);
        edgeEffectBottom.setColor(color);

        try {
            Field f1 = AbsListView.class.getDeclaredField("mEdgeGlowTop");
            f1.setAccessible(true);
            f1.set(list, edgeEffectTop);

            Field f2 = AbsListView.class.getDeclaredField("mEdgeGlowBottom");
            f2.setAccessible(true);
            f2.set(list, edgeEffectBottom);
        } catch (Exception e) {
            e.printStackTrace();
        }

    }else{
        int glowDrawableId = cxt.getResources().getIdentifier("overscroll_glow", "drawable", "android");
        Drawable androidGlow = cxt.getResources().getDrawable(glowDrawableId);
        assert androidGlow != null;
        androidGlow.setColorFilter(cxt.getResources().getColor(color), PorterDuff.Mode.SRC_ATOP);
    }
}
like image 3
toni Avatar answered Nov 20 '22 21:11

toni


Please don't forget to change the overscroll edge line:

        final int edgeDrawableId = res.getIdentifier("overscroll_edge", "drawable", "android");
        final Drawable overscrollEdge = res.getDrawable(edgeDrawableId);
        overscrollEdge.setColorFilter(res.getColor(colorID), android.graphics.PorterDuff.Mode.SRC_ATOP);
like image 3
bapho Avatar answered Nov 20 '22 20:11

bapho