Andorid 屏幕适配

来源:互联网 发布:xp系统禁止安装软件 编辑:程序博客网 时间:2024/05/21 08:48

做Android开发就一定要做屏幕适配,网上搜一下Android屏幕适配这个关键词,结果都是大同小异,各种转载抄袭,而且都是比较老的文章,基本都是关于drawable-hdpi、drawable-ldpi、drawaable-mdpi三个文件夹的,看着就烦(个人感觉),现在主流的分辨率是1080*1920和720*1280左右的高清分辨率好么,960*540和480*800左右的分辨率基本都绝迹了好么,320*480的分辨率都是古董了好么!!最关键的是,哪个美工会有耐心给你各种分辨率对应的图片啊??!!! 

其实做屏幕适配很简单,跟屏幕相关的属性无非就是分辨率和密度,围绕这两点做些处理就OK了。


先说下分辨率(我用这个做的适配):


获取屏幕的分辨率很简单,就两三行代码:

DisplayMetrics dm = mContext.getResources().getDisplayMetrics();int width = dm.widthPixels;int height = dm.heightPixels;Toast.makeText(mContext, "手机屏幕的分辨率为:" + width + " X " + height, Toast.LENGTH_SHORT).show();


然后计算屏幕分辨率与原始图片分辨率的宽高比,可以使用如下方法:

/** * @author SheXiaoHeng *  *  * @param screenWidth *            手机屏幕的宽度 *  * @param picWidth *            原始图片所用分辨率的宽度 *  * @param retainValue *            保留小数位 *  * @return 手机屏幕分辨率与原始图片分辨率的宽度比 *  * */public double divideWidth(int screenWidth, int picWidth, int retainValue) {BigDecimal screenBD = new BigDecimal(Double.toString(screenWidth));BigDecimal picBD = new BigDecimal(Double.toString(picWidth));return screenBD.divide(picBD, retainValue, BigDecimal.ROUND_HALF_UP).doubleValue();}/** * @author SheXiaoHeng *  *  * @param screenHeight *            手机屏幕的高度 *  * @param picHeight *            原始图片所用分辨率的高度 *  * @param retainValue *            保留小数位 *  * @return 手机屏幕分辨率与原始图片分辨率的高度比 * */public double divideHeight(int screenHeight, int picHeight,int retainValue) {BigDecimal screenBD = new BigDecimal(Double.toString(screenHeight));BigDecimal picBD = new BigDecimal(Double.toString(picHeight));return screenBD.divide(picBD, retainValue, BigDecimal.ROUND_HALF_UP).doubleValue();}


接着计算新的宽度和高度值(假设原始图片的分辨率为:1080*1920、宽高均为47,宽高比保留两位小数):

        int newWidth = (int) (divideWidth(width, 1080, 2) * 47);        int newHeight = (int) (divideHeight(height, 1920, 2) * 47);

然后呢,给控件设置宽高即可:

LayoutParams lp = new LayoutParams(newWidth, newHeight);view.setLayoutParams(lp);


其实只需计算宽度,高度设为LayoutParams.WRAP_CONTENT即可,上面代码只需用一半 ( *^__^* )

至于原始图片的大小和图片资源的存放位置,鉴于目前分辨率以720*1280和1080*1920为主,我个人的建议是使用720*1280或1080*1920的原始图片放在drawable-xhdpi或drawable-xxhdpi下,本人实际开发使测试匹配480*800至2560*1440的分辨率都是OK的。



再说下密度,密度分为两种:actual density(实际密度)、generalized density(广义密度)。


实际密度的计算方法是:(平方根(手机屏幕的宽度的平方 + 手机屏幕的高度的平方))/ 手机屏幕尺寸


例如:


手机的分辨率是480*800,屏幕尺寸是4.0寸,那么该手机的实际密度为和实际密度dpi值为:

double actualDensity = Math.sqrt((480 * 480) + (800 * 800)) / 4.0 / 160;double actualDensityDpi = Math.sqrt((480 * 480) + (800 * 800)) / 4.0;

结果为(保留两位小数):actualDensity = 1.46(接近1.5) ,actualDensityDpi = 233.24(接近240) 

广义密度使用代码获取即可:(密度值为float类型,与之相对应的dpi值为int类型)

        DisplayMetrics dm = mContext.getResources().getDisplayMetrics();        float density = dm.density;        int densityDpi = dm.densityDpi;


densityDpi与density的对应关系如下:

        switch (dm.densityDpi) {case DisplayMetrics.DENSITY_LOW:// densityDpi = 120,此时density为0.75break;case DisplayMetrics.DENSITY_MEDIUM:// densityDpi = 160,此时density为1.0break;case DisplayMetrics.DENSITY_HIGH:// densityDpi = 240,此时density为1.5break;case DisplayMetrics.DENSITY_XHIGH:// densityDpi = 320,此时density为2.0break;case DisplayMetrics.DENSITY_XXHIGH:// densityDpi = 480,此时density为3.0break;case DisplayMetrics.DENSITY_XXXHIGH:// densityDpi = 640,此时density为4.0break;case DisplayMetrics.DENSITY_400:// densityDpi = 400,此时density为2.5break;case DisplayMetrics.DENSITY_TV:// densityDpi = 213,此时density为1.33125break;default:break;}

为什么提两个密度的概念,因为我实际测试两者的值还是有出入的,


例如:


我用的华为mate2,分辨率720*1280,6.1寸屏幕,计算实际密度:

double actualDensity = Math.sqrt((720 * 720) + (1280 * 1280)) / 6.1 / 160;double actualDensityDpi = Math.sqrt((720 * 720) + (1280 * 1280)) / 6.1;

结果为:1.50、240.75,但是使用代码获取的分辨率为:720*1208(底部3个虚拟按钮占了72),密度值为:2.0、密度dpi值为:320


再如:


联想k910分辨率1080*1920,5.5寸屏幕,计算实际密度:

double actualDensity = Math.sqrt((1080 * 1080) + (1920 * 1920)) / 5.5 / 160;double actualDensityDpi = Math.sqrt((1080 * 1080) + (1920 * 1920)) / 5.5;

结果为:2.50、400.53,代码获取的分辨率为:1080*1920,密度值为:3.0、密度dpi值为:480


所以我建议使用代码获取分辨率,计算宽高比来做适配,密度这块有待研究。


网络获取图片的话,获取分辨率计算宽高比的方法同样适用,如果不怕麻烦,想要完美加载图片,可以在发起网络请求的时候把获取的分辨率传给服务器,让服务器返回相对应分辨率下的图片(我感觉没必要,这样需要很多图片,服务器也会麻烦点)。


以上内容纯属个人观点,如有误导敬请谅解。


转载请注明出处:http://blog.csdn.net/shexiaoheng/article/details/41444175


0 0
原创粉丝点击