setBackground so với setBackgroundDrawable (Android)


258

Tôi muốn thiết lập nền có thể vẽ của một khung nhìn. Có hai phương pháp cho việc này (theo như tôi thấy): setBackgroundsetBackgroundDrawable .

Khi tôi sử dụng setBackground, nó nói rằng nó đã được thêm vào API cấp 16 nhưng phiên bản SDK tối thiểu của dự án của tôi là 7. Tôi cho rằng nó sẽ không hoạt động trên bất cứ thứ gì dưới 16, phải không? Nhưng khi tôi sử dụng setBackgroundDrawable, nó nói rằng nó không dùng nữa.

Tôi nên sử dụng cái gì?


Sử dụng: image.setImageResource (R.drawable.icon_dot1);
Dũng cảm

Câu trả lời:


403

Nó không dùng nữa nhưng nó vẫn hoạt động để bạn có thể sử dụng nó. Nhưng nếu bạn muốn hoàn toàn chính xác, chỉ vì sự hoàn chỉnh của nó ... Bạn sẽ làm một cái gì đó như sau:

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

Để làm việc này, bạn cần đặt buildTarget api 16 và min build thành 7 hoặc một cái gì đó tương tự.


4
Nó vẫn phàn nàn về setBackgroundDrawable bị phản đối. Tôi có thực sự phải loại bỏ chỉ vì Google muốn thay đổi tên phương thức không?
Charlie-Blake

2
@ santirivera92 Có, bạn có thể tạo 2 dự án 1 nhắm mục tiêu trước khi nó gặp sự cố và 1 sau đó. Nghe có vẻ như là một lựa chọn dễ dàng? (Trên thực tế đôi khi có, rất nhiều bản sửa lỗi trong ICS)
Warpzit

4
Tôi đã đặt android:minSdkVersion="7" android:targetSdkVersion="17", tuy nhiên setBackground () xuất hiện dưới dạng lỗi: Cuộc gọi yêu cầu API cấp 16 (tối thiểu hiện tại là 7)
Jonny

20
Nó ngăn cản tôi biên dịch. Tôi đặt mã có vấn đề trong chức năng của chính nó và chỉ vô hiệu hóa lint cho chức năng đó như thế này. @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 Có, IDE hoặc Android sẽ có thể thực hiện loại logic này cho chúng tôi.
Warpzit

111

Bạn có thể sử dụng setBackgroundResource()thay thế trong API cấp 1.


78
... nhưng chỉ khi bạn có id ressource chứ không phải lớp có thể vẽ tùy chỉnh mà bạn đã tạo!
Zordid

không có phương pháp nào để lấy ID của một drawable mà bạn có một tài liệu tham khảo?
Poutrathor

2
setBackgroundResource () không thay thế cho setBackgroundDrawable (); hoặc setBackground ();. Hoàn toàn không liên quan, cái đầu tiên để thêm tài nguyên có thể rút được và những cái khác để thêm TÙY CHỈNH có thể rút được.
MBH

Điều gì sẽ xảy ra nếu tôi phải thiết lập nền nhiều lần, nói trong listview? setBackgroundResource(int)chấp nhận id tài nguyên, do đó nó phải tăng cường xem mỗi lần để đặt nền. Tôi không muốn hành vi như vậy, giả sử tôi đã bị thổi phồng Drawable. Tui bỏ lỡ điều gì vậy?
azizbekian

Nếu tôi chỉ có khả năng rút ra thì sao!?
MBH

55

dường như hiện tại không có sự khác biệt giữa 2 chức năng, như được hiển thị trên mã nguồn (tín dụng cho bài đăng này ):

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

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

vì vậy, đó chỉ là một quyết định đặt tên, tương tự như quyết định điền vào cha mẹ và so khớp cha mẹ.


5
tuyệt quá! cảm ơn. Ngớ ngẩn rằng một cảnh báo được tạo ra cho một cái gì đó khập khiễng như một chức năng đổi tên.
Ai đó ở đâu đó

1
@ M.kazemAkhÿ Đây không phải là lần đầu tiên họ từ chối một cái gì đó chỉ để thay đổi tên. Chúng có "fill_parent" được thay đổi thành "match_parent" cho các giá trị params bố trí. Cả hai đều giống hệt nhau, chỉ vào cùng một giá trị ..
nhà phát triển Android

