android 平板适配

2023-05-16

首次进行平板开发,从一开始就在琢磨适配是怎么弄的,百度、google、群一大圈,还是没人告诉具体是怎么做的,都是基本的概念性的讲述怎么适配,写了一个界面发现存在很大适配问题,最后找到了几篇有价值的博客,文章末尾有链接;

先了解点基本概念:

px:pixel,像素,电子屏幕上组成一幅图画或照片的最基本单元;

dip : Density independent pixels ,设备无关像素,是安卓开发用的长度单位,1dp表示在屏幕像素点密度为160ppi时1px长度;

dp :就是dip;

sp: scale-independent pixel,安卓开发用的字体大小单位,一般情况下可认为sp=dp;

pt: point,点,印刷行业常用单位,等于1/72英寸,ios也适用这个作为大小单位;

ppi: pixel per inch,每英寸像素数,该值越高,则屏幕越细腻;

dpi :dots per inch , 直接来说就是一英寸多少个像素点。常见取值 120,160,240。我一般称作像素密度,简称密度;

density : 直接翻译的话貌似叫 密度。常见取值 1.5 , 1.0 。和标准dpi的比例(160px/inc);

分辨率 : 横纵2个方向的像素点的数量,常见取值 480X800 ,320X480;

这里引用文档的屏幕尺寸限定符描述:

官方文档:https://developer.android.com/guide/practices/screens_support

新的屏幕尺寸限定符(Android3.2 之后引入)

屏幕特性

限定符

描述

最小宽度限定符

sw<N>dp

例如sw600dp, sw720dp

屏幕的最小尺寸,就是屏幕可用区域的最小尺寸,是指屏幕可用高度或宽度的最小值(你可以默认是屏幕的最小宽度).你能用这个限定符确保,无论屏幕方向如何,这个限定符修饰下的布局需要的屏幕最小尺寸是Ndp.

例如,如果你的布局在运行时需要的最小屏幕宽度是600dp,则你可以利用这个限定符创建布局资源目录res/layout-sw600dp.只有当屏幕的最小宽度或最小高度是600dp时,系统才会使用这些布局文件或者资源文件.最小屏幕宽度是固定设备的特有屏幕尺寸,当屏幕方向发生变化时,设备的最小宽度值不变.

设备的最小宽度值要考虑屏幕的尺寸和系统UI.例如,如果在屏幕上有一些系统持久化UI元素,则系统的最小宽度值要比实现的屏幕尺寸小一些,因为这些系统的UI元素你的应用是无法使用到的.

当你使用之前的广义限定符是,你可以定义连续的一系列限定符.用最小宽度来决定广义屏幕尺寸是有意义的,是因为宽度是影响你UI设计的关键因素.UI在竖直方向上会经常滚动,但是在水平方向上往往是固定的布局.可见不论是适配手机或者平板,宽度往往都是布局的关键因素.因此,你需要关心你手机上的最小宽度值.

屏幕可用宽度

w<N>dp

Examples:

w720p

w1024p

指定资源使用时需要的最小宽度.当屏幕方向发生变化时,系统会调整这个值,使其始终为你UI显示的宽度.

这个属性经常被用来判断当前是否需要显示多屏布局,因为哪怕用户当前正在使用平板,你也可能不希望用户在平板竖屏时显示多个屏幕的布局样式.这时,你就可以使用这个限定符来标明你布局需要的最小宽度

屏幕可用高度

h<N>dp

Examples:

h720dp

h1024dp

etc.

标明资源使用时需要的最小高度.当屏幕发生旋转时,系统会自动选择当前大的一方作为高度值.大部分应用很少需要这个限定符,因此不做过多讲解

我的项目中建立这么几个values文件夹存放dimens(我的项目强制使用横屏,所以后面加了-land),那具体设备是获得那一个文件夹的尺寸呢?每一个文件夹中的尺寸一样吗?难道需要自己创建这么多文件夹里面的dimens文件慢慢添加吗?

如果横竖屏、不同屏幕设备有不同布局界面,也可以对应创建不同的layout文件夹;

第一问题:获取那个文件夹下的资源:

通过公式 sw*160/dpi 计算出结果之后,选择一个比这个结果小,而又最接近这个值的dp(即文件夹下的内容)。

sw*160/dpi计算示例:

比如

分辨率1280*800, sw 是800

分辨率1920*1080, sw 是1080

