经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 移动开发 » Android » 查看文章
android dimens density适配文件生成
来源:cnblogs  作者:翻滚的咸鱼  时间:2021/2/18 14:51:45  对本文有异议

在编写xml的时候,我们直接指定一个固定一个控件的宽高,给一个固定的dp值,在不同的屏幕上显示差别很大,导致有的手机布局无法正常显示,所以需要适配屏幕,这里讲的适配方式都一样,不过方法不一样

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

 

执行代码会根据定义的尺寸生成出对应的 dimens.xml 类,下面是代码

  1. package com.example.myapplication;
  2. import android.util.Log;
  3. import java.io.File;
  4. import java.io.FileNotFoundException;
  5. import java.io.FileOutputStream;
  6. import java.io.IOException;
  7. import java.math.BigDecimal;
  8. public class MakeUtils {
  9. private static final String XML_HEADER = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n";
  10. private static final String XML_RESOURCE_START = "<resources>\r\n";
  11. private static final String XML_RESOURCE_END = "</resources>\r\n";
  12. private static final String XML_DIMEN_TEMPLETE = "<dimen name=\"qb_%1$spx_%2$d\">%3$.2fdp</dimen>\r\n";
  13. private static final String XML_BASE_DPI = "<dimen name=\"base_dpi\">%ddp</dimen>\r\n";
  14. private static final int MAX_SIZE = 720;
  15. private static final String XML_NAME = "dimens.xml";
  16. public static float px2dip(float pxValue, int sw,int designWidth) {
  17. float dpValue = (pxValue/(float)designWidth) * sw;
  18. BigDecimal bigDecimal = new BigDecimal(dpValue);
  19. float dp = bigDecimal.setScale(2, BigDecimal.ROUND_HALF_UP).floatValue();
  20. return dp;
  21. }
  22. /**
  23. * 生成所有的尺寸数据
  24. */
  25. private static String createDimens(DimenTypes type, int designWidth) {
  26. float dpValue;
  27. String temp;
  28. StringBuilder sb = new StringBuilder();
  29. try {
  30. sb.append(XML_HEADER);
  31. sb.append(XML_RESOURCE_START);
  32. //备份生成的相关信息
  33. temp = String.format(XML_BASE_DPI, type.getSwWidthDp());
  34. sb.append(temp);
  35. for (int i = 0; i <= MAX_SIZE; i++) {
  36. dpValue = px2dip((float) i,type.getSwWidthDp(),designWidth);
  37. temp = String.format(XML_DIMEN_TEMPLETE,"", i, dpValue);
  38. sb.append(temp);
  39. }
  40. sb.append(XML_RESOURCE_END);
  41. } catch (Exception e) {
  42. e.printStackTrace();
  43. }
  44. return sb.toString();
  45. }
  46. /**
  47. * 生成的目标文件夹
  48. */
  49. public static void create(int designWidth, DimenTypes type, String buildDir) {
  50. try {
  51. //生成规则
  52. final String folderName;
  53. if (type.getSwWidthDp() > 0) {
  54. //适配Android 3.2+
  55. folderName = "values-sw" + type.getSwWidthDp() + "dp";
  56. }else {
  57. return;
  58. }
  59. //生成目标目录
  60. File file = new File(buildDir + File.separator + folderName);
  61. if (!file.exists()) {
  62. file.mkdirs();
  63. }
  64. Log.e("===",file.getAbsolutePath());
  65. //生成values文件
  66. FileOutputStream fos = new FileOutputStream(file.getAbsolutePath() + File.separator + XML_NAME);
  67. fos.write(createDimens(type,designWidth).getBytes());
  68. fos.flush();
  69. fos.close();
  70. } catch (IOException e) {
  71. e.printStackTrace();
  72. }
  73. }
  74. }
