setBackground vs setBackgroundDrawable (Android)

258

Saya ingin mengatur latar belakang yang dapat digambar tampilan. Ada dua metode untuk ini (sejauh yang saya lihat): setBackgrounddan setBackgroundDrawable.

Ketika saya menggunakan setBackground, dikatakan telah ditambahkan di API level 16 tetapi versi min SDK proyek saya adalah 7. Saya menganggap itu tidak akan bekerja pada apa pun di bawah 16, apakah saya benar? Tetapi ketika saya menggunakan setBackgroundDrawable, dikatakan sudah usang.

Apa yang harus saya gunakan?

Pijusn
sumber
Gunakan: image.setImageResource (R.drawable.icon_dot1);
Berani

Jawaban:

403

Sudah usang tetapi masih berfungsi sehingga Anda bisa menggunakannya. Tetapi jika Anda ingin benar sepenuhnya, hanya untuk kelengkapannya ... Anda akan melakukan sesuatu seperti berikut:

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

Agar ini berfungsi, Anda perlu menetapkan buildTarget api 16 dan min build menjadi 7 atau yang serupa.

Warpzit
sumber
4
Masih mengeluh tentang setBackgroundDrawable yang ditinggalkan. Apakah saya benar-benar harus menekan pernis hanya karena Google ingin mengubah nama metode?
Charlie-Blake
2
@ santirivera92 Ya Anda punya, atau Anda dapat membuat 2 proyek 1 penargetan sebelum masalah dan 1 setelah. Apakah itu terdengar seperti opsi yang mudah? (Sebenarnya terkadang memang demikian, begitu banyak perbaikan di ICS)
Warpzit
4
Saya menetapkan android:minSdkVersion="7" android:targetSdkVersion="17", namun setBackground () keluar sebagai kesalahan: Panggilan membutuhkan API level 16 (min saat ini adalah 7)
Jonny
20
Itu mencegah saya dari kompilasi. Saya menempatkan kode yang bermasalah dalam fungsinya sendiri dan menonaktifkan serat hanya untuk fungsi seperti ini. @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 Ya, IDE atau Android harus dapat melakukan logika seperti ini untuk kita.
Warpzit
111

Kamu bisa memakai setBackgroundResource() yang ada di API level 1.

Ludovic
sumber
78
... tetapi hanya jika Anda mendapat id sumber daya ulang dan bukan kelas yang dapat digambar khusus yang Anda buat!
Zordid
tidak ada metode untuk mengambil ID dari drawable Anda memiliki referensi?
Poutrathor
2
setBackgroundResource () bukan alternatif untuk setBackgroundDrawable (); atau setBackground () ;. Tidak terkait sama sekali, yang pertama menambahkan sumber daya yang dapat ditarik dan yang lainnya untuk menambahkan CUSTOM yang dapat digambar.
MBH
Bagaimana jika saya harus mengatur latar belakang berulang kali, katakan dalam listview? setBackgroundResource(int)menerima id sumber daya, oleh karena itu ia harus mengembang tampilan setiap kali untuk mengatur latar belakang. Saya tidak ingin perilaku seperti itu, dengan asumsi saya sudah menggembungkan Drawable. Apakah saya melewatkan sesuatu?
azizbekian
Bagaimana jika saya hanya memiliki drawable !?
MBH
55

Tampaknya saat ini tidak ada perbedaan antara 2 fungsi, seperti yang ditunjukkan pada kode sumber (kredit untuk posting ini ):

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

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

jadi itu hanya keputusan penamaan, mirip dengan yang berisi orang tua vs orang tua pertandingan.

pengembang android
sumber
5
Bagus! Terima kasih. Konyol bahwa peringatan dihasilkan untuk sesuatu yang lumpuh seperti fungsi ganti nama.
Seseorang di suatu tempat
1
@ M.kazemAkhgary Ini bukan pertama kalinya mereka mencela sesuatu hanya untuk mengganti nama. Mereka memiliki "fill_parent" yang diubah menjadi "match_parent" untuk nilai tata letak params. Keduanya sama persis, menunjuk ke nilai yang sama ..
pengembang android
18

saya tahu ini adalah pertanyaan lama tetapi saya memiliki situasi yang sama, dan solusi saya adalah

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

