dp 密度 分辨率 屏幕 状态栏 标题栏 适配

一篇总结的非常完善的博文: http://www.jianshu.com/p/ec5a1a30694b

屏幕像素参数相关信息表格

屏幕级别   像素密度  每英寸像素数   通常分辨率       分辨率别称     默认图标大小
 
    
xxhdpi       3           480       1080*1920       1080P        144*144       重点关注
xhdpi        2            320        720*1280         720P          96*96          适配基准
hdpi         1.5          240        480*800          WVGA        72*72  
mdpi        1.0          160        320*480          HVGA         48*48          基准
ldpi          0.75        120        240*320          QVGA         36*36
795730-20170825115055808-854002339.png
System.out.println(Math.sqrt(Math.pow(1920, 2) + Math.pow(1080, 2)) / 5);//440.58
System.out.println(Math.sqrt(Math.pow(1920, 2) + Math.pow(1080, 2)) / 5.5);//400.53
System.out.println(Math.sqrt(Math.pow(1920, 2) + Math.pow(1080, 2)) / 6.0);//367.15
 

主流Android手机分辨率

屏幕级别  倍数/比例    像素密度范围      主流分辨率/宽高比   分辨率别称    标准图标大小
xxxhdpi        4            480-640         2560*1440/16:9       2K              192*192
                                                        3840*2160/16:9       4K
xxhdpi          3            320-480        1920*1080/16:9       1080P         144*144
xhdpi            2            240-320        1280*720/16:9         720P           96*96
                                                        960*540                   QHD
hdpi            1.5          160-240         800*480/5:3             WVGA         72*72
                                                        854*480/16:9           FWVGA
                                                        640*480/4:3             VGA
                                                        800*600/4:3             SVGA
mdpi          1.0          120-160         320*480                    HVGA         48*48
ldpi            0.75        120                 240*320                   QVGA         36*36

iPhone系列手机的分辨率

iPhone 3G/3GS          480 x 320
iPhone 4/4S                960 x 640
iPhone 5/5s/5c           1136 x 640
iPhone 6/6s/7             1334*750
iPhone 6p/6sp/7p       1920*1080

名词解释

 
  
 
  
 
  
  • Px(像素Pixel)
    • px即像素,一个像素则表明在屏幕上的一个点,一个显示单位。
    • 不同设备上显示时像素数不会变,比如指定控件的长度是100px,那不管分辨率是多少控件长度都是100px。也正是因为如此才产生了屏幕适配问题。
  • Screen Size(屏幕的尺寸)
    一般所说的手机屏幕大小如5.0英寸,都是指的手机屏幕对角线的长度,而不是手机面积。
  • Resolution(屏幕的分辨率)
    • 在屏幕上显示的物理像素总和,单位是px,1px=1个像素点。
    • 一般以纵向像素*横向像素表示,比如分辨率是1280*720,则指设备垂直方向有1280个像素点,水平方向有720个像素点。
    • 需要注意的是:分辨率并不意味着具体的屏幕高宽比,比如分辨率为1280*720的手机屏幕宽高比不一定是1280*720(16:9)。但是为了显示效果和谐,两者一般都是一致的(或者有一丢丢的差距)。
  • Dpi(像素密度dots per inch)
    • 即“dot per inch”的缩写,指每英寸中的像素数。
    • 屏幕像素密度与屏幕尺寸和屏幕分辨率有关,在单一变化条件下,屏幕尺寸越小、分辨率越高,像素密度越大。
    • DisplayMetrics类中属性density的值即为此值,可用于px与dip的互相转换
    • dp是一个与密度无关的像素,在不同的像素密度的设备上会自动适配,在逻辑尺寸上,与一个位于像素密度为 160DPI 的屏幕上的像素是一致的,在运行的时候,平台会以目标屏幕的密度作为基准,处理所有需要的DIP缩放操作。假定设备分辨率为320*240,屏幕长2英寸宽1.5英寸,dpi=320/2=240/1.5=160,此160dpi表示手机水平或垂直方向上每英寸距离有160个像素点。
  • Dip(设备独立像素Device-independent pixel)
    • dp和dip是一个意思,翻译为设备独立像素,或是密度无关像素
    • 在Android中,规定以160dpi为基准,此时1dip=1px;如果像素密度是320dpi,则1dip=2px
    • 要把DIP像素转换为屏幕像素,可以用这样一个简单的公式: pixels = dips * (density / 160)。
  • Sp(放大像素ScaledPixels)
    主要用于字体显示(best for textsize)。根据 google 的建议,TextView 的字号最好使用 sp 做单位,而且查看TextView的源码可知 Android 默认使用 sp 作为字号单位。

