zoukankan      html  css  js  c++  java
  • 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
    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("
    " + DensityUtils.getDisplayMetrics(this));//像素密度。奇酷2.875。华为3.0
            tv_info.append("
    " + DensityUtils.dp2px(this, 10.3f));
            tv_info.append("
    " + DensityUtils.px2dp(this, 10.3f));
            tv_info.append("
    " + DensityUtils.sp2px(this, 10.3f));
            tv_info.append("
    " + DensityUtils.px2sp(this, 10.3f));
            tv_info.append("
    " + DensityUtils.getScreenWidth(this) + "-" + DensityUtils.getScreenWidth2(this));
            tv_info.append("
    屏幕高度:" + DensityUtils.getScreenHeight(this));//奇酷1920。华为1794
            tv_info.append("
    状态栏高度:" + 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("
    标题栏高度:" + 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




  • 相关阅读:
    面向对象之类属性、类方法,静态方法
    python面向对象之继承
    python之面向对象练习
    python面向对象
    CentOS7.5最小化安装之后的配置
    怎么在一台电脑上安装win7与centos7双系统
    安装Win7时删除系统保留的100M隐藏分区
    win7在安装时跳过输入用户名界面,直接开启管理员用户
    ESP8266 wifi干扰钓鱼实现
    ESP8266 wifi干扰、钓鱼实现
  • 原文地址:https://www.cnblogs.com/baiqiantao/p/5634279.html
Copyright © 2011-2022 走看看