Como posso descobrir o tamanho da minha tela de forma programática, nas unidades usadas pelos eventos de toque e Exibir medição / layout? Em outras palavras, quero as coordenadas do canto inferior direito da tela, no sistema de coordenadas usado pelos eventos de toque '
getRawX()/getRawY()
e View.getLocationOnScreen()
.
Eu hesito em chamar as unidades de evento / exibição desejadas como "pixels", pois, evidentemente, existem várias noções de "pixels" no meu telefone em vários modos, e elas não estão adicionando uma história consistente.
Vejo que isso foi solicitado e respondido muito no stackoverflow e em outros lugares, mas nenhuma das respostas realmente funciona no meu telefone (droid 4, android 4.1.2) em todos os modos:
- Posso descobrir a largura da tela programaticamente no aplicativo Android?
- Como faço para obter o ScreenSize programaticamente no android
- Conjunto Android Ver visibilidade programaticamente com base no tamanho da tela
- Como obtenho a altura da tela no Android?
- Obter a altura da tela no Android
- https://groups.google.com/forum/#!topic/android-developers/IpxnfvDFrpc
- http://shuklaxyz.blogspot.com/2012/02/how-to-programmatically-figure-out.html
- http://coderock.net/how-to-determine-screen-resolution-programmatically/
- http://www.codeproject.com/Tips/313848/Get-actual-screen-size-for-the-application-layout
- Android e configuração de largura e altura programaticamente em unidades dp
- http://www.simplecodestuffs.com/how-to-get-screen-dimensions-programmatically-in-android/
- http://www.androidsnippets.com/get-size-and-orientation-of-the-screen
- http://grokbase.com/t/gg/android-developers/127aatfqb6/how-to-determine-screen-resolution-programmatically
(Uau!)
Isso é para código de biblioteca que precisa funcionar, independentemente de o aplicativo estar no "modo de compatibilidade de tela" (ou seja, targetSdkVersion <= 10 no manifesto) ou não, e também não quero fazer suposições sobre a posição, tamanho , ou existência da barra de status ou quaisquer outras decorações de tela semelhantes.
Aqui estão os fatos:
meu telefone (um droid 4 com o Android 4.1.2) tem 540x960 pixels físicos, ou seja, pequenos pontos brilhantes coloridos.
o tamanho da tela nas unidades desejadas, observando eventos de toque e Exibir medições, é 360x640 quando o aplicativo está no modo de compatibilidade de tela e 540x960 quando o aplicativo não está no modo de compatibilidade de tela. Esses são os números que preciso encontrar de forma programática, sem mexer com os eventos de toque ou as exibições para encontrá-los, mas estou com extrema dificuldade em encontrar qualquer API que retorne esses números.
Os objetos Display e DisplayMetrics obtidos de várias maneiras afirmam que o tamanho da tela é de 540x960 "pixels" (no modo compatível com a tela ou não). Para ser específico, o seguinte diz 540x960 o tempo todo: DisplayMetrics. {Width, height} Pixels, Display.getSize (), Display.getRealSize (), Display.get {Width, Height} (),
Objetos de configuração obtidos de várias maneiras, todos dizem tela {Largura, Altura} Dp = 360x614 (seja no modo de tela compatível ou não). Não acredito que isso represente a tela inteira, pois a proporção está errada. (Eu acho que é a tela inteira menos a barra de status; eu preciso da tela inteira.) Acho que é seguro dizer que a tela inteira tem 360 x 640 dp, embora eu não conheça nenhuma API que retorne essa 640.
Os DisplayMetrics obtidos de várias maneiras dizem que a "densidade" é 1,0f quando está no modo de compatibilidade de tela, 1,5f quando não está no modo de compatibilidade de tela.
A atividade
getWindow().getAttributes().{width,height}
não é útil, pois geralmente contémMATCH_PARENT
tamanhos e não tamanhos reais. Mas aparentemente posso obter a resposta desejada de uma atividadegetWindow().getDecorView().getMeasured{Width,Height}()
(o que é realmente surpreendente, já que o decorView da janela da atividade não parece ocupar a tela inteira; parece estar ocupando a tela menos a barra de status). Mas não quero confiar nisso, porque se a janela for redimensionada (o teclado virtual aparecerá? Alguém chamando window.setAttributes ()? Ou talvez eu não esteja em nenhuma atividade), isso claramente será tudo errado.
Entendo que a seguinte fórmula deve conter: pixels = dp * densidade Isso parece concordar com todos os números relatados ((3), (4), (5) acima) quando não estiver no modo de compatibilidade de tela: 540x960 = 360x640 * 1,5 Mas, no modo de compatibilidade de tela, isso não ocorre: 540x960! = 360x640 * 1 Então, algo está errado.
A explicação mais simples, eu acho, é que os métodos listados em (3) acima estão simplesmente dando a resposta errada para "pixels" quando no modo de compatibilidade de tela - ou seja, eles pretendiam retornar "pixels" de 360x640, mas estão incorretamente retornando 540x960. Mas pode haver outras maneiras de ver isso.
De qualquer forma, obter os números desejados, independentemente do modo, das peças do quebra-cabeça acima, é certamente um quebra-cabeça complicado. Eu encontrei uma maneira que parece funcionar no meu telefone nos dois modos, mas é extremamente tortuosa e se baseia em duas suposições que ainda parecem bastante instáveis (conforme descrito nos comentários de código abaixo).
Aqui está a minha receita:
/** get screen size in "pixels", i.e. touchevent/view units.
* on my droid 4, this is 360x640 or 540x960
* depending on whether the app is in screen compatibility mode
* (i.e. targetSdkVersion<=10 in the manifest) or not. */
public void getScreenSizePixels(int widthHeightInPixels[/*2*/])
{
Resources resources = getResources();
Configuration config = resources.getConfiguration();
DisplayMetrics dm = resources.getDisplayMetrics();
// Note, screenHeightDp isn't reliable
// (it seems to be too small by the height of the status bar),
// but we assume screenWidthDp is reliable.
// Note also, dm.widthPixels,dm.heightPixels aren't reliably pixels
// (they get confused when in screen compatibility mode, it seems),
// but we assume their ratio is correct.
double screenWidthInPixels = (double)config.screenWidthDp * dm.density;
double screenHeightInPixels = screenWidthInPixels * dm.heightPixels / dm.widthPixels;
widthHeightInPixels[0] = (int)(screenWidthInPixels + .5);
widthHeightInPixels[1] = (int)(screenHeightInPixels + .5);
}
Existe alguma maneira melhor / mais limpa de encontrar o tamanho da tela?
DisplayMetrics
nunca seja atualizada dessas alterações. Já existem problemas como esse .