Como obter dimensões da tela em pixels no Android

1843

Criei alguns elementos personalizados e quero colocá-los programaticamente no canto superior direito ( npixels da borda superior e mpixels da borda direita). Portanto, preciso obter a largura e a altura da tela e definir a posição:

int px = screenWidth - m;
int py = screenHeight - n;

Como recebo screenWidthe screenHeightna Atividade principal?

Niko Gamulin
fonte
Use dp em vez de px. porque ele vai distorcer o seu layout com outros dispositivos ..
Jawad Zeb
Não se esqueça de multiplicar por getResources () getDisplayMetrics () densidade a conta para dimensionamento da exibição..
jmaculate
Isso prova que a resposta mais votada nem sempre é a melhor (muitas pessoas repetem as respostas por representante). Em vez de getSize e getWidth / getHeight combo obsoleto (ignorando erros), tente o Balaji.K's getMetrics. O comentário de Nik em sua resposta até explica getDisplayMetricspara considerar o tamanho da barra de sistema / status. Além disso, você pode usar a densidade como jmaculate e LoungeKatt explicou ter a EXATO valor: DisplayMetrics dm = getResources().getDisplayMetrics(); float fwidth = dm.density * dm.widthPixels;Testado em v2.2 Android (API 8) e v4.0 com bons resultados e sem erros / avisos .
Armfoot 02/09
DisplayMetrics displaymetrics = new DisplayMetrics (); getWindowManager (). getDefaultDisplay (). getMetrics (displaymetrics); int height = displaymetrics.heightPixels; int width = displaymetrics.widthPixels;
Azahar
Outra maneira de obter os DisplayMetrics: Resources.getSystem().getDisplayMetrics(). Você não precisará de um Contextpara obtê-los.
TAG

Respostas:

3479

Se você quiser as dimensões de exibição em pixels, poderá usar getSize:

Display display = getWindowManager().getDefaultDisplay();
Point size = new Point();
display.getSize(size);
int width = size.x;
int height = size.y;

Se você não estiver em um, Activitypode obter o padrão Displayvia WINDOW_SERVICE:

WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
Display display = wm.getDefaultDisplay();

Se você estiver em um fragmento e deseja realizar isso, use Activity.WindowManager (em Xamarin.Android) ou getActivity (). GetWindowManager () (em java).

Antes getSizefoi introduzida (em nível de API 13), você pode usar o getWidthegetHeight métodos que agora estão obsoletos:

Display display = getWindowManager().getDefaultDisplay(); 
int width = display.getWidth();  // deprecated
int height = display.getHeight();  // deprecated

No entanto, para o caso de uso que você está descrevendo, uma margem / preenchimento no layout parece mais apropriada.

Outra maneira é: DisplayMetrics

Uma estrutura que descreve informações gerais sobre uma exibição, como tamanho, densidade e escala de fonte. Para acessar os membros do DisplayMetrics, inicialize um objeto como este:

DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);

Podemos usar widthPixelspara obter informações sobre:

"A largura absoluta da tela em pixels."

Exemplo:

Log.d("ApplicationTagName", "Display width in px is " + metrics.widthPixels);
Josef Pfleger
fonte
13
getWidth () ou getSize ()? O que eu usaria se precisar que meu aplicativo seja executado na API <13 e na API> 13?
Carol
52
tente {display.getSize (tamanho); width = size.x; height = size.y; } catch (NoSuchMethodError e) {width = display.getWidth (); altura = display.getHeight (); }
Arnaud
248
Não vejo por que você deseja usar try/catchpara esse cheque? Por que não usar simplesmente if (android.os.Build.VERSION.SDK_INT >= 13)sem nenhuma exceção lançada? Penso try/catchem um fluxo de aplicativo normal como uma prática ruim.
Patrik
2
@ A-Live, o aplicativo também quebraria (mas não travaria). Nós, desenvolvedores, devemos verificar previamente uma nova versão do sistema operacional e isso talvez oculte apenas um problema. Também com esse argumento, pode-se / deve-se envolver todas as poucas linhas de código com try / catch, o que, na minha opinião, é uma má prática, como já mencionado.
Patrik
11
E se você deseja obter o tamanho da tela excluindo a barra de navegação e / ou barra de notificação
desenvolvedor android
375

