Como determinar a largura da tela em termos de dp ou dip em tempo de execução no Android?

192

Preciso codificar o layout dos widgets do Android usando dip / dp (em arquivos java). Em tempo de execução, se eu codificar

int pixel=this.getWindowManager().getDefaultDisplay().getWidth();

isso retorna a largura da tela em pixels (px). Para converter isso em dp, eu codifiquei:

int dp =pixel/(int)getResources().getDisplayMetrics().density ;

Isso não parece estar retornando a resposta correta. Eu criei o emulador de WVGA800, cuja resolução de tela é de 480 por 800. Quando o emulador é executado e o código imprime os valores de pixel e dp, chegou a 320 em ambos. Este emulador é de 240 dpi cujo fator de escala seria 0,75.

Khushboo
fonte

Respostas:

376

Tente isto

Display display = getWindowManager().getDefaultDisplay();
DisplayMetrics outMetrics = new DisplayMetrics ();
display.getMetrics(outMetrics);

float density  = getResources().getDisplayMetrics().density;
float dpHeight = outMetrics.heightPixels / density;
float dpWidth  = outMetrics.widthPixels / density;

OU

Obrigado @ Tomáš Hubálek

DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics();    
float dpHeight = displayMetrics.heightPixels / displayMetrics.density;
float dpWidth = displayMetrics.widthPixels / displayMetrics.density;
Dax
fonte
90
Por que é necessário chamar o WindowManager? E esse código? DisplayMetrics displayMetrics = resources.getDisplayMetrics (); float screenWidthDp = displayMetrics.widthPixels / displayMetrics.density;
Tomáš Hubálek
2
Isso não funcionou para mim usando uma tela de densidade muito alta. Era como se tivesse apenas uma pequena parte da tela. Esta solução funcionou para mim: stackoverflow.com/a/18712361/956975 Display display = getWindowManager (). GetDefaultDisplay (); Tamanho do ponto = novo Point (); display.getSize (tamanho); int width = tamanho.x; int height = size.y;
Marianke
1
@dsdsdsdsd: context é qualquer instância da classe Context. Mais notavelmente, Activity é uma subclasse de Contexto (portanto, use isso em uma Activity e getActivity () em um Fragmento). Aplicativo e Serviço também são subclasses de Contexto.
François POYER 07/07/16
112

Eu me deparei com essa pergunta do Google e, mais tarde, encontrei uma solução fácil, válida para a API> = 13.

Para referências futuras:

Configuration configuration = yourActivity.getResources().getConfiguration();
int screenWidthDp = configuration.screenWidthDp; //The current width of the available screen space, in dp units, corresponding to screen width resource qualifier.
int smallestScreenWidthDp = configuration.smallestScreenWidthDp; //The smallest screen size an application will see in normal operation, corresponding to smallest screen width resource qualifier.

Consulte Referência da classe de configuração

Editar: Como observado por Nick Baicoianu, isso retorna a largura / altura utilizável da tela (que devem ser as mais interessantes na maioria dos usos). Se você precisar das dimensões reais da tela, atenha-se à resposta superior.

serjlee
fonte
23
Uma diferença importante entre o uso de screenWidthDp / screenHeightDp vs DisplayMetrics widthPixels / heightPixels é Configuration retorna as dimensões de exibição utilizáveis (menos a barra de status, etc.), enquanto DisplayMetrics retorna as dimensões de tela inteira.
Nick Baicoianu 22/09
Esta é apenas para API Nível 13 e para cima
ono
Para adicionar ao comentário de @ NickBaicoianu, os métodos getConfiguration () e getDisplayMetrics () funcionam no modo de várias janelas. ou seja, os tamanhos refletem o da janela, não a tela.
nmw
7

Está faltando o valor de densidade padrão 160.

    2 px = 3 dip if dpi == 80(ldpi), 320x240 screen
    1 px = 1 dip if dpi == 160(mdpi), 480x320 screen
    3 px = 2 dip if dpi == 240(hdpi), 840x480 screen

Em outras palavras, se você projetar seu layout com largura igual a 160dip no modo retrato, será metade da tela em todos os dispositivos ldpi / mdpi / hdpi (exceto os tablets, eu acho)