View Code
  1. package com.example.myapplication;
  2. /**
  3. * created by YooJin.
  4. * date: 2021/2/3 13:50
  5. * ldpi: 120 density:1dp=0.75px 代表尺寸 240*320
  6. * mdpi: 160 density:1dp=1px 代表尺寸 320*480
  7. * hdpi: 240 density:1dp=1.5px 代表尺寸 480*800
  8. * xhdpi: 320 density:1dp=2px 代表尺寸720*1280
  9. * xxhdpi: 480 density:1dp=3px 代表尺寸1080*1920
  10. */
  11. enum DimenTypes {
  12. DP_sw__160(160),
  13. DP_sw__240(240),
  14. DP_sw__280(280),
  15. DP_sw__320(320),
  16. DP_sw__360(360),
  17. DP_sw__400(400),
  18. DP_sw__420(420),
  19. DP_sw__440(440),
  20. DP_sw__480(480),
  21. DP_sw__560(560),
  22. DP_sw__640(640),
  23. DP_sw__720(720),
  24. DP_sw__800(800);
  25. /**
  26. * 屏幕最小宽度
  27. */
  28. private int swWidthDp;
  29. DimenTypes(int swWidthDp) {
  30. this.swWidthDp = swWidthDp;
  31. }
  32. public int getSwWidthDp() {
  33. return swWidthDp;
  34. }
  35. public void setSwWidthDp(int swWidthDp) {
  36. this.swWidthDp = swWidthDp;
  37. }
  38. }
View Code
  1. package com.example.myapplication;
  2. import androidx.annotation.NonNull;
  3. import androidx.appcompat.app.AppCompatActivity;
  4. import androidx.core.app.ActivityCompat;
  5. import androidx.core.content.ContextCompat;
  6. import android.Manifest;
  7. import android.content.pm.PackageManager;
  8. import android.os.Bundle;
  9. import android.os.Environment;
  10. import android.widget.TextView;
  11. import java.io.File;
  12. import java.util.ArrayList;
  13. import java.util.List;
  14. public class MainActivity extends AppCompatActivity {
  15. /**
  16. * 设计稿尺寸,从零开始,生成的最大尺寸
  17. */
  18. private static final int DESIGN_WIDTH = 375;
  19. String[] permissions = new String[]{Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE};
  20. List<String> mPermissionList = new ArrayList<>();
  21. private static final int PERMISSION_REQUEST = 1;
  22. @Override
  23. protected void onCreate(Bundle savedInstanceState) {
  24. super.onCreate(savedInstanceState);
  25. setContentView(R.layout.activity_main);
  26. checkPermission();
  27. String path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).getAbsolutePath() + File.separator + "res";
  28. TextView tvTag = findViewById(R.id.tv_tag);
  29. tvTag.setText(path);
  30. DimenTypes[] values = DimenTypes.values();
  31. for (DimenTypes value : values) {
  32. MakeUtils.create(DESIGN_WIDTH, value, path);
  33. }
  34. }
  35. private void checkPermission() {
  36. mPermissionList.clear();
  37. //判断哪些权限未授予
  38. for (int i = 0; i < permissions.length; i++) {
  39. if (ContextCompat.checkSelfPermission(this, permissions[i]) != PackageManager.PERMISSION_GRANTED) {
  40. mPermissionList.add(permissions[i]);
  41. }
  42. }
  43. /**
  44. * 判断是否为空
  45. */
  46. if (mPermissionList.isEmpty()) {//未授予的权限为空,表示都授予了
  47. } else {//请求权限方法
  48. String[] permissions = mPermissionList.toArray(new String[mPermissionList.size()]);//将List转为数组
  49. ActivityCompat.requestPermissions(MainActivity.this, permissions, PERMISSION_REQUEST);
  50. }
  51. }
  52. /**
  53. * 响应授权
  54. * 这里不管用户是否拒绝,都进入首页,不再重复申请权限
  55. */
  56. @Override
  57. public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
  58. super.onRequestPermissionsResult(requestCode, permissions, grantResults);
  59. switch (requestCode) {
  60. case PERMISSION_REQUEST:
  61. break;
  62. default:
  63. super.onRequestPermissionsResult(requestCode, permissions, grantResults);
  64. break;
  65. }
  66. }
  67. }
View Code

执行代码后打印出路径,我这里是下载目录下的res文件,注意需要先申请权限,然后把生成的文件剪切出来

里面都把dimens文件生成好了

 

直接把文件复制到项目里就可以直接使用了,那么有没有什么便捷一点的开关呢,还真有

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

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

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

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

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

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

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

  

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

  

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

github:https://github.com/1024477951/KotlinStrong

原文链接:http://www.cnblogs.com/LiuZhen/p/14367974.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号