Uma maneira é:

Display display = getWindowManager().getDefaultDisplay(); 
int width = display.getWidth();
int height = display.getHeight();

Ele está obsoleto e você deve tentar o seguinte código. As duas primeiras linhas de código fornecem os DisplayMetricsobjetivos. Esta objetos contém campos como heightPixels, widthPixels.

DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);

int height = metrics.heightPixels;
int width = metrics.widthPixels;
Balaji.K
fonte
14
Observe que as métricas (largura, altura) mudam dependendo da rotação do dispositivo.
Tony Chan
8
As métricas retornarão o tamanho da exibição, mas, no HoneyComb e acima, sua atividade terá menos espaço do que o retornado devido à barra do sistema.
Guy
3
@ Compre, depende da sua implementação. Você pode ocultar a barra de status: requestWindowFeature (Window.FEATURE_NO_TITLE); getWindow (). setFlags (WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
Hagai L
79
Também existe desta forma: getContext () getResources () getDisplayMetrics () widthPixels...
Nik
escala final de flutuação = getResources (). getDisplayMetrics (). density; int width = (int) (metrics.widthPixels * scale + 0.5f); - Você deve considerar a densidade do dispositivo ao fazê-lo dessa maneira.
Carrinho abandonado
120

Pode não responder à sua pergunta, mas pode ser útil saber (eu estava procurando por mim quando cheguei a essa pergunta) que, se você precisar da dimensão de um View, mas seu código estiver sendo executado quando o layout ainda não estiver definido. (por exemplo, em onCreate()), você pode configurar um ViewTreeObserver.OnGlobalLayoutListenercom View.getViewTreeObserver().addOnGlobalLayoutListener()e colocar o código relevante que precisa da dimensão da visualização. O retorno de chamada do ouvinte será chamado quando o layout tiver sido definido.

Francesco Feltrinelli
fonte
ou simplesmente escreva view.post
Lukas Hanacek
O view.post não garante que funcione. É apenas uma solução alternativa.
Marsbear
@marsbear, onde diz que View.post()não é garantido que funcione? Estou curioso, porque também confio neste método para obter o tamanho de uma visualização após o layout e não o sabia.
Tony Chan
@ Turbo eu digo que: p Usamos essa solução alternativa antes e ela acabou não sendo confiável. Essa solução alternativa é baseada na suposição de que o layout inicial é feito na mesma volta do UIThread que a inicialização. Portanto, você pode agendar seu código para execução antes da próxima interface do usuário virar via post () e ficar bem. Aconteceu que o layout pode demorar ainda mais em determinadas circunstâncias e a exibição ainda não estava no layout quando o código postado foi executado. O que faço agora é adicionar o ViewTreeObserver no onCreate e removê-lo após o primeiro onLayout. Inicie suas coisas durante o primeiro onLayout.
Marsbear # 28/14
@marsbear importa de onde Viewvocê é ViewTreeObserver? Ou todos eles compartilham o mesmo?
Tony Chan
109

(Resposta de 2012, pode estar desatualizada) Se você deseja oferecer suporte ao Honeycomb pré, precisará colocar uma compatibilidade com versões anteriores à API 13. Algo como:

int measuredWidth = 0;
int measuredHeight = 0;
WindowManager w = getWindowManager();

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR2) {
    Point size = new Point();
    w.getDefaultDisplay().getSize(size);
    measuredWidth = size.x;
    measuredHeight = size.y;
} else {
    Display d = w.getDefaultDisplay();
    measuredWidth = d.getWidth();
    measuredHeight = d.getHeight();
}

É claro que os métodos descontinuados acabarão sendo retirados dos SDKs mais recentes, mas, embora ainda contemos com a maioria dos usuários com Android 2.1, 2.2 e 2.3, é isso que nos resta.

digiphd
fonte
Sim, isso foi em 2012.
digiphd 22/06/2015
desculpe, permita-me esclarecer o que eu quis dizer. É altamente improvável que alguém iria apoiar API <14 a partir de 2015/06/22
sudocoder
69

