getColorStateList已被弃用

32

我有一个问题。我刚刚从SDK 22更新到23,之前版本的“getColorStateList()”已经被弃用。

我的代码是这样的

seekBar.setProgressTintList(getResources().getColorStateList(R.color.bar_green));
valorslide.setTextColor(getResources().getColorStateList(R.color.text_green));

旧的“getColorStateList”已经过时

getColorStateList(int id)

还有一个新的

getColorStateList(int id, Resources.Theme theme)

我如何使用主题变量?谢谢。

5个回答

52
虽然anthonycr的答案可行,但只需写得更简洁一些即可。
ContextCompat.getColorStateList(context, R.color.haml_indigo_blue);

1
这很酷!有没有类似于seekbar方法的东西?我在seekBar.setProgressTintList()上遇到了兼容性问题(已通过Anthony的答案解决)。(我并不真正需要它,只是为了了解) - fkchaud
1
如何从自定义颜色而不是资源颜色创建ColorStateList - Amir Hossein Ghasemi

43

Theme对象是用于样式化颜色状态列表的主题。如果您没有使用单独资源的特殊主题,则可以传递 null 或当前主题,如下所示:

TextView valorslide; // initialize
SeekBar seekBar; // initialize
Context context = this;
Resources resources = context.getResources();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M){
    seekBar.setProgressTintList(resources.getColorStateList(R.color.bar_green, context.getTheme()));
    valorslide.setTextColor(resources.getColorStateList(R.color.text_green, context.getTheme()));
} else {
    seekBar.setProgressTintList(resources.getColorStateList(R.color.bar_green));
    valorslide.setTextColor(resources.getColorStateList(R.color.text_green));
}

如果你不关心主题,可以将其传递为 null:

getColorStateList(R.color.text_green, null)

请查看文档以获取更多解释。 注意,只有在API 23(Android Marshmallow)及以上版本中才需要使用新版本。


2
或者,您可以继续使用已弃用的版本,因为除非您的minSdkVersion为23或更高版本,否则在旧设备上仍需要使用已弃用的版本。 - CommonsWare
@CommonsWare 我应该指出这一点,已经更新以反映这些信息。谢谢。 - anthonycr
我之前尝试过null,但它崩溃了。现在我尝试了两种方法(null和getTheme()),但仍然崩溃。14635-14635/golden.imper.csystemhelper E/MessageQueue-JNI﹕ java.lang.NoSuchMethodError: No virtual method getColorStateList(ILandroid/content/res/Resources$Theme;)Landroid/content/res/Co‌​lorStateList; in class Landroid/content/res/Resources; or its super classes (declaration of 'android.content.res.Resources' appears in /system/framework/framework.jar) - fkchaud
1
@fkchaud 在使用下面 API 23 的方法之前,你需要检查 API 版本,因为如果你尝试在 Android M 之前的版本上使用更新的方法,它会抛出错误。另外,请确保你正在编译 API 23。 - anthonycr
@anthonycr,就是这样,我在API 21中进行测试,所以它崩溃了。现在它可以工作了。谢谢你们两个! - fkchaud
ContextCompat.getColor(context, R.color.my_color) - saravanan

3

如果你使用它们,将失去所有样式。对于旧版本,你应该动态创建ColorStateList,这是保持样式的主要机会。

这适用于所有版本。

layout.setColorStateList(buildColorStateList(this,
   R.attr.colorPrimaryDark, R.attr.colorPrimary)
);


public ColorStateList buildColorStateList(Context context, @AttrRes int pressedColorAttr, @AttrRes int defaultColorAttr){
    int pressedColor = getColorByAttr(context, pressedColorAttr);
    int defaultColor = getColorByAttr(context, defaultColorAttr);

    return new ColorStateList(
            new int[][]{
                    new int[]{android.R.attr.state_pressed},
                    new int[]{} // this should be empty to make default color as we want
            }, new int[]{
            pressedColor,
            defaultColor
    }
    );
}

@ColorInt
public static int getColorByAttr(Context context, @AttrRes int attrColor){

    if (context == null || context.getTheme() == null)
        return -1;

    Resources.Theme theme = context.getTheme();
    TypedValue typedValue = new TypedValue();

    theme.resolveAttribute(attrColor, typedValue,true);

    return typedValue.data;
} 

2

还有一种较新的方法:

AppCompatResources.getColorStateList(context, R.color.bar_green)

这个类会保留一个对颜色状态列表缓存的弱引用。如果它无法加载其中任何一个,它将回退到使用ContextCompat.getColorStateList


0

你需要使用ContextCompat.getColor(),它是Support V4库的一部分(因此它适用于所有以前的API)。

ContextCompat.getColor(context, R.color.my_color)

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