使用编程方式设置android.R.attr.listChoiceIndicatorMultiple时出现android.content.res.Resources$NotFoundException异常

12

我正在尝试编程方式设置ListView中的CheckedTextView项目上的"android:checkMark"属性。运行我的应用程序时,我收到以下异常:

android.content.res.Resources$NotFoundException: Resource ID #0x101021a

资源ID为# 0x101021a对应于android.R.attr.listChoiceIndicatorMultiple,这恰好是我传递给我的CheckedTextView的值:

mCheckedTextView.setCheckMarkDrawable(android.R.attr.listChoiceIndicatorMultiple)

这不是从Java中实现的方法吗?我尝试过(并成功地)从XML布局中触发所需行为:

<CheckedTextView
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:checkMark="?android:attr/listChoiceIndicatorMultiple"
    android:id="@android:id/text1" />

问题在于我不知道在编译时它应该是什么。

android:checkMark="?android:attr/listChoiceIndicatorMultiple"
或者
android:checkMark="?android:attr/listChoiceIndicatorSingle"
因此,我需要在运行时设置这些值。

谢谢!那帮了我很多,解决了我今天遇到的一个问题。 - Chris
2个回答

27

我猜测在编程中设置一个属性引用而不是Drawable引用是问题所在。

在这种情况下,android.R.attr.listChoiceIndicatorMultiple 对应于 android.R.drawable.btn_check,因此您可以尝试设置它。


或者,如果您可以获取属性,您可以在TypedArray上调用getDrawable()以动态获取Drawable值。

编辑:
由于listChoiceIndicatorMultiple的值取决于当前主题,因此您需要询问当前主题以解析引用:

int[] attrs = { android.R.attr.listChoiceIndicatorMultiple };
TypedArray ta = getContext().getTheme().obtainStyledAttributes(attrs);
Drawable indicator = ta.getDrawable(0);
view.setCheckMarkDrawable(indicator);
ta.recycle();

请确保缓存可绘制对象,而不是为您的ListView中的每个项目执行此操作。
那只是一个非常基本的例子,但它适用于默认主题。如果您有自定义主题,则不确定需要做什么才能完全解决attrs。

1
这是一个非常好的答案(因为我已经走过这条路了:-),但是,似乎没有“android.R.drawable.btn_check”可绘制。如果我浏览文件系统,我确实找到它(它在“[path_to_android_SDK]/platforms/android-9/data/res/drawable”文件夹中,它是一个XML文件),但是当我相应地编写我的代码时,我得到编译错误,抱怨“btn_check不能被解决或不是一个有效的字段”。 - dbm
另一个建议(关于“getDrawable()”)对我来说是新的。虽然我以前没有执行过这样的操作,但我需要做一些“功课”:-) - dbm
啊是的,你说得对。我已经添加了一个非常基本的代码示例,对我来说它可以工作。 - Christopher Orr
谢谢!你的代码运行得非常好!对于那些设备上有自定义主题而且无法从主题中获取“...Multiple”和“...Single”指示器的情况,我很可能会实施一个备用解决方案。再次感谢你提供高质量的帮助(如果可以的话,我会一遍又一遍地点赞这个答案 :-) - dbm
1
关于@Christopher的缓存建议,我想简单评论一下:我还没有找到一种安全的方法来缓存可绘制对象。如果我这样做缓存,似乎所有的列表项都会获得与我点击的项相同的状态。是的,我已经调用了“indicator.mutate()”。目前,我依靠我的适配器,并确保在创建/重用列表项时正确地重用“convertView”,以减少不必要的可绘制对象获取。 - dbm

1
如果使用appcompat库,简单的替代方法如下:
setCheckMarkDrawable(android.support.v7.appcompat.R.drawable.abc_btn_check_material);

或者:

setCheckMarkDrawable(android.support.v7.appcompat.R.drawable.abc_btn_radio_material);  

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