屏幕适配方法

1、使用不同套图适配
使用套图适配目前来说是针对 图片适配的最好适配方法,可以 防止图片的失真以及变形
但针对不同手机进行不同的套图适配,会对UI人员施加过大的工作压力以及对我们app本身也会造成冗余的影响。

2、9path适配
9path图片作为特殊的png图片,可以在特定的情况下对不同机型进行适配,而达到图片不失真的情况。

3、布局适配
使用权重适配。 在格局比较明朗的页面中,如果我们能少用具体大小dp值,多用权重,可以在不同的分辨率下都能做到完美适配。
 
4、使用dimens适配
根据不同values下的dimens进行适配,android项目会自动找寻相适应的dimens,我们可以在多种不同的values下建立dimens文件。
在使用dimens的时候,我们可以在dimens文件中,用px为单位,这样就能达到完美适配。

5、代码适配
我们也可以在java文件中,使用java代码 并结合dimens进行适配,相比较xml的话,此种适配方法更迅捷。

Activity

public class MainActivity extends Activity {
    private TextView tv_info;
    public static final String FILE_PATH = Environment.getExternalStorageDirectory().getAbsolutePath();
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        tv_info = new TextView(this);
        setContentView(tv_info);
        tv_info.setText("" + DensityUtils.getStatusBarHeight(this));//状态栏高度。奇酷72。华为75
        tv_info.append("\n" + DensityUtils.getDisplayMetrics(this));//像素密度。奇酷2.875。华为3.0
        tv_info.append("\n" + DensityUtils.dp2px(this, 10.3f));
        tv_info.append("\n" + DensityUtils.px2dp(this, 10.3f));
        tv_info.append("\n" + DensityUtils.sp2px(this, 10.3f));
        tv_info.append("\n" + DensityUtils.px2sp(this, 10.3f));
        tv_info.append("\n" + DensityUtils.getScreenWidth(this) + "-" + DensityUtils.getScreenWidth2(this));
        tv_info.append("\n屏幕高度:" + DensityUtils.getScreenHeight(this));//奇酷1920。华为1794
        tv_info.append("\n状态栏高度:" + DensityUtils.getStatusBarHeight(this));//奇酷72。华为75
        //需要 root 权限,且可能会被360报毒
        //        DensityUtils.saveBitmap2Pic(DensityUtils.snapShotWithStatusBar(this), FILE_PATH + "1.png");
        //        DensityUtils.saveBitmap2Pic(DensityUtils.snapShotWithoutStatusBar(this), FILE_PATH + "2.png");
    }
    @Override
    public void onWindowFocusChanged(boolean hasFocus) {
        super.onWindowFocusChanged(hasFocus);
        if (hasFocus) {
            tv_info.append("\n标题栏高度:" + DensityUtils.getTitleBarHeight(this));//奇酷161。华为168
        }
    }
}

演示效果

奇酷1080P    华为1080P    华为720P
状态栏高度25dp*3=75    25dp*2=50    25dp*2.875=71.875
     

工具类

