【问题标题】:How to retrieve drawable from attributes reference如何从属性引用中检索可绘制对象
【发布时间】:2013-03-11 13:17:24
【问题描述】:

我在我的应用程序中定义了主题和样式。图标(可绘制)使用样式文件中的引用定义为

<attr name="myicon" format="reference" />

样式为

<style name="CustomTheme" parent="android:Theme.Holo">
    <item name="myicon">@drawable/ajout_produit_light</item>

我需要以编程方式检索可绘制对象以在对话框片段中使用良好的图像。 如果我喜欢

mydialog.setIcon(R.style.myicon);

我得到一个 id 等于 0,所以没有图像

我尝试使用类似的东西

int[] attrs = new int[] { R.drawable.myicon};
TypedArray ta = getActivity().getApplication().getTheme().obtainStyledAttributes(attrs);
Drawable mydrawable = ta.getDrawable(0);
mTxtTitre.setCompoundDrawables(mydrawable, null, null, null);

我尝试了类似的不同方法,但结果始终为 0 或 null :-/

我该怎么做?

【问题讨论】:

    标签: android user-interface


    【解决方案1】:

    我找到了解决方案 Access resource defined in theme and attrs.xml android

    TypedArray a = getTheme().obtainStyledAttributes(R.style.AppTheme, new int[] {R.attr.homeIcon});     
    int attributeResourceId = a.getResourceId(0, 0);
    Drawable drawable = getResources().getDrawable(attributeResourceId);
    

    【讨论】:

    • 别忘了调用a.recycle
    • 对于其他想知道的人:a.recycle() 将发出已分配的内存不再使用的信号,与a 关联的数据可以立即返回到内存池,而不是等待垃圾收藏。如回答here
    【解决方案2】:

    Kotlin 解决方案:

    val typedValue = TypedValue()
    context.theme.resolveAttribute(R.attr.yourAttr, typedValue, true)
    val imageResId = typedValue.resourceId
    val drawable = ContextCompat.getDrawable(context, imageResId) ?: throw IllegalArgumentException("Cannot load drawable $imageResId")
    

    【讨论】:

    • 如何在Fragment 中使用它?
    • 单线解决方案:val drawable = ContextCompat.getDrawable(context, TypedValue().apply { context.theme.resolveAttribute(R.attr.myIcon, this, true) }.resourceId)
    • @PeterKeefe .apply 使代码的可读性降低,应谨慎使用。 Kotlin 不是为了简洁,而是为了可读性。
    【解决方案3】:

    假设您的context(活动)是您想要的主题,您可以在主题上使用resolveAttribute

    TypedValue themedValue = new TypedValue();
    this.getTheme().resolveAttribute(R.attr.your_attribute, themedValue, true);
    myView.setBackgroundResource(themedValue.resourceId);
    

    所以在你的情况下,它看起来像这样:

    TypedValue themedValue = new TypedValue();
    this.getTheme().resolveAttribute(R.attr.myicon, themedValue, true);
    Drawable mydrawable = AppCompatResources.getDrawable(this, themedValue.resourceId);
    mTxtTitre.setCompoundDrawables(mydrawable, null, null, null);
    

    在示例中,this 将是您的活动。如果您不在活动中,请获取有效的context

    【讨论】:

      【解决方案4】:

      似乎您正在尝试使用资源设置 myDialog 的图标并尝试通过 R.style 访问它,但您的其他代码段让我相信您拥有位于 R.drawable 中的资源

      考虑到这一点,您应该能够使用 myDialog.setIcon(R.drawable.myicon); 获得您想要的效果

      【讨论】: