在 RippleDrawable 内改变 StateListDrawable 的 TintList

3

范围

RippleDrawable中有selector作为内部的item。它可用。

<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
    android:color="@color/pink_highlight">        
    <item
        android:id="@android:id/mask"
        android:drawable="@color/pink_highlight" />
    <item 
        android:drawable="@drawable/bg_selectable_item" />
</ripple>

+

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@color/pink_highlight_focus" android:state_focused="true" />
    <item android:drawable="@color/pink_highlight_press" android:state_pressed="true" />
    <item android:drawable="@color/pink_highlight_press" android:state_activated="true" />
    <item android:drawable="@color/pink_highlight_press" android:state_checked="true" />
    <item android:drawable="@android:color/transparent" />
</selector>

问题

DrawableCompat.setTintList 无法更改选择器的默认状态颜色。

RippleDrawable bg = (RippleDrawable) 
ResourcesCompat.getDrawable(context.getResources(), R.drawable.bg_navigation_item, null);
StateListDrawable bgWrap = (StateListDrawable) DrawableCompat.wrap(bg.getDrawable(1));
DrawableCompat.setTintList(bgWrap, new ColorStateList(new int[][]{new int[]{}}, new int[]{Color.WHITE}));
//
someView.setBackground(bg);

它不会改变默认选择器的状态,其他一切都没问题。

解决方案

问题出现在以下原因: - 对染色应该如何工作的误解; - 最好完全加载ColorStateList

<ripple xmlns:android="http://schemas.android.com/apk/res/android"
    android:color="@color/pink_highlight">
    <item>
        <shape
            android:shape="rectangle"
            android:tint="@color/selectable_transparent_item" />
    </item>
    <item
        android:id="@android:id/mask"
        android:drawable="@color/pink_highlight" />
</ripple>

+

LayerDrawable bg = (LayerDrawable) ResourcesCompat.getDrawable(context.getResources(), R.drawable.bg_selectable_item, null);
Drawable bgWrap = DrawableCompat.wrap(bg.getDrawable(0));
DrawableCompat.setTintList(bgWrap, context.getResources().getColorStateList(R.color.selectable_white_item));
someView.setBackground(bg);
2个回答

2

你尝试过 someView.setBackground(bgWrap) 吗?你已经给 bgWrap 设置了色调,但也需要将其设置为背景,而不是旧背景。

编辑:你确定 setTintList 有问题吗?对于我所有 API >= 15 的 AppCompat 都可以使用以下代码:

public static void tintWidget(View view, ColorStateList colorStateList) {
    final Drawable originalDrawable = view.getBackground();
    final Drawable wrappedDrawable = DrawableCompat.wrap(originalDrawable);
    DrawableCompat.setTintList(wrappedDrawable, colorStateList);
    view.setBackground(wrappedDrawable);
}

是的,尝试设置bgWrap。无论如何,这没有意义,因为“wrap”不会创建新实例。 - Oleksii Malovanyi
对于API>=21,“包装的Drawable和原始的Drawable-是相同的对象。”这只是真实的,抱歉。所以基本上是的,必须使用包装器drawable。无论如何,如果我为“<selector>”填充器drawable设置色调,在任何api上都不起作用:( - Oleksii Malovanyi
你使用哪个API?也许你和我有类似的问题 - https://dev59.com/7Izda4cB1Zd3GeqPm3nC - Damian Kozlak
另外,我发现对于透明的可绘制对象,如下所示的着色不会产生任何影响:<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle"> <solid android:color="@android:color/transparent" /> </shape> - Oleksii Malovanyi

1

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