为何ImageView.setImageDrawable无法显示ShapeDrawable?
为什么ShapeDrawable用setImageDrawable不显示,setBackground却正常?
这是Android开发里挺常见的小坑,我来给你掰扯清楚原因和解决办法:
核心区别:背景层 vs 内容层
setBackground() 和 setImageDrawable() 完全是两个不同的绘制逻辑:
setBackground():把Drawable当成视图的背景,它会直接填充整个ImageView的布局边界(就是你xml里设的100dp×200dp),不管Drawable自己的尺寸多大,都会被拉伸/缩放到匹配视图大小,根本不需要Drawable有“内在尺寸”的概念。setImageDrawable():把Drawable作为ImageView的内容主体,它的显示逻辑完全依赖ImageView的scaleType(默认是FIT_CENTER),而且关键是:ImageView需要知道这个Drawable的“内在宽高”(intrinsicWidth/intrinsicHeight),不然会把它当成尺寸为0的Drawable,自然就看不到了。
你的代码问题出在哪?
你创建的ShapeDrawable默认是没有内在宽高的,而且你手动设置的bounds(0,0,300,250)是像素值,但ImageView的布局尺寸是100dp×200dp(转换成像素的话,比如3倍屏是300px×600px)。当你用setImageDrawable()时:
ImageView发现这个Drawable没有内在尺寸,就不知道该怎么缩放它,直接判定为“无内容”,所以就不显示了。而setBackground()根本不管这些,直接铺满整个视图,所以能正常显示。
解决办法
办法1:给ShapeDrawable设置内在尺寸(最推荐)
直接告诉ImageView这个Drawable的默认大小,它就会按照scaleType来处理显示了:
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ShapeDrawable drawable = new ShapeDrawable(new OvalShape()); drawable.getPaint().setColor(0xff74AC23); // 设置Drawable的内在宽高,让ImageView知道它的默认尺寸 drawable.setIntrinsicWidth(300); drawable.setIntrinsicHeight(250); ImageView iv = findViewById(R.id.myImageView); iv.setImageDrawable(drawable); // 现在就能正常显示了 }
办法2:适配ImageView的实际尺寸设置bounds
等ImageView完成布局后,获取它的实际宽高,再给Drawable设置对应的bounds:
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ImageView iv = findViewById(R.id.myImageView); // 用post确保视图已经完成布局,能拿到正确的宽高 iv.post(() -> { int width = iv.getWidth(); int height = iv.getHeight(); ShapeDrawable drawable = new ShapeDrawable(new OvalShape()); drawable.getPaint().setColor(0xff74AC23); drawable.setBounds(0, 0, width, height); iv.setImageDrawable(drawable); }); }
办法3:调整ImageView的scaleType
如果你的Drawable尺寸和ImageView布局尺寸匹配,也可以把scaleType改成CENTER或者CENTER_CROP之类的,但前提是Drawable的bounds要在ImageView的范围内,不过还是办法1最省心。
内容的提问来源于stack exchange,提问作者tronman
相关产品推荐
相关产品推荐

