setBackground vs setBackgroundDrawable(Android)


258

ビューの背景ドローアブルを設定したい。これには二つの方法が(私の知る限り見るように)がありますsetBackgroundsetBackgroundDrawable

を使用するとsetBackgroundAPIレベル16で追加されたと表示されますが、プロジェクトの最小SDKバージョンは7です。16未満では機能しないと思いますか?しかし、setBackgroundDrawableを使用すると、廃止されたと表示されます。

何を使うべきですか?


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

回答:


403

廃止予定ですが、引き続き機能するため、そのまま使用できます。しかし、完全を期すために、完全に正確になりたい場合は、次のようにします。

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が廃止されていることについて不満があります。Googleがメソッド名を変更したかったからといって、本当に警告を抑制しなければなりませんか?
Charlie-Blake

2
@ santirivera92はい、代わりに、問題が発生する前と後の2つのプロジェクトを作成できます。それは簡単なオプションのように聞こえますか?(実際にはときどき、ICSには多くの修正が加えられています)
Warpzit 2012年

4
設定しましたがandroid:minSdkVersion="7" android:targetSdkVersion="17"、setBackground()がエラーとして表示されます:呼び出しにはAPIレベル16(現在の最小値は7)が必要です
Jonny

20
コンパイルできませんでした。問題のあるコードを独自の関数に入れ、このような関数に対してのみlintを無効にしました。@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 2013

111

setBackgroundResource()APIレベル1の代わりに使用できます。


78
...ただし、作成したカスタムの描画可能なクラスではなく、リソースIDを取得した場合のみ!
Zordid 2013年

参照しているドローアブルのIDを取得する方法はありませんか?
Poutrathor

2
setBackgroundResource()はsetBackgroundDrawable();に代わるものではありません。またはsetBackground();。まったく関連がありません。最初にリソースドローアブルを追加し、その他はCUSTOMドローアブルを追加します。
MBH、2015

listviewで、背景を繰り返し設定する必要がある場合はどうなりますか?setBackgroundResource(int)リソースIDを受け入れるため、背景を設定するために毎回ビューを膨らませる必要があります。Drawableがすでに拡張されていると仮定すると、このような動作は望みません。何か不足していますか?
アジズベキアン

ドローアブルしかない!?
MBH

55

現在、ソースコードに示されているように、2つの関数に違いはないようですこの投稿のクレジット)。

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

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

したがって、これは単なる名前の決定であり、fill-parentとmatch-parentの場合と同様です。


5
すごい!ありがとう。関数の名前変更と同じように不十分なものに対して警告が生成されるという愚かなこと。
誰かどこか14

1
@ M.kazemAkhgary彼らが名前変更のためだけに何かを廃止するのは初めてではありません。それらには、レイアウトparams値の「fill_parent」が「match_parent」に変更されていました。どちらも同じ値を指し、まったく同じことです。..
Androidデベロッパー

18

私はこれが古い質問であることを知っていますが、同様の状況にあり、私の解決策は

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

次に、「Drawable」で遊んだり、カラーフィルターを適用したりできます。


6
これは、元の画像がリソースからのものである場合にのみ機能します。
Matt Huggins 2013年

これはOPの質問にも答えません。
Petro


12

setBackgroundResource()つまり、代わりに使用できますrelativeLayout.setBackgroundResource(R.drawable.back);

これでうまくいきます。


7

これで、これらのオプションのいずれかを使用できます。そして、それはどんな場合でも機能するでしょう。あなたの色は次のような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);

それが役に立てば幸い!


6

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);
    }

1

これは私にとってはうまくいきます:ビュービューはあなたのeditText、スピナーなどです。そして、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));
        }    
    }


-2

私もこの問題を抱えていましたが、ImageViewを使用して回避策を作りました。

RelativeLayoutを使用して、その中にImageViewを追加してみてください(幅と高さ:fill_parent、scaleType:center)。

また、imageviewがRelativeLayout内の最初の要素であることを確認してください。これにより、背景として機能します。


1
実際、それはif単なる条項にすぎなかったはずです。正解をご覧ください。
Pijusn 14

-4

これを行うこともできます:

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をご覧ください。


4
@BlazejCzapp LOL、しかしそれは質問に答えるので、説明なしで反対票を投じるべきではありません。子供がなぜそうするのかを言わずに何かをしないように言うとき;)
Fabricio

11
私はトピックから離れたくありませんが、ここにいくつかの理由があります:1. Javaは静的に型付けされた言語です-コンパイラーを使用してください。2.これは変装したif文のみです(真のロジックを難読化しています)。3.それは蚊を殺すために大砲を引き出すことです-このコードは些​​細な問題を解決するためにいくつかの深刻な大砲を使用しています。希望詰め、それはややその
BłażejCzapp

@BlazejCzappのおかげで、あなたは正しい、私は上記のコードのようなことをする必要があるここでユースケースを持っていましたが、これを処理する適切な方法があるならそれは使われるべきではありません。
Fabricio

2
これはばかげています...これを達成するためにリフレクションを使用する理由は絶対にありません。
Alex Lockwood

はい、簡単な質問をした人に「何を使用するのですか?」ランタイムの変更を開始します。
Petro
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.