Tentei todas as "soluções" possíveis sem êxito e notei que o aplicativo "Dalvik Explorer" de Elliott Hughes sempre mostra a dimensão correta em qualquer versão de dispositivo / sistema operacional Android. Acabei analisando seu projeto de código aberto que pode ser encontrado aqui: https://code.google.com/p/enh/

Aqui está todo o código relevante:

WindowManager w = activity.getWindowManager();
Display d = w.getDefaultDisplay();
DisplayMetrics metrics = new DisplayMetrics();
d.getMetrics(metrics);
// since SDK_INT = 1;
widthPixels = metrics.widthPixels;
heightPixels = metrics.heightPixels;
try {
    // used when 17 > SDK_INT >= 14; includes window decorations (statusbar bar/menu bar)
    widthPixels = (Integer) Display.class.getMethod("getRawWidth").invoke(d);
    heightPixels = (Integer) Display.class.getMethod("getRawHeight").invoke(d);
} catch (Exception ignored) {
}
try {
    // used when SDK_INT >= 17; includes window decorations (statusbar bar/menu bar)
    Point realSize = new Point();
    Display.class.getMethod("getRealSize", Point.class).invoke(d, realSize);
    widthPixels = realSize.x;
    heightPixels = realSize.y;
} catch (Exception ignored) {
}

EDIT: versão ligeiramente melhorada (evite disparar exceções na versão do sistema operacional não suportada):

WindowManager w = activity.getWindowManager();
Display d = w.getDefaultDisplay();
DisplayMetrics metrics = new DisplayMetrics();
d.getMetrics(metrics);
// since SDK_INT = 1;
widthPixels = metrics.widthPixels;
heightPixels = metrics.heightPixels;
// includes window decorations (statusbar bar/menu bar)
if (Build.VERSION.SDK_INT >= 14 && Build.VERSION.SDK_INT < 17)
try {
    widthPixels = (Integer) Display.class.getMethod("getRawWidth").invoke(d);
    heightPixels = (Integer) Display.class.getMethod("getRawHeight").invoke(d);
} catch (Exception ignored) {
}
// includes window decorations (statusbar bar/menu bar)
if (Build.VERSION.SDK_INT >= 17)
try {
    Point realSize = new Point();
    Display.class.getMethod("getRealSize", Point.class).invoke(d, realSize);
    widthPixels = realSize.x;
    heightPixels = realSize.y;
} catch (Exception ignored) {
}
Dragan Marjanović
fonte
9
Esta é a única publicação aqui que leva em consideração as decorações da janela (barra de status / barra de menus). funcionou muito bem para mim.
Andy Cochrane
5
Impressionante, porém você nunca deveria ter esperado exceções de acionamento da lógica de negócios. O disparo de exceção (mesmo quando capturado) é horrível para o desempenho. Além disso, você está fazendo mais trabalho do que o necessário se o SDK_INT for> 13. Em vez disso, você deve adicionar alguns ifs no Build.VERSION.SDK_INT.
Erik B
3
@ Erik B, eu concordo. Eu adicionei versão melhorada. Ainda assim, deixei a parte "desde o SDK 1" para o caso de algo dar errado na tentativa / captura (já vi muitas coisas ruins no Android, especialmente quando você acha impossível algo dar errado, então eu gosto de mantê-lo seguro :)) . De qualquer forma, não deve haver sobrecarga demais, pois esse cálculo deve ser feito apenas uma vez (por exemplo, os valores podem ser mantidos em alguns atributos estáticos).
Dragan Marjanović
8
Observe que esse código está licenciado sob a GPL v3, o que tem implicações para o uso em aplicativos de produção.
TalkLittle
GPL e dependendo da reflexão para chamar métodos que podem não estar presentes em versões futuras do Android. Mhhh
Michel
47

Maneira mais simples:

 int screenHeight = getResources().getDisplayMetrics().heightPixels;
 int screenWidth = getResources().getDisplayMetrics().widthPixels; 
Zelleriation
fonte
46

Para acessar a altura da barra de status para dispositivos Android, preferimos uma maneira programática de obtê-lo:

Código de amostra

int resId = getResources().getIdentifier("status_bar_height", "dimen", "android");
if (resId > 0) {
    result = getResources().getDimensionPixelSize(resId);
}

