Android多屏幕适配-平板

2023-11-14

http://blog.csdn.net/qq_27570955/article/details/53207600

1、常用单位及其关系

 px:像素

inch:英寸

pt:1/72 英寸

dpi:一英寸长的直线上的像素点的数量,即像素密度。不同的设备,dpi值不同,显示效果不同,dpi的值跟设备硬件有关。标准值是160dp。

dp(dip):独立像素密度。即在标准屏幕下,1个像素点的长度,标准屏幕是160dpi,可以理解为1英寸长度上有160个像素。标准屏幕中1dp=1px。

px = dp*(dpi/160);//当dpi=160时,1px=1dp

分辨率:屏幕上长宽方向上像素点的数量,即一个屏幕上像素的数量。

例如:720*1280 = 屏幕x轴上有720个像素,屏幕y轴上有1280个像素

分辨率单位:dpi(点每英寸)、lpi(线每英寸)、ppi(像素每英寸)

屏幕的物理尺寸:屏幕对角线的长度,单位是inch

sp:专用于设定文字大小,受dpi影响和用户的字体偏好设定影响。

各单位和px的换算关系见TypedValue.applyDimension方法

[java]  view plain  copy   在CODE上查看代码片 派生到我的代码片
  1. public static float applyDimension(int unit, float value,  
  2.                                        DisplayMetrics metrics)  
  3.     {  
  4.         switch (unit) {  
  5.         case COMPLEX_UNIT_PX:  
  6.             return value;  
  7.         case COMPLEX_UNIT_DIP:  
  8.             return value * metrics.density;  
  9.         case COMPLEX_UNIT_SP:  
  10.             return value * metrics.scaledDensity;  
  11.         case COMPLEX_UNIT_PT:  
  12.             return value * metrics.xdpi * (1.0f/72);  
  13.         case COMPLEX_UNIT_IN:  
  14.             return value * metrics.xdpi;  
  15.         case COMPLEX_UNIT_MM:  
  16.             return value * metrics.xdpi * (1.0f/25.4f);  
  17.         }  
  18.         return 0;  
  19.     }  

[java]  view plain  copy   在CODE上查看代码片 派生到我的代码片
  1. //显示器  
  2. DisplayMetrics d = getResources().getDisplayMetrics();//可以获得scaledDensity,densityDpi,heightPixels,widthPixels等信息。  
  3. Configuration configuration = getResources().getConfiguration();//获取设备的配置信息  
  4. //configuration.screenHeightDp  当前屏幕可用空间的高度,单位是dp  
  5. //configuration.screenWidthDp   当前屏幕可用空间的宽度,单位是dp  
  6. //configuration.densityDpi      当前设备的dpi信息  

例子:

已知设备1080*1920,使用DisplayMetrics获取的实际信息是1080*1776y轴方向上的像素有误差是因为软键盘,实际屏幕要小。

使用Configuration获取的设备的dpi=480dpi,根据公式px=dp*(dpi/160)

现在px=1080dpi=480,则dp=360.

使用configuration.screenWidthDp得到的数值为360,和上面用公式算出的一致。

但是y轴方向上用公式计算出来的应该是1776/3=592.但是用scrrenHeightDp获取的只有567

 

通过源码验证上述是否成立:

applyDimension方法就是通过输入的任何值转换成px,也就是说,该方法是任何单位和px的换算关系。

COMPLEX_UNIT_DIP 就是dip单位,就是平时说的dp。和px的换算关系是

value * metrics.density;

metrics.density是密度,默认值是

SystemProperties.getInt("qemu.sf.lcd_density",SystemProperties.getInt("ro.sf.lcd_density", DENSITY_DEFAULT)) / 160

160是中密度屏幕的标准dpi

所以屏幕密度density=设备dpi/160

DENSITY_DEFAULT=160

densityDpi=SystemProperties.getInt("qemu.sf.lcd_density",SystemProperties.getInt("ro.sf.lcd_density", DENSITY_DEFAULT))/ DENSITY_DEFAULT

