欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

我的学习篇四:屏幕适配方案,自动生成dimens文件

程序员文章站 2022-05-24 20:14:36
...

首先讲一下我自己使用的是屏幕分辨率适配方案

就是建 不同分辨率下的 value 文件如下图:

我的学习篇四:屏幕适配方案,自动生成dimens文件

这些是不用自己建的,简单配置下即可自动生成不同分辨率dimens文件,下面这些链接完了之后会说到

原理网上有很多,我这边就不讲解了,推荐几个大哥的链接,做下记录:

分辨率,限定符的讲解:

https://www.jianshu.com/p/1302ad5a4b04

一种 drawable 适配的一些问题:

https://blog.csdn.net/a2241076850/article/details/52535351

虚拟键产生生的适配bug处理:

https://blog.csdn.net/yljme/article/details/40071593

 

Android 资源加载机制详解

https://blog.csdn.net/thesingularityisnear/article/details/51581311

bitmap获取的尺寸被放大的问题讲解

https://blog.csdn.net/duolaimila/article/details/79033673

我调试后一键生成dimens文件的代码 完整代码会在文章最后给出:

创建 test调试类调用 createOneDimensFile 方法 会在value生成要使用的dimens文件

public void createOneDimensFile() {
        File pathFile = new File(filePath);
        File file = new File(filePath + "/" + fileName);
        if (!pathFile.exists()) {
            pathFile.mkdirs();
        }
        /* 不存在则创建 dimens 文件 */
        if (!file.exists()) {
            try {
                file.createNewFile();
                writeIn();
            } catch (IOException e) {
                e.printStackTrace();
            }
        } else {
            writeIn();
        }
    }

如下图所示:

我的学习篇四:屏幕适配方案,自动生成dimens文件

调用 init() 方法 会 读取value下的 dimens 文件,生成你需要适配的各个分辨率下的value文件夹和根据比例计算出的dimens文件(要配置下给你的标注的分辨率宽度是多少)

 public void init() {
        /* 初始化分辨率 */
        resolutionRatios.add(new ResolutionRatio(1080, 1920));
        resolutionRatios.add(new ResolutionRatio(1080, 2160));
        resolutionRatios.add(new ResolutionRatio(1080, 2220));
        resolutionRatios.add(new ResolutionRatio(1440, 2560));
        resolutionRatios.add(new ResolutionRatio(1440, 2880));
        resolutionRatios.add(new ResolutionRatio(1440, 2960));
        for (int i = 0; i < resolutionRatios.size(); i++) {
            pathList.add(filePath + "-" + (int) resolutionRatios.get(i).y + "x" + (int) resolutionRatios.get(i).x);
            stringBuilderList.add(new StringBuilder());
        }
        readDimens();
    }

如下图:

我的学习篇四:屏幕适配方案,自动生成dimens文件

说下需要配置那些地方:

我的学习篇四:屏幕适配方案,自动生成dimens文件

其他就不说了下面的是完整代码,使用方式是使用 AS 的测试类直接运行即可如图

1:

我的学习篇四:屏幕适配方案,自动生成dimens文件

2:

我的学习篇四:屏幕适配方案,自动生成dimens文件

3:

我的学习篇四:屏幕适配方案,自动生成dimens文件

完整代码(调试过很多遍没有问题可以直接用的):

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.List;

public class DimenTool {

    /* 尺寸单位 */
    String unitStr = "px";
    /* dimens 名称 */
    String dimensName = "my_dimens_";// + i
    /* 标注分辨率 */
    private final double labelResolutionRatio = 750;
    /* 读取文件名称 */
    private String fileName = "dimens.xml";
    /* 读取文件路径 */
    private String filePath = "C:/ASWorkSpace/WYEasyAndroid/app/src/main/res/values";
    /* 生成dimens文件 中总 单位数量 从 1 到 n */
    private int dimensNum = 1440;


    /* dimens文件头部 */
    /* <?xml version="1.0" encoding="utf-8"?> */
    String headStr = "<?xml version=\"1.0\" encoding=\"utf-8\"?>";
    /* 开始和结束标签 */
    String startLabel = "<resources>";
    String endLabel = "</resources>";
    /* 尺寸标签 */
    /* <dimen name="ydimen_1_dip">1.0px</dimen> */
    String dimenStartLabel = "<dimen name=\"";
    String dimenCenterStr = "\">";
    String dimenEndLabel = "</dimen>";

    /* 分辨率集合 */
    private List<ResolutionRatio> resolutionRatios = new ArrayList<>();
    /* 存储路径集合 */
    private List<String> pathList = new ArrayList<>();
    /* stringbuilder 集合 */
    private List<StringBuilder> stringBuilderList = new ArrayList<>();