A variável resultfornece a altura no pixel.

Para acesso rápido

Digite a descrição da imagem aqui

Para mais informações sobre a altura de Title bar, Navigation bare Content View, olhar com bons olhos Android tamanhos de tela do dispositivo .

Swapnil Sonar
fonte
Apenas o que eu precisava! getResources().getDisplayMetrics().heightPixels + resultfornece a altura real da tela cheia. A resposta de Dragan Marjanović também funciona, mas eu prefiro essa solução muito mais curta e mais simples.
Michel
Essa abordagem está desatualizada no Android Marshmallow. A altura da barra de status pode mudar da versão do dispositivo ou Android. Melhor uso OnApplyWindowInsetsListener.
Heinrich
32

Primeiro obtenha a view (por exemplo, by findViewById()) e então você pode usar getWidth () na própria view.

Marcin Gil
fonte
3
É assim que a documentação diz para você fazer isso ... mas é meio inútil se você NÃO estiver usando uma visualização. você pode estar usando outra coisa, por exemplo, mglsurfaceview.
gcb
2
isso é melhor, pois a visualização principal pode não ter o tamanho da tela. Mas certifique-se de que isso seja feito em um ponto em que a exibição da qual você está consultando o tamanho já tenha sido apresentada, o que geralmente não estará dentro de onCreate (). Você pode usar um retorno de chamada personalizado de onWindowFocusChanged (boolean hasFocus), que será chamado depois que todas as visualizações forem medidas e assim por diante, garantindo que você não receba dimensões incorretas para a exibição que lhe interessa ...
Dori
27

Eu tenho duas funções, uma para enviar o contexto e outra obtendo altura e largura em pixels:

public static int getWidth(Context mContext){
    int width=0;
    WindowManager wm = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
    Display display = wm.getDefaultDisplay();
    if(Build.VERSION.SDK_INT>12){
        Point size = new Point();
        display.getSize(size);
        width = size.x;
    }
    else{
        width = display.getWidth();  // Deprecated
    }
    return width;
}

e

public static int getHeight(Context mContext){
    int height=0;
    WindowManager wm = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
    Display display = wm.getDefaultDisplay();
    if(Build.VERSION.SDK_INT>12){
        Point size = new Point();
        display.getSize(size);
        height = size.y;
    }
    else{
        height = display.getHeight();  // Deprecated
    }
    return height;
}
Jorgesys
fonte
Você precisa adicionar @SuppressLint("NewApi")logo acima da assinatura da função para poder compilar.
Adil Malik 14/10
Eu acho que é melhor obter a altura e a largura de uma só vez, em vez de chamadas separadas para as APIs, porque, caso contrário, elas podem estar fora de sincronia. Isso pode acontecer se a orientação da tela estiver mudando enquanto o código estiver em execução.
26515 Sam
17

Para dimensionar dinamicamente usando XML, existe um atributo chamado "android: layout_weight"

O exemplo abaixo, modificado a partir da resposta da synic nesse segmento , mostra um botão que ocupa 75% da tela (peso = 0,25) e uma exibição de texto ocupa os 25% restantes da tela (peso = 0,75).

<LinearLayout android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal">

    <Button android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_weight=".25"
        android:text="somebutton">

    <TextView android:layout_width="fill_parent"
        android:layout_height="Wrap_content"
        android:layout_weight=".75">
</LinearLayout>
Crbreingan
fonte
17

Este é o código que eu uso para a tarefa:

// `activity` is an instance of Activity class.
Display display = activity.getWindowManager().getDefaultDisplay();
Point screen = new Point();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR2) {
    display.getSize(screen);
} else {            
    screen.x = display.getWidth();
    screen.y = display.getHeight();
}

Parece bastante limpo e, no entanto, cuida da depreciação.

Pijusn
fonte
17

Não é uma solução muito melhor? O DisplayMetrics vem com tudo o que você precisa e funciona a partir da API 1.

public void getScreenInfo(){
    DisplayMetrics metrics = new DisplayMetrics();
    getActivity().getWindowManager().getDefaultDisplay().getMetrics(metrics);

    heightPixels = metrics.heightPixels;
    widthPixels = metrics.widthPixels;
    density = metrics.density;
    densityDpi = metrics.densityDpi;
}