density= densityDpi/ DENSITY_DEFAULT

scaledDensity=density

xdpi= densityDpi

ydpi= densityDpi

但是实际上得到的xdpi!=ydpi

xdpi:x轴屏幕每英寸的实际物理像素


2、换算方程式

[java]  view plain  copy   在CODE上查看代码片 派生到我的代码片
  1. px=dp*(dpi/160)  
  2. px=sp* metrics.scaledDensity   px=sp*(dpi/160)  
  3. px=pt*xdpi*(1.0f/72)   pt*(1/72)=inch  
  4. px=inch*xdpi  
  5. px=mm*xdpi*(1.0f*25.4f)  mm*(1.0f/25.4f)=inch  

易乱点:

分辨率1080*1920单位是像素,有的认为单位是dpi,但是通过源码验证,单位就是px

物理尺寸单位是inch

dpi跟设备有关系

只有在dpi=160时,1px=1dp


3、资源查找原则

app运行时,系统会根据属性选择适配的资源进行展示。如果有符合的资源则使用,反之,当符合的资源不存在时,系统会去寻找最相近的可用资源来代替。但是,查找的属性不同,查找的顺序会有所有差异。

 

res文件夹下的资源文件以优先级从高到低排列,命名规则:资源名-属性1-属性2-…..

v15修饰的资源仅用于4.0及以上的设备

w640dp修饰的适配640dp宽度的设备

h720dp修饰的资源适配720dp高度的设备

屏幕密度属性ldpimdpihdpixhdpixxhdpinodpitvdpi

ldpi=120

mdpi=160

hdpi=240

xhdpi=320

xxhdpi=480

xxxhdpi=640

 

其中nodpi用于开发者不希望系统对图片进行缩放的情况

tvdpi介于hdpimdpi之间。tvdpi一般在213左右,多用于Android系统的只能电视,大部分app很少用到

 

dpi属性来说,查找的顺序为,高dpi的资源优先。例如,没能找到hdpi的图片资源,则系统的搜索顺序是

drawable-xhdpi->drawable-xxhdpi->drawable-mdip->drawable->drawable->drawable-ldpi

这里drawable被认为比drawable-ldpi更接近hdpi

 

有时候,我们的图片资源不一定是从drawable文件夹中读取的,还有可能是从sd卡上读取的,或者从网络上下载的。这个时候,我们需要注意,默认情况下,通过BitmapFactory.decodeFile()函数生成的图片被认为是MDPI的,如果想让图片也获得与drawable文件夹相似的缩放能力,则需要通过BitmapFactory.Option.inDensity属性设置(例如如果图片是为hdpi准备的,则设置为240)。

 

对于screan size,查找的顺序则是小尺寸优先,大尺寸放弃。例如,在Galaxy note 2上执行apk时,如果未能找到layout-large资源,则查找顺序为:layout-normal->layout->layout-small,不会查找layout-xlarge


4、屏幕适配方案一

步骤:

1) 假设设计图的基准是720*1280,那么在设计图中1px对于1920*1080分辨率的手机应该是1.5px




在布局文件中就可以直接使用像素标识了,其实本质上是百分比

布局文件中的使用,比如说现在做一个670*80px的按钮,在density=1的时候,1dp=1px,在density=2.0的手机,1px=2.0dp,在density=1.5的手机中1px=1.5dp

如果使用dp设置这个button的大小,以2.0为基准,设置大小335*40dp

density=1.5的手机上,实际占的大小是502.5*60px。如果手机的分辨率是480*800px的就会出现button显示不全的情况。

 

但是,使用上面指定分辨率属性资源的,根据不同的手机分辨率应用自动寻找对应的资源文件。dimen_670_dip*dimen_80_dip在分辨率720*1280手机中是670*80px

1080*1920分辨率的手机中是1005*120px。不需要计算就可以得到相应的尺寸。(不需要人为去计算,根据资源查找原则,系统会自动选择最适合屏幕的资源)

