如何更改超滚动边缘和超滚动发光的颜色

44
如何更改超滚动边缘和超滚动发光的颜色,或如何更改安卓5.0棒棒糖版本的白色(默认颜色)?

1
可能是android棒棒糖滚动视图边缘效果颜色的重复问题。 - alanv
4个回答

89

在整个应用程序中,过度滚动发光颜色继承由android:colorPrimary设置的主要颜色值。但是,如果您需要指定不同的值,只需使用android:colorEdgeEffect(仅适用于API 21及以上)。

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

7
请注意,android:colorPrimary 同时设置了操作栏(ActionBar)或工具栏(Toolbar)的颜色。而 android:colorEdgeEffect 则更加具体,只适用于 ListView、RecyclerView 等组件。 - Mr-IDE

24

LOLLIPOP 版本中,边缘发光效果的颜色继承自 colorPrimary。在视图创建完成后,只能通过反射来修改边缘发光效果的颜色。当您使用 Palette 动态加载颜色时,这将非常有用。

编辑: 简短概括一下:从这里下载整个类:https://github.com/consp1racy/android-commons/blob/71b5c65689786b1d52d701d81d8c7445495807c3/commons/src/main/java/net/xpece/android/widget/XpEdgeEffect.java

PROGUARD 设置: 如果您要在支持库中使用此功能,则需要保留字段名称。最快捷的方法是执行以下操作(尽管仍然浪费):

-keepclassmembers class android.support.v4.widget.EdgeEffectCompat {
    <fields>;    
}
创建一个实用类,其中包括以下代码:
private static final Class<?> CLASS_SCROLL_VIEW = ScrollView.class;
private static final Field SCROLL_VIEW_FIELD_EDGE_GLOW_TOP;
private static final Field SCROLL_VIEW_FIELD_EDGE_GLOW_BOTTOM;

private static final Class<?> CLASS_LIST_VIEW = AbsListView.class;
private static final Field LIST_VIEW_FIELD_EDGE_GLOW_TOP;
private static final Field LIST_VIEW_FIELD_EDGE_GLOW_BOTTOM;

static {
  Field edgeGlowTop = null, edgeGlowBottom = null;

  for (Field f : CLASS_SCROLL_VIEW.getDeclaredFields()) {
    switch (f.getName()) {
      case "mEdgeGlowTop":
        f.setAccessible(true);
        edgeGlowTop = f;
        break;
      case "mEdgeGlowBottom":
        f.setAccessible(true);
        edgeGlowBottom = f;
        break;
    }
  }

  SCROLL_VIEW_FIELD_EDGE_GLOW_TOP = edgeGlowTop;
  SCROLL_VIEW_FIELD_EDGE_GLOW_BOTTOM = edgeGlowBottom;

  for (Field f : CLASS_LIST_VIEW.getDeclaredFields()) {
    switch (f.getName()) {
      case "mEdgeGlowTop":
        f.setAccessible(true);
        edgeGlowTop = f;
        break;
      case "mEdgeGlowBottom":
        f.setAccessible(true);
        edgeGlowBottom = f;
        break;
    }
  }

  LIST_VIEW_FIELD_EDGE_GLOW_TOP = edgeGlowTop;
  LIST_VIEW_FIELD_EDGE_GLOW_BOTTOM = edgeGlowBottom;
}

@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public static void setEdgeGlowColor(AbsListView listView, int color) {
  if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
    try {
      EdgeEffect ee;
      ee = (EdgeEffect) LIST_VIEW_FIELD_EDGE_GLOW_TOP.get(listView);
      ee.setColor(color);
      ee = (EdgeEffect) LIST_VIEW_FIELD_EDGE_GLOW_BOTTOM.get(listView);
      ee.setColor(color);
    } catch (Exception ex) {
      ex.printStackTrace();
    }
  }
}

@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public static void setEdgeGlowColor(ScrollView scrollView, int color) {
  if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
    try {
      EdgeEffect ee;
      ee = (EdgeEffect) SCROLL_VIEW_FIELD_EDGE_GLOW_TOP.get(scrollView);
      ee.setColor(color);
      ee = (EdgeEffect) SCROLL_VIEW_FIELD_EDGE_GLOW_BOTTOM.get(scrollView);
      ee.setColor(color);
    } catch (Exception ex) {
      ex.printStackTrace();
    }
  }
}

1
太好了!我一直在寻找以编程方式更改发光颜色的方法,但每个答案都与在xml上设置样式有关。你的方法对我非常有效,现在我可以根据上下文动态地更改颜色,就像我为状态栏颜色和工具栏颜色所做的那样。谢谢! - MrBrightside
1
@sajad 这是我用来处理大多数滚动容器的类 http://pastebin.com/TAujMUu9,唯一缺少的是 HorizontalScrollView 我想。 - Eugen Pechanec
@EugenPechanec 问题是我不太擅长反射,并且我搜索了一下,找不到更新的ViewPager源代码,只有一个旧版本(可能没有超滚动效果,因为它是在Lollipop之前):http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/4.0.1_r1/android/support/v4/view/ViewPager.java - Felipe Ribeiro R. Magalhaes
@EugenPechanec,那么关于Web视图呢?刚刚意识到它们也可以滚动,并且也具有边缘效果! - Felipe Ribeiro R. Magalhaes
这个链接已经失效了,顺便说一下。(https://github.com/consp1racy/android-commons/blob/master/android/src/main/java/net/xpece/android/widget/XpEdgeEffect.java) - Martin Marconcini
显示剩余12条评论

19
如果您正在使用最新的RecyclerView实现,那么通过编程方式更改溢出颜色非常简单。使用以下代码(Kotlin实现):
recyclerView.edgeEffectFactory = object : RecyclerView.EdgeEffectFactory() {
    override fun createEdgeEffect(view: RecyclerView, direction: Int): EdgeEffect {
        return EdgeEffect(view.context).apply { setColor(color) }
    }
}

请注意,此方法仅适用于API级别21(棒棒糖)及以上。如果您在编译时知道值,请使用由Ahmed指出的colorEdgeEffect方法。


1
对于Java...getRecyclerView().setEdgeEffectFactory(new RecyclerView.EdgeEffectFactory() { @NonNull @Override protected EdgeEffect createEdgeEffect(@NonNull RecyclerView view, int direction) { EdgeEffect edge = new EdgeEffect(view.getContext()); edge.setColor(ContextCompat.getColor(view.getContext(), R.color.blue)); return edge; } }); - Javatar

1

在Android 5.0以下版本中,发光效果实际上是嵌入在操作系统资源中的Drawable,您可以在其上应用ColorFilter:

public static void changeOverScrollGlowColor(Resources res, int colorID ) {
    try {
        final int glowDrawableId = res.getIdentifier("overscroll_glow", "drawable", "android");
        final Drawable overscrollGlow = res.getDrawable(glowDrawableId);
        overscrollGlow.setColorFilter(res.getColor(colorID), android.graphics.PorterDuff.Mode.SRC_ATOP);

        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);
    } catch (Exception ignored) {
    }
}

在onCreate中调用一次就足够了。
changeOverScrollGlowColor(getResources(), R.color.colorPrimary);

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