Bil*_*yan 3 android colors android-appcompat android-recyclerview
我正在寻找一种方法来在使用appcompat材料主题时在RecyclerView pre-lollip中设置过度滚动指示器的颜色.
在内部,它使用EdgeEffect设置为内部可设置属性,除非你已经在棒棒糖(讽刺),否则无法设置.
使用反射不起作用,只能在棒棒糖上设置EdgeEffect的颜色.
在我的API21应用程序上它从主要材料颜色绘制,在Kitkat它是白色的,之前它是全息蓝色,我想要统一我的设计.
关于它是如何完成的任何想法?
使用以下设置边缘效果发光颜色.适用于支持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) {
}
}
Run Code Online (Sandbox Code Playgroud)
感谢@Lukas Novak提供了大部分代码.
正如Lukas所说,这些方法必须从onScrollListener
你的内部调用RecyclerView
:
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));
}
});
Run Code Online (Sandbox Code Playgroud)
谢谢@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) {}
}
}
Run Code Online (Sandbox Code Playgroud)
不像像ListView的滚动型或其他组件的解决方案,在这里,你必须调用包私有方法ensureTopGlow
,ensureBottomGlow
等等,并调用setEdgeEffectColor(RecyclerView recycler, int color)
上面onScrollStateChanged
的方法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));
}
});
Run Code Online (Sandbox Code Playgroud)
默认情况下,Android通过ensure*Glow
滚动开始调用方法.在这些方法中,初始化的new EdgeEffect
具有默认颜色,但仅在尚未初始化时.要防止出现这种情况,您必须调用ensure*Glow
方法,然后更改边缘的颜色,以便后续初始化EdgeEffect
将被忽略(如setEdgeGlowColor
上面的方法)
归档时间: |
|
查看次数: |
4491 次 |
最近记录: |