    public void createOneDimensFile() {
        File pathFile = new File(filePath);
        File file = new File(filePath + "/" + fileName);
        if (!pathFile.exists()) {
            pathFile.mkdirs();
        }
        /* 不存在则创建 dimens 文件 */
        if (!file.exists()) {
            try {
                file.createNewFile();
                writeIn();
            } catch (IOException e) {
                e.printStackTrace();
            }
        } else {
            writeIn();
        }
    }

    private void writeIn() {
        StringBuilder builder = new StringBuilder();
        builder.append(headStr).append("\r\n")
                .append(startLabel).append("\n");
        for (int i = 1; i <= dimensNum; i++) {
            builder.append("    ").append(dimenStartLabel).append(dimensName).append(i).append(dimenCenterStr).append(i).append(unitStr).append(dimenEndLabel).append("\n");
        }
        for (int i = 1; i <= dimensNum; i++) {
            builder.append(dimenStartLabel).append(dimensName).append("fu_").append(i).append(dimenCenterStr).append("-").append(i).append(unitStr).append(dimenEndLabel).append("\n");
        }
        builder.append(endLabel);
        writeFile(filePath + "/" + fileName, builder.toString());
    }

    public void init() {
        /* 初始化分辨率 */
        resolutionRatios.add(new ResolutionRatio(1080, 1920));
        resolutionRatios.add(new ResolutionRatio(1080, 2160));
        resolutionRatios.add(new ResolutionRatio(1080, 2220));
        resolutionRatios.add(new ResolutionRatio(1440, 2560));
        resolutionRatios.add(new ResolutionRatio(1440, 2880));
        resolutionRatios.add(new ResolutionRatio(1440, 2960));
        for (int i = 0; i < resolutionRatios.size(); i++) {
            pathList.add(filePath + "-" + (int) resolutionRatios.get(i).y + "x" + (int) resolutionRatios.get(i).x);
            stringBuilderList.add(new StringBuilder());
        }
        readDimens();
    }

    private void readDimens() {
        File file = new File(filePath + "/" + fileName);
        BufferedReader reader = null;
        try {
            reader = new BufferedReader(new FileReader(file));
            String tempString;
            int line = 1;
            while ((tempString = reader.readLine()) != null) {
                if (tempString.contains("</dimen>")) {
                    String start = tempString.substring(0, tempString.indexOf(">") + 1);
                    String end = tempString.substring(tempString.lastIndexOf("<") - 2);
                    //截取<dimen></dimen>标签内的内容,从>右括号开始,到左括号减2,取得配置的数字
                    Double num = Double.parseDouble
                            (tempString.substring(tempString.indexOf(">") + 1,
                                    tempString.indexOf("</dimen>") - 2));
                    //根据不同的尺寸,计算新的值,拼接新的字符串,并且结尾处换行。
                    for (int i = 0; i < stringBuilderList.size(); i++) {
                        stringBuilderList.get(i).append(start).append(getDimens(num, resolutionRatios.get(i).x)).append(end).append("\r\n");
                    }
                } else {
                    for (int i = 0; i < stringBuilderList.size(); i++) {
                        stringBuilderList.get(i).append(tempString).append("");
                    }
                }
                line++;
            }
            for (int i = 0; i < pathList.size(); i++) {
                File fileTemp = new File(pathList.get(i));
                fileTemp.mkdirs();
                File dimensFile = new File(pathList.get(i) + "/" + fileName);
                dimensFile.createNewFile();
                writeFile(pathList.get(i) + "/" + fileName, stringBuilderList.get(i).toString());
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (reader != null) {
                try {
                    reader.close();
                } catch (IOException e1) {
                    e1.printStackTrace();
                }
            }
        }
    }

    /**
     * 写入方法
     */
    private static void writeFile(String file, String text) {
        PrintWriter out = null;
        try {
            out = new PrintWriter(new BufferedWriter(new FileWriter(file)));
            out.println(text);
        } catch (IOException e) {
            e.printStackTrace();
        }
        out.close();
    }

    /**
     * 获取计算后的数值
     *
     * @param readDimens              读取的数值
     * @param adaptiveResolutionRatio 适配分辨率
     */
    private double getDimens(double readDimens, double adaptiveResolutionRatio) {
        double ratio = adaptiveResolutionRatio / labelResolutionRatio;
        double calculate = readDimens * ratio;
        double temp = new BigDecimal(calculate).setScale(2, RoundingMode.HALF_UP).doubleValue();
        return temp;
    }

    private class ResolutionRatio {
        double x;
        double y;

        public ResolutionRatio(double x, double y) {
            this.x = x;
            this.y = y;
        }
    }

}

 

相关标签: 屏幕适配