Android 使用appcompat时设置RecyclerView edge glow pre棒棒糖

Android 使用appcompat时设置RecyclerView edge glow pre棒棒糖,android,android-recyclerview,colors,android-appcompat,Android,Android Recyclerview,Colors,Android Appcompat,我正在寻找一种方法,在使用appcompat材质主题时,在RecyclerView pre-lollip中设置over scroll指示器的颜色样式 在内部,它将EdgeEffect设置为内部可设置样式的属性,除非您已经在吃棒棒糖(讽刺) 使用反射不起作用,设置边缘效果的颜色也只能在棒棒糖上使用 在我的API21应用程序中,它是从原材料颜色绘制的,在Kitkat上它是白色的,在这之前它是全息蓝色的,我希望统一我的设计 有什么想法吗?我也找不到为RecyclerViews设置overscroll颜

我正在寻找一种方法,在使用appcompat材质主题时,在RecyclerView pre-lollip中设置over scroll指示器的颜色样式

在内部,它将EdgeEffect设置为内部可设置样式的属性,除非您已经在吃棒棒糖(讽刺)

使用反射不起作用,设置边缘效果的颜色也只能在棒棒糖上使用

在我的API21应用程序中,它是从原材料颜色绘制的,在Kitkat上它是白色的,在这之前它是全息蓝色的,我希望统一我的设计


有什么想法吗?

我也找不到为RecyclerViews设置overscroll颜色的方法

因此,一个可能的解决方案是为v21之前和v21之后提供不同的布局文件

  • v21之前版本:使用列表视图并通过
  • v21后:使用recyclerviews并通过colorAccent设置overscroll颜色

缺点是您的代码会很混乱,需要为recyclerview/listview使用两个不同的适配器。

感谢@TomášLinhart指出这一点。下面的解决方案仅适用于API>21时更改边缘颜色。它可以与AppCompat一起使用,但改变颜色的效果只有在棒棒糖和更高版本中才可见


我找到了一种利用反射设置颜色的方法。例如,下面是更改顶部和底部边缘颜色的代码:

public static void setEdgeGlowColor(final RecyclerView recyclerView, final int color) {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
        try {
            final Class<?> clazz = RecyclerView.class;
            for (final String name : new String[] {"ensureTopGlow", "ensureBottomGlow"}) {
                Method method = clazz.getDeclaredMethod(name);
                method.setAccessible(true);
                method.invoke(recyclerView);
            }
            for (final String name : new String[] {"mTopGlow", "mBottomGlow"}) {
                final Field field = clazz.getDeclaredField(name);
                field.setAccessible(true);
                final Object edge = field.get(recyclerView); // android.support.v4.widget.EdgeEffectCompat
                final Field fEdgeEffect = edge.getClass().getDeclaredField("mEdgeEffect");
                fEdgeEffect.setAccessible(true);
                ((EdgeEffect) fEdgeEffect.get(edge)).setColor(color);
            }
        } catch (final Exception ignored) {}
    }
}

默认情况下,Android在开始滚动时调用
sure*Glow
方法。在这些方法中,使用默认颜色初始化新的
EdgeEffect
,但前提是它尚未初始化。为了防止这种行为,您必须调用
sure*Glow
方法,然后更改边的颜色,这样后续初始化
EdgeEffect
将被忽略(如上面的
setEdgeGlowColor
方法)

EdgeEffect正在使用可绘制文件,因此您可以按照中的描述更改可绘制文件,但它将影响您上下文中的所有
EdgeEffect

基本上,它只是介绍和调用这个方法,但是文章中描述了一些陷阱,所以我建议您先阅读它

static void brandGlowEffect(Context context, int brandColor) {
      //glow
      int glowDrawableId = context.getResources().getIdentifier("overscroll_glow", "drawable", "android");
      Drawable androidGlow = context.getResources().getDrawable(glowDrawableId);
      androidGlow.setColorFilter(brandColor, PorterDuff.Mode.SRC_IN);
      //edge
      int edgeDrawableId = context.getResources().getIdentifier("overscroll_edge", "drawable", "android");
      Drawable androidEdge = context.getResources().getDrawable(edgeDrawableId);
      androidEdge.setColorFilter(brandColor, PorterDuff.Mode.SRC_IN);
}

