美文网首页Android
dimens density 屏幕适配文件

dimens density 屏幕适配文件

作者: 猿规 | 来源:发表于2021-09-10 10:20 被阅读0次

    在编写xml的时候,直接固定一个控件的宽高,给一个固定的dp值,在不同的屏幕上显示差别很大,导致有的手机布局无法正常显示,为了更好的达到兼容适配,会在不同尺寸下面生成不同的适配文件处理。

    首先古老的适配一般就是自己计算,然后生成文件,直接规定好自己需要的尺寸,然后代码去计算生成,然后复制到项目中使用,一般常用的尺寸如下。


    这里有一套计算工具类,来自动计算各尺寸下的资源。

    package com.example.myapplication;
    
    import android.util.Log;
    
    import java.io.File;
    import java.io.FileNotFoundException;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.math.BigDecimal;
    
    public class MakeUtils {
    
        private static final String XML_HEADER = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n";
        private static final String XML_RESOURCE_START = "<resources>\r\n";
        private static final String XML_RESOURCE_END = "</resources>\r\n";
        private static final String XML_DIMEN_TEMPLETE = "<dimen name=\"qb_%1$spx_%2$d\">%3$.2fdp</dimen>\r\n";
    
        private static final String XML_BASE_DPI = "<dimen name=\"base_dpi\">%ddp</dimen>\r\n";
        private  static final int MAX_SIZE = 720;
    
        private static final String XML_NAME = "dimens.xml";
    
        public static float px2dip(float pxValue, int sw,int designWidth) {
            float dpValue =   (pxValue/(float)designWidth) * sw;
            BigDecimal bigDecimal = new BigDecimal(dpValue);
            float dp = bigDecimal.setScale(2, BigDecimal.ROUND_HALF_UP).floatValue();
            return dp;
        }
    
        /**
         * 生成所有的尺寸数据
         */
        private static String createDimens(DimenTypes type, int designWidth) {
            float dpValue;
            String temp;
            StringBuilder sb = new StringBuilder();
            try {
                sb.append(XML_HEADER);
                sb.append(XML_RESOURCE_START);
                //备份生成的相关信息
                temp = String.format(XML_BASE_DPI, type.getSwWidthDp());
                sb.append(temp);
                for (int i = 0; i <= MAX_SIZE; i++) {
    
                    dpValue = px2dip((float) i,type.getSwWidthDp(),designWidth);
                    temp = String.format(XML_DIMEN_TEMPLETE,"", i, dpValue);
                    sb.append(temp);
                }
                sb.append(XML_RESOURCE_END);
            } catch (Exception e) {
                e.printStackTrace();
            }
            return sb.toString();
        }
    
        /**
         * 生成的目标文件夹
         */
        public static void create(int designWidth, DimenTypes type, String buildDir) {
            try {
                //生成规则
                final String folderName;
                if (type.getSwWidthDp() > 0) {
                    //适配Android 3.2+
                    folderName = "values-sw" + type.getSwWidthDp() + "dp";
                }else {
                    return;
                }
    
                //生成目标目录
                File file = new File(buildDir + File.separator + folderName);
                if (!file.exists()) {
                    file.mkdirs();
                }
                Log.e("===",file.getAbsolutePath());
                //生成values文件
                FileOutputStream fos = new FileOutputStream(file.getAbsolutePath() + File.separator + XML_NAME);
                fos.write(createDimens(type,designWidth).getBytes());
                fos.flush();
                fos.close();
    
    
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    
    }
    
    package com.example.myapplication;
    
    /**
     * created by YooJin.
     * date: 2021/2/3 13:50
     * ldpi: 120 density:1dp=0.75px 代表尺寸 240*320
     * mdpi: 160 density:1dp=1px 代表尺寸 320*480
     * hdpi: 240 density:1dp=1.5px 代表尺寸 480*800
     * xhdpi: 320 density:1dp=2px 代表尺寸720*1280
     * xxhdpi: 480 density:1dp=3px 代表尺寸1080*1920
     */
    enum DimenTypes {
    
        DP_sw__160(160),
        DP_sw__240(240),
        DP_sw__280(280),
        DP_sw__320(320),  
        DP_sw__360(360),
        DP_sw__400(400),
        DP_sw__420(420),
        DP_sw__440(440),
        DP_sw__480(480),
        DP_sw__560(560),
        DP_sw__640(640),
        DP_sw__720(720),
        DP_sw__800(800);
    
        /**
         * 屏幕最小宽度
         */
        private int swWidthDp;
    
        DimenTypes(int swWidthDp) {
    
            this.swWidthDp = swWidthDp;
        }
    
        public int getSwWidthDp() {
            return swWidthDp;
        }
    
        public void setSwWidthDp(int swWidthDp) {
            this.swWidthDp = swWidthDp;
        }
    
    }
    
    /**
         * 设计稿尺寸,从零开始,生成的最大尺寸
         */
        private static final int DESIGN_WIDTH = 375;
    
        String[] permissions = new String[]{Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE};
        List<String> mPermissionList = new ArrayList<>();
        public void main() {
            String path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).getAbsolutePath() + File.separator + "res";
            DimenTypes[] values = DimenTypes.values();
            for (DimenTypes value : values) {
                MakeUtils.create(DESIGN_WIDTH, value, path);
            }
        }
    

    执行代码后,我这里是下载目录下的res文件,然后把生成的文件剪切出来。


    里面都把dimens文件生成好了。


    直接把文件复制到项目里就可以直接使用了,不过不太便捷。

    androidstudio上面有个插件 ScreenMatch,安装后可以直接生成这些文件,并且可以动态配置,很方便。

    难得我夸一次as,一般都是喷,没少吭开发者。


    安装好后直接右键会有一个ScreenMatch菜单,点它。


    会发现项目里已经有两个配置文件了。


    一个dimens.xml文件,是例子,生成文件的基类,需要把里面的值复制到自己values下的dimens.xml文件中,如果你项目里没有这个文件,就手动创建它。

    另外一个是生成的配置文件,配置一些你需要生成的尺寸,它默认会有一些尺寸,你可以把你需要没有的添加上,把不需要的过滤掉。


    在次右键选择 ScreenMatch,项目里会出现配置里的尺寸xml文件了。


    跟老的值对比一下,验证是否正确,同时打开sw240dp里的xml,对应里面的值。



    左边的是代码生成的,右边的是插件生成的,dp1=0.64,dp2=1.28,然后我们在打开sw800dp里的xml看看。



    dp1=2.13,dp2=4.27,说明两种方式都一样,有插件省去了我们的计算。

    相关文章

      网友评论

        本文标题:dimens density 屏幕适配文件

        本文链接:https://www.haomeiwen.com/subject/zfpgwltx.html