Você também pode obter a exibição real (incluindo decorações de tela, como Barra de Status ou barra de navegação do software) usando getRealMetrics , mas isso funciona apenas para 17 anos.

Estou esquecendo de algo?

David Corsalini
fonte
1
Não está subtraindo espaço para controles na tela (como em tablets ou dispositivos Nexus). Além disso, recebo um valor diferente (750 x 800) no meu Tablet de 10 ", dependendo da atividade estar ativa quando o cálculo é feito. Mas, para meus propósitos, isso é mais do que bom. Obrigado!
Steven L,
15

Apenas adicionando à resposta de Francesco. O outro observador que é mais apto, se você deseja descobrir o local na janela ou local na tela é ViewTreeObserver.OnPreDrawListener ()

Isso também pode ser usado para encontrar outros atributos de uma exibição que é quase desconhecida no momento do onCreate (), por exemplo, a posição rolada, a posição escalada.

pelucida
fonte
15

Usando o seguinte código em Atividade.

DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
int height = metrics.heightPixels;
int wwidth = metrics.widthPixels;
Vinothkumar Arputharaj
fonte
15

Encontre a largura e a altura da tela:

width = getWindowManager().getDefaultDisplay().getWidth();
height = getWindowManager().getDefaultDisplay().getHeight();

Com isso, podemos obter o SDK 13 mais recente e acima.

// New width and height
int version = android.os.Build.VERSION.SDK_INT;
Log.i("", " name == "+ version);
Display display = getWindowManager().getDefaultDisplay();
int width;
if (version >= 13) {
    Point size = new Point();
    display.getSize(size);
    width = size.x;
    Log.i("width", "if =>" +width);
}
else {
    width = display.getWidth();
    Log.i("width", "else =>" +width);
}
NagarjunaReddy
fonte
15
DisplayMetrics dimension = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(dimension);
int w = dimension.widthPixels;
int h = dimension.heightPixels;
Cristiana Chavez
fonte
12

Eu achei que isso fez o truque.

Rect dim = new Rect();
getWindowVisibleDisplayFrame(dim);
Justin
fonte
5
Arrefecer, mas o é uma coisa assustadora sobre este método no código fonte: este comentário
Norbert
12

É preciso dizer que, se você não estiver dentro Activity, mas dentro View(ou tiver uma variável do Viewtipo em seu escopo), não será necessário usarWINDOW_SERVICE . Então você pode usar pelo menos duas maneiras.

Primeiro:

DisplayMetrics dm = yourView.getContext().getResources().getDisplayMetrics();

Segundo:

DisplayMetrics dm = new DisplayMetrics();
yourView.getDisplay().getMetrics(dm);

Todos esses métodos que chamamos aqui não são preteridos.

Sergei Pikalev
fonte
12
public class AndroidScreenActivity extends Activity {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        DisplayMetrics dm = new DisplayMetrics();
        getWindowManager().getDefaultDisplay().getMetrics(dm);
        String str_ScreenSize = "The Android Screen is: "
                                   + dm.widthPixels
                                   + " x "
                                   + dm.heightPixels;

        TextView mScreenSize = (TextView) findViewById(R.id.strScreenSize);
        mScreenSize.setText(str_ScreenSize);
    }
}
Shoaib Ahmed
fonte
12

Para obter as dimensões da tela, use as métricas de exibição

DisplayMetrics displayMetrics = new DisplayMetrics();
if (context != null) 
      WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
      Display defaultDisplay = windowManager.getDefaultDisplay();
      defaultDisplay.getRealMetrics(displayMetrics);
    }

Obter a altura e largura em pixels

int width  =displayMetrics.widthPixels;
int height =displayMetrics.heightPixels;
Sharath kumar
fonte
9

