Android使用TypedValue将dp/sp等转换为px的方式介绍

一、之前习惯的dp转px和sp转px的写法

import android.content.Context;

/**
 * 尺寸转换工具
 * <p>
 * Created by ouyangpeng on 2015/9/21.
 */
public class SizeConvertUtil {
    /**
     * 根据手机的分辨率从 dp 的单位 转成为 px(像素)
     *
     * @param context 上下文
     * @param dp      dp的值
     * @return px的值
     */
    public static int dpTopx(Context context, float dp) {
        final float scale = context.getResources().getDisplayMetrics().density;
        return (int) (dp * scale + 0.5f);
    }

    /**
     * 根据手机的分辨率从 px(像素) 的单位 转成为 dp
     *
     * @param context 上下文
     * @param px      px的值
     * @return dp的值
     */
    public static int pxTodp(Context context, float px) {
        final float scale = context.getResources().getDisplayMetrics().density;
        return (int) (px / scale + 0.5f);
    }

    /**
     * 将px值转换为sp值,保证文字大小不变
     *
     * @param context 上下文
     * @param px      px的值
     * @return sp的值
     */
    public static int pxTosp(Context context, float px) {
        //DisplayMetrics类中属性scaledDensity
        final float fontScale = context.getResources().getDisplayMetrics().scaledDensity;
        return (int) (px / fontScale + 0.5f);
    }

    /**
     * 将sp值转换为px值,保证文字大小不变
     *
     * @param context 上下文
     * @param sp      sp的值
     * @return px的值
     */
    public static int spTopx(Context context, float sp) {
        //DisplayMetrics类中属性scaledDensity
        final float fontScale = context.getResources().getDisplayMetrics().scaledDensity;
        return (int) (sp * fontScale + 0.5f);
    }
}


二、另一种转换方式:TypedValue
2.1 android.widget.TextView的源码
今天在看android.widget.TextView的源码的时候,发现使用了 TypedValue。

android.widget.TextView#setTextSize(float) 方法源代码如下


    /**
     * Set the default text size to the given value, interpreted as "scaled
     * pixel" units.  This size is adjusted based on the current density and
     * user font size preference.
     *
     * <p>Note: if this TextView has the auto-size feature enabled than this function is no-op.
     *
     * @param size The scaled pixel size.
     *
     * @attr ref android.R.styleable#TextView_textSize
     */
    @android.view.RemotableViewMethod
    public void setTextSize(float size) {
        setTextSize(TypedValue.COMPLEX_UNIT_SP, size);
    }

使用了TypedValue.COMPLEX_UNIT_SP 这个单位,

    /** {@link #TYPE_DIMENSION} complex unit: Value is raw pixels. */
    public static final int COMPLEX_UNIT_PX = 0;
    /** {@link #TYPE_DIMENSION} complex unit: Value is Device Independent
     *  Pixels. */
    public static final int COMPLEX_UNIT_DIP = 1;
    /** {@link #TYPE_DIMENSION} complex unit: Value is a scaled pixel. */
    public static final int COMPLEX_UNIT_SP = 2;
    /** {@link #TYPE_DIMENSION} complex unit: Value is in points. */
    public static final int COMPLEX_UNIT_PT = 3;
    /** {@link #TYPE_DIMENSION} complex unit: Value is in inches. */
    public static final int COMPLEX_UNIT_IN = 4;
    /** {@link #TYPE_DIMENSION} complex unit: Value is in millimeters. */
    public static final int COMPLEX_UNIT_MM = 5;

上面调用的方法 android.widget.TextView#setTextSize(int, float)源代码如下


    /**
     * Set the default text size to a given unit and value. See {@link
     * TypedValue} for the possible dimension units.
     *
     * <p>Note: if this TextView has the auto-size feature enabled than this function is no-op.
     *
     * @param unit The desired dimension unit.
     * @param size The desired size in the given units.
     *
     * @attr ref android.R.styleable#TextView_textSize
     */
    public void setTextSize(int unit, float size) {
        if (!isAutoSizeEnabled()) {
            setTextSizeInternal(unit, size, true /* shouldRequestLayout */);
        }
    }