dpi获取方法:

1、 adb shell getprop ro.sf.lcd_density 获得

2、代码中

DisplayMetrics dm = new DisplayMetrics();

getWindowManager().getDefaultDisplay().getMetrics(dm);

int  dpi = dm.density*160;

       分辨率

sw

   dpi= ro.sf.lcd_density  

         sw *160/dpi    =  dp

1280*720     

720

213     

720*160/213=540.84 =       sw480dp

1280*800

800

320

800*160/320=400 =       sw340dp

1024*768     

768

160    

768*160/160 =768 =            sw720dp

800*480      

480

120      

480*160/120 =640=             sw600dp

800*480    

480

160    

480*160/160 =480=             sw480dp

比如第一条数据,计算sw*160/dpi的值是540.84,就会去找sw540的文件夹资源,找不到就会向下找,找到sw480dp的文件夹

第二个问题:每一个文件夹中的尺寸一样吗?难道需要自己创建这么多文件夹里面的dimens文件慢慢添加吗?一会回答

里面的值肯定不一样,也不需要一个一个计算一个一个添加,创建一个类DimenTool,自动帮你计算同步;

注意⚠️:要添加dp和sp只需要在values文件夹下的dimens文件添加,然后运行DimenTool工具类即可达到同步(可以根据自己需要的尺寸在DimenTool类中修改,里面的换算比例暂时还不知道是怎么换算来的,引用时注意下,网上有很多不同的换算比例)

/**
 * Created by zyt on 2018/7/11.
 * 自动计算dimens的工具
 */

public class DimenTool {

    public static void gen() {

        File file = new File("./app/src/main/res/values/dimens.xml");
        BufferedReader reader = null;
        StringBuilder sw480 = new StringBuilder();
        StringBuilder sw600 = new StringBuilder();
        StringBuilder sw720 = new StringBuilder();
        StringBuilder sw800 = new StringBuilder();
        StringBuilder w820 = new StringBuilder();


        try {
            System.out.println("生成不同分辨率:");
            reader = new BufferedReader(new FileReader(file));
            String tempString;
            int line = 1;
            // 一次读入一行,直到读入null为文件结束

            while ((tempString = reader.readLine()) != null) {

                if (tempString.contains("</dimen>")) {
                    //tempString = tempString.replaceAll(" ", "");
                    String start = tempString.substring(0, tempString.indexOf(">") + 1);
                    String end = tempString.substring(tempString.lastIndexOf("<") - 2);
                    double num = Double.valueOf(tempString.substring(tempString.indexOf(">") + 1, tempString.indexOf("</dimen>") - 2));
//这里的换算比例现在还不知道为什么是这样,等找到了在更新上来
                    sw480.append(start).append((int) Math.round(num * 0.6)).append(end).append("\n");
                    sw600.append(start).append((int) Math.round(num * 0.75)).append(end).append("\n");
                    sw720.append(start).append((int) Math.round(num * 0.9)).append(end).append("\n");
                    sw800.append(tempString).append("\n");
                    w820.append(tempString).append("\n");

                } else {
                    sw480.append(tempString).append("\n");
                    sw600.append(tempString).append("\n");
                    sw720.append(tempString).append("\n");
                    sw800.append(tempString).append("\n");
                    w820.append(tempString).append("\n");
                }
                line++;
            }
            reader.close();
            System.out.println("<!--  sw480 -->");
            System.out.println(sw480);
            System.out.println("<!--  sw600 -->");
            System.out.println(sw600);

            System.out.println("<!--  sw720 -->");
            System.out.println(sw720);
            System.out.println("<!--  sw800 -->");
            System.out.println(sw800);

            String sw480file = "./app/src/main/res/values-sw480dp-land/dimens.xml";
            String sw600file = "./app/src/main/res/values-sw600dp-land/dimens.xml";
            String sw720file = "./app/src/main/res/values-sw720dp-land/dimens.xml";
            String sw800file = "./app/src/main/res/values-sw800dp-land/dimens.xml";
            String w820file = "./app/src/main/res/values-w820dp/dimens.xml";
            writeFile(sw480file, sw480.toString());
            writeFile(sw600file, sw600.toString());
            writeFile(sw720file, sw720.toString());
            writeFile(sw800file, sw800.toString());
            writeFile(w820file, w820.toString());
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (reader != null) {
                try {
                    reader.close();
                } catch (IOException e1) {
                    e1.printStackTrace();
                }
            }
        }
    }

