SkillAgentSearch skills...

ScreenAdaptation

Andoid屏幕适配终极手段(小编用过最得劲的dp适配),1.工具类解析values目录下的dimens文件,根据其中所有的dimen标签,name和values,生成其他各种dp对应的dimens文件 2.DP_BASE可修改为自己定的基准(你可以根据实际情况定为其他dp,一般情况下,定义为360dp,因为大部分手机sw都是360dp) 3.root对应的是当前android项目的主目录路径,千万不能出错 4.size_thread,线程池大小默认5,你可以设置其他数值 5.你还可以根据自己强迫症的各种习惯和喜好,各种更改成自己喜欢的风格,代码很精简,修改很容易 6.在每次打包之前,记得执行DPGeneratorLittle的main方法,以确保所有的dimen文件都是最新的 7.负数的dp,小数的dp,甚至小数的sp(一般没这情况)都可以生成,放心大胆使用 8.如果发现某台手机适配效果不是很好,那么真机调试,得到其swdp,然后在用DPGeneratorLittle生成对应的swdp,dimen文件 9.执行DPGeneratorLittle报错的时候,记得删除所有生成的valuse目录,clean项目,重新执行

Install / Use

/learn @AnJiaoDe/ScreenAdaptation
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

APKdemo

[toc]

小编尝试过2种屏幕适配方法:

1.PX适配

使用PXGenerator代码生成各种分辨率的文件夹以及文件, 以某分辨率比如480x800为基准,1px=1px, 按比例生成其他各种分辨率的dimen文件,会有1px=4px,1px=3px之类的情况, 以次达到屏幕适配的目的

20181020192203851.png

<dimen name="py11">14.7px</dimen>
	<dimen name="py12">16.0px</dimen>
	<dimen name="py13">17.3px</dimen>
	<dimen name="py14">18.7px</dimen>
	<dimen name="py15">20.0px</dimen>
	<dimen name="py16">21.3px</dimen>
	<dimen name="py17">22.7px</dimen>
	<dimen name="py18">24.0px</dimen>
	<dimen name="py19">25.3px</dimen>
	<dimen name="py20">26.7px</dimen>
	<dimen name="py21">28.0px</dimen>
	<dimen name="py22">29.3px</dimen>
	<dimen name="py23">30.7px</dimen>
	<dimen name="py24">32.0px</dimen>
	<dimen name="py25">33.3px</dimen>
	<dimen name="py26">34.7px</dimen>
	<dimen name="py27">36.0px</dimen>
	<dimen name="py28">37.3px</dimen>
	<dimen name="py29">38.7px</dimen>
public class PXGenerator {
	
	private static final String HEAD="<?xml version=\"1.0\" encoding=\"utf-8\"?>\n";//头部
	private static final String START_TAG="<resources>\n";//开始标签
	private static final String END_TAG="</resources>\n";//结束标签
	
	private static final String ROOT="F:\\AndroidStudioWorkSpace\\ScreenAdaptation\\app\\src\\main\\res\\values-2560x1800\\";//文件夹
	private static final String FILE_NAME="dimen_py2560.xml";//文件名
	
	private static final String path=ROOT+FILE_NAME;//文件路径
	
	private static final float TIMES=1920*1.0f/2560;
	
	private static final int DIMENSION=1920;//以次为基准
	
	
	public static void main(String[] args) {
		generateXMl();
	}
	
	private static void generateXMl()
	{
		try 
		{
			File diectoryFile = new File(ROOT);
			if(!diectoryFile.exists()){
				diectoryFile.mkdirs();
			}
			File file = new File(path);
			if(file.exists()){
				file.delete();
			}
			FileWriter fileWriter = new FileWriter(file);
			fileWriter.write(HEAD);
			fileWriter.write(START_TAG);
			for(int i=0;i<=DIMENSION;i++){
				String output="\t<dimen name=\"py"+i+"\">"+roundString(i)+"px</dimen>\n";
				fileWriter.write(output);
			}
			fileWriter.write(END_TAG);
			fileWriter.flush();
			fileWriter.close();
			
			System.out.println("写入成功");
		} catch (IOException e) {
			e.printStackTrace();
			System.out.println("写入失败");
		}
	}
	
	private static String roundString(int data)
	{
		String result="";
		float floatResult=data/TIMES;
		DecimalFormat df = new DecimalFormat("0.00");
		result = df.format(floatResult);
		return result;
	}
	
}