Mykhailo Gaidai
fonte
O que você respondeu é o raciocínio lógico por trás da minha pergunta. Eu entendo isso Como devo codificar isso em java para que, em tempo de execução, seja qual for a resolução da tela, a largura correta de dpi é escolhida pelo código?
Khushboo
Espero que eu acerte desta vez :) Use DisplayMetrics outMetrics = null; getWindowManager().getDefaultDisplay().getMetrics(outMetrics);dentro de Activity. Em seguida, outMetrics.densityfornecerá o fator de escala do dispositivo atual, conforme declarado na documentação
Mykhailo Gaidai
6

Que tal usar isso?

final DisplayMetrics displayMetrics=getResources().getDisplayMetrics();
final float screenWidthInDp=displayMetrics.widthPixels/displayMetrics.density;
final float screenHeightInDp=displayMetrics.heightPixels/displayMetrics.density;
desenvolvedor android
fonte
6
DisplayMetrics displayMetrics = new DisplayMetrics();

getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);

int width_px = Resources.getSystem().getDisplayMetrics().widthPixels;

int height_px =Resources.getSystem().getDisplayMetrics().heightPixels;

int pixeldpi = Resources.getSystem().getDisplayMetrics().densityDpi;


int width_dp = (width_px/pixeldpi)*160;
int height_dp = (height_px/pixeldpi)*160;
Supun Madushanka
fonte
8
Considere dar uma explicação
bigbounty
5

Resposta em kotlin:

  context?.let {
        val displayMetrics = it.resources.displayMetrics
        val dpHeight = displayMetrics.heightPixels / displayMetrics.density
        val dpWidth = displayMetrics.widthPixels / displayMetrics.density
    }
Bolling
fonte
4

Simplificado para Kotlin:

val widthDp = resources.displayMetrics.run { widthPixels / density }
val heightDp = resources.displayMetrics.run { heightPixels / density }
TheYogi
fonte
2

Obtenha largura e altura da tela em termos de DP com uma boa decoração:

Etapa 1: criar interface

public interface ScreenInterface {

   float getWidth();

   float getHeight();

}

Etapa 2: criar classe de implementador

public class Screen implements ScreenInterface {
    private Activity activity;

    public Screen(Activity activity) {
        this.activity = activity;
    }

    private DisplayMetrics getScreenDimension(Activity activity) {
        DisplayMetrics displayMetrics = new DisplayMetrics();
        activity.getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
        return displayMetrics;
    }

    private float getScreenDensity(Activity activity) {
        return activity.getResources().getDisplayMetrics().density;
    }

    @Override
    public float getWidth() {
        DisplayMetrics displayMetrics = getScreenDimension(activity);
        return displayMetrics.widthPixels / getScreenDensity(activity);
    }

    @Override
    public float getHeight() {
        DisplayMetrics displayMetrics = getScreenDimension(activity);
        return displayMetrics.heightPixels / getScreenDensity(activity);
    }
} 

Etapa 3: obtenha largura e altura na atividade:

Screen screen = new Screen(this); // Setting Screen
screen.getWidth();
screen.getHeight();
Ali Azaz Alam
fonte
Isso retorna altura e largura em pixel ou dp?
Taslim Oseni 5/08/19
como chamado .density é por isso que dá a você no dp
Ali Azaz Alam
Eu não acho que é uma boa idéia para adicionar tons de código para seu aplicativo para resolver uma tarefa simples
Ruslan Berozov
Senhor, cabe a você implementar a classe ou codificá-la diretamente. Da classe definida, você pode extrair facilmente o código para implementação direta.
Ali Azaz Alam
0

Se você quer apenas saber sobre a largura da tela, basta pesquisar por "menor largura de tela" nas opções do desenvolvedor. Você pode até editá-lo.

canal de matemática
fonte
0

Tente o seguinte:

Display display   = getWindowManager().getDefaultDisplay();
Point displaySize = new Point();
display.getSize(displaySize);
int width  = displaySize.x;
int height = displaySize.y;
Muhammed naseef Koppilakkal
fonte
-5

Seu problema está em converter o float para um int, perdendo precisão. Você também deve multiplicar com o fator e não dividir.

Faça isso:

int dp = (int)(pixel*getResources().getDisplayMetrics().density);
Dirk le Roux
fonte
3
Esta resposta está incorreta. Em developer.android.com/guide/practices/… , Pixel = Dp * Densidade.
Vance-Turner