setBackground与setBackgroundDrawable的区别(Android)

259
我想设置一个视图的背景可绘制。根据我看到的,有两种方法:setBackground和setBackgroundDrawable。
当我使用setBackground时,它说它已经在API级别16中添加,但我的项目的最小SDK版本为7。我认为它在低于16的任何设备上都不起作用,我是对的吗?但是当我使用setBackgroundDrawable时,它说已被弃用。
我应该使用什么?

使用:image.setImageResource(R.drawable.icon_dot1); - Brave
12个回答

405

虽然它已经被弃用,但它仍然可以正常工作,所以你可以直接使用它。但是如果你想要完全正确,为了完整性考虑......你可以像以下这样做:

int sdk = android.os.Build.VERSION.SDK_INT;
if(sdk < android.os.Build.VERSION_CODES.JELLY_BEAN) {
    setBackgroundDrawable();
} else {
    setBackground();
}

为了让这个工作起来,您需要将buildTarget api 16设置为最低构建版本为7或类似版本。


4
它仍然抱怨setBackgroundDrawable被弃用了。我真的需要压制警告,只因为谷歌想改变方法名吗? - Charlie-Blake
2
@santirivera92 是的,你可以选择创建两个项目,一个针对出现问题之前的版本,另一个针对之后的版本。这听起来是一个简单的选择吗?(实际上有时候确实是这样,因为ICS中有很多修复措施) - Warpzit
4
我将android:minSdkVersion="7" android:targetSdkVersion="17"设置为了我的Android应用程序,但是使用setBackground()时出现错误:需要API级别16的函数调用(当前最低级别为7) - Jonny
20
这段代码导致我的编译失败。我把有问题的代码放进了一个新的函数里,然后只为那个函数禁用了代码检查,方法如下:@TargetApi(Build.VERSION_CODES.JELLY_BEAN) @SuppressWarnings("deprecation") private static void setBg(RelativeLayout layout, BitmapDrawable TileMe) { if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.JELLY_BEAN) { layout.setBackgroundDrawable(TileMe); } else { layout.setBackground(TileMe); } } - Jonny
2
@Snicolas 是的,IDE或Android应该能够为我们执行这种逻辑。 - Warpzit
显示剩余10条评论

111
您可以使用 API level 1 中的 setBackgroundResource() 替代。

80
只有当你拥有一个资源 ID 而不是自己创建的自定义 drawable 类时,才能这样做! - Zordid
你有一个drawable的引用,但是没有方法可以检索它的ID吗? - Poutrathor
2
setBackgroundResource()并不是setBackgroundDrawable()或setBackground()的替代品。它们完全不相关,第一个用于添加资源drawable,而其他两个用于添加自定义drawable。 - MBH
如果我需要重复设置背景,比如在ListView中怎么办?setBackgroundResource(int)接受资源ID,因此每次都必须膨胀视图才能设置背景。我不想要这样的行为,假设我已经膨胀了Drawable。我有什么遗漏吗? - azizbekian
如果我只有drawable怎么办? - MBH

55

目前似乎这两个函数没有区别,如源代码所示(感谢这篇文章):

public void setBackground(Drawable background) {
    //noinspection deprecation
    setBackgroundDrawable(background);
}

@Deprecated
public void setBackgroundDrawable(Drawable background) { ... }

所以这只是一个命名决策,类似于 fill-parent vs match-parent 的决策。


5
好的,谢谢。有点傻,只是因为函数重命名而生成一个警告。 - Someone Somewhere
1
@M.kazemAkhgary 这不是他们第一次废弃某些东西只为了更改名称。他们曾经将“fill_parent”更改为“match_parent”以用于布局参数值。两者完全相同,指向相同的值。 - android developer

19

我知道这是一个老问题,但我遇到了类似的情况,我的解决方案是

button.setBackgroundResource( R.drawable.ic_button );
Drawable d = button.getBackground();

然后你可以处理 "Drawable" ,应用颜色过滤器等操作。


7
只有当原始图像来自资源时才有效。 - Matt Huggins
这甚至没有回答楼主的问题。 - Petro

13
使用 ViewCompat.setBackground(view, background);

12

你可以使用setBackgroundResource()代替,例如relativeLayout.setBackgroundResource(R.drawable.back);

这个方法对我有效。


7

使用 Android Studio 1.5.1,我得到了以下警告:

Call requires API level 16 (current min is 9): android.view.View#setBackground

以及有关弃用的投诉

'setBackgroundDrawable(android.graphics.drawable.Drawable)' is deprecated

使用这种格式,我摆脱了两者的限制:
    if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.JELLY_BEAN) {
        //noinspection deprecation
        layout.setBackgroundDrawable(drawable);
    } else {
        layout.setBackground(drawable);
    }

7
现在你可以使用这两个选项中的任何一个。而且它们都可以正常工作。 你的颜色可以是十六进制代码,就像这样:
myView.setBackgroundResource(ContextCompat.getColor(context, Color.parseColor("#FFFFFF")));

像这样的颜色资源

myView.setBackgroundResource(ContextCompat.getColor(context,R.color.blue_background));

或者一个自定义的XML资源,如下所示:

或者自定义XML资源,像这样:

myView.setBackgroundResource(R.drawable.my_custom_background);

希望这有所帮助!


1
这对我有用: View view 是您的 editText,spinner 等等。而 int drawable 是您的可绘制路径示例(R.drawable.yourDrawable)。
 public void verifyDrawable (View view, int drawable){

        int sdk = Build.VERSION.SDK_INT;

        if(sdk < Build.VERSION_CODES.JELLY_BEAN) {
            view.setBackgroundDrawable(
                    ContextCompat.getDrawable(getContext(),drawable));
        } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
            view.setBackground(getResources().getDrawable(drawable));
        }    
    }

0
使用setBackgroundResource(R.drawable.xml/png)

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