上面调用的方法 android.widget.TextView#setTextSizeInternal 源代码如下

    private void setTextSizeInternal(int unit, float size, boolean shouldRequestLayout) {
        Context c = getContext();
        Resources r;

        if (c == null) {
            r = Resources.getSystem();
        } else {
            r = c.getResources();
        }

        setRawTextSize(TypedValue.applyDimension(unit, size, r.getDisplayMetrics()),
                shouldRequestLayout);
    }

2.2 android.util.TypedValue#applyDimension方法的源码
上面调用的方法 android.util.TypedValue#applyDimension 源代码如下


 /**
     * Converts an unpacked complex data value holding a dimension to its final floating 
     * point value. The two parameters <var>unit</var> and <var>value</var>
     * are as in {@link #TYPE_DIMENSION}.
     *  
     * @param unit The unit to convert from.
     * @param value The value to apply the unit to.
     * @param metrics Current display metrics to use in the conversion -- 
     *                supplies display density and scaling information.
     * 
     * @return The complex floating point value multiplied by the appropriate 
     * metrics depending on its unit. 
     */
    public static float applyDimension(int unit, float value,
                                       DisplayMetrics metrics)
    {
        switch (unit) {
        case COMPLEX_UNIT_PX:
            return value;
        case COMPLEX_UNIT_DIP:
            return value * metrics.density;
        case COMPLEX_UNIT_SP:
            return value * metrics.scaledDensity;
        case COMPLEX_UNIT_PT:
            return value * metrics.xdpi * (1.0f/72);
        case COMPLEX_UNIT_IN:
            return value * metrics.xdpi;
        case COMPLEX_UNIT_MM:
            return value * metrics.xdpi * (1.0f/25.4f);
        }
        return 0;
    }

2.3 android.util.TypedValue#applyDimension方法的使用
这个方法的作用是 把Android系统中的非标准度量尺寸转变为标准度量尺寸 (Android系统中的标准尺寸是px, 即像素)

标准单位
px (px是安卓系统内部使用的单位, dp是与设备无关的尺寸单位 )

非标准单位
dp, in, mm, pt, sp

TypedValue.applyDimension()方法的功能就是把非标准尺寸转换成标准尺寸, 比如:

dp->px
TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 20, context.getResources().getDisplayMetrics());

in->px
TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_IN, 20, context.getResources().getDisplayMetrics());

mm->px
 TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_MM, 20, context.getResources().getDisplayMetrics());

pt->px
 TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_PT, 20, context.getResources().getDisplayMetrics());

sp->px
 TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, 20, context.getResources().getDisplayMetrics());

这样我们就可以使用系统自带的android.util.TypedValue#applyDimension来转换 非标准单位为 标准单位px了。三、android.util.TypedValue的源代码

/*
 * Copyright (C) 2007 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.util;

import android.annotation.AnyRes;
import android.content.pm.ActivityInfo.Config;

/**
 * Container for a dynamically typed data value.  Primarily used with
 * {@link android.content.res.Resources} for holding resource values.
 */
public class TypedValue {
    /** The value contains no data. */
    public static final int TYPE_NULL = 0x00;

    /** The <var>data</var> field holds a resource identifier. */
    public static final int TYPE_REFERENCE = 0x01;
    /** The <var>data</var> field holds an attribute resource
     *  identifier (referencing an attribute in the current theme
     *  style, not a resource entry). */
    public static final int TYPE_ATTRIBUTE = 0x02;
    /** The <var>string</var> field holds string data.  In addition, if
     *  <var>data</var> is non-zero then it is the string block
     *  index of the string and <var>assetCookie</var> is the set of
     *  assets the string came from. */
    public static final int TYPE_STRING = 0x03;
    /** The <var>data</var> field holds an IEEE 754 floating point number. */
    public static final int TYPE_FLOAT = 0x04;
    /** The <var>data</var> field holds a complex number encoding a
     *  dimension value. */
    public static final int TYPE_DIMENSION = 0x05;
    /** The <var>data</var> field holds a complex number encoding a fraction
     *  of a container. */
    public static final int TYPE_FRACTION = 0x06;

