【问题标题】:setBackground vs setBackgroundDrawable (Android)setBackground 与 setBackgroundDrawable (Android)
【发布时间】:2012-08-10 11:13:03
【问题描述】:

我想设置视图的背景可绘制对象。有两种方法(据我所知):setBackgroundsetBackgroundDrawable

当我使用setBackground 时,它说它已添加到 API 级别 16 但我的项目的最低 SDK 版本是 7。我认为它不适用于 16 以下的任何东西,是吗?正确的?但是当我使用 setBackgroundDrawable 时,它​​说它已被弃用。

我应该使用什么?

【问题讨论】:

  • 使用:image.setImageResource(R.drawable.icon_dot1);

标签: android view background drawable


【解决方案1】:

它已被弃用,但它仍然有效,因此您可以直接使用它。但是如果你想完全正确,只是为了它的完整性......你会做如下的事情:

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

为此,您需要将 buildTarget api 16 和 min build 设置为 7 或类似的值。

【讨论】:

  • 它仍然抱怨 setBackgroundDrawable 被弃用。我真的必须仅仅因为 Google 想要更改方法名称就取消警告吗?
  • @santirivera92 是的,您有,或者您可以创建 2 个项目,1 个在问题之前定位,1 个在之后。这听起来像是一个简单的选择吗? (实际上有时确实如此,ICS 中有很多修复)
  • 我设置了android:minSdkVersion="7" android:targetSdkVersion="17",但是 setBackground() 出现错误:调用需要 API 级别 16(当前最小值为 7)
  • 它阻止了我编译。我将有问题的代码放在它自己的函数中,并且只为这样的函数禁用 lint。 @TargetApi(Build.VERSION_CODES.JELLY_BEAN) @SuppressWarnings("deprecation") private static void setBg(RelativeLayout layout, BitmapDrawable TileMe) { if (android.os.Build.VERSION.SDK_INT &lt; android.os.Build.VERSION_CODES.JELLY_BEAN) { layout.setBackgroundDrawable(TileMe); } else { layout.setBackground(TileMe); } }
  • @Snicolas 是的,IDE 或 Android 应该能够为我们做这种逻辑。
【解决方案2】:

您可以使用 API 级别 1 中的setBackgroundResource()

【讨论】:

  • ...但前提是您有资源 id 而不是您创建的自定义可绘制类!
  • 没有方法可以检索您有参考的可绘制对象的 ID 吗?
  • setBackgroundResource() 不能替代 setBackgroundDrawable();或 setBackground();。完全不相关,第一个添加资源drawable,其他添加CUSTOM drawable。
  • 如果我必须重复设置背景怎么办,比如在列表视图中? setBackgroundResource(int) 接受资源 id,因此每次都必须为视图充气以设置背景。我不想要这样的行为,假设我已经膨胀了 Drawable。我错过了什么吗?
  • 如果我只有drawable怎么办!?
【解决方案3】:

目前看来这2个功能没有区别,如source code所示(感谢this post):

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

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

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

【讨论】:

  • 太棒了!谢谢。愚蠢的是,对于像函数重命名这样蹩脚的东西会产生警告。
  • @M.kazemAkhgary 这不是他们第一次只为更改名称而弃用某些东西。他们将布局参数值的“fill_parent”更改为“match_parent”。两者完全相同,指向相同的值..
【解决方案4】:

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

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

然后你可以玩“Drawable”,应用颜色过滤器等

【讨论】:

  • 这仅适用于原始图像来自资源的情况。
  • 这甚至不能回答 OP 的问题。
【解决方案5】:

使用ViewCompat.setBackground(view, background);

【讨论】:

    【解决方案6】:

    您可以改用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);
          }
      

      【讨论】:

        【解决方案8】:

        现在您可以使用其中任何一个选项。无论如何它都会起作用。 您的颜色可以是 HEX 代码,如下所示:

        myView.setBackgroundResource(ContextCompat.getColor(context, Color.parseColor("#FFFFFF")));
        

        一个颜色资源,像这样:

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

        或者一个自定义xml资源,像这样:

        myView.setBackgroundResource(R.drawable.my_custom_background);
        

        希望对你有帮助!

        【讨论】:

          【解决方案9】:

          这对我有用: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));
                  }    
              }
          

          【讨论】:

            【解决方案10】:

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

            【讨论】:

              【解决方案11】:

              我也遇到了这个问题,但我使用 ImageView 解决了这个问题。

              尝试使用 RelativeLayout 并在其中添加一个 ImageView(宽度和高度:fill_parent,scaleType:中心)。

              还要确保 imageview 是RelativeLayout 中的第一个元素,所以它将充当背景。

              【讨论】:

              • 其实它应该不过是一个if 子句。查看正确答案。
              【解决方案12】:

              您也可以这样做:

              try {
                   myView.getClass().getMethod(android.os.Build.VERSION.SDK_INT >= 16 ? "setBackground" : "setBackgroundDrawable", Drawable.class).invoke(myView, myBackgroundDrawable);
              } catch (Exception ex) {
                   // do nothing
              }
              

              编辑:正如 @BlazejCzapp 所指出的,如果您可以设法在没有反射的情况下解决问题,则最好避免使用反射。我有一个用例,我无法在没有反射的情况下解决,但上面不是这种情况。更多信息请查看http://docs.oracle.com/javase/tutorial/reflect/index.html

              【讨论】:

              • @BlazejCzapp 大声笑,但它确实回答了这个问题,所以它不应该在没有解释的情况下被否决。当你告诉孩子不要做某事而不告诉他们为什么会这样做时;)
              • 我不想跑题,但这里有一些原因: 1. Java 是一种静态类型的语言 - 使用编译器; 2.这只是一个变相的if语句(它混淆了真正的逻辑); 3. 出大炮杀蚊子——这段代码是用一些大炮来解决一个小问题;希望在某种程度上证明它是合理的
              • 谢谢@BlazejCzapp,你说得对,我在这里有一个用例,需要执行上述代码之类的操作,但如果有适当的处理方法,则不应使用它。
              • 这很愚蠢......绝对没有理由使用反射来实现这一点。
              • 是的,告诉问一个简单问题的人“我应该使用什么?”开始修改运行时。
              猜你喜欢
              • 2012-11-23
              • 2014-02-22
              • 2012-08-04
              • 1970-01-01
              • 2011-06-27
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多