缺点:需要生成的相关分辨率的dimen实在太多,增大APK包体积

2.DP适配由来

参考CSDN阿杜,写得贼好,帮助贼大,贼感谢

先熟知如下图所示的各种参数 1540035378(1).png

1540043028(1).png

1540043059(1).png

 private String getScreenParams() {
        DisplayMetrics dm = new DisplayMetrics();
        getWindowManager().getDefaultDisplay().getMetrics(dm);
        int heightPixels = dm.heightPixels;//高的像素
        int widthPixels = dm.widthPixels;//宽的像素
        int densityDpi = dm.densityDpi;//dpi
        float xdpi = dm.xdpi;//xdpi
        float ydpi = dm.ydpi;//ydpi
        float density = dm.density;//density=dpi/160,密度比
        float scaledDensity = dm.scaledDensity;//scaledDensity=dpi/160 字体缩放密度比
        float heightDP = heightPixels / density;//高度的dp
        float widthDP = widthPixels / density;//宽度的dp
        String str = "heightPixels: " + heightPixels + "px";
        str += "\nwidthPixels: " + widthPixels + "px";
        str += "\ndensityDpi: " + densityDpi + "dpi";
        str += "\nxdpi: " + xdpi + "dpi";
        str += "\nydpi: " + ydpi + "dpi";
        str += "\ndensity: " + density;
        str += "\nscaledDensity: " + scaledDensity;
        str += "\nheightDP: " + heightDP + "dp";
        str += "\nwidthDP: " + widthDP + "dp";

        return str;
    }

1.px:

屏幕分辨率:在橫纵向上的像素点数。单位:px即1px=1个像素点。 一般以纵向像素x横向像素表示,如1920x1080

2.dpi:

屏幕像素密度,指每英寸上的像素点数,dot per inch的缩写,与屏幕尺寸和屏幕分辨率有关。以Nexus5为例,官方参数为1920*1080,dpi=445,4.95 inch 那么,这个445的dpi是怎么算出来的呢?由上面介绍可知,屏幕尺寸4.95是屏幕对角线的长度,而dpi是指每英寸上的像素点数,所以应该由对角线所占的像素值除以4.95,如下: 20161111133928845.png

3.dp/dip:

dp和dip是一样的,密度无关像素,Density Independent Pixels的缩写,以160dpi为基准。在160dpi设备 上1dp=1px,在240dpi设备上1dp=1.5px,以此类推

4.density: density=dpi/160,密度比

5.scaledDensity : scaledDensity=dpi/160 字体缩放密度比

6.heightDP: heightDP = heightPixels / density;//高度的dp

7.widthDP: heightDP = widthPixels / density;//宽度的dp

参考android官网,官网告诉我们如何去适配 1540034794(1).png

1540034888(1).png

先看上图sw< N >dp: smallestWidth,最小宽度, 1540036835(1).png

官方提供了多种尺寸限制符,sw指的是最小宽度,和竖屏横屏无关:

如800DPx480DP(最小宽度是480dp,比如部分800x480手机), 592DPx360DP(最小宽度是360dp,比如部分1920x1080手机), 604DPx360DP(最小宽度是360dp,比如部分1920x1080手机), 680DPx360DP(最小宽度是360dp.比如部分2160x1080手机(2018年左右开始流行长屏幕手机、刘海屏手机)), 1232DPx900DP(最小宽度是900dp,比如部分2560x1800手机(平板))

这里发现多种分辨率手机最小宽度都是360DP,尤其是1920x1080,是2018年左右最流行的屏幕分辨率,因此考虑以宽度360dp为基准做适配(这也是为何使用DP适配,而不使用PX适配的原因,因为DP适配需要的dimens文件会少很多)

sw< N >dp会向上兼容:

比如valuse-sw481dp文件夹,当且仅当手机最小宽度dp>=481dp才会去该目录寻找数值,800DPx480DP最小宽度480dp,是无法进入valuse-sw481dp寻找数值的,如果values目录下没有对应的数值,只有一个结果GG=APP崩溃。所以任何时候都记得一定要在values目录下创建对应的数值 20181020225528473.png

800DPx480DP手机,由于没有valuse-sw480dp文件夹,只能向下寻找,找到valuse-sw100dp文件夹,结果界面当然很丑,(适配具体操作 容后再谈)

1540048214(1).png