    /** Identifies the start of plain integer values.  Any type value
     *  from this to {@link #TYPE_LAST_INT} means the
     *  <var>data</var> field holds a generic integer value. */
    public static final int TYPE_FIRST_INT = 0x10;

    /** The <var>data</var> field holds a number that was
     *  originally specified in decimal. */
    public static final int TYPE_INT_DEC = 0x10;
    /** The <var>data</var> field holds a number that was
     *  originally specified in hexadecimal (0xn). */
    public static final int TYPE_INT_HEX = 0x11;
    /** The <var>data</var> field holds 0 or 1 that was originally
     *  specified as "false" or "true". */
    public static final int TYPE_INT_BOOLEAN = 0x12;

    /** Identifies the start of integer values that were specified as
     *  color constants (starting with '#'). */
    public static final int TYPE_FIRST_COLOR_INT = 0x1c;

    /** The <var>data</var> field holds a color that was originally
     *  specified as #aarrggbb. */
    public static final int TYPE_INT_COLOR_ARGB8 = 0x1c;
    /** The <var>data</var> field holds a color that was originally
     *  specified as #rrggbb. */
    public static final int TYPE_INT_COLOR_RGB8 = 0x1d;
    /** The <var>data</var> field holds a color that was originally
     *  specified as #argb. */
    public static final int TYPE_INT_COLOR_ARGB4 = 0x1e;
    /** The <var>data</var> field holds a color that was originally
     *  specified as #rgb. */
    public static final int TYPE_INT_COLOR_RGB4 = 0x1f;

    /** Identifies the end of integer values that were specified as color
     *  constants. */
    public static final int TYPE_LAST_COLOR_INT = 0x1f;

    /** Identifies the end of plain integer values. */
    public static final int TYPE_LAST_INT = 0x1f;

    /* ------------------------------------------------------------ */

    /** Complex data: bit location of unit information. */
    public static final int COMPLEX_UNIT_SHIFT = 0;
    /** Complex data: mask to extract unit information (after shifting by
     *  {@link #COMPLEX_UNIT_SHIFT}). This gives us 16 possible types, as
     *  defined below. */
    public static final int COMPLEX_UNIT_MASK = 0xf;

    /** {@link #TYPE_DIMENSION} complex unit: Value is raw pixels. */
    public static final int COMPLEX_UNIT_PX = 0;
    /** {@link #TYPE_DIMENSION} complex unit: Value is Device Independent
     *  Pixels. */
    public static final int COMPLEX_UNIT_DIP = 1;
    /** {@link #TYPE_DIMENSION} complex unit: Value is a scaled pixel. */
    public static final int COMPLEX_UNIT_SP = 2;
    /** {@link #TYPE_DIMENSION} complex unit: Value is in points. */
    public static final int COMPLEX_UNIT_PT = 3;
    /** {@link #TYPE_DIMENSION} complex unit: Value is in inches. */
    public static final int COMPLEX_UNIT_IN = 4;
    /** {@link #TYPE_DIMENSION} complex unit: Value is in millimeters. */
    public static final int COMPLEX_UNIT_MM = 5;

    /** {@link #TYPE_FRACTION} complex unit: A basic fraction of the overall
     *  size. */
    public static final int COMPLEX_UNIT_FRACTION = 0;
    /** {@link #TYPE_FRACTION} complex unit: A fraction of the parent size. */
    public static final int COMPLEX_UNIT_FRACTION_PARENT = 1;

    /** Complex data: where the radix information is, telling where the decimal
     *  place appears in the mantissa. */
    public static final int COMPLEX_RADIX_SHIFT = 4;
    /** Complex data: mask to extract radix information (after shifting by
     * {@link #COMPLEX_RADIX_SHIFT}). This give us 4 possible fixed point 
     * representations as defined below. */ 
    public static final int COMPLEX_RADIX_MASK = 0x3;