    public 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();
    }

    public static void main(String[] args) {
        gen();
    }
}

最后再补充一些其他适配知识:

我们常说的mdpi、hdpi、xhdpi、xxhdpi、xxxhdpi对应使用的是多少像素密度呢,看下图:

应用启动图标的适配

至少要提供一个xxxhdpi类型的启动图标,因为Android会帮你自动缩小图标到对应的别的分辨率上(放大是会变模糊的)

最后直接推荐使用今日头条的android适配终极武器(修改手机的设备密度 density):

https://github.com/JessYanCoding/AndroidAutoSize

关于比较好的一篇博客:骚年你的屏幕适配方式该升级了!-今日头条适配方案 - 掘金

参考链接:

Android(density屏幕密度)_hhuleaves的博客-CSDN博客_ro.sf.lcd_density

最清晰的Android多屏幕适配方案 - soaringEveryday - 博客园

Android开发中如何获得正确的layout资源(layout-sw480dp layout-sw600dp-land layout-sw720dp-port)_Felix.Ma的博客-CSDN博客

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

android 平板适配 的相关文章

  • Altium Designer PCB设置电源线粗细宽度+绘制时改变粗细

    一般电源线要给多个设备供电 xff0c 所以比信号线要粗一些 新建布线 Routing 的宽度规则 xff1a 然后如下图所示 xff0c 把这条规则重命名为width 5v 命名随意 并设置这条规则的作用对象为 xff1a 名字为 34
  • AndroidStudio安装BindView注解插件

    新版本androidStudio添加BindVIew插件可以直接在Build gradle Module app 里面的dependencies下添加 compile 39 com jakewharton butterknife 8 8 1
  • 漫话程序员们的家庭装修——书房篇

    身为一名程序员 xff0c 辛辛苦苦码代码N年 xff0c 终于攒下钱买了自己的小窝 xff0c 不好好犒劳一下自己都对不起自己的近视眼和鼠标手 这就来分享一下我装修的心得 xff0c 从书房开始 xff01 书房作为程序员在公司战斗一天回
  • 首次安装Android Studio 新建项目构建失败解决

    首次安装AS xff0c 新建项目需要下载构建所需jar包 xff0c 如果没有翻墙 xff0c 就很可能会导致下载失败 解决方案 xff1a 1 打开项目根目录下的build gradle文件 xff0c 把goole 和jcenter
  • Arch Linux安装中文输入法

    1 安装fcitx span class token function sudo span pacman S fcitx im 2 配置 如果以startx方式进入gnome 在 xinitrc xff0c exec之前中加入 xff1a
  • Activity和fragment的简单切换效果

    Activity有默认的切换效果 xff0c 但是这个效果我们也可以自定义 xff0c 主要用到overridePendingTransition int enterAnim int exitAnim 这个方法 xff0c 这个方法必须在s
  • java maven 连接mysql 8.0数据库

    JAVA maven项目 连接数据库 mysql8 0 查询 xff0c 插入 xff0c 删除 xff0c 更新 1 在pom xml加入mysql connector java依赖包 xff0c version要跟你的mysql版本对应
  • Windows无法安装到这个磁盘,选中的磁盘具有MBR分区表。在EFI系统上,Windows只能安装GPT磁盘。

    报错 xff1a Windows无法安装到这个磁盘 xff0c 选中的磁盘具有MBR分区表 在EFI系统上 xff0c Windows只能安装GPT磁盘 操作 xff1a 1 Windows安装程序界面如下 xff0c 使用快捷键shift
  • 华为Taishan服务器安装UOS操作系统

    今天2020 12 18 折腾了一遍华为Taishan服务器重装UOS20操作系统 xff0c 没经验 xff0c 一堆问题 xff0c 逐个排查解决的 做个记录 xff0c 以免下次再坑 1 光驱引导 最开始 xff0c 选择光驱引导安装
  • SLF4J用户手册(谷歌翻译版)

    本文翻译自slf4j官方用户手册 xff0c 地址 SLF4J Manual Java 的简单日志门面 SLF4J 用作各种日志框架的简单门面或抽象 xff0c 例如 java util logging logback 和 reload4j
  • 读java编程思想的一点感触

    学习一些java基础语法后 xff0c 能应付简单的日常工作 但是觉得还是得系统学习一下这门语言 xff0c 就选择了java编程思想 原书第4版 xff0c 机械工业出版社 xff0c 陈昊鹏译的这本 看懂的不是很多 xff0c 还是学到
  • Unable to determine application id: com.android.tools.idea.run.ApkProvisionException: No outputs for

    错误 xff1a Unable to determine application id com android tools idea run ApkProvisionException No outputs for the main art
  • 完善二叉树的右指针

    对于一个二叉树 xff0c 每个结点有三个指针 xff0c 除了左右子节点指针外还有一个指向右边的结点的指针 现在给定一个二叉树 xff0c 每个结点的右指针为空 xff0c 让你把每一层的结点都连起来 xff08 默认是完全二叉树 xff
  • 什么是AOSP?

    AOSP全名为Android Open Source Project xff0c 中文为安卓开源项目 xff0c 开源即开放源代码 Android是一个基于Linux xff0c 由Google主导的开源系统 严格意义上来说 xff0c A
  • 什么是APT攻击

    什么是APT攻击 APT攻击即高级可持续威胁攻击 也称为定向威胁攻击 xff0c 指某组织对特定对象展开的持续有效的攻击活动 APT是黑客以窃取核心资料为目的 xff0c 针对客户所发动的网络攻击和侵袭行为 xff0c 是一种蓄谋已久的 恶
  • CEO、COO、CFO、CTO、CMO是什么意思

    一 什么是CEO COO CFO CTO xff1f CEO总裁 CFO财务总监 CTO技术总监 COO运营总监 CEO Chief Executive officer 首席执行官 可以理解为是企业领导人和职业经理人两种身份的合一 xff0
  • POC测试是什么

    POC测试 xff0c 即Proof of Concept 可以理解为 xff1a 根据客户需求进行测试 是业界流行的针对客户具体应用的验证性测试 xff0c 根据用户对采用系统提出的性能要求和扩展需求的指标 xff0c 在选用服务器上进行
  • 开发环境、测试环境、生产环境

    生产环境 是可以对外开放 xff0c 已通过测试验证 xff0c 对外提供服务的环境 开发环境 程序员做开发的环境 xff0c 该环境已经部署好需要的开发工具和服务 测试环境 一般是从生产环境复制过来的环境 xff0c 用于要发布的服务 业
  • Yml的基本配置(服务器端口、日志、JPA、Druid、环境激活、thymeleaf、resource)

    springboot配置文件很强大 也丰富 xff0c 约定优于配置 xff0c 只需做少量的配置 xff0c 其它采用默认的就行 application properties xff08 传统 xff09 xff0c applicatio
  • 使用BitLocker实现磁盘加密、u盘加密、移动硬盘加密

    一 使用系统自带的工具BitLocker实现 Bitlocker是属于win7版本以后有的系统功能 Windows BitLocker驱动器加密通过加密Windows操作系统卷上存储的所有数据可以更好地保护计算机中的数据 BitLocker

