volumen utilizar una secundaria qué que pueden personalizadas métrica metrica medidas logistica las informes google dimensión dimensiones android android-layout

android - utilizar - Cómo analizar una cadena de dimensión y convertirla en un valor de dimensión



¿en qué informes se pueden utilizar las dimensiones personalizadas? (4)

Si necesita el dimen de recursos de Android como int puede hacerlo en su código:

context.getResources().getDimensionPixelSize(R.dimen.your_dimen_res);

Estoy buscando una forma de convertir dinámicamente una cadena como "30dp" en una int que se asemeja a la cantidad de píxeles. Esto significaría que StaticClass.theMethodImSearchingFor("16px") devolvería 16 .
Mi aplicación obtendrá estas cadenas dinámicamente y necesito una forma de almacenarlo como un valor de píxel para usarlo más adelante.
Ya he visto el código fuente de Android , principalmente las clases Resources , TypedArray y TypedValue , pero no pude encontrar nada útil.


Gracias a mindriot, funciona muy bien y es un salvavidas.

Aquí está en C #

Nota : Si por alguna razón no puede usar tipos enteros (vs int) (que serán enteros Java en Mono), dejé el código que usa C # int en los comentarios en todos los sitios asociados. Simplemente intercambie el código int comentado para el código entero sin comentar dondequiera que lo vea.

Tuve que usar Entero para que se pueda determinar si no hay coincidencia al verificar el Diccionario / Mapa (TryGetValue) de los sufijos (en cuyo caso será nulo; si se usan ints en su lugar, entonces el parámetro out será 0, que corresponde a la primera entrada del mapa, lo que obviamente no funciona. ¡Qué pena que TryGetValue no haya devuelto un valor negativo al no haber coincidencia !?).