    /** Complex data: the mantissa is an integral number -- i.e., 0xnnnnnn.0 */
    public static final int COMPLEX_RADIX_23p0 = 0;
    /** Complex data: the mantissa magnitude is 16 bits -- i.e, 0xnnnn.nn */
    public static final int COMPLEX_RADIX_16p7 = 1;
    /** Complex data: the mantissa magnitude is 8 bits -- i.e, 0xnn.nnnn */
    public static final int COMPLEX_RADIX_8p15 = 2;
    /** Complex data: the mantissa magnitude is 0 bits -- i.e, 0x0.nnnnnn */
    public static final int COMPLEX_RADIX_0p23 = 3;

    /** Complex data: bit location of mantissa information. */
    public static final int COMPLEX_MANTISSA_SHIFT = 8;
    /** Complex data: mask to extract mantissa information (after shifting by
     *  {@link #COMPLEX_MANTISSA_SHIFT}). This gives us 23 bits of precision;
     *  the top bit is the sign. */
    public static final int COMPLEX_MANTISSA_MASK = 0xffffff;

    /* ------------------------------------------------------------ */

    /**
     * {@link #TYPE_NULL} data indicating the value was not specified.
     */
    public static final int DATA_NULL_UNDEFINED = 0;
    /**
     * {@link #TYPE_NULL} data indicating the value was explicitly set to null.
     */
    public static final int DATA_NULL_EMPTY = 1;

    /* ------------------------------------------------------------ */

    /**
     * If {@link #density} is equal to this value, then the density should be
     * treated as the system's default density value: {@link DisplayMetrics#DENSITY_DEFAULT}.
     */
    public static final int DENSITY_DEFAULT = 0;

    /**
     * If {@link #density} is equal to this value, then there is no density
     * associated with the resource and it should not be scaled.
     */
    public static final int DENSITY_NONE = 0xffff;

    /* ------------------------------------------------------------ */

    /** The type held by this value, as defined by the constants here.
     *  This tells you how to interpret the other fields in the object. */
    public int type;

    /** If the value holds a string, this is it. */
    public CharSequence string;

    /** Basic data in the value, interpreted according to {@link #type} */
    public int data;

    /** Additional information about where the value came from; only
     *  set for strings. */
    public int assetCookie;

    /** If Value came from a resource, this holds the corresponding resource id. */
    @AnyRes
    public int resourceId;

    /**
     * If the value came from a resource, these are the configurations for
     * which its contents can change.
     *
     * <p>For example, if a resource has a value defined for the -land resource qualifier,
     * this field will have the {@link android.content.pm.ActivityInfo#CONFIG_ORIENTATION} bit set.
     * </p>
     *
     * @see android.content.pm.ActivityInfo#CONFIG_MCC
     * @see android.content.pm.ActivityInfo#CONFIG_MNC
     * @see android.content.pm.ActivityInfo#CONFIG_LOCALE
     * @see android.content.pm.ActivityInfo#CONFIG_TOUCHSCREEN
     * @see android.content.pm.ActivityInfo#CONFIG_KEYBOARD
     * @see android.content.pm.ActivityInfo#CONFIG_KEYBOARD_HIDDEN
     * @see android.content.pm.ActivityInfo#CONFIG_NAVIGATION
     * @see android.content.pm.ActivityInfo#CONFIG_ORIENTATION
     * @see android.content.pm.ActivityInfo#CONFIG_SCREEN_LAYOUT
     * @see android.content.pm.ActivityInfo#CONFIG_UI_MODE
     * @see android.content.pm.ActivityInfo#CONFIG_SCREEN_SIZE
     * @see android.content.pm.ActivityInfo#CONFIG_SMALLEST_SCREEN_SIZE
     * @see android.content.pm.ActivityInfo#CONFIG_DENSITY
     * @see android.content.pm.ActivityInfo#CONFIG_LAYOUT_DIRECTION
     * @see android.content.pm.ActivityInfo#CONFIG_COLOR_MODE
     *
     */
    public @Config int changingConfigurations = -1;

    /**
     * If the Value came from a resource, this holds the corresponding pixel density.
     * */
    public int density;

    /* ------------------------------------------------------------ */

    /** Return the data for this value as a float.  Only use for values
     *  whose type is {@link #TYPE_FLOAT}. */
    public final float getFloat() {
        return Float.intBitsToFloat(data);
    }

