使用appcompat时设置RecyclerView边缘发光预棒棒糖 [英] Set RecyclerView edge glow pre-lollipop when using appcompat

查看:636
本文介绍了使用appcompat时设置RecyclerView边缘发光预棒棒糖的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在寻找一种方法,在使用appcompat材质主题时,在RecyclerView预先lollip中设置过度滚动指示器的颜色。

I'm looking for a way to style the color of the over scroll indicator in a RecyclerView pre-lollip when using the appcompat material theme.

在内部,它使用一个EdgeEffect设置为一个内部styleable属性,除非你已经在lollipop(讽刺),否则不能设置。

Internally it uses an EdgeEffect set to a internal styleable attribute that can't be set unless your already on lollipop (ironic).

使用反射不起作用,设置EdgeEffect的颜色只能在棒棒糖上使用。

Using reflection doesn't work, setting the color of the EdgeEffect is only possible on lollipop too.

在我的API21应用程序中,材料颜色,在Kitkat它是白色的,之前它是全蓝色,我想统一我的设计。

On my API21 app it draws from the primary material color, on Kitkat it is white, before that it is holo blue and I'm looking to unify my design.

有关如何做的任何想法? >

Any ideas on how its done?

推荐答案

感谢@TomášLinhart指出它。以下解决方案仅用于在API> 21中更改边缘颜色。它可以与AppCompat一起使用,但改变颜色的效果只会在Lollipop及以上版本中显示。

Thanks @Tomáš Linhart for pointing it out. Solution below is for changing edge color only in API >21. It can be used with AppCompat, but effect of changing color will be visible only in Lollipop and above.

发现了一种使用反射设置颜色的方法。例如这里是改变顶部和底部边缘颜色的代码:

I've found a way to set color with use of reflection. For example here is code for change top and bottom edge color:

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

不像其他组件像ListView或ScrollView的解决方案,这里你必须调用package-private方法 ensureTopGlow ensureBottomGlow 等,并在中调用 setEdgeEffectColor(RecyclerView recycler,int color)> onScrollStateChanged c $ c> RecyclerView.OnScrollListener 。

Unlike solutions with other components like ListView or ScrollView, here you must call package-private methods ensureTopGlow, ensureBottomGlow, etc. and call setEdgeEffectColor(RecyclerView recycler, int color) above in onScrollStateChanged method of RecyclerView.OnScrollListener.

例如:

recyclerView.setOnScrollListener(new RecyclerView.OnScrollListener() {
      @Override
      public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
           super.onScrollStateChanged(recyclerView, newState);
           EdgeChanger.setEdgeGlowColor(recycler, getResources().getColor(R.color.your_color));
      }
});

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

By default, Android calls ensure*Glow methods with start of scrolling. In these methods there is initialized new EdgeEffect with default color, but only if it is not initialized yet. To prevent this behaviour you must call ensure*Glow methods and then change the color of edge, so subsequent initializing of EdgeEffect will be ignored (as in setEdgeGlowColor method above)

这篇关于使用appcompat时设置RecyclerView边缘发光预棒棒糖的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