1.概况

作为Android开发者,最头疼的莫过于让自己开发的程序在不同终端上面的显示效果看起来尽量一致(当然。假设要充分利用大屏幕的优势另当别论)。在全球范围内来讲。android有着数以亿计的设备,当中就不乏设备分辨率多种多样。以及设备屏幕物理尺寸的多样化。

总得来说我们须要做的有三点。其一让APP的每一个UI中的每一个View宽和高更加灵活以适应不同分辨率、其二对于大屏幕设备(PAD)须要有不同的设计,竟可能多的展示内容。获取你整个APP的全部UI都能够做到一个布局中来、其三图标资源需提供不同尺寸(MDPI、HDPI、XHDPI、XXHDPI、XXXHDPI),你也能够图方便仅仅提供一套较高尺寸的API,没问题,这可能仅仅会使那些配置低的设备(或者说分辨率低,事实上实际这两者普遍成正比)耗费很多其它的内存在载入资源图片上面。

2.官方支持

 1.图标资源

官方建议APP中使用的图标资源都需提供drawable-ldpi(眼下来看,已经没有必要)、drawable-mdpi、drawable-hdpi、drawable-xhdpi。

说到DPI(Dots Per Inch)事实上就是单位尺寸有多少个像素,计算方式就是手机分辨率宽的平方+高的平方,再开根号得到斜对角线分辨率。

然后用这个除以屏幕的实际尺寸(也就是我们常说的4寸、5寸、7寸、10寸),这个尺寸实际也是屏幕的斜对角尺寸。这样计算出来的结果就是像素密度。像素密度越大说明手机显示越细腻。举个样例HTC One分辨率是1920*1080,屏幕尺寸是4.7英寸,拿上面的公式计算一下2202/4.7=468那么它属于上面哪个区域呢?android给出了一个范围,例如以下:

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbHVvd2VubG9uZzg2MDUwMg==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="">

非常显然HTC One 被归入xhdpi这一类里面。

所以假设你的APP提供了drawable-xhdpi以下的图标,HTC One执行你APP时会自己选择载入那里面的。

2.布局

Android的五大布局各自是LinearLayout(线性布局)、FrameLayout(帧布局)、RelativeLayout(相对布局)、AbsoluteLayout(绝对布局)和TableLayout(表格布局)。

当中用得最多的要数LinearLayout和RelativeLayout,FrameLayout和TableLayout可在有特效需求的页面使用,这里就不介绍,而AbsoluteLayout已经被标记位Deprecated
since API level 3,不建议再使用。

线性布局的特点是。里面的每一个view都是按顺序摆放,要么是垂直要么是水平,谁声明在前面谁显示时就排在前面。

而相对布局位置不受排放顺序的限制,能够在xml中指定它位于哪个view的上方、下方、左边或右边。

做自适应最关键的地方就在布局上面,首先拿到需求后分析页面採用何种布局结构才干更好的做到自适应,或者APP设计时就设计得比較简单,而手机端软件的设计规则也是越简单越好用!在布局上尽量使用match_parent个wrap_content,绝对不要使用px(当然假设你的APK仅仅须要支持某一种分辨率除外),非要设置详细大小时使用dp做单位,这样才干在不同DPI但物理尺寸大小一样的手机上面通用。

但都用dp并不能满足同一时候适应手机和平板(物理尺寸存在较大差异)。由于平板的物理尺寸比較大一般是7寸以上。举个样例。两个Button将其大小设置为width
50dp height 50dp,它在800*480 尺寸为4寸的手机上面显示效果例如以下:

而在1024*600的七寸平板上面显示效果例如以下:

非常显然在平板上面显示效果感觉太小了。为什么会出现如此差异,我们能够通过计算得出答案。800*400 4寸 DPI是230。normal状态下DPI是160,据此我们能够算出50dp在这个800*480 4寸设备上面占用的像素是230/160*50 = 72px ,显然这个宽度仅仅占到整个屏幕宽度的72/480=0.15。再看看截图,应该几乎相同是这么个比例吧。假设是在1024*600的7寸(DPI是170)设备上面50dp占用的像素是170/160*50=53px,这样整个button占领屏幕的宽度就仅仅有53/600=0.09,也就是如截图看到的一样占用非常小的一坨。

所以,通过dp作为单位不能解决不同尺寸设备的自适应问题,相同android也提供了对应的解决的方法,在android3.2 (API 13)曾经对屏幕大小做了例如以下分类:

要想在布局文件里区分不同尺寸设备能够通过layout-small、layout-normal、layout-large和layout-xlarge,依据我们刚才计算的值,仅仅需在layout-large中指定button的大小为x这个x的值能够通过公式算出来x*(170/160)/600=0.15  x = 600*0.15/(170/160)=95dp,再看下效果例如以下:

这样就它们显示起来的效果就差点儿一样了。同一时候,不光是大小,显示的位置都能够依据屏幕的大小做不同的显示。普通情况下你须要维护layout layout-large和layout-xlarge三套布局文件,在android 3.2以后官方又提供了更加精确的尺寸大小区分办法。sw<N>dp,当中sw指的是长和宽中的较小者。比方1024*600的7寸,sw的计算方式是600/(170/160)=565dp,但实际是不正确的,參考网页《官方六》中的描写叙述:

Note: The sizes that you specify using thesequalifiers are not the actual screen sizes. Rather, the sizes arefor the width or height in dp units that are available to youractivity's window.
The Android system might use some of the screen forsystem UI (such as the system bar at the bottom of the screen or the status barat the top), so some of the screen might not be available for your layout.Thus, the sizes you declare should be specifically about
the sizes needed byyour activity—the system accounts for any space used by system UI whendeclaring how much space it provides for your layout. Also beware thatthe Action
Bar
 isconsidered a part of your application's window space, although your layout doesnot declare it, so it reduces the space available for your layout and you mustaccount for it in your design.

所以说须要注意的是计算sw时会有一定得区间浮动,我们须要尽量定义小些。比方565dp假设你定义为sw565dp。但实际是sw564dp,那么就不会走到sw565dp里面去了。而是採用向下找近期的原则,假设都没找到就使用默认的layout。

对于官方为什么会引入sw这个概念,是由于large xlarge已经不能适应各种厂商太多的中间尺寸,比方5.5 、5.7、 6 、 6.5等等,假设是android3.2下面。这些将所有被归入large的范畴。这种话5.5和7寸设备显示的效果就会有些出入,当然不会有非常大出入。

为了满足人们对设计的精益求精,在android3.2以后的设备中都能够使用sw来做更细的划分。如sw480dp sw600dp sw720dw sw1024dp等等。

当然为了避免维护如此多的layout布局文件我们还能够用另外的版本号来完毕自适应的动作。如上面的样例,每一个button都是占屏幕宽度的0.15,我们能够用layout_weight权重这一概念,设置该button的权重为0.15就可以,它就会在每一个设备上面达到相同的效果—均占屏幕宽度的0.15,高也是同理。对与宽高比例一致的设备这是一个不错的选择,但对与不同宽高比的设备,全然使用layout_weight来做自适应显然是不能达到效果的,比方800*480和854*480的设备,假设高採用相同的weight,854的高肯定会显得拉伸。假设button上面有背景图片。则图片会变形。

有一个小技巧能够解决此问题。就是用ImageView来取代Button,同一时候将背景图片设置为android:src。曾经景的模式显示。这样能够利用imageview的属性,使图片保持原始的比例填充。

3.数值

布局文件里会用到各种数值。如view的宽、高,字体的大小padding大小,magin大小等均能够在values目录中定义当中就包含strings.xml dimens.xml styles.xmlcolor.xml等等,当然跟自适应相关的就是dimens.xml。这里面定义了各种view属性的大小,比如button的高为50dp能够在dimens里面定义<dimen name="btn_size">50dp</dimen>然后将button的android:layout_width="@dimen/btn_size
"。在布局部分我们讲到用layout-large layout-sw600dp等来区分不同屏幕大小的设备,相同在values里面也能够加上values-largevalues-sw600dp等来区分。比方最開始的样例里面我们能够仅仅定义一个layout 将button的宽高都设置为@dimen/ btn_size,然后定义一个values/dimen.xml 和一个values-large/dimen.xml,分别写上<dimen name="btn_size">50dp</dimen>和<dimen name="btn_size">95dp</dimen>,这和写多个layout效果是一样的。但我个人认为假设页面相对照较简单。在values里面下功夫比写多个layout要简单些。

3. 扩展

有时我们APP须要支持到比較旧的API版本号。但我们有想用到一些比較高级的API里面的功能,这时我们能够在values后面加上-v<xx>如values-v11。当中11就是API版本号,也就是11以上API的设备就会採用values-v11里面的内容。就比方API 11里面增加了Action Bar的功能。那么假设你想利用这个特性,能够在values-v11里面定义一个style.xml,继承自action
bar相关的style,而在values里面的style.xml中定义不支持action bar的style。但在布局中用其它view来模拟action bar的效果。

4.总结

对与UI自适应总结一下主要是两点。同样屏幕尺寸不同分辨率以及不同屏幕尺寸同样分辨率。对于前者,仅仅需在布局中用到单位的地方所实用dp就可以解决(有条件的话drawable最好能提供不同分辨率icon,实在不行。提供同意范围内尽量大分辨率图片)。对于后者,则须要依据尺寸的等级写不同的layout文件或者values文件。这个需依据项目的详细负责程度来自由选择。