随机推荐

  • k8s的dashboard无法正常访问

    本场景为使用google浏览器访问vmware搭建的虚拟机 建议使用google浏览器的无痕模式 网页提示信息Client sent an HTTP request to an HTTPS server 原因 xff1a 因为直接使用ip
  • k8s删除pod失败,一直处于deleted的界面

    我们在删除pod的时候出现以下情况 xff1a span class token comment 删除pod span span class token punctuation span root 64 master1 yaml span
  • journalctl命令

    journalctl简介 journalctl命令是Systemd的 个命令 xff0c 是用来管理查看日志信息的 因为日志的信息多 xff0c 复杂 xff0c journalctl命令用参数的方式来帮助用户更快地定位日志 注释 xff1
  • 如何在微信小程序里使用Lottie动画库

    先看效果图 xff1a 前言 xff1a 微信小程序的lottie动画库是按照lottie web动画库改造而来 参考lottie web xff1a https github com airbnb lottie web xff0c 以及官
  • mysql中grant all privileges on赋给用户远程权限

    mysql中grant all privileges on赋给用户远程权限 改表法 当你的帐号不允许从远程登陆 xff0c 只能在localhost连接时 这个时候只要在mysql服务器上 xff0c 更改 mysql 数据库里的 user
  • Shell之function函数的定义及调用

    文章目录 96 function 96 函数的定义及调用 96 function 96 函数的定义 96 function 96 函数的调用 位置传参 函数使用return返回值 位置传参 函数的调用 数组传参 function函数的定义及
  • springboot集成activeMQ实现Queue队列

    1 首先下载 activeMQ地址 xff1a https activemq apache org 下载完成以后 xff0c 进行启动 启动步骤很简单 xff0c 就tomcat差不多 这里要注意 xff0c 看你电脑是32位还是64位 x
  • Docker Desktop Vmmem内存占用过高问题解决方案

    Docker Desktop Vmmem内存占用过高问题解决方案 内存占用过高原因 主要原因是docker desktop的实现及基于wsl Windows子系统 相当于在Windows上同时开了一个虚拟机 如果不对wsl的资源进行限制 它
  • spring mvc 预习

    spring mvc 概述 Web 框架 xff0c 是目前最主流的 MVC 框架之一 Spring3 0 后全面超越 Struts2 xff0c 成为最优秀的 MVC 框架 Spring MVC 通过一套 MVC 注解 xff0c 让 P
  • windows server 2012 进程 出现大量桌面窗口管理器的 解决方法

    windows server 2012 进程 出现 桌面窗口管理器 打开运行 打Cmd xff0c 执行 taskkill f im winlogon exe t 记住 这个命令会让远程桌面黑屏 xff0c 不要着急 xff0c 远程按下C
  • 在线医疗系统(毕设)

    小白的成长之路从自己写毕设开始 从整个设计说明书中截取了一部分 相关技术 Springboot VUE MySQL数据库 Bootstrap AJAX 融云 shiro等总体设计 数据库相关表设计 数据库截图了一张图 详细设计与实现 系统整
  • Android 终极推送方案(结束应用进程依然可以接收通知)

    开发中总会遇到产品经理需求是 xff1a 结束掉应用依然想接收到通知 xff0c iOS轻而易举就可以实现 xff0c 但Android一直都是杀掉应用后就无法接收到通知 xff01 网上给的结果大概是 xff1a 1 集成各大厂商的推送s
  • error: resource android:attr/lStar not found完美解决

    今天突然项目出现如下错误 xff0c 编译就报错 D AndroidProjects XXXXX app build intermediates incremental mergeDebugResources merged dir valu
  • android 动态引用含占位符的字符串时,出现红波浪线如何解决

    现象 xff1a 在开发时 xff0c 想动态引用含占位符的字符串 xff0c 发现有红色波浪线警告 xff0c 项目可以正常运行 xff0c 既然是警告 xff0c 肯定就是我们代码有问题 将鼠标放上去提示警告 xff1a Format
  • Mac电脑安装apktool工具包

    开发中少不了想看看别人怎么实现某个功能 xff0c 于是会用到apktool反编译apk xff0c apktool工具包是一个压缩包 xff0c 下载后无需安装 xff0c 简单配置下执行命令就能反编译apk了 xff0c 下面我们看一下
  • 查看 AndroidManifest.xml 文件内容,解决全是二进制代码问题

    想查看打包后apk的AndroidManifest xml文件内容 xff0c 之前都是将后缀apk改为zip xff0c 直接解压查看 xff0c 有时会遇到都是二进制代码 xff0c 给出集中查看明文的方法 xff1a 方法一 通过an
  • unknown error (Sqlite code 14): Could not open database解决方案

    今天在运行之前一个项目是突然一运行就崩溃 xff0c 感觉甚是奇怪 xff0c 查看log日志发现 Caused by android database sqlite SQLiteCantOpenDatabaseException unkn
  • Android RecyclerView Item点击事件

    RecyclerView控件出来后可以代替ListView xff0c 功能更强大 xff0c 但是RecyclerView却没有ListView的setOnItemClickListener和setOnLongClickListener方
  • GitHub上README.md编写教程(基本语法)

    今天在编写github中的readme md文档时 xff0c 发现自己写的和别人写的样式完全不一样 xff0c 自己的好难看 xff0c 于是百度了一番 xff0c 很多都是转载的别人13年的博客 xff0c 其中还发现一片17年写的原创
  • android 平板适配

    首次进行平板开发 xff0c 从一开始就在琢磨适配是怎么弄的 xff0c 百度 google 群一大圈 xff0c 还是没人告诉具体是怎么做的 xff0c 都是基本的概念性的讲述怎么适配 xff0c 写了一个界面发现存在很大适配问题 xff