    private static final float MANTISSA_MULT =
        1.0f / (1<<TypedValue.COMPLEX_MANTISSA_SHIFT);
    private static final float[] RADIX_MULTS = new float[] {
        1.0f*MANTISSA_MULT, 1.0f/(1<<7)*MANTISSA_MULT,
        1.0f/(1<<15)*MANTISSA_MULT, 1.0f/(1<<23)*MANTISSA_MULT
    };

    /**
     * Retrieve the base value from a complex data integer.  This uses the 
     * {@link #COMPLEX_MANTISSA_MASK} and {@link #COMPLEX_RADIX_MASK} fields of 
     * the data to compute a floating point representation of the number they 
     * describe.  The units are ignored. 
     *  
     * @param complex A complex data value.
     * 
     * @return A floating point value corresponding to the complex data.
     */
    public static float complexToFloat(int complex)
    {
        return (complex&(TypedValue.COMPLEX_MANTISSA_MASK
                   <<TypedValue.COMPLEX_MANTISSA_SHIFT))
            * RADIX_MULTS[(complex>>TypedValue.COMPLEX_RADIX_SHIFT)
                            & TypedValue.COMPLEX_RADIX_MASK];
    }

    /**
     * Converts a complex data value holding a dimension to its final floating 
     * point value. The given <var>data</var> must be structured as a 
     * {@link #TYPE_DIMENSION}.
     *  
     * @param data A complex data value holding a unit, magnitude, and 
     *             mantissa.
     * @param metrics Current display metrics to use in the conversion -- 
     *                supplies display density and scaling information.
     * 
     * @return The complex floating point value multiplied by the appropriate 
     * metrics depending on its unit. 
     */
    public static float complexToDimension(int data, DisplayMetrics metrics)
    {
        return applyDimension(
            (data>>COMPLEX_UNIT_SHIFT)&COMPLEX_UNIT_MASK,
            complexToFloat(data),
            metrics);
    }

    /**
     * Converts a complex data value holding a dimension to its final value
     * as an integer pixel offset.  This is the same as
     * {@link #complexToDimension}, except the raw floating point value is
     * truncated to an integer (pixel) value.
     * The given <var>data</var> must be structured as a 
     * {@link #TYPE_DIMENSION}.
     *  
     * @param data A complex data value holding a unit, magnitude, and 
     *             mantissa.
     * @param metrics Current display metrics to use in the conversion -- 
     *                supplies display density and scaling information.
     * 
     * @return The number of pixels specified by the data and its desired
     * multiplier and units.
     */
    public static int complexToDimensionPixelOffset(int data,
            DisplayMetrics metrics)
    {
        return (int)applyDimension(
                (data>>COMPLEX_UNIT_SHIFT)&COMPLEX_UNIT_MASK,
                complexToFloat(data),
                metrics);
    }

    /**
     * Converts a complex data value holding a dimension to its final value
     * as an integer pixel size.  This is the same as
     * {@link #complexToDimension}, except the raw floating point value is
     * converted to an integer (pixel) value for use as a size.  A size
     * conversion involves rounding the base value, and ensuring that a
     * non-zero base value is at least one pixel in size.
     * The given <var>data</var> must be structured as a 
     * {@link #TYPE_DIMENSION}.
     *  
     * @param data A complex data value holding a unit, magnitude, and 
     *             mantissa.
     * @param metrics Current display metrics to use in the conversion -- 
     *                supplies display density and scaling information.
     * 
     * @return The number of pixels specified by the data and its desired
     * multiplier and units.
     */
    public static int complexToDimensionPixelSize(int data,
            DisplayMetrics metrics)
    {
        final float value = complexToFloat(data);
        final float f = applyDimension(
                (data>>COMPLEX_UNIT_SHIFT)&COMPLEX_UNIT_MASK,
                value,
                metrics);
        final int res = (int) ((f >= 0) ? (f + 0.5f) : (f - 0.5f));
        if (res != 0) return res;
        if (value == 0) return 0;
        if (value > 0) return 1;
        return -1;
    }

    /**
     * @hide Was accidentally exposed in API level 1 for debugging purposes.
     * Kept for compatibility just in case although the debugging code has been removed.
     */
    @Deprecated
    public static float complexToDimensionNoisy(int data, DisplayMetrics metrics)
    {
        return complexToDimension(data, metrics);
    }