Android 之UI自适应解决方式的更多相关文章

  1. android程序报错“error launching activity com.android.ddmlib.shellcommandunresponsiveexception”的解决方式

    今天在调试android程序的时候,因为是NDK开发,要先编译.so库再打包下载到android模拟器,所以花费的时间比較长.控制台就会报例如以下错误: error launching activit ...

  2. Android 多屏适配解决方式

    1.主流手机必要測量的參数(通过详细的方法.測量出,须要測试手机的 以下的这些參数,我们主要使用的仅仅是 screenwidth  这个參数,其它參数仅仅是帮助我们更好的理解 屏幕适配) Displa ...

  3. Android内存优化-内存泄漏的几个场景以及解决方式

    转自:http://blog.csdn.net/a910626/article/details/50849760 一.什么是内存泄漏 在Java程序中,如果一个对象没有利用价值了,正常情况下gc是会对 ...

  4. Android之——常见Bug及其解决方式

    转载请注明出处:http://blog.csdn.net/l1028386804/article/details/46942139 1.android.view.WindowManager$BadTo ...

  5. Android Activity启动黑/白屏原因与解决方式

    Android Activity启动黑/白屏原因与解决方式 我们新建一个HelloWorld项目,运行在手机上时,Activity打开之前会有一个动画,而这个动画里是全白或者全黑的(取决于你的主题是亮 ...

  6. Android加载图片OOM错误解决方式

    前几天做项目的时候,甲方要求是PAD (SAMSUNG P600 10.1寸 2560*1600)的PAD上显示高分辨率的大图片. SQLITE採用BOLD方式存储图片,这个存取过程就不说了哈,网上一 ...

  7. 【Android使用Shape绘制虚线,在4.0以上的手机显示实线】解决方式

    问题描写叙述: 用下面代码绘制虚线: <span style="font-family:Comic Sans MS;font-size:18px;"><? xml ...

  8. Android Studio 错误: 非法字符: &#39;\ufeff&#39; 解决方式|错误: 须要class, interface或enum

    在导入eclipse项目到Android Studio出现这种错误, 非法字符: '\ufeff' 解决方式|错误: 须要class, interface或enum.查阅后了解到Eclipse能够智能 ...

  9. android升级adt和sdk之后无法识别SDK Location的一个解决方式

    我把android的adt和sdk从4.0升级到4.2,发现eclipse的android设置里面原来列出的各种api level的platform消失了,而且无法新建android工程.而且检查过了 ...

随机推荐

  1. 【hdoj_1051】WoodenSticks

    题目:http://acm.hdu.edu.cn/showproblem.php?pid=1051 题意可以理解为:给定若干个二元数对,要将这些数对分为不同的组,同一组中的若干个二元数对可以排列成一个 ...

  2. MATLAB作图方法与技巧(三)

    1.利用指令plot绘制圆的参数方程x = sin(t),y = cos(t),(0<=t<=2*pi)的曲线图. 代码如下 t = linspace(0,2*pi,100); x = s ...

  3. eclipse 关键字高亮显示

    关键字高亮显示(变量.函数名……) Toggle Mark Occurrences  (Alt + Shift + O), 也可以在eclipse主界面的快捷工具栏:按下那个小黄蜡笔图标,来设置高亮显 ...

  4. 极光推送配置(Android Studio),亲测有效

    进行到这里就可以接收到通知了,但是如果你还想根据接收的消息做点什么 step8: public class MyReceiver extends BroadcastReceiver { private ...

  5. centos中pyenv安装

    1.先安装git yum install git -y 2.克隆pyenv到本地 git clone git://github.com/yyuu/pyenv.git .pyenv 或自动安装 curl ...

  6. Don't Be a Subsequence

    问题 F: Don't Be a Subsequence 时间限制: 1 Sec  内存限制: 128 MB提交: 33  解决: 2[提交] [状态] [讨论版] [命题人:] 题目描述 A sub ...

  7. 微信小程序开发教程(五)开发框架:MINA

    微信团队为小程序提供的框架命名为MINA应用框架.MINA框架通过封装微信客户端提供的文件系统.网络通信.任务管理.数据安全等基础功能,对上层提供一整套JavaScript API,让开发者能够非常方 ...

  8. [BZOJ 2342] 双倍回文

    Link:https://www.lydsy.com/JudgeOnline/problem.php?id=2342 Algorithm: 解决回文串问题,一般从对称轴下手. 肯定先跑一边Manach ...

  9. SD 一轮集训 day1 carcar

    可以发现每条边只能选一次或者两次,并且最后每个点的度数(∑邻接边选的次数和)都是偶数(代表有欧拉回路). 然后根据题意列一个 n 行 m+1 列的01矩阵,每一行代表一个异或方程组(每个点的度数是偶数 ...

  10. Exercise03_12

    import java.util.Scanner; public class Palindrome { public static void main(String[] args){ int a; S ...