[java]  view plain  copy   在CODE上查看代码片 派生到我的代码片
  1. <Button   
  2.            android:layout_width="@dimen/dimen_670_dip"  
  3.            android:layout_height="@dimen/dimen_80_dip"  
  4.            android:text="登陆"  
  5. />  

因为大小按照不同的手机不同的分辨率进行了适配但是字体也要进行适配不然大小变小了字体没有适配就会出现太小或太大的问题

ptsp的换算关系还跟用户的设置有关系,所以最好的方法就是,字体大小也使用px单位的换算。


5、屏幕适配方案二-------谷歌百分比布局库

android-support-percent.jar

方案一的适配已经运用在多款互联网应用,但是方案一的适配有一个缺点,就是会增加apk的大小。

使用谷歌的百分比布局库就可以解决这个问题

百分比布局库就是讲RelativeLayout换成PercentRelativeLayout

将FrameLayout换成PercentFrameLayout

支持宽高设置和margin设置

 

Eclipse中直接将jar复制进libs文件夹,并依赖库percent

F:\Android\SDK\extras\android\support\percent

sdk路径/extras/android/support/percent

AndroidStudiobuild.gradle添加compile 'com.android.support:percent:22.2.0'

使用示例

[java]  view plain  copy   在CODE上查看代码片 派生到我的代码片
  1. <android.support.percent.PercentRelativeLayout  
  2.    xmlns:app="http://schemas.android.com/apk/res-auto"  
  3.         android:layout_width="match_parent"  
  4.         android:layout_height="match_parent" >  
  5.         <TextView  
  6.             android:layout_width="0dp"  
  7.             android:layout_height="0dp"  
  8.             app:layout_heightPercent="20%"  
  9.             app:layout_widthPercent="30%"  
  10.             android:text="w:30%,h:20%" />  
  11.     </android.support.percent.PercentRelativeLayout>  

6、常用方法

[java]  view plain  copy   在CODE上查看代码片 派生到我的代码片
  1. /** 
  2.      * 根据手机的分辨率从 dp 的单位 转成为 px(像素) 
  3.      */  
  4.     public static int dip2px(Context context, float dpValue) {  
  5.         final float scale = context.getResources().getDisplayMetrics().density;  
  6.         return (int) (dpValue * scale + 0.5f);  
  7.     }  
  8.   
  9.     /** 
  10.      * 根据手机的分辨率从 px(像素) 的单位 转成为 dp 
  11.      */  
  12.     public static int px2dip(Context context, float pxValue) {  
  13.         final float scale = context.getResources().getDisplayMetrics().density;  
  14.         return (int) (pxValue / scale + 0.5f);  
  15.     }  
  16.   
  17.   
  18.     public static int getScreenWidth(Activity activity){  
  19.         DisplayMetrics dm = new DisplayMetrics();  
  20.         activity.getWindowManager().getDefaultDisplay().getMetrics(dm);  
  21.         int screenWidth = dm.widthPixels;  
  22.         return screenWidth;  
  23.     }  
  24.   
  25.     public static int getScreenHeigth(Activity activity){  
  26.         DisplayMetrics dm = new DisplayMetrics();  
  27.         activity.getWindowManager().getDefaultDisplay().getMetrics(dm);  
  28.         int screenHeigh = dm.heightPixels;  
  29.         return screenHeigh;  
  30.     }  
  31.   
  32.   
  33.     public static int measureHeight(View view){  
  34.   
  35.         int w = View.MeasureSpec.makeMeasureSpec(0,View.MeasureSpec.UNSPECIFIED);  
  36.         int h = View.MeasureSpec.makeMeasureSpec(0,View.MeasureSpec.UNSPECIFIED);  
  37.         view.measure(w, h);  
  38.         int height =view.getMeasuredHeight();  
  39.         return height;  
  40.     }  
  41.   
  42.     public static int measureWidth(View view){  
  43.         int w = View.MeasureSpec.makeMeasureSpec(0,View.MeasureSpec.UNSPECIFIED);  
  44.         int h = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);  
  45.         view.measure(w, h);  
  46.         int width =view.getMeasuredWidth();  
  47.         return width;  
  48.     }  