    /**
     * Return the complex unit type for this value. For example, a dimen type
     * with value 12sp will return {@link #COMPLEX_UNIT_SP}. Only use for values
     * whose type is {@link #TYPE_DIMENSION}.
     *
     * @return The complex unit type.
     */
     public int getComplexUnit()
     {
         return COMPLEX_UNIT_MASK & (data>>TypedValue.COMPLEX_UNIT_SHIFT);
     }

    /**
     * Converts an unpacked complex data value holding a dimension to its final floating 
     * point value. The two parameters <var>unit</var> and <var>value</var>
     * are as in {@link #TYPE_DIMENSION}.
     *  
     * @param unit The unit to convert from.
     * @param value The value to apply the unit to.
     * @param metrics Current display metrics to use in the conversion -- 
     *                supplies display density and scaling information.
     * 
     * @return The complex floating point value multiplied by the appropriate 
     * metrics depending on its unit. 
     */
    public static float applyDimension(int unit, float value,
                                       DisplayMetrics metrics)
    {
        switch (unit) {
        case COMPLEX_UNIT_PX:
            return value;
        case COMPLEX_UNIT_DIP:
            return value * metrics.density;
        case COMPLEX_UNIT_SP:
            return value * metrics.scaledDensity;
        case COMPLEX_UNIT_PT:
            return value * metrics.xdpi * (1.0f/72);
        case COMPLEX_UNIT_IN:
            return value * metrics.xdpi;
        case COMPLEX_UNIT_MM:
            return value * metrics.xdpi * (1.0f/25.4f);
        }
        return 0;
    }

    /**
     * Return the data for this value as a dimension.  Only use for values 
     * whose type is {@link #TYPE_DIMENSION}. 
     * 
     * @param metrics Current display metrics to use in the conversion -- 
     *                supplies display density and scaling information.
     * 
     * @return The complex floating point value multiplied by the appropriate 
     * metrics depending on its unit. 
     */
    public float getDimension(DisplayMetrics metrics)
    {
        return complexToDimension(data, metrics);
    }

    /**
     * Converts a complex data value holding a fraction to its final floating 
     * point value. The given <var>data</var> must be structured as a 
     * {@link #TYPE_FRACTION}.
     * 
     * @param data A complex data value holding a unit, magnitude, and 
     *             mantissa.
     * @param base The base value of this fraction.  In other words, a 
     *             standard fraction is multiplied by this value.
     * @param pbase The parent base value of this fraction.  In other 
     *             words, a parent fraction (nn%p) is multiplied by this
     *             value.
     * 
     * @return The complex floating point value multiplied by the appropriate 
     * base value depending on its unit. 
     */
    public static float complexToFraction(int data, float base, float pbase)
    {
        switch ((data>>COMPLEX_UNIT_SHIFT)&COMPLEX_UNIT_MASK) {
        case COMPLEX_UNIT_FRACTION:
            return complexToFloat(data) * base;
        case COMPLEX_UNIT_FRACTION_PARENT:
            return complexToFloat(data) * pbase;
        }
        return 0;
    }

    /**
     * Return the data for this value as a fraction.  Only use for values whose 
     * type is {@link #TYPE_FRACTION}. 
     * 
     * @param base The base value of this fraction.  In other words, a 
     *             standard fraction is multiplied by this value.
     * @param pbase The parent base value of this fraction.  In other 
     *             words, a parent fraction (nn%p) is multiplied by this
     *             value.
     * 
     * @return The complex floating point value multiplied by the appropriate 
     * base value depending on its unit. 
     */
    public float getFraction(float base, float pbase)
    {
        return complexToFraction(data, base, pbase);
    }

    /**
     * Regardless of the actual type of the value, try to convert it to a
     * string value.  For example, a color type will be converted to a
     * string of the form #aarrggbb.
     * 
     * @return CharSequence The coerced string value.  If the value is
     *         null or the type is not known, null is returned.
     */
    public final CharSequence coerceToString()
    {
        int t = type;
        if (t == TYPE_STRING) {
            return string;
        }
        return coerceToString(t, data);
    }

