setBackground vs setBackgroundDrawable (Android)


258

Quero definir o plano de fundo que pode ser desenhado de uma exibição. Existem dois métodos para isso (tanto quanto eu vejo): setBackgrounde setBackgroundDrawable.

Quando uso setBackground, ele diz que foi adicionado no nível 16 da API, mas a versão mínima do SDK do meu projeto é 7. Suponho que não funcionará em nada abaixo de 16, estou certo? Mas quando eu uso o setBackgroundDrawable, ele diz que está obsoleto.

O que devo usar?


Use: image.setImageResource (R.drawable.icon_dot1);
bravo

Respostas:


403

Ele foi descontinuado, mas ainda funciona para que você possa usá-lo. Mas se você quiser estar completamente correto, apenas pela integridade ... Você faria algo como o seguinte:

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

Para que isso funcione, você precisa definir buildTarget api 16 e min build como 7 ou algo semelhante.


4
Ele ainda reclama que o setBackgroundDrawable está sendo preterido. Eu realmente preciso suprimir avisos apenas porque o Google queria alterar o nome do método?
Charlie-Blake

2
@ santirivera92 Sim, você pode criar 2 projetos, 1 direcionado antes de um problema e 1 depois. Isso soa como uma opção fácil? (Na verdade, às vezes ele faz, tantas correções no ICS)
Warpzit

4
Eu definir android:minSdkVersion="7" android:targetSdkVersion="17", no entanto setBackground () sai como erro: Chamada exige nível API 16 (atual min é 7)
Jonny

20
Isso me impediu de compilar. Coloquei o código problemático em sua própria função e desabilitei o fiapo apenas para essa função como esta. @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); } }
quer

2
@Snicolas Sim, o IDE ou o Android deve ser capaz de fazer esse tipo de lógica para nós.
Warpzit

111

Você pode usar o setBackgroundResource()que está no nível 1 da API.


78
... mas apenas se você tiver um ID de recurso e não uma classe de desenho personalizada que você criou!
Zordid

não existe um método para recuperar o ID de um drawable que você tenha referência?
Poutrathor 23/09

2
setBackgroundResource () não é alternativa para setBackgroundDrawable (); ou setBackground () ;. Não está relacionado, o primeiro a adicionar drawable de recursos e os outros a adicionar drawable PERSONALIZADO.
MBH

E se eu tiver que definir o plano de fundo repetidamente, digamos no listview? setBackgroundResource(int)aceita o ID do recurso, portanto, ele deve aumentar a exibição toda vez para definir o plano de fundo. Eu não quero esse comportamento, supondo que eu já tenha inflado o Drawable. Estou esquecendo de algo?
Azizbekian

e se eu tiver apenas o drawable!?
MBH

55

Parece que atualmente não há diferença entre as 2 funções, conforme mostrado no código-fonte (crédito para este post ):

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

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

portanto, é apenas uma decisão de nomeação, semelhante àquela com pai de preenchimento versus pai de correspondência.


5
ótimo! obrigado. Bobo que um aviso é gerado para algo tão coxo quanto uma função renomeada.
Someone Somewhere

1
@ M.kazemAkhgary Não é a primeira vez que depreciam algo apenas para mudar de nome. Eles tiveram "fill_parent" sendo alterado para "match_parent" para valores de parâmetros de layout. Ambos são exatamente a mesma coisa, apontando para o mesmo valor ..
desenvolvedor Android

18

sei que essa é uma pergunta antiga, mas tenho uma situação semelhante e minha solução foi

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

e então você pode brincar com o "Drawable", aplicando filtros de cores, etc.


6
Isso funciona apenas se a imagem original vier de um recurso.
Matt Huggins

Isso nem responde à pergunta do OP.
Petro

13

Usar ViewCompat.setBackground(view, background);


12

você poderia usar em setBackgroundResource()vez disso ou sejarelativeLayout.setBackgroundResource(R.drawable.back);

isso funciona para mim.


7

Agora você pode usar qualquer uma dessas opções. E vai funcionar em qualquer caso. Sua cor pode ser um código HEX , assim:

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

Um recurso de cores , como este:

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

Ou um recurso xml personalizado , assim:

myView.setBackgroundResource(R.drawable.my_custom_background);

Espero que ajude!


6

Usando o Android studio 1.5.1, recebi os seguintes avisos:

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

e as reclamações sobre depreciação

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

Usando este formato, me livrei de ambos:

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

1

Isso funciona para mim: o modo de exibição de exibição é o seu editText, spinner ... etc. E int drawable é o seu exemplo de rota 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

Eu também tive esse problema, mas fiz uma solução alternativa usando um ImageView .

Tente usar um RelativeLayout e adicione um ImageView dentro dele (largura e altura: fill_parent, scaleType: center).

Verifique também se a visualização de imagem é o primeiro elemento dentro do RelativeLayout, para que ela atue como plano de fundo.


1
Na verdade, não deveria ter sido mais do que uma ifcláusula. Veja a resposta correta.
Pijusn

-4

Você também pode fazer isso:

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

EDIT: Assim como apontado por @BlazejCzapp , é preferível evitar o uso de reflexão se você conseguir resolver o problema sem ele. Eu tive um caso de uso em que não consegui resolver sem reflexão, mas esse não é o caso acima. Para mais informações, consulte http://docs.oracle.com/javase/tutorial/reflect/index.html


4
@BlazejCzapp LOL, mas responde à pergunta, por isso não deve ser votado sem uma explicação. Quando você diz a uma criança para não fazer algo sem dizer por que eles vão fazer isso;)
Fabricio

11
Não quero sair do tópico, mas aqui estão alguns motivos: 1. Java é uma linguagem de tipo estaticamente - use o compilador; 2. Esta é apenas uma declaração if disfarçada (está ofuscando a verdadeira lógica); 3. Está lançando um canhão para matar um mosquito - esse código está usando uma artilharia séria para resolver um problema trivial; Esperança de que justifica-lo um pouco
Błażej Czapp

Obrigado @BlazejCzapp, você está certo, eu tinha um caso de uso aqui em que era necessário fazer coisas como o código acima, mas não deveria ser usado se houver uma maneira adequada de lidar com isso.
Fabricio

2
Isso é idiota ... não há absolutamente nenhuma razão para usar a reflexão para conseguir isso.
Alex Lockwood

Sim, diga a alguém que fez uma pergunta simples "O que devo usar?" comece a modificar o tempo de execução.
Petro das
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.