lalu Anda bisa bermain dengan "Drawable", menerapkan filter warna, dll

Jose De Gouveia
sumber
6
Ini hanya berfungsi jika gambar asli berasal dari sumber daya.
Matt Huggins
Ini bahkan tidak menjawab pertanyaan OP.
Petro
13

Menggunakan ViewCompat.setBackground(view, background);

krawa
sumber
12

Anda bisa menggunakan setBackgroundResource()misrelativeLayout.setBackgroundResource(R.drawable.back);

ini bekerja untuk saya.

ponnex
sumber
7

Sekarang Anda dapat menggunakan salah satu opsi itu. Dan itu akan berhasil dalam hal apa pun. Warna Anda dapat berupa kode HEX , seperti ini:

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

Sebuah sumber daya warna , seperti ini:

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

Atau sumber daya xml khusus , seperti:

myView.setBackgroundResource(R.drawable.my_custom_background);

Semoga ini bisa membantu!

Geraldo Neto
sumber
6

Menggunakan Android studio 1.5.1 saya mendapat peringatan berikut:

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

dan keluhan tentang penghinaan

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

Dengan menggunakan format ini, saya menyingkirkan keduanya:

    if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.JELLY_BEAN) {
        //noinspection deprecation
        layout.setBackgroundDrawable(drawable);
    } else {
        layout.setBackground(drawable);
    }
Aksel Willgert
sumber
1

Ini berfungsi untuk saya: Tampilan tampilan adalah editText Anda, pemintal ... dll. Dan int drawable adalah contoh rute drawable Anda (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));
        }    
    }
pengguna0987
sumber
0

Gunakan setBackgroundResource (R.drawable.xml / png)

baburao
sumber
-2

Saya juga punya masalah ini, tapi saya membuat solusi menggunakan ImageView .

Coba gunakan RelativeLayout dan tambahkan ImageView di dalamnya (lebar dan tinggi: fill_parent, scaleType: center).

Pastikan juga imageview adalah elemen pertama di dalam RelativeLayout, sehingga akan bertindak sebagai latar belakang.

Jens-Joris Decorte
sumber
1
Sebenarnya seharusnya tidak lebih dari ifklausa. Lihat jawaban yang benar.
Pijusn
-4

Anda juga dapat melakukan ini:

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

EDIT: Seperti yang ditunjukkan oleh @BlazejCzapp , lebih baik untuk menghindari menggunakan refleksi jika Anda bisa menyelesaikan masalah tanpa itu. Saya memiliki kasus penggunaan di mana saya tidak dapat menyelesaikan tanpa refleksi tetapi itu tidak terjadi di atas. Untuk informasi lebih lanjut silakan lihat di http://docs.oracle.com/javase/tutorial/reflect/index.html

Fabricio
sumber
4
@BlazejCzapp LOL, tetapi TIDAK menjawab pertanyaan, jadi itu tidak boleh diturunkan tanpa penjelasan. Ketika Anda memberi tahu seorang anak untuk tidak melakukan sesuatu tanpa memberi tahu mengapa mereka akan melakukan itu;)
Fabricio
11
Saya tidak ingin keluar dari topik, tetapi berikut adalah beberapa alasan: 1. Java adalah bahasa yang diketik secara statis - gunakan kompiler; 2. Ini hanya pernyataan if yang menyamar (itu mengaburkan logika yang benar); 3. Ini mengeluarkan meriam untuk membunuh nyamuk - kode ini menggunakan beberapa artileri serius untuk menyelesaikan masalah sepele; Harapan yang agak membenarkannya
Błażej Czapp
Terima kasih @BlazejCzapp, Anda benar, saya punya use case di sini di mana perlu untuk melakukan hal-hal seperti kode di atas tetapi tidak boleh digunakan jika ada cara yang tepat untuk menangani ini.
Fabricio
2
Ini bodoh ... sama sekali tidak ada alasan untuk menggunakan refleksi untuk mencapai ini.
Alex Lockwood
Ya, beri tahu seseorang yang mengajukan pertanyaan sederhana, "Apa yang harus saya gunakan?" mulai memodifikasi run-time.
Petro