blob: 7f1ee302903baa313f211c262106e9d6188d69e7 [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
2 * Copyright (C) 2007 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package android.util;
18
Tor Norbye7b9c9122013-05-30 16:48:33 -070019import android.annotation.AnyRes;
Alan Viveretteac85f902016-03-11 15:15:51 -050020import android.content.pm.ActivityInfo.Config;
Tor Norbye7b9c9122013-05-30 16:48:33 -070021
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080022/**
23 * Container for a dynamically typed data value. Primarily used with
24 * {@link android.content.res.Resources} for holding resource values.
25 */
26public class TypedValue {
27 /** The value contains no data. */
28 public static final int TYPE_NULL = 0x00;
29
30 /** The <var>data</var> field holds a resource identifier. */
31 public static final int TYPE_REFERENCE = 0x01;
32 /** The <var>data</var> field holds an attribute resource
33 * identifier (referencing an attribute in the current theme
34 * style, not a resource entry). */
35 public static final int TYPE_ATTRIBUTE = 0x02;
36 /** The <var>string</var> field holds string data. In addition, if
37 * <var>data</var> is non-zero then it is the string block
38 * index of the string and <var>assetCookie</var> is the set of
39 * assets the string came from. */
40 public static final int TYPE_STRING = 0x03;
41 /** The <var>data</var> field holds an IEEE 754 floating point number. */
42 public static final int TYPE_FLOAT = 0x04;
43 /** The <var>data</var> field holds a complex number encoding a
44 * dimension value. */
45 public static final int TYPE_DIMENSION = 0x05;
46 /** The <var>data</var> field holds a complex number encoding a fraction
47 * of a container. */
48 public static final int TYPE_FRACTION = 0x06;
49
50 /** Identifies the start of plain integer values. Any type value
51 * from this to {@link #TYPE_LAST_INT} means the
52 * <var>data</var> field holds a generic integer value. */
53 public static final int TYPE_FIRST_INT = 0x10;
54
55 /** The <var>data</var> field holds a number that was
56 * originally specified in decimal. */
57 public static final int TYPE_INT_DEC = 0x10;
58 /** The <var>data</var> field holds a number that was
59 * originally specified in hexadecimal (0xn). */
60 public static final int TYPE_INT_HEX = 0x11;
61 /** The <var>data</var> field holds 0 or 1 that was originally
62 * specified as "false" or "true". */
63 public static final int TYPE_INT_BOOLEAN = 0x12;
64
65 /** Identifies the start of integer values that were specified as
66 * color constants (starting with '#'). */
67 public static final int TYPE_FIRST_COLOR_INT = 0x1c;
68
69 /** The <var>data</var> field holds a color that was originally
70 * specified as #aarrggbb. */
71 public static final int TYPE_INT_COLOR_ARGB8 = 0x1c;
72 /** The <var>data</var> field holds a color that was originally
73 * specified as #rrggbb. */
74 public static final int TYPE_INT_COLOR_RGB8 = 0x1d;
75 /** The <var>data</var> field holds a color that was originally
76 * specified as #argb. */
77 public static final int TYPE_INT_COLOR_ARGB4 = 0x1e;
78 /** The <var>data</var> field holds a color that was originally
79 * specified as #rgb. */
80 public static final int TYPE_INT_COLOR_RGB4 = 0x1f;
81
82 /** Identifies the end of integer values that were specified as color
83 * constants. */
84 public static final int TYPE_LAST_COLOR_INT = 0x1f;
85
86 /** Identifies the end of plain integer values. */
87 public static final int TYPE_LAST_INT = 0x1f;
88
89 /* ------------------------------------------------------------ */
90
91 /** Complex data: bit location of unit information. */
92 public static final int COMPLEX_UNIT_SHIFT = 0;
93 /** Complex data: mask to extract unit information (after shifting by
94 * {@link #COMPLEX_UNIT_SHIFT}). This gives us 16 possible types, as
95 * defined below. */
96 public static final int COMPLEX_UNIT_MASK = 0xf;
97
98 /** {@link #TYPE_DIMENSION} complex unit: Value is raw pixels. */
99 public static final int COMPLEX_UNIT_PX = 0;
100 /** {@link #TYPE_DIMENSION} complex unit: Value is Device Independent
101 * Pixels. */
102 public static final int COMPLEX_UNIT_DIP = 1;
103 /** {@link #TYPE_DIMENSION} complex unit: Value is a scaled pixel. */
104 public static final int COMPLEX_UNIT_SP = 2;
105 /** {@link #TYPE_DIMENSION} complex unit: Value is in points. */
106 public static final int COMPLEX_UNIT_PT = 3;
107 /** {@link #TYPE_DIMENSION} complex unit: Value is in inches. */
108 public static final int COMPLEX_UNIT_IN = 4;
109 /** {@link #TYPE_DIMENSION} complex unit: Value is in millimeters. */
110 public static final int COMPLEX_UNIT_MM = 5;
111
112 /** {@link #TYPE_FRACTION} complex unit: A basic fraction of the overall
113 * size. */
114 public static final int COMPLEX_UNIT_FRACTION = 0;
115 /** {@link #TYPE_FRACTION} complex unit: A fraction of the parent size. */
116 public static final int COMPLEX_UNIT_FRACTION_PARENT = 1;
117
118 /** Complex data: where the radix information is, telling where the decimal
119 * place appears in the mantissa. */
120 public static final int COMPLEX_RADIX_SHIFT = 4;
121 /** Complex data: mask to extract radix information (after shifting by
122 * {@link #COMPLEX_RADIX_SHIFT}). This give us 4 possible fixed point
123 * representations as defined below. */
124 public static final int COMPLEX_RADIX_MASK = 0x3;
125
126 /** Complex data: the mantissa is an integral number -- i.e., 0xnnnnnn.0 */
127 public static final int COMPLEX_RADIX_23p0 = 0;
128 /** Complex data: the mantissa magnitude is 16 bits -- i.e, 0xnnnn.nn */
129 public static final int COMPLEX_RADIX_16p7 = 1;
130 /** Complex data: the mantissa magnitude is 8 bits -- i.e, 0xnn.nnnn */
131 public static final int COMPLEX_RADIX_8p15 = 2;
132 /** Complex data: the mantissa magnitude is 0 bits -- i.e, 0x0.nnnnnn */
133 public static final int COMPLEX_RADIX_0p23 = 3;
134
135 /** Complex data: bit location of mantissa information. */
136 public static final int COMPLEX_MANTISSA_SHIFT = 8;
137 /** Complex data: mask to extract mantissa information (after shifting by
138 * {@link #COMPLEX_MANTISSA_SHIFT}). This gives us 23 bits of precision;
139 * the top bit is the sign. */
140 public static final int COMPLEX_MANTISSA_MASK = 0xffffff;
141
142 /* ------------------------------------------------------------ */
143
144 /**
Alan Viverettef2969402014-10-29 17:09:36 -0700145 * {@link #TYPE_NULL} data indicating the value was not specified.
146 */
147 public static final int DATA_NULL_UNDEFINED = 0;
148 /**
149 * {@link #TYPE_NULL} data indicating the value was explicitly set to null.
150 */
151 public static final int DATA_NULL_EMPTY = 1;
152
153 /* ------------------------------------------------------------ */
154
155 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800156 * If {@link #density} is equal to this value, then the density should be
Dianne Hackborna53b8282009-07-17 11:13:48 -0700157 * treated as the system's default density value: {@link DisplayMetrics#DENSITY_DEFAULT}.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800158 */
159 public static final int DENSITY_DEFAULT = 0;
160
Dianne Hackborna53b8282009-07-17 11:13:48 -0700161 /**
162 * If {@link #density} is equal to this value, then there is no density
163 * associated with the resource and it should not be scaled.
164 */
165 public static final int DENSITY_NONE = 0xffff;
166
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800167 /* ------------------------------------------------------------ */
168
169 /** The type held by this value, as defined by the constants here.
170 * This tells you how to interpret the other fields in the object. */
171 public int type;
172
173 /** If the value holds a string, this is it. */
174 public CharSequence string;
175
176 /** Basic data in the value, interpreted according to {@link #type} */
177 public int data;
178
179 /** Additional information about where the value came from; only
180 * set for strings. */
181 public int assetCookie;
182
183 /** If Value came from a resource, this holds the corresponding resource id. */
Tor Norbye7b9c9122013-05-30 16:48:33 -0700184 @AnyRes
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800185 public int resourceId;
186
Alan Viveretteac85f902016-03-11 15:15:51 -0500187 /**
188 * If the value came from a resource, these are the configurations for
189 * which its contents can change.
Adam Lesinski41a2fb12017-04-12 15:05:53 -0700190 *
191 * <p>For example, if a resource has a value defined for the -land resource qualifier,
192 * this field will have the {@link android.content.pm.ActivityInfo#CONFIG_ORIENTATION} bit set.
193 * </p>
194 *
195 * @see android.content.pm.ActivityInfo#CONFIG_MCC
196 * @see android.content.pm.ActivityInfo#CONFIG_MNC
197 * @see android.content.pm.ActivityInfo#CONFIG_LOCALE
198 * @see android.content.pm.ActivityInfo#CONFIG_TOUCHSCREEN
199 * @see android.content.pm.ActivityInfo#CONFIG_KEYBOARD
200 * @see android.content.pm.ActivityInfo#CONFIG_KEYBOARD_HIDDEN
201 * @see android.content.pm.ActivityInfo#CONFIG_NAVIGATION
202 * @see android.content.pm.ActivityInfo#CONFIG_ORIENTATION
203 * @see android.content.pm.ActivityInfo#CONFIG_SCREEN_LAYOUT
204 * @see android.content.pm.ActivityInfo#CONFIG_UI_MODE
205 * @see android.content.pm.ActivityInfo#CONFIG_SCREEN_SIZE
206 * @see android.content.pm.ActivityInfo#CONFIG_SMALLEST_SCREEN_SIZE
207 * @see android.content.pm.ActivityInfo#CONFIG_DENSITY
208 * @see android.content.pm.ActivityInfo#CONFIG_LAYOUT_DIRECTION
209 * @see android.content.pm.ActivityInfo#CONFIG_COLOR_MODE
210 *
Alan Viveretteac85f902016-03-11 15:15:51 -0500211 */
212 public @Config int changingConfigurations = -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800213
214 /**
215 * If the Value came from a resource, this holds the corresponding pixel density.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800216 * */
217 public int density;
218
Aurimas Liutikasce7c99c2018-12-18 16:20:49 -0800219 /**
Aurimas Liutikas949b05d2019-01-30 17:20:41 -0800220 * If the Value came from a style resource or a layout resource (set in an XML layout), this
221 * holds the corresponding style or layout resource id against which the attribute was resolved.
Aurimas Liutikasce7c99c2018-12-18 16:20:49 -0800222 */
Aurimas Liutikas949b05d2019-01-30 17:20:41 -0800223 public int sourceResourceId;
Aurimas Liutikasce7c99c2018-12-18 16:20:49 -0800224
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800225 /* ------------------------------------------------------------ */
226
227 /** Return the data for this value as a float. Only use for values
228 * whose type is {@link #TYPE_FLOAT}. */
229 public final float getFloat() {
230 return Float.intBitsToFloat(data);
231 }
232
233 private static final float MANTISSA_MULT =
234 1.0f / (1<<TypedValue.COMPLEX_MANTISSA_SHIFT);
235 private static final float[] RADIX_MULTS = new float[] {
236 1.0f*MANTISSA_MULT, 1.0f/(1<<7)*MANTISSA_MULT,
237 1.0f/(1<<15)*MANTISSA_MULT, 1.0f/(1<<23)*MANTISSA_MULT
238 };
239
240 /**
Ashley Rose2b9a3352018-09-06 19:00:48 -0400241 * Determine if a value is a color.
242 *
243 * This works by comparing {@link #type} to {@link #TYPE_FIRST_COLOR_INT}
Ashley Roseaa554ae2018-09-05 16:04:01 -0400244 * and {@link #TYPE_LAST_COLOR_INT}.
245 *
246 * @return true if this value is a color
247 */
248 public boolean isColorType() {
249 return (type >= TYPE_FIRST_COLOR_INT && type <= TYPE_LAST_COLOR_INT);
250 }
251
252 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800253 * Retrieve the base value from a complex data integer. This uses the
254 * {@link #COMPLEX_MANTISSA_MASK} and {@link #COMPLEX_RADIX_MASK} fields of
255 * the data to compute a floating point representation of the number they
256 * describe. The units are ignored.
257 *
258 * @param complex A complex data value.
259 *
260 * @return A floating point value corresponding to the complex data.
261 */
262 public static float complexToFloat(int complex)
263 {
264 return (complex&(TypedValue.COMPLEX_MANTISSA_MASK
265 <<TypedValue.COMPLEX_MANTISSA_SHIFT))
266 * RADIX_MULTS[(complex>>TypedValue.COMPLEX_RADIX_SHIFT)
267 & TypedValue.COMPLEX_RADIX_MASK];
268 }
269
270 /**
271 * Converts a complex data value holding a dimension to its final floating
272 * point value. The given <var>data</var> must be structured as a
273 * {@link #TYPE_DIMENSION}.
274 *
275 * @param data A complex data value holding a unit, magnitude, and
276 * mantissa.
277 * @param metrics Current display metrics to use in the conversion --
278 * supplies display density and scaling information.
279 *
280 * @return The complex floating point value multiplied by the appropriate
281 * metrics depending on its unit.
282 */
283 public static float complexToDimension(int data, DisplayMetrics metrics)
284 {
285 return applyDimension(
286 (data>>COMPLEX_UNIT_SHIFT)&COMPLEX_UNIT_MASK,
287 complexToFloat(data),
288 metrics);
289 }
290
291 /**
292 * Converts a complex data value holding a dimension to its final value
293 * as an integer pixel offset. This is the same as
294 * {@link #complexToDimension}, except the raw floating point value is
295 * truncated to an integer (pixel) value.
296 * The given <var>data</var> must be structured as a
297 * {@link #TYPE_DIMENSION}.
298 *
299 * @param data A complex data value holding a unit, magnitude, and
300 * mantissa.
301 * @param metrics Current display metrics to use in the conversion --
302 * supplies display density and scaling information.
303 *
304 * @return The number of pixels specified by the data and its desired
305 * multiplier and units.
306 */
307 public static int complexToDimensionPixelOffset(int data,
308 DisplayMetrics metrics)
309 {
310 return (int)applyDimension(
311 (data>>COMPLEX_UNIT_SHIFT)&COMPLEX_UNIT_MASK,
312 complexToFloat(data),
313 metrics);
314 }
315
316 /**
317 * Converts a complex data value holding a dimension to its final value
318 * as an integer pixel size. This is the same as
319 * {@link #complexToDimension}, except the raw floating point value is
320 * converted to an integer (pixel) value for use as a size. A size
321 * conversion involves rounding the base value, and ensuring that a
322 * non-zero base value is at least one pixel in size.
323 * The given <var>data</var> must be structured as a
324 * {@link #TYPE_DIMENSION}.
325 *
326 * @param data A complex data value holding a unit, magnitude, and
327 * mantissa.
328 * @param metrics Current display metrics to use in the conversion --
329 * supplies display density and scaling information.
330 *
331 * @return The number of pixels specified by the data and its desired
332 * multiplier and units.
333 */
334 public static int complexToDimensionPixelSize(int data,
335 DisplayMetrics metrics)
336 {
337 final float value = complexToFloat(data);
338 final float f = applyDimension(
339 (data>>COMPLEX_UNIT_SHIFT)&COMPLEX_UNIT_MASK,
340 value,
341 metrics);
Chet Haase724792d2016-06-07 16:05:12 -0700342 final int res = (int) ((f >= 0) ? (f + 0.5f) : (f - 0.5f));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800343 if (res != 0) return res;
344 if (value == 0) return 0;
345 if (value > 0) return 1;
346 return -1;
347 }
348
Jeff Brown8aca9e32014-01-24 12:40:23 -0800349 /**
350 * @hide Was accidentally exposed in API level 1 for debugging purposes.
351 * Kept for compatibility just in case although the debugging code has been removed.
352 */
353 @Deprecated
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800354 public static float complexToDimensionNoisy(int data, DisplayMetrics metrics)
355 {
Jeff Brown8aca9e32014-01-24 12:40:23 -0800356 return complexToDimension(data, metrics);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800357 }
358
359 /**
Christopher Lane9f357ae2014-10-31 14:52:06 -0700360 * Return the complex unit type for this value. For example, a dimen type
361 * with value 12sp will return {@link #COMPLEX_UNIT_SP}. Only use for values
362 * whose type is {@link #TYPE_DIMENSION}.
363 *
364 * @return The complex unit type.
365 */
366 public int getComplexUnit()
367 {
368 return COMPLEX_UNIT_MASK & (data>>TypedValue.COMPLEX_UNIT_SHIFT);
369 }
370
371 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800372 * Converts an unpacked complex data value holding a dimension to its final floating
373 * point value. The two parameters <var>unit</var> and <var>value</var>
374 * are as in {@link #TYPE_DIMENSION}.
375 *
376 * @param unit The unit to convert from.
377 * @param value The value to apply the unit to.
378 * @param metrics Current display metrics to use in the conversion --
379 * supplies display density and scaling information.
380 *
381 * @return The complex floating point value multiplied by the appropriate
382 * metrics depending on its unit.
383 */
384 public static float applyDimension(int unit, float value,
385 DisplayMetrics metrics)
386 {
387 switch (unit) {
388 case COMPLEX_UNIT_PX:
389 return value;
390 case COMPLEX_UNIT_DIP:
391 return value * metrics.density;
392 case COMPLEX_UNIT_SP:
393 return value * metrics.scaledDensity;
394 case COMPLEX_UNIT_PT:
395 return value * metrics.xdpi * (1.0f/72);
396 case COMPLEX_UNIT_IN:
397 return value * metrics.xdpi;
398 case COMPLEX_UNIT_MM:
399 return value * metrics.xdpi * (1.0f/25.4f);
400 }
401 return 0;
402 }
403
404 /**
405 * Return the data for this value as a dimension. Only use for values
406 * whose type is {@link #TYPE_DIMENSION}.
407 *
408 * @param metrics Current display metrics to use in the conversion --
409 * supplies display density and scaling information.
410 *
411 * @return The complex floating point value multiplied by the appropriate
412 * metrics depending on its unit.
413 */
414 public float getDimension(DisplayMetrics metrics)
415 {
416 return complexToDimension(data, metrics);
417 }
418
419 /**
420 * Converts a complex data value holding a fraction to its final floating
421 * point value. The given <var>data</var> must be structured as a
422 * {@link #TYPE_FRACTION}.
423 *
424 * @param data A complex data value holding a unit, magnitude, and
425 * mantissa.
426 * @param base The base value of this fraction. In other words, a
427 * standard fraction is multiplied by this value.
428 * @param pbase The parent base value of this fraction. In other
429 * words, a parent fraction (nn%p) is multiplied by this
430 * value.
431 *
432 * @return The complex floating point value multiplied by the appropriate
433 * base value depending on its unit.
434 */
435 public static float complexToFraction(int data, float base, float pbase)
436 {
437 switch ((data>>COMPLEX_UNIT_SHIFT)&COMPLEX_UNIT_MASK) {
438 case COMPLEX_UNIT_FRACTION:
439 return complexToFloat(data) * base;
440 case COMPLEX_UNIT_FRACTION_PARENT:
441 return complexToFloat(data) * pbase;
442 }
443 return 0;
444 }
445
446 /**
447 * Return the data for this value as a fraction. Only use for values whose
448 * type is {@link #TYPE_FRACTION}.
449 *
450 * @param base The base value of this fraction. In other words, a
451 * standard fraction is multiplied by this value.
452 * @param pbase The parent base value of this fraction. In other
453 * words, a parent fraction (nn%p) is multiplied by this
454 * value.
455 *
456 * @return The complex floating point value multiplied by the appropriate
457 * base value depending on its unit.
458 */
459 public float getFraction(float base, float pbase)
460 {
461 return complexToFraction(data, base, pbase);
462 }
463
464 /**
465 * Regardless of the actual type of the value, try to convert it to a
466 * string value. For example, a color type will be converted to a
467 * string of the form #aarrggbb.
468 *
469 * @return CharSequence The coerced string value. If the value is
470 * null or the type is not known, null is returned.
471 */
472 public final CharSequence coerceToString()
473 {
474 int t = type;
475 if (t == TYPE_STRING) {
476 return string;
477 }
478 return coerceToString(t, data);
479 }
480
481 private static final String[] DIMENSION_UNIT_STRS = new String[] {
482 "px", "dip", "sp", "pt", "in", "mm"
483 };
484 private static final String[] FRACTION_UNIT_STRS = new String[] {
485 "%", "%p"
486 };
487
488 /**
489 * Perform type conversion as per {@link #coerceToString()} on an
490 * explicitly supplied type and data.
491 *
492 * @param type The data type identifier.
493 * @param data The data value.
494 *
495 * @return String The coerced string value. If the value is
496 * null or the type is not known, null is returned.
497 */
498 public static final String coerceToString(int type, int data)
499 {
500 switch (type) {
501 case TYPE_NULL:
502 return null;
503 case TYPE_REFERENCE:
504 return "@" + data;
505 case TYPE_ATTRIBUTE:
506 return "?" + data;
507 case TYPE_FLOAT:
508 return Float.toString(Float.intBitsToFloat(data));
509 case TYPE_DIMENSION:
510 return Float.toString(complexToFloat(data)) + DIMENSION_UNIT_STRS[
511 (data>>COMPLEX_UNIT_SHIFT)&COMPLEX_UNIT_MASK];
512 case TYPE_FRACTION:
513 return Float.toString(complexToFloat(data)*100) + FRACTION_UNIT_STRS[
514 (data>>COMPLEX_UNIT_SHIFT)&COMPLEX_UNIT_MASK];
515 case TYPE_INT_HEX:
516 return "0x" + Integer.toHexString(data);
517 case TYPE_INT_BOOLEAN:
518 return data != 0 ? "true" : "false";
519 }
520
521 if (type >= TYPE_FIRST_COLOR_INT && type <= TYPE_LAST_COLOR_INT) {
522 return "#" + Integer.toHexString(data);
523 } else if (type >= TYPE_FIRST_INT && type <= TYPE_LAST_INT) {
524 return Integer.toString(data);
525 }
526
527 return null;
528 }
529
530 public void setTo(TypedValue other)
531 {
532 type = other.type;
533 string = other.string;
534 data = other.data;
535 assetCookie = other.assetCookie;
536 resourceId = other.resourceId;
537 density = other.density;
538 }
539
540 public String toString()
541 {
542 StringBuilder sb = new StringBuilder();
543 sb.append("TypedValue{t=0x").append(Integer.toHexString(type));
544 sb.append("/d=0x").append(Integer.toHexString(data));
545 if (type == TYPE_STRING) {
546 sb.append(" \"").append(string != null ? string : "<null>").append("\"");
547 }
548 if (assetCookie != 0) {
549 sb.append(" a=").append(assetCookie);
550 }
551 if (resourceId != 0) {
552 sb.append(" r=0x").append(Integer.toHexString(resourceId));
553 }
554 sb.append("}");
555 return sb.toString();
556 }
557};
558