ListView如何自定义滚动边缘颜色?

10

我有一个 ListView,和一个定制的样式,基本上看起来就像 Holo,但是黄色的强调代替了蓝色。

当我滚动到列表的底部或顶部时,会出现不适合的蓝色。我为 overscroll_glow.pngoverscroll_edge.png 制作了定制可绘制资源,但我不知道如何使用它们。

如何让我的 ListView 使用这些可绘制资源而不是系统的资源?

OverScroller 类会有帮助吗?

6个回答

8
你可以使用类似反射的解决方案来修改这个发光颜色:
int glowDrawableId = context.getResources().getIdentifier("overscroll_glow", "drawable", "android");
Drawable androidGlow = context.getResources().getDrawable(glowDrawableId);
androidGlow.setColorFilter(brandColor, PorterDuff.Mode.MULTIPLY);

我遇到了同样的问题,而且似乎这是一个不错的解决方案,至少在Google添加API以更改颜色(或品牌化颜色)之前是这样的:

http://evendanan.net/android/branding/2013/12/09/branding-edge-effect/

2
Multiply不好,因为它会将你的颜色与默认蓝色混合。你应该使用SrcAtop。它会完全替换旧颜色。 - Stephane Mathis
就ScrollView而言,这段代码应该在哪里调用? - chochim
嘿,Menny,感谢你的帖子。我似乎无法让它工作。我已经设置了上下文,就像这样:Context context = this; - iqueqiorio
这里有一个可用的代码:https://gist.github.com/menny/7878762#file-brandgloweffect_full-java - Menny

5

4

你试过这个吗?setOverscrollFooter(Drawable)

更新1:

哎呀,算了吧。你可能已经看到这个讨论了。

发光行为包含在EdgeEffect类中。您可以通过在ListView上调用setOverScrollMode(OVER_SCROLL_NEVER)来禁用默认边缘效果,然后滚动自己的EdgeEffect类(细节超出我现在的范围)。

更新2:

糟糕。在AbsListView内创建的EdgeEffect对象上的调用被深深地嵌入了滚动逻辑中。可能很难。一个简单的解决方法是向Android团队提出特性请求,要求在AbsListView中添加setEdgeEffect(EdgeEffect)方法...


1
尝试了页脚,但不是我需要的。 那么,我唯一能做的就是创建一个自定义的AbsListView类?这对我来说太过hacky了 :( - Steven Schoen
我现在相信可以通过子类化ListView并覆盖一系列方法(onOverScrolled()是重要的一个)来完成,但我不确定这是否值得。 :( - heycosmo

3
请不要忘记更改过度滚动边缘线:
        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);

3

以下是解决方案:

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);
    }
}

0
我添加了这个答案,因为这是该主题的顶级结果之一,而顶级答案现在已经不正确了。 嗯,对于棒棒糖版本之前的版本实际上是正确的,但是正如预期的那样,当您使用Java反射时,您会受到反弹,这就是发生的事情,如果您使用以下代码
int glowDrawableId = context.getResources().getIdentifier("overscroll_glow", "drawable", "android");
Drawable androidGlow = context.getResources().getDrawable(glowDrawableId);
androidGlow.setColorFilter(context.getResources().getColor(R.color.gm_color), PorterDuff.Mode.MULTIPLY);

这将在Lollipop+设备上崩溃,因为该资源不再存在。因此,对于Android 5.+,您应该使用:

       <item name="android:colorEdgeEffect">@color/custom_color</item>

如果您的目标版本不是21及以上,则在values-v21/themes.xml文件中覆盖主题。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接