Android 界面适配笔记

1,px,dp的转换

ldpi:mdpi:hdpi:xhdpi=120:160:240:320=3:4:6:8

在mdpi下,1dp=1px

UI切图按照hdpi设计,设计图上标注px,要先除以1.5换算成dp,存放在dimens.xml里 <dimen name="width">18dip</dimen>

然后getResourses().getDimensionPixelSize(R,dimens.width)会通过方法TypedValue.complexToDimensionPixelSize(int data,DisplayMetrics metrics)调用   

 TypedValue.applyDimension(int unit, float value,DisplayMetrics metrics)方法将dimens里的数据根据设备的dpi转换成px

 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.5f);
        if (res != 0) return res;
        if (value == 0) return 0;
        if (value > 0) return 1;
        return -1;
    }

   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;
    }

DisplayMetrics.density屏幕密度值为ldpi:0.75  mdpi:1  hdpi:1.5 xhdpi=2,它是将dp换算成px的比例

applyDimension转换将dp转成的px要加上0.5f来修正,因为float强制转换成int是舍去小数部分来取整,而我们需要四舍五入,因此getDimensionPixelSize里要加上0.5f


也可以不用系统给的方法来转换dp和px

public static int dip2px(Context context, float dpValue) {
final float scale = context.getResources().getDisplayMetrics().density;
return (int) (dpValue * scale + 0.5f);
}
 
public static int px2dip(Context context, float pxValue) {
final float scale = context.getResources().getDisplayMetrics().density;
return (int) (pxValue / scale + 0.5f);
}


2,setTextSize

不指定参数类型的方法    public void setTextSize(float size) {
        setTextSize(TypedValue.COMPLEX_UNIT_SP, size);
    }默认的单位是sp,但是我们通过getDimensionPixelSize将dimens里的数据转成了px,因此我们需要这个方法setTextSize(TypedValue.COMPLEX_UNIT_PX,
                getDimensionPixelSize(R.dimens.textSize)

另外,getTextSize返回的是px


3,wrapContent

一个长的RelativeLayout的最右侧有一个RelativeLayout控件,这个控件里有一个ImageView和一个TextView,它们在控件里是水平居中,TextView位于控件底部,ImageView位于TextView之上,并且距控件右边的距离是固定的margin_right。RelativeLayout控件和ImageView、TextView宽度都是WrapContent

我原本想的是,通过设置ImageView的layout_marginright来设置图片距右边缘距离,但是实际上RelativeLayout控件的宽度被先放置的TextView的宽度限定了,结果TextView占满宽度靠上了边缘,而ImageView的margin_right起不到撑大整个控件的效果,反而有可能为了达到这个margin_right而把图片缩小



Android 界面适配笔记_第1张图片

解决方法:我根据设计图上的图片宽度和margin_right设计值计算出整个控件应该有的宽度,直接设置了控件宽度值。

4,动态添加布局时,如果是RelativeLayout,要记得给其中的View设置ID,因为RelativeLayout.LayoutParams.addRule(RelativeLayout.ABOVE,xxxView.getId())方法用来设置相对位置时,需要相对的view的ID





你可能感兴趣的:(android,dp,适配,RelativeLayout)