Carregar valor da dimensão de res / values ​​/ dimension.xml do código-fonte

337

Eu gostaria de carregar o valor como está. Eu tenho dois dimension.xmlarquivos, um em /res/values/dimension.xmle outra no /res/values-sw360dp/dimension.xml.

No código fonte, eu gostaria de fazer algo como

getResources().getDimension(R.dimen.tutorial_cross_marginTop);

Isso funciona, mas o valor que recebo é multiplicado pelo fator de densidade da tela (1,5 para hdpi, 2,0 para xhdpi, etc.).

Eu também tentei fazer

getResources().getString(R.dimen.tutorial_cross_marginTop);

Isso funcionaria em princípio, mas recebo uma string que termina em "dip" ...

Héctor Júdez Sapena
fonte
11
Eu me pergunto se é bug no Android como Resources tem método getDimensionPixelSize(int id)que exatamente afirma que ele retorna em Pixel, então getDimension(int id)deve retornar no dp (dependência unidades independentes), que estaria pronto para uso, por exemplo, com VistasetPadding
Paul Verest

Respostas:

811

No meu dimens.xml eu tenho

<dimen name="test">48dp</dimen>

No código Se eu fizer

int valueInPixels = (int) getResources().getDimension(R.dimen.test)

isso retornará 72 que, como o estado dos documentos, é multiplicado pela densidade do telefone atual (48dp x 1,5 no meu caso)

exatamente como os documentos afirmam:

Recupere uma dimensão para um ID de recurso específico. As conversões de unidade são baseadas nos DisplayMetrics atuais associados aos recursos.

portanto, se você quiser o valor exato do dp, como no xml, apenas divida-o com a densidade do DisplayMetrics

int dp = (int) (getResources().getDimension(R.dimen.test) / getResources().getDisplayMetrics().density)

dp será 48 agora

AndroidGecko
fonte
3
Eu acho que a documentação é particularmente clara aqui. "As conversões de unidades são baseadas nos DisplayMetrics atuais associados aos recursos." quando tudo o que eles querem dizer é que eles convertem em pixels.
Trilarion
Se você basicamente descartar o multiplicador de métricas de exibição, pode também definir sua dimensão em px. <dimen name = "test"> 48px </dimen>. getDimension (R.dimen.test) retornará 48.
Michael Peterson
Não funciona para mim: stackoverflow.com/questions/55972518/...
Alex
@ Trilarion Eles simplesmente não convertem em pixels. Eles estão dizendo que dpfornecerá o valor de pixel em escala em relação à escala do objeto de recurso usado para recuperá-lo. Depois de encontrar várias maneiras de obter recursos, isso será mais relevante. Para simplificar, você pode pensar nisso como sendo relativo à escala da tela. Também existem sppixels em relação ao tamanho do texto do sistema e pxpixels diretamente. Cada um é diferente e tem um propósito diferente.
Carrinho abandonado
20
Context.getResources().getDimension(int id);
Jug6ernaut
fonte
17

A Resourceclasse também possui um método getDimensionPixelSize () que, penso, será adequado às suas necessidades.

Ovidiu Latcu
fonte
24
Isto está errado! a conversão métricas também faz ocorre em getDimensionPixelSize()se você pode consultar os docs ele afirma claramente Returns Resource dimension value multiplied by the appropriate metric and truncated to integer pixels.
Muhammad Babar
Isto está errado. A conversão de métricas também ocorre usando esse método.
Michael Peterson
14

Para aqueles que precisam apenas economizar algum intvalor nos recursos, você pode fazer o seguinte.

integers.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <integer name="default_value">100</integer>
</resources> 

Código

int defaultValue = getResources().getInteger(R.integer.default_value);
Suragch
fonte
2
Obrigado por isso, era mais do que eu estava procurando, embora talvez não para os outros, mas esta solução fornecida na verdade me proporcionou alguns insights sobre outras áreas do meu código
JamisonMan111
11

Você pode usar getDimensionPixelOffset () em vez de getDimension, para não precisar converter para int.

int valueInPixels = getResources().getDimensionPixelOffset(R.dimen.test)
Jonny Right
fonte
2
    This works but the value I get is multiplied times the screen density factor
  (1.5 for hdpi, 2.0 for xhdpi, etc).

Eu acho que é bom obter o valor conforme a resolução, mas se você não quiser fazer isso, dê isso em px .......

Pixel independente da densidade (dp)

Uma unidade virtual de pixels que você deve usar ao definir o layout da interface do usuário para expressar dimensões ou posição do layout de maneira independente da densidade. O pixel independente da densidade é equivalente a um pixel físico em uma tela de 160 dpi, que é a densidade da linha de base assumida pelo sistema para uma tela de densidade "média". No tempo de execução, o sistema lida com qualquer escalonamento transparente das unidades dp, conforme necessário. based on the actual density of the screen in use. The conversion of dp units to screen pixels is simple: px = dp * (dpi / 160). For example, on a 240 dpi screen, 1 dp equals 1.5 physical pixels.Você sempre deve usar unidades dp ao definir a interface do usuário do aplicativo, para garantir a exibição adequada da interface do usuário em telas com densidades diferentes.

Eu acho que é bom alterar o valor conforme a resolução, mas se você não quiser fazer isso, dê isso em px .......

consulte este link

de acordo com isso

dp

Pixels independentes da densidade - Uma unidade abstrata que se baseia na densidade física da tela. Essas unidades são relativas a uma tela de 160 dpi (pontos por polegada), na qual 1dp é aproximadamente igual a 1px. When running on a higher density screen, the number of pixels used to draw 1dp is scaled up by a factor appropriate for the screen's dpi. Likewise, when on a lower density screen, the number of pixels used for 1dp is scaled down.A proporção de dp para pixel mudará com a densidade da tela, mas não necessariamente na proporção direta. O uso de unidades de DP (em vez de unidades de px) é uma solução simples para fazer com que as dimensões da vista em seu layout sejam redimensionadas corretamente para diferentes densidades de tela. Em outras palavras, ele fornece consistência para os tamanhos reais dos elementos da interface do usuário em diferentes dispositivos.

px

Pixels - corresponde aos pixels reais na tela. Esta unidade de medida não é recomendada porque a representação real pode variar entre dispositivos; cada dispositivo pode ter um número diferente de pixels por polegada e pode ter mais ou menos pixels totais disponíveis na tela.

Dheeresh Singh
fonte
2

Use uma extensão Kotlin

Você pode adicionar uma extensão para simplificar esse processo. Permite que você chame apenas context.dp(R.dimen. tutorial_cross_marginTop)para obter o valor de flutuação

fun Context.px(@DimenRes dimen: Int): Int = resources.getDimension(dimen).toInt()

fun Context.dp(@DimenRes dimen: Int): Float = px(dimen) / resources.displayMetrics.density

Se você quiser lidar com isso sem contexto, poderá usar Resources.getSystem():

val Int.dp get() = this / Resources.getSystem().displayMetrics.density // Float

val Int.px get() = (this * Resources.getSystem().displayMetrics.density).toInt()

Por exemplo, em um dispositivo xhdpi, use 24.dppara obter 12.0 ou 12.px24

Gibolt
fonte