上文说到:多种分辨率手机最小宽度都是360DP,尤其是1920x1080,是2018年左右最流行的屏幕分辨率,因此考虑以宽度360dp为基准做适配

3.DP适配原理以及具体操作

常见的swdp如下:

    //    private static final int[] dps = {360, 384, 392, 400, 410, 411, 480, 533, 592,
    //            600, 640, 662, 720, 768, 800, 811, 820,900, 960, 961, 1024, 1280};//常见dp列表

为了适配更多手机,dp应尽可能包含更多,而且连续性强,间隔小

dp适配原理: 和px适配原理类似(按比例计算),以sw360dp为基准,

 <dimen name="height_title">48dp</dimen>
    <dimen name="sp18">18sp</dimen>
    <dimen name="padding_icon">12dp</dimen>
    <dimen name="dp360">360dp</dimen>
    <dimen name="sp10">10sp</dimen>
    <dimen name="dp30">30dp</dimen>
    <dimen name="dp10">10dp</dimen>
    <dimen name="sp14">14sp</dimen>
    <dimen name="dp40">40dp</dimen>
    <dimen name="dp70">70dp</dimen>
    <dimen name="dp100">100dp</dimen>
    <dimen name="dp80">80dp</dimen>
    <dimen name="sp12">12sp</dimen>
    <dimen name="dp60">60dp</dimen>
    <dimen name="_dp10">-10dp</dimen>
    <dimen name="dp4_5">4.5dp</dimen>
    <dimen name="_dp5_5">-5.5dp</dimen>

那么sw720dp如下: 全是2倍值

<dimen name="height_title">96dp</dimen>
    <dimen name="sp18">36sp</dimen>
    <dimen name="padding_icon">24dp</dimen>
    <dimen name="dp360">720dp</dimen>
    <dimen name="sp10">20sp</dimen>
    <dimen name="dp30">60dp</dimen>
    <dimen name="dp10">20dp</dimen>
    <dimen name="sp14">28sp</dimen>
    <dimen name="dp40">80dp</dimen>
    <dimen name="dp70">140dp</dimen>
    <dimen name="dp100">200dp</dimen>
    <dimen name="dp80">160dp</dimen>
    <dimen name="sp12">24sp</dimen>
    <dimen name="dp60">120dp</dimen>
    <dimen name="_dp10">-20dp</dimen>
    <dimen name="dp4_5">9dp</dimen>
    <dimen name="_dp5_5">-11dp</dimen>

具体操作:

1) 以sw360dp为基准,按照1920x1080的UI设计图,可以让设计师用“标你妹”等软件标注dp和sp,也可以上传到蓝湖,蓝湖上的标注更爽,在values下的dimens文件中定义dp值对应的dimen标签。 比如,UI图上标注的一个按钮高度是40dp,那么在dimens文件中创建

<dimen name="height_btn_">40dp</dimen>

name名字可以随便取

2) 将如下代码类放到当前android项目的app module下,记得更改root目录为自己的android项目的目录, 1540050491(1).png

public class DPGeneratorLittle {

    private static final String HEAD = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n";//头部
    private static final String START_TAG = "<resources>\n";//开始标签
    private static final String END_TAG = "</resources>\n";//结束标签


    private static final float DP_BASE = 360;//360dp为基准

    private static final int DP_MAX = 720;//所有dimens文件dp从0生成到这个值
    private static final int SP_MAX = 48;//SP最大

    private static final int[] dps = {360, 384, 392, 400, 410, 411, 480, 533, 592,
            600, 640, 662, 720, 768, 800, 811, 820,900, 960, 961, 1024, 1280};//常见dp列表
//    private static final int[] dps = {100,481,510,720,900};//常见dp列表

    private static final String root="F:\\AndroidStudioWorkSpace\\ScreenAdaptation\\app\\src\\main\\res\\";//生成文件的主目录

    private static ExecutorService fixedThreadPool;//线程池,用于生成XML文件
    private static int size_thread = 5;//线程池大小


    private static DocumentBuilderFactory dbFactory;
    private static DocumentBuilder db;
    private static Document document;


    public static void main(String[] args) {
        try {
            dbFactory = DocumentBuilderFactory.newInstance();
            db = dbFactory.newDocumentBuilder();
            //将
View on GitHub
GitHub Stars17
CategoryDevelopment
Updated2mo ago
Forks7

Languages

Java

Security Score

90/100

Audited on Jan 12, 2026

No findings