调用setCompoundDrawables()方法不能显示复合图标

373

我调用了setCompoundDrawables方法后,合成图标没有显示。

Drawable myDrawable = getResources().getDrawable(R.drawable.btn);
btn.setCompoundDrawables(myDrawable, null, null, null);

有什么想法吗?


12
正如下面的答案所述,需要调用名为“(…)WithIntrinsicBounds”的方法变体。顺便提一句,在调用此方法后必须设置 Compound Drawable 的 padding 才能产生效果。 - Dr1Ku
8
这篇文档的意思是:这些Drawable对象必须先调用过 setBounds(Rect)方法。 - user1521536
嗨,hunterp,我在咖啡店(Angel)遇见了你,现在知道你知道什么是Android Drawables了(也许你在使用很多时遇到了内存不足的错误),我可以告诉你一些我合作过的项目如何处理这个问题,去看看https://github.com/JakeWharton/DiskLruCache(我协助使其更加适合Android),它被Picasso(https://github.com/square/picasso)所使用。 - Gubatron
1
@Dr1Ku 实际上我以前就有它,而且它仍然有效。 - Sotti
请查看此链接 https://dev59.com/dm445IYBdhLWcg3wg6tm#71966649 - Mori
11个回答

706

9
非常感谢,这对我很有效。我可以知道这两者之间的区别吗? - Arundas K V
1
@user1324936,“relative”版本需要API 17,其他版本可以在之前的版本中使用。 - milosmns
12
setCompoundDrawablesWithIntrinsicBounds 方法被添加于 API Level 3 - Greg Ennis
我正在使用setCompoundDrawableRelativeWithIntrinsicBounds <- 这个函数是在API 17中添加的。要注意智能感知提示。 - Neon Warge
它正在工作,谢谢。它们之间有什么区别? - Punithapriya
1
SetcCompoundDrawable文档:设置要出现在文本左侧、上方、右侧和下方的可绘制对象(如果有)。 如果您不想在那里放置Drawable,请使用null。 这些Drawable必须已经调用setBounds(Rect)。 setBounds()不会在您的可绘制对象上调用。 - Mahendra Chhimwal

76

使用此方法(我已经测试过)。它效果很好。

Drawable image = context.getResources().getDrawable( R.drawable.ic_action );
int h = image.getIntrinsicHeight(); 
int w = image.getIntrinsicWidth();   
image.setBounds( 0, 0, w, h );
button.setCompoundDrawables( image, null, null, null );

1
这在针对低于17的API时非常有用,因为EditText#setCompoundDrawablesWithIntrinsicBounds至少需要API 17。 - Krøllebølle
6
你能提供这个信息的来源吗?我看到的所有文档都表明这个功能从 API 1 就已经存在了。参考链接为:https://developer.android.com/reference/android/widget/TextView.html - kurifu

52

图片显示为空白,因为它没有指定边界。您可以使用setCompoundDrawables()方法,但在此之前,您需要使用Drawable.setBounds()方法指定图片的边界。


1
最佳答案是因为您实际上提供了setBounds的重要性原因。 - Andy
@Andy 没错,讨厌那些只复制粘贴一行代码而没有任何解释的得到800票的顶级答案。 - Big_Chair

48

示例设置到顶部:

view.setCompoundDrawablesWithIntrinsicBounds(
    null,
    getResources().getDrawable(R.drawable.some_img),
    null,
    null
);

参数顺序:(左,上,右,下)


1
这应该是被接受的答案,在我的情况下使用按钮。它按预期工作!!!它还具有向后兼容性。 - mochadwi

24

再简单一点:

Drawable image = context.getResources().getDrawable(R.drawable.ic_action );
image.setBounds( 0, 0, image.getIntrinsicWidth(), image.getIntrinsicHeight() );
button.setCompoundDrawables( image, null, null, null );

20

由于您没有指定范围,因此图像未显示,因此您有两个选项。

第一种方法

使用setCompoundDrawablesWithIntrinsicBounds方法,如下所示:

Drawable myDrawable = getResources().getDrawable(R.drawable.btn);
btn. setCompoundDrawablesWithIntrinsicBounds(myDrawable, null, null, null);

第二种方法

在应用到TextView之前,可以对Drawable应用边界,如下所示

Drawable myDrawable = getResources().getDrawable(R.drawable.btn);
myDrawable.setBounds( 0, 0, myDrawable.getIntrinsicWidth(), myDrawable.getIntrinsicHeight());
btn.setCompoundDrawables(myDrawable, null, null, null);

就这样了。


很好,你实际上包含了示例和预 API 17 实现,这更直接地解决了 setCompoundDrawables 方法。 - Androidcoder

11

它在API 22中已被弃用。

这段代码对我很有用:

Drawable drawable = ResourcesCompat.getDrawable(getResources(),R.drawable.wen, null);
drawable.setBounds(0, 0, drawable.getMinimumWidth(),
drawable.getMinimumHeight());
tv.setCompoundDrawables(drawable, null, null, null);

4

在Kotlin中:

1)设置drawable

val drawable = ContextCompat.getDrawable(context!!,R.drawable.ic_image)?.apply {
    setBounds(0, 0, intrinsicWidth, intrinsicHeight)
}

或者

val drawable = ResourcesCompat.getDrawable(resources, R.drawable.ic_image, null)?.apply {
    setBounds(0, 0, minimumWidth, minimumHeight)
}

2)设置TextView

textView.setCompoundDrawablesWithIntrinsicBounds(drawable, null, null, null)

或者

button.setCompoundDrawables(null, drawable, null, null)

对于TextView,setCompoundDrawablesWithIntrinsicBounds会起作用。 - Akash Bisariya

3

2
为什么?是为了移除一个可绘制对象吗? - CoolMind

2

Kotlin示例:

    val myView = layoutInflater.inflate(R.layout.my_view, null) as TextView
    myView.setCompoundDrawablesWithIntrinsicBounds(0, myDrawable, 0, 0)

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