使用以下设置边缘效果辉光颜色。适用于支持EdgeEffect(API 14+)的所有平台版本,否则会自动失败

void themeRecyclerView(Context context, RecyclerView recyclerView) {
    int yourColor = Color.parseColor("#your_color");
    try {
        final Class<?> clazz = RecyclerView.class;
        for (final String name : new String[]{"ensureTopGlow", "ensureBottomGlow", "ensureLeftGlow", "ensureRightGlow"}) {
            Method method = clazz.getDeclaredMethod(name);
            method.setAccessible(true);
            method.invoke(recyclerView);
        }
        for (final String name : new String[]{"mTopGlow", "mBottomGlow", "mRightGlow", "mLeftGlow"}) {
            final Field field = clazz.getDeclaredField(name);
            field.setAccessible(true);
            final Object edge = field.get(recyclerView);
            final Field fEdgeEffect = edge.getClass().getDeclaredField("mEdgeEffect");
            fEdgeEffect.setAccessible(true);
            setEdgeEffectColor((EdgeEffect) fEdgeEffect.get(edge), yourColor);
        }
    } catch (final Exception | NoClassDefFoundError ignored) {
    }
}

void setEdgeEffectColor(EdgeEffect edgeEffect, int color) {
    try {
        if (Build.VERSION.SDK_INT >= 21) {
            edgeEffect.setColor(color);
            return;
        }

        for(String name : new String[]{"mEdge", "mGlow"}){
            final Field field = EdgeEffect.class.getDeclaredField(name);
            field.setAccessible(true);
            final Drawable drawable = (Drawable) field.get(edgeEffect);
            drawable.setColorFilter(color, PorterDuff.Mode.SRC_IN);
            drawable.setCallback(null);
        }
    } catch (final Exception | NoClassDefFoundError ignored) {
    }
}

我写了实用类EdgeChanger,它是我以前的文章@Jared Hummler和@Eugen Pechanec的混合体

此实用程序类使用反射更改对象的边辉光颜色

ScrollView, NestedScrollView, ListView, ViewPager and RecyclerView
并且在使用AppCompat时可与棉花糖、棒棒糖和预棒棒糖设备配合使用,因此您无需使用第三方库(如EdgeEffectOverride)或使用不同的布局

仅当要在onCreate()之后更改边辉光颜色时才使用此选项,否则应使用setTheme和具有不同颜色属性colorPrimary或colorEdgeEffect的不同主题

public class EdgeChanger {

private static final Class<?> CLASS_SCROLL_VIEW = ScrollView.class;
private static Field SCROLL_VIEW_FIELD_EDGE_GLOW_TOP;
private static Field SCROLL_VIEW_FIELD_EDGE_GLOW_BOTTOM;

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

private static final Class<?> CLASS_NESTED_SCROLL_VIEW = NestedScrollView.class;
private static Field NESTED_SCROLL_VIEW_FIELD_EDGE_GLOW_TOP;
private static Field NESTED_SCROLL_VIEW_FIELD_EDGE_GLOW_BOTTOM;
private static Method NESTED_SCROLL_VIEW_METHOD_ENSURE_GLOWS;

private static final Class<?> CLASS_RECYCLER_VIEW = RecyclerView.class;
private static Field RECYCLER_VIEW_FIELD_EDGE_GLOW_TOP;
private static Field RECYCLER_VIEW_FIELD_EDGE_GLOW_BOTTOM;
private static Method RECYCLER_VIEW_METHOD_ENSURE_GLOW_TOP;
private static Method RECYCLER_VIEW_METHOD_ENSURE_GLOW_BOTTOM;

private static final Class<?> CLASS_VIEW_PAGER = ViewPager.class;
private static Field VIEW_PAGER_FIELD_EDGE_GLOW_LEFT;
private static Field VIEW_PAGER_FIELD_EDGE_GLOW_RIGHT;

static {

    Field edgeGlowTop = null, edgeGlowBottom = null;
    Method ensureGlowTop = null, ensureGlowBottom = 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;

    for (Field f : CLASS_NESTED_SCROLL_VIEW.getDeclaredFields()) {
        switch (f.getName()) {
            case "mEdgeGlowTop":
                f.setAccessible(true);
                edgeGlowTop = f;
                break;
            case "mEdgeGlowBottom":
                f.setAccessible(true);
                edgeGlowBottom = f;
                break;
        }
    }
    for (Method m : CLASS_NESTED_SCROLL_VIEW.getDeclaredMethods()) {
        switch (m.getName()) {
            case "ensureGlows":
                m.setAccessible(true);
                ensureGlowTop = m;
                break;
        }
    }
    NESTED_SCROLL_VIEW_FIELD_EDGE_GLOW_TOP = edgeGlowTop;
    NESTED_SCROLL_VIEW_FIELD_EDGE_GLOW_BOTTOM = edgeGlowBottom;
    NESTED_SCROLL_VIEW_METHOD_ENSURE_GLOWS = ensureGlowTop;

    for (Field f : CLASS_RECYCLER_VIEW.getDeclaredFields()) {
        switch (f.getName()) {
            case "mTopGlow":
                f.setAccessible(true);
                edgeGlowTop = f;
                break;
            case "mBottomGlow":
                f.setAccessible(true);
                edgeGlowBottom = f;
                break;
        }
    }
    for (Method m : CLASS_RECYCLER_VIEW.getDeclaredMethods()) {
        switch (m.getName()) {
            case "ensureTopGlow":
                m.setAccessible(true);
                ensureGlowTop = m;
                break;
            case "ensureBottomGlow":
                m.setAccessible(true);
                ensureGlowBottom = m;
                break;
        }
    }
    RECYCLER_VIEW_FIELD_EDGE_GLOW_TOP = edgeGlowTop;
    RECYCLER_VIEW_FIELD_EDGE_GLOW_BOTTOM = edgeGlowBottom;
    RECYCLER_VIEW_METHOD_ENSURE_GLOW_TOP = ensureGlowTop;
    RECYCLER_VIEW_METHOD_ENSURE_GLOW_BOTTOM = ensureGlowBottom;

    for (Field f : CLASS_VIEW_PAGER.getDeclaredFields()) {
        switch (f.getName()) {
            case "mLeftEdge":
                f.setAccessible(true);
                edgeGlowTop = f;
                break;
            case "mRightEdge":
                f.setAccessible(true);
                edgeGlowBottom = f;
                break;
        }
    }
    VIEW_PAGER_FIELD_EDGE_GLOW_LEFT = edgeGlowTop;
    VIEW_PAGER_FIELD_EDGE_GLOW_RIGHT = edgeGlowBottom;

}

public static void setEdgeGlowColor(AbsListView listView, int color) {

    try {
        setEdgeEffectColor(LIST_VIEW_FIELD_EDGE_GLOW_TOP.get(listView), color);
        setEdgeEffectColor(LIST_VIEW_FIELD_EDGE_GLOW_BOTTOM.get(listView), color);
    } catch (Exception e) {
        e.printStackTrace();
    }

}

public static void setEdgeGlowColor(ScrollView scrollView, int color) {

    try {
        setEdgeEffectColor(SCROLL_VIEW_FIELD_EDGE_GLOW_TOP.get(scrollView), color);
        setEdgeEffectColor(SCROLL_VIEW_FIELD_EDGE_GLOW_BOTTOM.get(scrollView), color);
    } catch (Exception e) {
        e.printStackTrace();
    }

}

public static void setEdgeGlowColor(final ViewPager viewPager, final int color) {

    try {
        setEdgeEffectColor(VIEW_PAGER_FIELD_EDGE_GLOW_LEFT.get(viewPager), color);
        setEdgeEffectColor(VIEW_PAGER_FIELD_EDGE_GLOW_RIGHT.get(viewPager), color);
    } catch (final Exception e) {
        e.printStackTrace();
    }

}

public static void setEdgeGlowColor(NestedScrollView scrollView, int color) {

    try {
        NESTED_SCROLL_VIEW_METHOD_ENSURE_GLOWS.invoke(scrollView);
        setEdgeEffectColor(NESTED_SCROLL_VIEW_FIELD_EDGE_GLOW_TOP.get(scrollView), color);
        setEdgeEffectColor(NESTED_SCROLL_VIEW_FIELD_EDGE_GLOW_BOTTOM.get(scrollView), color);
    } catch (final Exception | NoClassDefFoundError e) {
        e.printStackTrace();
    }

}

public static void setEdgeGlowColor(final RecyclerView recyclerView, final int color) {

    try {
        RECYCLER_VIEW_METHOD_ENSURE_GLOW_TOP.invoke(recyclerView);
        RECYCLER_VIEW_METHOD_ENSURE_GLOW_BOTTOM.invoke(recyclerView);
        setEdgeEffectColor(RECYCLER_VIEW_FIELD_EDGE_GLOW_TOP.get(recyclerView), color);
        setEdgeEffectColor(RECYCLER_VIEW_FIELD_EDGE_GLOW_BOTTOM.get(recyclerView), color);
    } catch (final Exception | NoClassDefFoundError e) {
        e.printStackTrace();
    }

}

private static void setEdgeEffectColor(Object object, int color) {

    try {
        EdgeEffect edgeEffect = null;
        if (object instanceof EdgeEffectCompat) {
            final Field fEdgeEffect = object.getClass().getDeclaredField("mEdgeEffect");
            fEdgeEffect.setAccessible(true);
            edgeEffect = (EdgeEffect) fEdgeEffect.get(object);
        } else if (object instanceof EdgeEffect) {
            edgeEffect = (EdgeEffect) object;
        }

        if (Build.VERSION.SDK_INT >= 21) {
            edgeEffect.setColor(color);
        } else {
            for (String name : new String[] {"mEdge", "mGlow"}) {
                final Field field = EdgeEffect.class.getDeclaredField(name);
                field.setAccessible(true);
                final Drawable drawable = (Drawable) field.get(edgeEffect);
                drawable.setColorFilter(color, PorterDuff.Mode.SRC_IN);
                drawable.setCallback(null);
            }
        }
    } catch (final Exception | NoClassDefFoundError e) {
        e.printStackTrace();
    }

}

我建议您使用CardView我在我的回收器视图中使用CardView布局。我关心的是当用户滚动通过recyclerview的上边缘或下边缘时,滚动指示器的颜色。您的解决方案没有回答这个问题,因为它是关于如何在使用appcompat时在预棒棒糖上执行此操作,并且您的解决方案仅适用于棒棒糖。请确保将其包装在参考资料中。NotFoundException try/catch。此资源在棒棒糖中不可用。我想您可能会发现它对边缘阴影使用了
colorPrimary
。我已经尝试了您的实用程序类,它成功了!奇怪的是,我只将其应用于一个回收器视图作为测试,但它适用于所有其他组件,如视图寻呼机、选项卡等。看起来所有这些组件都只使用一个可绘制的overscroll,所以您可以更改该可绘制的颜色。最重要的是,不需要思考(某种程度上)。查看此答案我在最近的支持库中为NestedScrollView编辑了
setEdgeEffectColor
的代码。NestedScrollView现在直接使用
EdgeEffect
而不是
EdgeEffectCompat
,但上面的解决方案可以同时使用这两种方法。
ScrollView, NestedScrollView, ListView, ViewPager and RecyclerView
public class EdgeChanger {

private static final Class<?> CLASS_SCROLL_VIEW = ScrollView.class;
private static Field SCROLL_VIEW_FIELD_EDGE_GLOW_TOP;
private static Field SCROLL_VIEW_FIELD_EDGE_GLOW_BOTTOM;

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

private static final Class<?> CLASS_NESTED_SCROLL_VIEW = NestedScrollView.class;
private static Field NESTED_SCROLL_VIEW_FIELD_EDGE_GLOW_TOP;
private static Field NESTED_SCROLL_VIEW_FIELD_EDGE_GLOW_BOTTOM;
private static Method NESTED_SCROLL_VIEW_METHOD_ENSURE_GLOWS;

private static final Class<?> CLASS_RECYCLER_VIEW = RecyclerView.class;
private static Field RECYCLER_VIEW_FIELD_EDGE_GLOW_TOP;
private static Field RECYCLER_VIEW_FIELD_EDGE_GLOW_BOTTOM;
private static Method RECYCLER_VIEW_METHOD_ENSURE_GLOW_TOP;
private static Method RECYCLER_VIEW_METHOD_ENSURE_GLOW_BOTTOM;

private static final Class<?> CLASS_VIEW_PAGER = ViewPager.class;
private static Field VIEW_PAGER_FIELD_EDGE_GLOW_LEFT;
private static Field VIEW_PAGER_FIELD_EDGE_GLOW_RIGHT;

static {

    Field edgeGlowTop = null, edgeGlowBottom = null;
    Method ensureGlowTop = null, ensureGlowBottom = 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;

    for (Field f : CLASS_NESTED_SCROLL_VIEW.getDeclaredFields()) {
        switch (f.getName()) {
            case "mEdgeGlowTop":
                f.setAccessible(true);
                edgeGlowTop = f;
                break;
            case "mEdgeGlowBottom":
                f.setAccessible(true);
                edgeGlowBottom = f;
                break;
        }
    }
    for (Method m : CLASS_NESTED_SCROLL_VIEW.getDeclaredMethods()) {
        switch (m.getName()) {
            case "ensureGlows":
                m.setAccessible(true);
                ensureGlowTop = m;
                break;
        }
    }
    NESTED_SCROLL_VIEW_FIELD_EDGE_GLOW_TOP = edgeGlowTop;
    NESTED_SCROLL_VIEW_FIELD_EDGE_GLOW_BOTTOM = edgeGlowBottom;
    NESTED_SCROLL_VIEW_METHOD_ENSURE_GLOWS = ensureGlowTop;

    for (Field f : CLASS_RECYCLER_VIEW.getDeclaredFields()) {
        switch (f.getName()) {
            case "mTopGlow":
                f.setAccessible(true);
                edgeGlowTop = f;
                break;
            case "mBottomGlow":
                f.setAccessible(true);
                edgeGlowBottom = f;
                break;
        }
    }
    for (Method m : CLASS_RECYCLER_VIEW.getDeclaredMethods()) {
        switch (m.getName()) {
            case "ensureTopGlow":
                m.setAccessible(true);
                ensureGlowTop = m;
                break;
            case "ensureBottomGlow":
                m.setAccessible(true);
                ensureGlowBottom = m;
                break;
        }
    }
    RECYCLER_VIEW_FIELD_EDGE_GLOW_TOP = edgeGlowTop;
    RECYCLER_VIEW_FIELD_EDGE_GLOW_BOTTOM = edgeGlowBottom;
    RECYCLER_VIEW_METHOD_ENSURE_GLOW_TOP = ensureGlowTop;
    RECYCLER_VIEW_METHOD_ENSURE_GLOW_BOTTOM = ensureGlowBottom;

    for (Field f : CLASS_VIEW_PAGER.getDeclaredFields()) {
        switch (f.getName()) {
            case "mLeftEdge":
                f.setAccessible(true);
                edgeGlowTop = f;
                break;
            case "mRightEdge":
                f.setAccessible(true);
                edgeGlowBottom = f;
                break;
        }
    }
    VIEW_PAGER_FIELD_EDGE_GLOW_LEFT = edgeGlowTop;
    VIEW_PAGER_FIELD_EDGE_GLOW_RIGHT = edgeGlowBottom;

}

public static void setEdgeGlowColor(AbsListView listView, int color) {

    try {
        setEdgeEffectColor(LIST_VIEW_FIELD_EDGE_GLOW_TOP.get(listView), color);
        setEdgeEffectColor(LIST_VIEW_FIELD_EDGE_GLOW_BOTTOM.get(listView), color);
    } catch (Exception e) {
        e.printStackTrace();
    }

}

public static void setEdgeGlowColor(ScrollView scrollView, int color) {

    try {
        setEdgeEffectColor(SCROLL_VIEW_FIELD_EDGE_GLOW_TOP.get(scrollView), color);
        setEdgeEffectColor(SCROLL_VIEW_FIELD_EDGE_GLOW_BOTTOM.get(scrollView), color);
    } catch (Exception e) {
        e.printStackTrace();
    }

}

public static void setEdgeGlowColor(final ViewPager viewPager, final int color) {

    try {
        setEdgeEffectColor(VIEW_PAGER_FIELD_EDGE_GLOW_LEFT.get(viewPager), color);
        setEdgeEffectColor(VIEW_PAGER_FIELD_EDGE_GLOW_RIGHT.get(viewPager), color);
    } catch (final Exception e) {
        e.printStackTrace();
    }

}

public static void setEdgeGlowColor(NestedScrollView scrollView, int color) {

    try {
        NESTED_SCROLL_VIEW_METHOD_ENSURE_GLOWS.invoke(scrollView);
        setEdgeEffectColor(NESTED_SCROLL_VIEW_FIELD_EDGE_GLOW_TOP.get(scrollView), color);
        setEdgeEffectColor(NESTED_SCROLL_VIEW_FIELD_EDGE_GLOW_BOTTOM.get(scrollView), color);
    } catch (final Exception | NoClassDefFoundError e) {
        e.printStackTrace();
    }

}

public static void setEdgeGlowColor(final RecyclerView recyclerView, final int color) {

    try {
        RECYCLER_VIEW_METHOD_ENSURE_GLOW_TOP.invoke(recyclerView);
        RECYCLER_VIEW_METHOD_ENSURE_GLOW_BOTTOM.invoke(recyclerView);
        setEdgeEffectColor(RECYCLER_VIEW_FIELD_EDGE_GLOW_TOP.get(recyclerView), color);
        setEdgeEffectColor(RECYCLER_VIEW_FIELD_EDGE_GLOW_BOTTOM.get(recyclerView), color);
    } catch (final Exception | NoClassDefFoundError e) {
        e.printStackTrace();
    }

}

private static void setEdgeEffectColor(Object object, int color) {

    try {
        EdgeEffect edgeEffect = null;
        if (object instanceof EdgeEffectCompat) {
            final Field fEdgeEffect = object.getClass().getDeclaredField("mEdgeEffect");
            fEdgeEffect.setAccessible(true);
            edgeEffect = (EdgeEffect) fEdgeEffect.get(object);
        } else if (object instanceof EdgeEffect) {
            edgeEffect = (EdgeEffect) object;
        }

        if (Build.VERSION.SDK_INT >= 21) {
            edgeEffect.setColor(color);
        } else {
            for (String name : new String[] {"mEdge", "mGlow"}) {
                final Field field = EdgeEffect.class.getDeclaredField(name);
                field.setAccessible(true);
                final Drawable drawable = (Drawable) field.get(edgeEffect);
                drawable.setColorFilter(color, PorterDuff.Mode.SRC_IN);
                drawable.setCallback(null);
            }
        }
    } catch (final Exception | NoClassDefFoundError e) {
        e.printStackTrace();
    }

}
-keepnames class android.widget.ScrollView { *; }
-keepnames class android.widget.AbsListView { *; }
-keepnames class android.support.v4.widget.NestedScrollView { *; }
-keepnames class android.support.v7.widget.RecyclerView { *; }
-keepnames class android.support.v4.view.ViewPager { *; }
-keepnames class android.widget.EdgeEffect { *; }
-keepnames class android.support.v4.widget.EdgeEffectCompat { *; }