注意:

该适配方法只适用于手机。平板不适用该方法的适配。


参考资料:

谷歌官方资料:http://developer.android.com/guide/topics/resources/providing-resources.html

Android屏幕适配工具包(像素最大值是599pxsp最大值是49sp)http://download.csdn.net/detail/zmobs/8597341

屏幕分辨率信息查询:http://screensiz.es/phone

百分比布局库使用示例:https://github.com/JulienGenoud/android-percent-support-lib-sample

Android屏幕适配工具包2(像素最大值是2000pxsp最大值是200)http://download.csdn.NET/detail/qq_27570955/9653790

开源,原创,实用Android 屏幕适配方案分享http://blog.csdn.net/i7788/article/details/44937277

Android多屏幕适配学习笔记

开源,原创,实用Android 屏幕适配方案分享


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

Android多屏幕适配-平板 的相关文章

  • 关于模板类重载流operator<<

    关于模板类重载流operator lt lt template
  • 机器学习之逻辑回归算法笔记

    逻辑回归是一种用于解决分类问题的机器学习方法 它是一种基于概率思想的预测分析技术 分类算法 Logistic 回归用于预测分类因变量的似然性 逻辑回归中的因变量是二进制变量 数据编码为 1 是 真 正常 成功等 或 0 否 假 异常 失败等
  • C++ 类的构建,继承,派生上的小细节

    自己从C过渡到学C 的时候 对于面向过程和面向对象两种编程思想一直模模糊糊分不清楚 所以花了很大的功夫 侧面说明我可能不适合编程 为了提醒 也是为了做一点小总结 特意总结了一些学习的时候发现的易错点 一 类在声明的时候 必须要写清priva
  • UCOS-III 互斥量

    互斥量 一 互斥量基本概念 二 互斥量优先级继承机制 三 互斥量应用场景 四 互斥量运作机制 五 互斥量创建流程 1 定义互斥量 2 创建互斥量 六 互斥量接口函数 1 创建互斥量函数OSMutexCreate 2 删除互斥量函数 OSMu
  • VisibleDeprecationWarning: Creating an ndarray from ragged nested sequences (which is a list-or-tupl

    VisibleDeprecationWarning Creating an ndarray from ragged nested sequences which is a list or tuple of lists or tuples o
  • VS2015创建C语言工程

    http blog csdn net hao134838 article details 53142442 foxhandler RssReadRenderProcessHandler 引言 之前我们在完成C语言工程的时候都是在VC 6 0
  • 【数字音频】采样率、声道与采样深度

    前言 最近因为项目需要 接触了一些简单的数字音频知识 内容来源于网络 百度百科及相关博客 这里做一个简单的记录 方便以后查阅 1 采样率 采样频率 也称为采样速度或者采样率 定义了每秒从连续信号中提取并组成离散信号的采样个数 它用赫兹 Hz
  • uni app 调用网络打印机_Taro 和 uni-app选型对比

    一 Taro和uni app的介绍 1 taro的介绍 taro是多端统一开发框架 支持用 React 的开发方式编写一次代码 生成能运行在微信 百度 支付宝 字节跳动小程序 H5 React Native 等的应用 2 uni app的介
  • 修改Jar包源码(无需反编译工具)(文章看起来很长,其实方法超级简单!)

    前言 本文结合实际项目案例 介绍修改jar包源码的方式 其中运用了一些小技巧 正文 场景 在项目中用了第三方的jar包 但是jar包某个类的成员变量是private的 想将其改为public属性 以便为其赋值 源码中没有其提供简单的set方
  • 05_寄存器和RAM

    计算机的组成原理中 存储是必不可少的部分 可以用来存储计算的结果 图片 文字等等 本文将介绍存储是如何实现的 锁存器 首先我们来看一个门电路 当两个输入引脚都为0时 输出引脚也为0 如果A引脚输入1 输出为1 B引脚也会变为1 此时将A引脚
  • 指针:引领程序灵魂的精准指引

    指针 引领程序灵魂的精准指引 在计算机编程中 指针是一种强大而又常用的概念 它具备着引领和指引程序执行流程的作用 为我们开辟了更加广阔的编程世界 在本文中 我们将深入探讨指针的基本概念 使用方法和示例代码 帮助您更好地理解和运用指针 一 指
  • [leetcode] 2039. 网络空闲的时刻

    题目链接 题意 给定一张n个点不含重边的无向图 点的编号从0开始到n 1 两点之间如果有连边 可以认为耗时为1秒 1 gt n 1的点都需要向0号点发送消息 从第0秒开始 在0号收到消息之后 会回复消息 从第一秒开始 如果1 gt n 1号
  • django2.2 通过redis 存储session

    1 安装pip install django redis 2 配置setting文件 vi setting py 配置session使用redis CACHES default BACKEND django redis cache Redi
  • Python 2.7(3.x)以及numpy、matplotlib和scipy库三种方法实战安装

    Python是目前十分流行的跨平台编程语言 由于其具有优美简洁的特性以及简单的语法 同时支持工程应用 因而得到了越来越多的关注 Ubuntu下python和其比较常用的库 比如numpy matplotlib和scipy都是比较容易安装的
  • Visual Studio开发Qt5.12.3,使用QChartView widget时报错问题

    Visual Studio开发Qt5 12 3 使用QChartView widget时报错问题 使用场景 在Visual studio2017上开发Qt5 12 3项目 在ui界面上将一个QWidget提升为QChartView作为图标展
  • HTML之表格篇-表格嵌套表格

    嵌套表格一 效果如图所示 代码如下
  • jar包加密程序,防止反编译

    本窗体程序基于开源项目xjar https gitee com core lib xjar tree 2 1 1 src main java io xjar 1 pom文件
  • waf 绕过之[RoarCTF 2019]Easy Calc1(还运用了chr代替)

    打开题目 查看源码 发现有PHP文件 打开发现 这是一道审计代码传参题 需要构造num 然而num不允许传字母进去 会报错 这就为什么会有WAF的知识呢 不懂 然后WAF的绕过 在num前加空格就可以了 这样waf就找不到num这个变量了

随机推荐

  • __dict__属性

    dict 是 Python 中的一个特殊属性 通常存在于大多数 Python 对象中 用于存储该对象的可变属性 以下是关于 dict 的一些关键点和详细信息 存储属性 对于大多数自定义的 Python 对象 dict 属性包含了这个对象的属
  • 信息学奥赛一本通C++语言——1163:阿克曼(Ackmann)函数

    题目描述 阿克曼 Ackmann 函数A m n 中 m n定义域是非负整数 m 3 n 10 函数值定义为 a k m m n n 1 m 0 时 a k m m 1 1 m gt 0 n 0 时 a k m m 1 a k m m
  • GNN论文周报|来自北航、港大、UIUC等机构前沿论文研究

    图神经网络 GNN 是一类专门针对图结构数据的神经网络模型 在社交网络分析 知识图谱等领域中取得了不错的效果 近来 相关研究人员在GNN的可解释性 架构搜索 对比学习等方面做了很多探究 本周精选了10篇GNN领域的优秀论文 来自北航 港大
  • 算法基础:素数环

    题目描述 一个环由n个圈组成 将自然数1 n放入圈内 使得任意相邻圈的两个数之和均为素数 第一个圈的元素均为1 下图为n 6时的一个例子 程序样例 输入为一个整数n 6 8 输出分别为 1 4 3 2 5 6 1 6 5 2 3 4 1 2
  • window10 几款好用的屏幕录制制作动图工具

    有时候静态图片不能够展示交互效果 需要录制一下视频 所以就去网上找了几个好用的屏幕录制软件 一 GifCam GifCam录制视频很方便 打开软件 将窗口拖动到需要录制的地方 点击 Rec 就可以开始录制 在录制的过程中 可以随意的改变窗口
  • SpringBoot之RESTful 接口的实现以及Postman的使用

    SpringBoot实现Restful以及Postman的使用 1 HTTP相关知识 1 1 HTTP 工作原理 1 2 HTTP请求过程 1 3 HTTP请求的方法 2 Restful接口的使用 2 1 Restful风格API 2 2
  • c++随笔-删除文件

    c 删除文件非常简单 只需remove 文件名 即可 需要包含 include
  • java servlet json_Java HttpServlet Json 数据交互

    Android 对其访问进行封装 服务端 packagecom server importjava io PrintWriter importjavax servlet annotation WebServlet importjavax s
  • Rabbit的工作(2)【牛客练习赛36_C + dp背包】

    题目链接 那么的巧合 竟是这题的原题 就是 我们既然一定要选取K个任务 就先去取K个任务 然后逐一加上需要的额外天数即可 include
  • 上采样和下采样层 nn.pixelshuffle and nn.pixelunshuffle

    前言 理论部分后面有空的时候补一下 这里先放代码和简要说明 Downsample 这里先对channel维度降低为原来 1 2 1 2 1 2 然后再对channel维度提升 r
  • 高级JAVA开发 MQ部分

    高级JAVA开发 MQ部分 MQ MQ的作用 为什么要用MQ 常见的MQ的优缺点 使用MQ带来的问题以及处理办法 MQ带来的问题列举 消息重复消费 幂等 问题 消息丢失问题 消息顺序性问题 消息过期丢失 大量积压等问题 如何保证MQ高可用性
  • 斯坦福小镇升级版——AI-Town搭建指南

    导语 8月份斯坦福AI小镇开源之后 引起了 AIGC 领域的强烈反响 但8月份还有另一个同样非常有意义的 AI Agent 的项目开源 a16z主导的 AI Town 本篇文章主要讲解如何搭建该项目 如有英文基础或者对这套技术栈熟悉 可直接
  • 用list列表以行方式创建DataFrame

    DataFrame默认会将一维list作为列处理 需要将一维list转为二维才能实现想要的效果 A 1 2 3 4 5 直接pd DataFrame a 得到的是一个1列5行的df 正确方式是 pd DataFrame A 原文链接 htt
  • 个人博客系统(附源码)

    前面学习了那么多的理论知识 一直比较枯燥 今天就做个小项目 来检验一下前面的学习成果吧 有需要源代码的小伙伴可以来看看 个人博客系统 这个小项目主要是模仿CSDN做的 但是功能还是比较少的 只是写出了一些主要的功能 下面就一起来看看吧 目录
  • Merge AVHD with VHD

    AVHD is a file created when you perform snapshot Once you delete the snapshot and shutdown the Virtual Machine automatic
  • Protobuf类型

    1 基本类型 这些是原始的基本数据类型 用于存储数值和字符串 包括 double 双精度浮点数 float 单精度浮点数 int32 32 位有符号整数 int64 64 位有符号整数 uint32 32 位无符号整数 uint64 64
  • centos7升级gcc10.1.0,gdb9.2

    https www gnu org prep ftp html 先找一个亚洲的镜像站点 选一个站点 打开gcc或者gdb目录 选择自己想要安装的版本 我这里选择的gcc 10 1 0和gdb 9 2 http mirrors nju edu
  • smart bi 学习

    Smartbi 安装 部署 测试 官方文档 数据连接 关系数据库 选择数据连接选关系数据库 配置 连电脑本地的数据库 用户名 密码 root root 端口 3306 ip localhost mysql 数据库选的lyj 1 数据库管理
  • [React]为什么写React组件的时候,需要先引入React?

    React相信各位伙伴都不陌生 那么你的React技术还好吗 来跟我一起重学一遍React 看看有什么知识是你没有记住的呢 一起来查漏补缺下 目录 为什么有的React页面及组件在写的时候需要引入 React 为什么会出现这个问题 Reac
  • Android多屏幕适配-平板

    http blog csdn net qq 27570955 article details 53207600 1 常用单位及其关系 px 像素 inch 英寸 pt 1 72 英寸 dpi 一英寸长的直线上的像素点的数量 即像素密度 不同