18

Tôi biết đây là một câu hỏi cũ nhưng tôi có một tình huống tương tự, và giải pháp của tôi là

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

và sau đó bạn có thể chơi với "Drawable", áp dụng các bộ lọc màu, v.v.


6
Điều này chỉ hoạt động nếu hình ảnh gốc đến từ một tài nguyên.
Matt Huggins

Điều này thậm chí không trả lời câu hỏi của OP.
Dầu khí

13

Sử dụng ViewCompat.setBackground(view, background);


12

bạn có thể sử dụng setBackgroundResource()thay vìrelativeLayout.setBackgroundResource(R.drawable.back);

cái này hiệu quả với tôi


7

Bây giờ bạn có thể sử dụng một trong những tùy chọn đó. Và nó sẽ làm việc trong mọi trường hợp. Màu của bạn có thể là mã HEX , như thế này:

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

Một tài nguyên màu , như thế này:

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

Hoặc một tài nguyên xml tùy chỉnh , như vậy:

myView.setBackgroundResource(R.drawable.my_custom_background);

Hy vọng nó giúp!


6

Sử dụng Android studio 1.5.1 tôi nhận được các cảnh báo sau:

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

và những lời phàn nàn về sự phản đối

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

Sử dụng định dạng này, tôi đã thoát khỏi cả hai:

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

1

Điều này hoạt động với tôi: Chế độ xem là chỉnh sửa của bạn, spinner ... vv. Và int drawable là ví dụ về lộ trình có thể vẽ của bạn (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

Sử dụng setBackgroundResource (R.drawable.xml / png)


-2

Tôi cũng gặp vấn đề này, nhưng tôi đã khắc phục bằng ImageView .

Hãy thử sử dụng RelativeLayout và thêm ImageView bên trong nó (chiều rộng và chiều cao: fill_parent, scaleType: centre).

Ngoài ra, hãy đảm bảo rằng lượt xem hình ảnh là thành phần đầu tiên bên trong RelativeLayout, vì vậy nó sẽ đóng vai trò là nền.


1
Trên thực tế, nó không nên có nhiều hơn một ifđiều khoản. Xem câu trả lời đúng.
Pijusn

-4

Bạn cũng có thể làm điều này:

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

EDIT: Như được chỉ ra bởi @BlazejCzapp , tốt nhất là tránh sử dụng sự phản chiếu nếu bạn có thể quản lý để giải quyết vấn đề mà không có nó. Tôi đã có một trường hợp sử dụng mà tôi không thể giải quyết mà không có sự phản ánh nhưng đó không phải là trường hợp trên. Để biết thêm thông tin, vui lòng xem tại http://docs.oracle.com/javase/tutorial/reflect/index.html


4
@BlazejCzapp LOL, nhưng nó trả lời câu hỏi, vì vậy nó không nên bị hạ thấp mà không có lời giải thích. Khi bạn bảo một đứa trẻ không làm điều gì đó mà không nói lý do tại sao chúng sẽ làm điều đó;)
Fabricio

11
Tôi không muốn lạc đề, nhưng đây là một số lý do: 1. Java là ngôn ngữ được gõ tĩnh - hãy sử dụng trình biên dịch; 2. Đây chỉ là một câu lệnh if ngụy trang (nó che giấu logic thực sự); 3. Nó mang ra một khẩu pháo để giết muỗi - mã này đang sử dụng một số loại pháo nghiêm trọng để giải quyết một vấn đề tầm thường; Hy vọng rằng điều đó biện minh phần nào
Błażej Czapp

Cảm ơn @BlazejCzapp, bạn đã đúng, tôi đã có một trường hợp sử dụng ở đây khi cần phải làm những việc như mã ở trên nhưng không nên sử dụng nếu có cách xử lý thích hợp.
Fabricio

2
Điều này thật ngu ngốc ... hoàn toàn không có lý do để sử dụng sự phản chiếu để đạt được điều này.
Alex Lockwood

Có nói với ai đó đã hỏi một câu hỏi đơn giản "Tôi nên sử dụng cái gì?" bắt đầu sửa đổi thời gian chạy
Dầu khí
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.