Esta não é uma resposta para o OP, pois ele queria as dimensões da tela em pixels reais. Eu queria as dimensões em "pixels independentes de dispositivo", e reuni respostas aqui https://stackoverflow.com/a/17880012/253938 e aqui https://stackoverflow.com/a/6656774/253938 eu vim com isso:

    DisplayMetrics displayMetrics = Resources.getSystem().getDisplayMetrics();
    int dpHeight = (int)(displayMetrics.heightPixels / displayMetrics.density + 0.5);
    int dpWidth = (int)(displayMetrics.widthPixels / displayMetrics.density + 0.5);
RenniePet
fonte
9

Você pode obter o tamanho da altura usando:

getResources().getDisplayMetrics().heightPixels;

e o tamanho da largura usando

getResources().getDisplayMetrics().widthPixels; 
Jéwôm '
fonte
8

Existe uma maneira não obsoleta de fazer isso usando o DisplayMetrics (API 1), que evita a confusão de tentar / capturar:

 // initialize the DisplayMetrics object
 DisplayMetrics deviceDisplayMetrics = new DisplayMetrics();

 // populate the DisplayMetrics object with the display characteristics
 getWindowManager().getDefaultDisplay().getMetrics(deviceDisplayMetrics);

 // get the width and height
 screenWidth = deviceDisplayMetrics.widthPixels;
 screenHeight = deviceDisplayMetrics.heightPixels;
paulrehkugler
fonte
8

Gostaria de quebrar o código getSize assim:

@SuppressLint("NewApi")
public static Point getScreenSize(Activity a) {
    Point size = new Point();
    Display d = a.getWindowManager().getDefaultDisplay();
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
        d.getSize(size);
    } else {
        size.x = d.getWidth();
        size.y = d.getHeight();
    }
    return size;
}
Simon
fonte
Isso trava em um emulador executando o Android 4.0 (API 14).
jww
6

Para quem está pesquisando a dimensão da tela utilizável sem a barra de status e a barra de ação (também graças à resposta do Swapnil):

DisplayMetrics dm = getResources().getDisplayMetrics();
float screen_w = dm.widthPixels;
float screen_h = dm.heightPixels;

int resId = getResources().getIdentifier("status_bar_height", "dimen", "android");
if (resId > 0) {
    screen_h -= getResources().getDimensionPixelSize(resId);
}

TypedValue typedValue = new TypedValue();
if(getTheme().resolveAttribute(android.R.attr.actionBarSize, typedValue, true)){
    screen_h -= getResources().getDimensionPixelSize(typedValue.resourceId);
}
Francesco Vadicamo
fonte
6

Primeiro carregue o arquivo XML e, em seguida, escreva este código:

setContentView(R.layout.main);      
Display display = getWindowManager().getDefaultDisplay();
final int width = (display.getWidth());
final int height = (display.getHeight());

Mostrar largura e altura de acordo com a resolução da tela.

duggu
fonte
6

Siga os métodos abaixo:

public static int getWidthScreen(Context context) {
    return getDisplayMetrics(context).widthPixels;
}

public static int getHeightScreen(Context context) {
    return getDisplayMetrics(context).heightPixels;
}

private static DisplayMetrics getDisplayMetrics(Context context) {
    DisplayMetrics displayMetrics = new DisplayMetrics();
    WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
    wm.getDefaultDisplay().getMetrics(displayMetrics);
    return displayMetrics;
}
sonida
fonte
6

Kotlin

fun getScreenHeight(activity: Activity): Int {
    val metrics = DisplayMetrics()
    activity.windowManager.defaultDisplay.getMetrics(metrics)
    return metrics.heightPixels
}

fun getScreenWidth(activity: Activity): Int {
    val metrics = DisplayMetrics()
    activity.windowManager.defaultDisplay.getMetrics(metrics)
    return metrics.widthPixels
}
Khemraj
fonte
5

Há momentos em que você precisa conhecer as dimensões precisas do espaço disponível para um layout no onCreate de uma atividade. Depois de pensar um pouco, trabalhei dessa maneira.

public class MainActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        startActivityForResult(new Intent(this, Measure.class), 1);
        // Return without setting the layout, that will be done in onActivityResult.
    }

    @Override
    protected void onActivityResult (int requestCode, int resultCode, Intent data) {
        // Probably can never happen, but just in case.
        if (resultCode == RESULT_CANCELED) {
            finish();
            return;
        }
        int width = data.getIntExtra("Width", -1);
        // Width is now set to the precise available width, and a layout can now be created.            ...
    }
}