public class DimensionConverter { // -- Initialize dimension string to constant lookup. //public static readonly Dictionary<string, int> dimensionConstantLookup = initDimensionConstantLookup(); public static readonly Dictionary<string, Integer> dimensionConstantLookup = initDimensionConstantLookup(); //private static Dictionary<string, int> initDimensionConstantLookup() private static Dictionary<string, Integer> initDimensionConstantLookup() { //Dictionary<string, int> m = new Dictionary<string, int>(); Dictionary<string, Integer> m = new Dictionary<string, Integer>(); m.Add("px", (Integer)((int)ComplexUnitType.Px)); m.Add("dip", (Integer)((int)ComplexUnitType.Dip)); m.Add("dp", (Integer)((int)ComplexUnitType.Dip)); m.Add("sp", (Integer)((int)ComplexUnitType.Sp)); m.Add("pt", (Integer)((int)ComplexUnitType.Pt)); m.Add("in", (Integer)((int)ComplexUnitType.In)); m.Add("mm", (Integer)((int)ComplexUnitType.Mm)); /*m.Add("px", (int)ComplexUnitType.Px); m.Add("dip", (int)ComplexUnitType.Dip); m.Add("dp", (int)ComplexUnitType.Dip); m.Add("sp", (int)ComplexUnitType.Sp); m.Add("pt", (int)ComplexUnitType.Pt); m.Add("in", (int)ComplexUnitType.In); m.Add("mm", (int)ComplexUnitType.Mm);*/ return m; } // -- Initialize pattern for dimension string. private static Regex DIMENSION_PATTERN = new Regex("^//s*(//d+(//.//d+)*)//s*([a-zA-Z]+)//s*$"); public static int stringToDimensionPixelSize(string dimension, DisplayMetrics metrics) { // -- Mimics TypedValue.complexToDimensionPixelSize(int data, DisplayMetrics metrics). InternalDimension internalDimension = stringToInternalDimension(dimension); float value = internalDimension.value; //float f = TypedValue.ApplyDimension((ComplexUnitType)internalDimension.unit, value, metrics); float f = TypedValue.ApplyDimension((ComplexUnitType)(int)internalDimension.unit, value, metrics); int res = (int)(f + 0.5f); if (res != 0) return res; if (value == 0) return 0; if (value > 0) return 1; return -1; } public static float stringToDimension(String dimension, DisplayMetrics metrics) { // -- Mimics TypedValue.complexToDimension(int data, DisplayMetrics metrics). InternalDimension internalDimension = stringToInternalDimension(dimension); //return TypedValue.ApplyDimension((ComplexUnitType)internalDimension.unit, internalDimension.value, metrics); return TypedValue.ApplyDimension((ComplexUnitType)(int)internalDimension.unit, internalDimension.value, metrics); } private static InternalDimension stringToInternalDimension(String dimension) { // -- Match target against pattern. MatchCollection matches = DIMENSION_PATTERN.Matches(dimension); if (matches.Count > 0) { Match matcher = matches[0]; // -- Match found. // -- Extract value. float value = Float.ValueOf(matcher.Groups[1].Value).FloatValue(); // -- Extract dimension units. string unit = matcher.Groups[3].ToString().ToLower(); // -- Get Android dimension constant. //int dimensionUnit; Integer dimensionUnit; dimensionConstantLookup.TryGetValue(unit, out dimensionUnit); //if (dimensionUnit == ????) if (dimensionUnit == null) { // -- Invalid format. throw new NumberFormatException(); } else { // -- Return valid dimension. return new InternalDimension(value, dimensionUnit); } } else { // -- Invalid format. throw new NumberFormatException(); } } private class InternalDimension { public float value; //public int unit; public Integer unit; //public InternalDimension(float value, int unit) public InternalDimension(float value, Integer unit) { this.value = value; this.unit = unit; } } }


Lo necesitaba yo mismo, así que escribí una clase para manejarlo. Todo el código de esta respuesta está autorizado bajo Apache License 2.0 . Disfrutar.

Hay dos métodos estáticos que imitan dos métodos TypedValue . DimensionConverter.stringToDimension () imita a TypedValue.complexToDimension . DimensionConverter.stringToDimensionPixelSize () imita a TypedValue.complexToDimensionPixelSize .

Admite todas las unidades actuales. Aceptará cadenas de dimensiones como "33sp", "44 dp" y lanzará una excepción para los formatos incorrectos.

Fácil de usar:

String dimension = "38dp"; Log.i(TAG, "Testing: " + dimension); try { Log.i(TAG, "Converts to: " + DimensionConverter.stringToDimension(dimension, resources.getDisplayMetrics())); } catch (NumberFormatException exception) { Log.i(TAG, "Unable to convert."); }

Clase aquí:

public class DimensionConverter { // -- Initialize dimension string to constant lookup. public static final Map<String, Integer> dimensionConstantLookup = initDimensionConstantLookup(); private static Map<String, Integer> initDimensionConstantLookup() { Map<String, Integer> m = new HashMap<String, Integer>(); m.put("px", TypedValue.COMPLEX_UNIT_PX); m.put("dip", TypedValue.COMPLEX_UNIT_DIP); m.put("dp", TypedValue.COMPLEX_UNIT_DIP); m.put("sp", TypedValue.COMPLEX_UNIT_SP); m.put("pt", TypedValue.COMPLEX_UNIT_PT); m.put("in", TypedValue.COMPLEX_UNIT_IN); m.put("mm", TypedValue.COMPLEX_UNIT_MM); return Collections.unmodifiableMap(m); } // -- Initialize pattern for dimension string. private static final Pattern DIMENSION_PATTERN = Pattern.compile("^//s*(//d+(//.//d+)*)//s*([a-zA-Z]+)//s*$"); public static int stringToDimensionPixelSize(String dimension, DisplayMetrics metrics) { // -- Mimics TypedValue.complexToDimensionPixelSize(int data, DisplayMetrics metrics). InternalDimension internalDimension = stringToInternalDimension(dimension); final float value = internalDimension.value; final float f = TypedValue.applyDimension(internalDimension.unit, value, metrics); final int res = (int)(f+0.5f); if (res != 0) return res; if (value == 0) return 0; if (value > 0) return 1; return -1; } public static float stringToDimension(String dimension, DisplayMetrics metrics) { // -- Mimics TypedValue.complexToDimension(int data, DisplayMetrics metrics). InternalDimension internalDimension = stringToInternalDimension(dimension); return TypedValue.applyDimension(internalDimension.unit, internalDimension.value, metrics); } private static InternalDimension stringToInternalDimension(String dimension) { // -- Match target against pattern. Matcher matcher = DIMENSION_PATTERN.matcher(dimension); if (matcher.matches()) { // -- Match found. // -- Extract value. float value = Float.valueOf(matcher.group(1)).floatValue(); // -- Extract dimension units. String unit = matcher.group(3).toLowerCase(); // -- Get Android dimension constant. Integer dimensionUnit = dimensionConstantLookup.get(unit); if (dimensionUnit == null) { // -- Invalid format. throw new NumberFormatException(); } else { // -- Return valid dimension. return new InternalDimension(value, dimensionUnit); } } else { // -- Invalid format. throw new NumberFormatException(); } } private static class InternalDimension { float value; int unit; public InternalDimension(float value, int unit) { this.value = value; this.unit = unit; } } }


Este enlace puede ayudarlo a determinar su conversión, sin embargo, dado que los píxeles y los píxeles independientes de la densidad no son un emparejamiento 1: 1, se esperan algunas distorsiones (menores).

Estas unidades (dp) son relativas a una pantalla de 160 ppp, por lo que una dp es un píxel en una pantalla de 160 ppp. La relación de dp-a-píxel cambiará con la densidad de la pantalla, pero no necesariamente en proporción directa.