注:该帖子为本人学习时随手记录的,内容杂乱,敬请见谅

一、各种适配相关知识

1.屏幕尺寸

屏幕对角线的长度,单位英寸,1英寸=2.54厘米

2.屏幕分辨率

在纵横向上的像素点数,单位px,1px=1个像素点,一般以纵向像素*横向像素,如1920*1080

3.屏幕像素密度

每英寸上的像素点数,单位dpi,屏幕的像素密度与屏幕尺寸和屏幕分辨率有关
计算方式:纵向像素的平方+横向像素的平方,开根号,结果除以屏幕尺寸
例如:Nexus 5,屏幕尺寸 4.95英寸,分辨率 1920*1080,dpi 445
         (√ ̄(1920^2+1080^2)) / 4.95 ≈ 445

4.px

构成图像的最小单位

5.dp,dip

密度无关像素,以160dpi为基准,1dip=1px

6.sp

可以根据文字大小首选项进行放缩,google推荐使用12sp以上大小的文字(12sp,14sp,18sp,22sp首选大小),不要使用奇数或小数,字体放缩时会造成精度的丢失。

7.ldpi,mdpi,hdpi,xdpi,xxdpi,xxxhdpi

名称

像素密度范围

倍数

图标尺寸

ldpi

小于或等于120dpi(过低,可以忽略,系统会自动根据hdpi尺寸的图标缩小到1/2进行匹配)

mdpi

120dpi~160dpi

1x

48x48px

hdpi

160dpi~240dpi

1.5x

72x72px

xdpi

240dpi~320dpi

2x

96x96px

xxhdpi

320dpi~480dpi

3x

144x144px

xxxhdpi

480dpi~640dpi(刚出)

4x

192x192px

在设计图标时,对于五种主流像素密度(mdpi,hdpi,xhdpi,xxhdpi,xxxhdpi)应按照2:3:4:6:8的比例进行缩放

二、屏幕适配解决方案

1.支持各种屏幕尺寸

使用wrap_content、match_parent、weight
weight计算出的宽度=原来宽度(width属性)+剩余空间所占百分比宽度

iOS 屏幕对角线如何计算 屏幕对角线怎么计算_android

iOS 屏幕对角线如何计算 屏幕对角线怎么计算_屏幕尺寸_02

iOS 屏幕对角线如何计算 屏幕对角线怎么计算_屏幕尺寸_03

iOS 屏幕对角线如何计算 屏幕对角线怎么计算_屏幕尺寸_04

使用相对布局,禁用绝对布局
使用限定符
尺寸限定符large(android3.2之前有作用)

iOS 屏幕对角线如何计算 屏幕对角线怎么计算_iOS 屏幕对角线如何计算_05

iOS 屏幕对角线如何计算 屏幕对角线怎么计算_iOS 屏幕对角线如何计算_06

最小宽度限定符small width最小宽度(android3.2之后推出的)

iOS 屏幕对角线如何计算 屏幕对角线怎么计算_iOS 屏幕对角线如何计算_07

为了兼容高低版本,减少布局,可以使用布局别名,进行统一管理

iOS 屏幕对角线如何计算 屏幕对角线怎么计算_屏幕尺寸_08

屏幕方向限定符 land,port

iOS 屏幕对角线如何计算 屏幕对角线怎么计算_android_09

例子:

iOS 屏幕对角线如何计算 屏幕对角线怎么计算_屏幕密度_10

iOS 屏幕对角线如何计算 屏幕对角线怎么计算_iOS 屏幕对角线如何计算_11

iOS 屏幕对角线如何计算 屏幕对角线怎么计算_屏幕密度_12

iOS 屏幕对角线如何计算 屏幕对角线怎么计算_屏幕尺寸_13

iOS 屏幕对角线如何计算 屏幕对角线怎么计算_System_14

iOS 屏幕对角线如何计算 屏幕对角线怎么计算_屏幕密度_15

iOS 屏幕对角线如何计算 屏幕对角线怎么计算_屏幕尺寸_16

iOS 屏幕对角线如何计算 屏幕对角线怎么计算_屏幕密度_17

使用自动拉伸位图 .9图

2.支持各种屏幕密度

使用非密度制约像素
提供备用位图(最好根据不同的屏幕密度提供不同的切图,从而保证使用图片资源的时候减少内存压力)

3.实施自适应用户界面流程

确定当前布局
根据当前布局做出响应
重复使用其-他活动中的片段
处理屏幕配置变化

4.最佳实践

关于高清设计图尺寸
动态设置

学习完成后,本人做了一个根据不同分辨率和屏幕密度计算生成dimens的小例子,主要思路如下:

1.确定设计图纸的宽度尺寸,如例子中的640