public final class Measure extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
       // Create a LinearLayout with a MeasureFrameLayout in it.
        // Just putting a subclass of LinearLayout in works fine, but to future proof things, I do it this way.
        LinearLayout linearLayout = new LinearLayout(this);
        LinearLayout.LayoutParams matchParent = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT);
        MeasureFrameLayout measureFrameLayout = new MeasureFrameLayout(this);
        measureFrameLayout.setLayoutParams(matchParent);
        linearLayout.addView(measureFrameLayout);
        this.addContentView(linearLayout, matchParent);
        // measureFrameLayout will now request this second activity to finish, sending back the width.
    }

    class MeasureFrameLayout extends FrameLayout {
        boolean finished = false;
        public MeasureFrameLayout(Context context) {
            super(context);
        }

        @SuppressLint("DrawAllocation")
        @Override
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
            if (finished) {
                return;
            }
            finished = true;
            // Send the width back as the result.
            Intent data = new Intent().putExtra("Width", MeasureSpec.getSize(widthMeasureSpec));
            Measure.this.setResult(Activity.RESULT_OK, data);
            // Tell this activity to finish, so the result is passed back.
            Measure.this.finish();
        }
    }
}

Se, por algum motivo, você não quiser adicionar outra atividade ao manifesto do Android, poderá fazê-lo desta maneira:

public class MainActivity extends Activity {
    static Activity measuringActivity;

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        Bundle extras = getIntent().getExtras();
        if (extras == null) {
            extras = new Bundle();
        }
        int width = extras.getInt("Width", -2);
        if (width == -2) {
            // First time in, just start another copy of this activity.
            extras.putInt("Width", -1);
            startActivityForResult(new Intent(this, MainActivity.class).putExtras(extras), 1);
            // Return without setting the layout, that will be done in onActivityResult.
            return;
        }
        if (width == -1) {
            // Second time in, here is where the measurement takes place.
            // Create a LinearLayout with a MeasureFrameLayout in it.
            // Just putting a subclass of LinearLayout in works fine, but to future proof things, I do it this way.
            LinearLayout linearLayout = new LinearLayout(measuringActivity = this);
            LinearLayout.LayoutParams matchParent = new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
            MeasureFrameLayout measureFrameLayout = new MeasureFrameLayout(this);
            measureFrameLayout.setLayoutParams(matchParent);
            linearLayout.addView(measureFrameLayout);
            this.addContentView(linearLayout, matchParent);
            // measureFrameLayout will now request this second activity to finish, sending back the width.
        }
    }

    @Override
    protected void onActivityResult (int requestCode, int resultCode, Intent data) {
        // Probably can never happen, but just in case.
        if (resultCode == RESULT_CANCELED) {
            finish();
            return;
        }
        int width = data.getIntExtra("Width", -3);
        // Width is now set to the precise available width, and a layout can now be created. 
        ...
    }

class MeasureFrameLayout extends FrameLayout {
    boolean finished = false;
    public MeasureFrameLayout(Context context) {
        super(context);
    }

    @SuppressLint("DrawAllocation")
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        if (finished) {
            return;
        }
        finished = true;
        // Send the width back as the result.
        Intent data = new Intent().putExtra("Width", MeasureSpec.getSize(widthMeasureSpec));
        MainActivity.measuringActivity.setResult(Activity.RESULT_OK, data);
        // Tell the (second) activity to finish.
        MainActivity.measuringActivity.finish();
    }
}    
Steve Waring
fonte
Obviamente, você também pode devolver a altura do pacote.
Steve Waring
5

Se você não deseja a sobrecarga de WindowManagers, Points ou Displays, pode pegar os atributos de altura e largura do item de exibição mais alto no seu XML, desde que a altura e a largura estejam definidas como match_parent. Isso é verdade desde que seu layout ocupe a tela inteira.

Por exemplo, se o seu XML começar com algo como isto:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/entireLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

Em seguida findViewById(R.id.entireLayout).getWidth(), retornará a largura findViewById(R.id.entireLayout).getHeight()da tela e a altura da tela.

christinac
fonte