package com.bqt.pop;
import java.lang.reflect.Method;
import android.app.Activity;
import android.content.Context;
import android.graphics.Point;
import android.graphics.Rect;
import android.util.DisplayMetrics;
import android.util.TypedValue;
import android.view.Display;
import android.view.Window;
import android.view.WindowManager;
public class DensityUtils {
    //******************************************************************************************
    //                                                                                    单位转换
    //******************************************************************************************
    /**像素密度*/
    public static float getDisplayMetrics(Context context) {
        return context.getResources().getDisplayMetrics().density;
    }
    /**  dp 转成为 px     */
    public static int dp2px(Context context, float dpValue) {
        return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dpValue, context.getResources().getDisplayMetrics());
    }
    /**  px 转成为 dp     */
    public static int px2dp(Context context, float pxValue) {
        return (int) (pxValue / getDisplayMetrics(context) + 0.5f);
    }
    /** sp转px */
    public static int sp2px(Context context, float spVal) {
        return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, spVal, context.getResources().getDisplayMetrics());
    }
    /** px转sp */
    public static float px2sp(Context context, float pxVal) {
        return (pxVal / context.getResources().getDisplayMetrics().scaledDensity);
    }
    //******************************************************************************************
    //                                                                                屏幕宽高
    //******************************************************************************************
    /**  获取屏幕宽  */
    public static int getScreenWidth(Context context) {
        DisplayMetrics metric = new DisplayMetrics();
        ((WindowManager) context.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay().getMetrics(metric);
        return metric.widthPixels;
    }
    /** 获取屏幕高,包含状态栏,但不包含某些手机最下面的【HOME键那一栏】,如1920屏幕只有1794  */
    public static int getScreenHeight(Context context) {
        DisplayMetrics metric = new DisplayMetrics();
        ((WindowManager) context.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay().getMetrics(metric);
        return metric.heightPixels;
    }
    /**  获取屏幕宽  */
    public static int getScreenWidth2(Context context) {
        Point point = new Point();
        ((WindowManager) context.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay().getSize(point);
        return point.x;
    }
    /**  获取屏幕高,包含状态栏,但不包含某些手机最下面的【HOME键那一栏】,如1920屏幕只有1794  */
    public static int getScreenHeight2(Context context) {
        Point point = new Point();
        ((WindowManager) context.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay().getSize(point);
        return point.y;
    }
    /**  获取屏幕原始尺寸高度,包括状态栏以及虚拟功能键高度  */
    public static int getAllScreenHeight(Context context) {
        Display display = ((WindowManager) context.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
        try {
            DisplayMetrics displayMetrics = new DisplayMetrics();
            Method method = Class.forName("android.view.Display").getMethod("getRealMetrics", DisplayMetrics.class);
            method.invoke(display, displayMetrics);
            return displayMetrics.heightPixels;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return 0;
    }
    //******************************************************************************************
    //                                                                        状态栏、标题栏、虚拟按键
    //******************************************************************************************
    /** 状态栏高度,单位px,一般为25dp  */
    public static int getStatusBarHeight(Context context) {
        int height = 0;
        int resourceId = context.getResources().getIdentifier("status_bar_height", "dimen", "android");
        if (resourceId > 0) {
            height = context.getResources().getDimensionPixelSize(resourceId);
        }
        return height;
    }
    /** 状态栏高度,单位px,【注意】要在onWindowFocusChanged中获取才可以 */
    public static int getStatusBarHeight2(Activity activity) {
        Rect rect = new Rect();
        //DecorView是Window中的最顶层view,可以从DecorView获取到程序显示的区域,包括标题栏,但不包括状态栏。所以状态栏的高度即为显示区域的top坐标值
        activity.getWindow().getDecorView().getWindowVisibleDisplayFrame(rect);
        return rect.top;
    }
    /**标题栏的高度,【注意】要在onWindowFocusChanged中获取才可以*/
    public static int getTitleBarHeight(Activity activity) {
        int contentTop = activity.getWindow().findViewById(Window.ID_ANDROID_CONTENT).getTop();
        return contentTop - getStatusBarHeight(activity);
    }
    /**获取 虚拟按键的高度     */
    public static int getBottomBarHeight(Context context) {
        return getAllScreenHeight(context) - getScreenHeight(context);
    }
}
2017-7-27




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值