14

I have a theme that derives from Android's default light theme. My ListViews are configured with a white background, and I guess as a side-effect of this, the color of the fading edge is white, which is not something that I want - I'd like them to be black.

It seems impossible to simply change the color of the edge (although I can control the length and other factors), and the usual suggestion of using a black color for listview's hint color results in some pretty horrible side-effects when the list scrolls.

Can anyone advise a reliable way of changing the color of the fading edge to an arbitrary color?

Melllvar
  • 2,056
  • 4
  • 24
  • 47

7 Answers7

35

It's actually much easier then that.

You can change the colour of the fade to anything you want using the: 'android:cacheColorHint' setting.

eg:

<ListView
....
android:cacheColorHint="#FFFFFF"
/>
Scott
  • 2,593
  • 1
  • 22
  • 23
  • I have mine set to transparent, with the consequence that the edges aren't fading at all. Can you get round this? – Andrew Wyld Nov 06 '12 at 15:11
  • 1
    Transparent would actually make the most sense and you would think that would actually be the default but due to the way it is implemented (in which it applies an overlay of the specified colour) this isn't possible. Your best bet is to either use a colour which best resembles your background or perhaps even having it transparent is the best solution. – Scott Nov 07 '12 at 02:11
  • No, it's using transparent without problems, but now I have no fading edges. – Andrew Wyld Nov 22 '12 at 12:24
  • That's what I mean. You do have fading edges, but they are transparent so you can't see them. The edges are applied as a colour overlay, so making them transparent means you can't see them. If you are looking for a transparent fading effect then I am afraid you will not find one using this control. – Scott Nov 23 '12 at 05:04
  • Ah, I get you now. Yes, I've managed to get fading overriding the `getSolidColor()` method in `ListView` now but as the method name suggests transparent fading is not an option. Bizarrely, it seems to be the default on `ScrollView`, as I can see the background image through the fade. – Andrew Wyld Nov 26 '12 at 11:01
  • It's been a while since I posed this question, but I should probably note that this solution will not work predictably - it failed on at least two devices I tested. Using a cacheColorHint that's not in tune with the background often causes color aberrations during scrolling. – Melllvar Oct 28 '13 at 19:04
19

Unfortunately you cannot do this easily. The whole point of the fading edges is to fade into the background, not to draw some random color. However, you can try to extend ListView and override getSolidColor() to return the color you want for the fading edges. It should work just fine.

Romain Guy
  • 97,993
  • 18
  • 219
  • 200
10

I had the problem that white was the "Overscroll" color, not actually the fading edge.

try this (assuming you want a fading edge, but not the horrid white glare when you hit the ends! (otherwise set requires fading edge to none)):

<ListView
    android:id="@+id/listview"
    android:layout_width="match_parent"
    android:layout_height="wrap_content" 
    android:cacheColorHint="#00000000"
    android:requiresFadingEdge="vertical"
    android:fadingEdgeLength="10dp" 
    android:overScrollMode="never" >      </-- this is the line you want i think -->
</ListView> 
Jared Rummler
  • 37,824
  • 19
  • 133
  • 148
Dan Harvey
  • 798
  • 1
  • 10
  • 23
4

You can change the EdgeEffect color of a ListView or GridView using reflection. Copy the following static factory methods into your project and use setEdgeGlowColor(yourListView, yourAwesomeColor);:

public static void setEdgeGlowColor(AbsListView listView, int color) {
    try {
        Class<?> clazz = AbsListView.class;
        Field fEdgeGlowTop = clazz.getDeclaredField("mEdgeGlowTop");
        Field fEdgeGlowBottom = clazz.getDeclaredField("mEdgeGlowBottom");
        fEdgeGlowTop.setAccessible(true);
        fEdgeGlowBottom.setAccessible(true);
        setEdgeEffectColor((EdgeEffect) fEdgeGlowTop.get(listView), color);
        setEdgeEffectColor((EdgeEffect) fEdgeGlowBottom.get(listView), color);
    } catch (Exception ignored) {
    }
}

public static void setEdgeEffectColor(EdgeEffect edgeEffect, int color) {
    try {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            edgeEffect.setColor(color);
            return;
        }
        Field edgeField = EdgeEffect.class.getDeclaredField("mEdge");
        Field glowField = EdgeEffect.class.getDeclaredField("mGlow");
        edgeField.setAccessible(true);
        glowField.setAccessible(true);
        Drawable mEdge = (Drawable) edgeField.get(edgeEffect);
        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 (Exception ignored) {
    }
}
Jared Rummler
  • 37,824
  • 19
  • 133
  • 148
2

I posted a complete solution for this problem in a class that extends ListView. Here: Is it possible to change the colour of the FadingEdge of a Listview?

Community
  • 1
  • 1
Thomson Comer
  • 3,919
  • 3
  • 30
  • 32
1

If you mean the "edge glow/effect", I found a very simple (but hackish) way to accomplish this (changing the color of the glow):

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

I took advantage of the fact that the glow effect is actually a Drawable (and un-mutate at that), and applied a filter on it. More about it, here: http://evendanan.net/android/branding/2013/12/09/branding-edge-effect/

Menny
  • 473
  • 6
  • 13
0

This library will solve your problem: https://github.com/AndroidAlliance/EdgeEffectOverride

jaxvy
  • 5,040
  • 1
  • 21
  • 22