2.获取需要适配手机的分辨率与屏幕密度,,可以根据手机型号在网上搜索,如ZOL产品报价网站,红米note手机,分辨率1280x720,屏幕密度267dpi

3.因为屏幕密度为160(mdpi)的手机1dp=1px,所以我们可以生成一个基准dimens.xml文件放在values中,里面的所有dimens数值都是1:1生成的,其余的屏幕密度倍数分别为:120(ldpi,0.75),240(hdpi,1.5),320(xhdpi,2),480(xxhdpi,3),640(xxxhdpi,4),以红米note为例,生成对应的dimens.xml文件,红米note屏幕密度为267,靠近240,所以我们取hdpi 1.5倍,以宽度为值,红米note的宽度为720,图纸尺寸为640,所以对应得dimens计算倍数为:720/(640*1.5),然后用该倍数就能获取红米note机器下的dimens值,具体代码如下:

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.PrintWriter;

public class DimensTools {
        private static final String BASE_FOLDER = "C:/Users/krubo/Desktop/dimens";
        /** 基准宽度 */
        private static final int BASE_WIDHT = 640;

        // ldpi-0.75(120),mdpi-1(160),hdpi-1.5(240),xhdpi-2(320),xxhdpi-3(480),xxxhdpi-4(640)

        public static void main(String[] args) {
                getBaseDimens();
                getDimens(1440, 2560, "xxxhdpi");
                getDimens(720, 1280, "xhdpi");
                getDimens(720, 1280, "hdpi");
                getDimens(540, 960, "hdpi");
                getDimens(480, 800, "hdpi");
        }

        private static void getBaseDimens() {
                File folder = new File(BASE_FOLDER + "/values");
                if (!folder.exists()) {
                        folder.mkdirs();
                }
                File file = new File(folder.getAbsoluteFile() + "/" + "dimens.xml");
                if (file.exists()) {
                        file.delete();
                }
                try {
                        file.createNewFile();
                } catch (IOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                        System.out.println("getBaseDimens fail");
                        return;
                }
                StringBuffer sb = new StringBuffer();
                sb.append("<?xml version=\"1.0\" encoding=\"utf-8\"?>").append("\n");
                sb.append("<resources>").append("\n");
                for (int i = 1; i <= 2000; i++) {
                        sb.append("<dimen name=\"DIMEN_" + i + "DP\">");
                        sb.append(i + "dp");
                        sb.append("</dimen>").append("\n");
                }
                sb.append("</resources>");
                try {
                        PrintWriter pw = new PrintWriter(file);
                        pw.write(sb.toString());
                        pw.flush();
                        pw.close();
                        System.out.println("getBaseDimens success");
                } catch (FileNotFoundException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                        System.out.println("getBaseDimens fail");
                }
        }

        private static void getDimens(int widht, int height, String dpiName) {
                double dpi = 1;
                if (dpiName.equals("ldpi")) {
                        dpi = 0.75d;
                } else if (dpiName.equals("mdpi")) {
                        dpi = 1;
                } else if (dpiName.equals("hdpi")) {
                        dpi = 1.5d;
                } else if (dpiName.equals("xhdpi")) {
                        dpi = 2;
                } else if (dpiName.equals("xxhdpi")) {
                        dpi = 3;
                } else if (dpiName.equals("xxxhdpi")) {
                        dpi = 4;
                }
                File folder = new File(BASE_FOLDER + "/values-" + dpiName + "-"
                                + height + "x" + widht);
                if (!folder.exists()) {
                        folder.mkdirs();
                }
                File file = new File(folder.getAbsoluteFile() + "/" + "dimens.xml");
                if (file.exists()) {
                        file.delete();
                }
                try {
                        file.createNewFile();
                } catch (IOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                        System.out.println("getdimens file fail");
                        return;
                }
                StringBuffer sb = new StringBuffer();
                sb.append("<?xml version=\"1.0\" encoding=\"utf-8\"?>").append("\n");
                sb.append("<resources>").append("\n");
                double multiple = (double) widht / (BASE_WIDHT * dpi);
                System.out.println("multiple:" + multiple);
                for (int i = 1; i <= 1500; i++) {
                        sb.append("<dimen name=\"DIMEN_" + i + "DP\">");
                        sb.append((double) i * 2 * multiple + "dp");
                        sb.append("</dimen>").append("\n");
                }
                sb.append("</resources>");
                try {
                        PrintWriter pw = new PrintWriter(file);
                        pw.write(sb.toString());
                        pw.flush();
                        pw.close();
                        System.out.println("getdimens success");
                } catch (FileNotFoundException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                        System.out.println("getdimens write fail");
                }
        }
}