Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to add a scrollview edge color effect in Android Lollipop?

In my app I change the overscroll glow effect color like this:

int glowDrawableId = contexto.getResources().getIdentifier("overscroll_glow", "drawable", "android");
Drawable androidGlow = contexto.getResources().getDrawable(glowDrawableId);
assert androidGlow != null;
androidGlow.setColorFilter(getResources().getColor(R.color.MyColor), PorterDuff.Mode.SRC_ATOP);

But when i updated to lollipop this code crashes. I get following error code:

FATAL EXCEPTION: main
Process: com.myproject.myapp, PID: 954
android.content.res.Resources$NotFoundException: Resource ID #0x0
at android.content.res.Resources.getValue(Resources.java:1233)
at android.content.res.Resources.getDrawable(Resources.java:756)
at android.content.res.Resources.getDrawable(Resources.java:724)

Seems that overscroll_glow resource is missing in lollipop.

How can I achieve this?

like image 353
user3065901 Avatar asked Nov 24 '14 12:11

user3065901


2 Answers

You can specify android:colorEdgeEffect in your theme to change the overscroll glow color within your entire app. By default, this inherits the primary color value set by android:colorPrimary.

res/values/themes.xml:

<style name="MyAppTheme" parent="...">
    ...
    <item name="android:colorEdgeEffect">@color/my_color</item>
</style>

Alternatively, you can modify this value for a single view using an inline theme overlay.

res/values/themes.xml:

<!-- Note that there is no parent style or additional attributes specified. -->
<style name="MyEdgeOverlayTheme">
    <item name="android:colorEdgeEffect">@color/my_color</item>
</style>

res/layout/my_layout.xml:

<ListView
    ...
    android:theme="@style/MyEdgeOverlayTheme" />
like image 88
alanv Avatar answered Nov 02 '22 01:11

alanv


The "android:colorEdgeEffect" solution works perfectly, and is much better than the previous hacks. However, it cannot be used if the edge color needs to be changed prorgrammatically.

It is possible, though, to use reflection to do so, setting the EdgeEffect objects directly in the AbsListView or ScrollView instances. For example:

EdgeEffect edgeEffectTop = new EdgeEffect(this);
edgeEffectTop.setColor(Color.RED);

EdgeEffect edgeEffectBottom = new EdgeEffect(this);
edgeEffectBottom.setColor(Color.RED);

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

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

EdgeEffect.setColor() was added in Lollipop.

Same caveats as any reflection-based solution, though.

like image 10
matiash Avatar answered Nov 02 '22 00:11

matiash