Estou tentando calcular uma quantidade variável de pixels para densificar pixels independentes e vice-versa.
Essa fórmula (px to dp): dp = (int)(px / (displayMetrics.densityDpi / 160));
não funciona em dispositivos pequenos porque é dividida por zero.
Esta é minha fórmula de dp para px:
px = (int)(dp * (displayMetrics.densityDpi / 160));
Alguém poderia me dar algumas dicas?
Respostas:
Nota: A solução amplamente usada acima é baseada em
displayMetrics.density
. No entanto, os documentos explicam que esse valor é um valor arredondado, usado com a tela 'buckets'. Por exemplo. no meu Nexus 10, ele retorna 2, onde o valor real seria 298dpi (real) / 160dpi (padrão) = 1,8625.Dependendo dos seus requisitos, você pode precisar da transformação exata, que pode ser alcançada assim:
[Editar] Isso não deve ser misturado com a unidade de DP interna do Android, pois isso ainda é baseado nos baldes de tela. Use-o onde desejar uma unidade que renderize o mesmo tamanho real em diferentes dispositivos.
Converter dp em pixel:
Converter pixel em dp:
Observe que existem propriedades xdpi e ydpi, você pode querer distinguir, mas não consigo imaginar uma exibição sadia em que esses valores sejam muito diferentes.
fonte
Resolvi meu problema usando as seguintes fórmulas. Que outras pessoas possam se beneficiar disso.
dp para px:
px para dp:
fonte
px para dp:
fonte
typedValue.applyDimension( TypedValue.COMPLEX_UNIT_PX, valueInDp , getResources() .getDisplayMetrics());
é de PX para DP, também esta é a melhor respostaapplyDimension
produz apenas pixels. Consulte android.googlesource.com/platform/frameworks/base/+/refs/heads/… em que nenhuma conversão é realizadaCOMPLEX_UNIT_PX
.dp
. Se você olhar o código-fonte, para o casoTypedValue.COMPLEX_UNIT_DIP
,value * metrics.density
será retornado, onde você realmente precisavalue * metrics.density
. Então, o que você está getting` valueInDp` não está emdp
porvalueInPx
empx
.value / metrics.density
"Maneira eficiente de sempre
DP para Pixel:
Pixel para DP:
Espero que isso ajude você.
fonte
displayMetrics.xdpi
que é diferente em qualquer dispositivo. Infelizmente, essa resposta errada tem mais votos positivos.private fun dpToPx(dp: Int) = (dp * Resources.getSystem().displayMetrics.density).toInt()
Basta ligar
getResources().getDimensionPixelSize(R.dimen.your_dimension)
para converter dedp
unidades em pixelsfonte
Use esta função
fonte
fonte
(displayMetrics.densityDpi / 160)
- esta parte pode obter 0 em dispositivos pequenos, onde calcula, por exemplo120/160
, ambos os valores são int, o que resulta em 0. O que acaba como(int) (px/0)
.Na maioria dos casos, as funções de conversão são chamadas com frequência. Podemos otimizá-lo adicionando memorização. Portanto, ele não calcula sempre que a função é chamada.
Vamos declarar um HashMap que irá armazenar os valores calculados.
Uma função que calcula valores de pixel:
Uma função de memorização que retorna o valor do HashMap e mantém o registro dos valores anteriores.
A memorização pode ser implementada de diferentes maneiras em Java. Para Java 7 :
O Java 8 suporta a função Lambda :
Obrigado.
fonte
tente isso http://labs.skinkers.com/content/android_dp_px_calculator/
fonte
As funções abaixo funcionaram bem para mim em todos os dispositivos.
É retirado de https://gist.github.com/laaptu/7867851
fonte
Você pode usar
[DisplayMatrics][1]
e determinar a densidade da tela. Algo assim:Pelo que me lembro, é melhor usar pisos para compensações e arredondamentos para larguras.
fonte
Se você está procurando uma calculadora on-line para converter DP, SP, polegadas, milímetros, pontos ou pixels entre si em densidades de tela diferentes, esta é a ferramenta mais completa que eu conheço .
fonte
// para obter em termos de decimal / flutuante
________________________________________________________________________________
fonte
Use estas extensões Kotlin:
fonte
Sinta-se livre para usar este método que escrevi:
fonte
A resposta aceita acima não é totalmente precisa. De acordo com as informações obtidas pela inspeção do código fonte do Android:
Resources.getDimension()
egetDimensionPixelOffset()
/getDimensionPixelSize()
diferem apenas no fato de o primeiro retornar,float
enquanto os dois últimos retornam o mesmo valor arredondado para o valorint
apropriado. Para todos eles, o valor de retorno está em pixels brutos.Todas as três funções são implementedy ligando
Resources.getValue()
e convertendo assim obtidoTypedValue
ligandoTypedValue.complexToDimension()
,TypedValue.complexToDimensionPixelOffset()
eTypedValue.complexToDimensionPixelSize()
, respectivamente.Portanto, se você deseja obter o valor "bruto" junto com a unidade especificada na fonte XML, chame
Resources.getValue()
e use os métodos daTypedValue
classe.fonte
com ajuda de outras respostas, escrevi esta função.
fonte
Aqui está outra maneira de fazer isso usando extensões kotlin:
e então pode ser usado assim em qualquer lugar
fonte
fonte
a variação na resposta ct_robs acima, se você estiver usando números inteiros, que não apenas evita a divisão por 0, como também produz um resultado utilizável em dispositivos pequenos:
nos cálculos inteiros envolvendo divisão para maior precisão, multiplique primeiro antes de dividir para reduzir os efeitos de truncamento.
ao invés de
se você quiser resultado arredondado, faça isso
fonte