    private static final String[] DIMENSION_UNIT_STRS = new String[] {
        "px", "dip", "sp", "pt", "in", "mm"
    };
    private static final String[] FRACTION_UNIT_STRS = new String[] {
        "%", "%p"
    };

    /**
     * Perform type conversion as per {@link #coerceToString()} on an
     * explicitly supplied type and data.
     * 
     * @param type The data type identifier.
     * @param data The data value.
     * 
     * @return String The coerced string value.  If the value is
     *         null or the type is not known, null is returned.
     */
    public static final String coerceToString(int type, int data)
    {
        switch (type) {
        case TYPE_NULL:
            return null;
        case TYPE_REFERENCE:
            return "@" + data;
        case TYPE_ATTRIBUTE:
            return "?" + data;
        case TYPE_FLOAT:
            return Float.toString(Float.intBitsToFloat(data));
        case TYPE_DIMENSION:
            return Float.toString(complexToFloat(data)) + DIMENSION_UNIT_STRS[
                (data>>COMPLEX_UNIT_SHIFT)&COMPLEX_UNIT_MASK];
        case TYPE_FRACTION:
            return Float.toString(complexToFloat(data)*100) + FRACTION_UNIT_STRS[
                (data>>COMPLEX_UNIT_SHIFT)&COMPLEX_UNIT_MASK];
        case TYPE_INT_HEX:
            return "0x" + Integer.toHexString(data);
        case TYPE_INT_BOOLEAN:
            return data != 0 ? "true" : "false";
        }

        if (type >= TYPE_FIRST_COLOR_INT && type <= TYPE_LAST_COLOR_INT) {
            return "#" + Integer.toHexString(data);
        } else if (type >= TYPE_FIRST_INT && type <= TYPE_LAST_INT) {
            return Integer.toString(data);
        }

        return null;
    }

    public void setTo(TypedValue other)
    {
        type = other.type;
        string = other.string;
        data = other.data;
        assetCookie = other.assetCookie;
        resourceId = other.resourceId;
        density = other.density;
    }

    public String toString()
    {
        StringBuilder sb = new StringBuilder();
        sb.append("TypedValue{t=0x").append(Integer.toHexString(type));
        sb.append("/d=0x").append(Integer.toHexString(data));
        if (type == TYPE_STRING) {
            sb.append(" \"").append(string != null ? string : "<null>").append("\"");
        }
        if (assetCookie != 0) {
            sb.append(" a=").append(assetCookie);
        }
        if (resourceId != 0) {
            sb.append(" r=0x").append(Integer.toHexString(resourceId));
        }
        sb.append("}");
        return sb.toString();
    }
};

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Android 设备上,像素(Pixel)是指显示屏上的最小颜色点,而 dpsppx 则用于描述在不同分辨率的设备上,一个视觉元素的尺寸和位置。 - dp(density-independent pixels):密度无关像素。是一种基于屏幕密度的抽象单位,它可以让布局在不同的设备上有相同的显示效果。1dp 对应的像素数取决于设备的屏幕密度。通常,在设计 UI 时应使用 dp 单位。 - sp(scale-independent pixels):与 dp 类似,但用于描述文字大小。与 dp 不同的是,用户可以在系统设置中调整字体大小,因此 sp 的值会随着用户在系统设置中的调整而发生变化。 - px(pixels):像素。是屏幕上的最小显示单位,1px 对应一个实际的像素点。在设计 UI 时,应该尽量避免使用 px,因为在不同分辨率的设备上会导致 UI 显示效果不一致。 在布局文件中,可以使用 dpsp 单位来设置视觉元素的尺寸和位置,例如: ``` <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="16sp" android:padding="8dp" android:text="Hello, world!" /> ``` 在代码中,可以使用以下方法将 dpsp 转换px: ``` // 将 dp 转换px int px = (int) TypedValue.applyDimension( TypedValue.COMPLEX_UNIT_DIP, 16, getResources().getDisplayMetrics()); // 将 sp 转换px int px = (int) TypedValue.applyDimension( TypedValue.COMPLEX_UNIT_SP, 16, getResources().getDisplayMetrics()); ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值