Android 之UI自适应解决方案

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给出了一个范围,如下:

很显然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自适应解决方案,布布扣,bubuko.com

时间: 2024-09-30 03:31:31

Android 之UI自适应解决方案的相关文章

4种必须知道的Android屏幕自适应解决方案

文章来源:http://blog.csdn.net/shimiso/article/details/19166167 demo下载:http://www.eoeandroid.com/forum.php?mod=attachment&aid=NjE0Njh8ZTIyZDA2M2N8MTMzODgyOTQxN3w1NzAwOTV8MTczOTcz一.细说layout_weight    目前最为推荐的Android多屏幕自适应解决方案.    该属性的作用是决定控件在其父布局中的显示权重,一般用于

Android闹钟设置的解决方案

Android设置闹钟并不像IOS那样这么简单,做过Android设置闹钟的开发者都知道里面的坑有多深.下面记录一下,我解决Android闹钟设置的解决方案. 主要问题 API19开始AlarmManager的机制修改. 应用程序被Kill掉后,设置的闹钟不响. 6.0以上进入Doze模式会使JobScheduler停止工作. 手机设置重启后,闹钟失效问题. API19以上AlarmManager机制的修改 API19之前AlarmManager提供了三个设置闹钟的方法,由于业务需求闹钟只需要一

看大家android界面设计是拿Android Design UI Kit设计的,不直接在eclipse里设计,但是UI KIT怎么用呢

============问题描述============ Android 4.4 Design UI Kit (Nexus 4 version)打开十psd格式的,看网上说吧psd里面自己需要用到的东西保存为png格式,然后是要把png格式的图片当做android控件的背景使用? 其他类似的工具呢? ============解决方案1============ 一切不问是不是就问为什么的都是耍流氓,不知道你是怎么得出"android界面设计是拿Android Design UI Kit设计的,不直

探讨android更新UI的几种方法

作为IT新手,总以为只要有时间,有精力,什么东西都能做出来.这种念头我也有过,但很快就熄灭了,因为现实是残酷的,就算一开始的时间和精力非常充足,也会随着项目的推进而逐步消磨殆尽.我们会发现,自己越来越消极怠工,只是在无意义的敲代码,敲的还是网上抄来的代码,如果不行,继续找. 这就是项目进度没有规划好而导致的. 最近在做有关蓝牙的项目,一开始的进度都安排得很顺利,但是因为测试需要两部手机,而且还要是android手机,暑假已经开始了,同学们都回家了,加上我手机的蓝牙坏了,导致我的进度严重被打乱!而

android ViewPaper高度自适应

1 tv_btn_web.measure(0, 0);//计算所需的真实宽高 2 LayoutParams params=vp_btn_menu.getLayoutParams(); 3 params.height=tv_btn_web.getMeasuredHeight();//得到计算后的真实高度 4 vp_btn_menu.setLayoutParams(params); 有时我真的真正的android高手不是对android的理论原理理解的多么深刻(感觉android还算好理解,好用),

(8 Android) 用户界面UI设计

(8 Android) 用户界面UI设计 3.1.1 Android界面视图类 Android 图形化的用户界面(Graphical User Interface , GUI) 采用了结构清晰的MVC模型(Model-View-Controller) ,其具体含义: ·提供了处理用户输入的控制器(Controller) ; ·显示用户界面的视图(View) ; ·保存数据和代码的模型(Model) . 在Android MVC中,控制器是由Activity组件完成的,它能够接受并响应程序的外部动

mac 无法连接android手机进行调试 解决方案

第一步: 查看usb设备信息 在 终端输入:system_profiler SPUSBDataType     可以查看连接的usb设备的信息 比如我的usb信息如下(部分内容): Android: Product ID: 0x2769              Vendor ID: 0x22d9              Version: 2.31              Serial Number: 6e5d48a4              Speed: Up to 480 Mb/sec

android自定义UI模板图文详解

不知道大家在实际开发中有没有自定义过UI模板?今天花时间研究了一下android中自定义UI模板,与大家分享一下. 每个设计良好的App都是自定义标题栏,在自定义标题栏的过程中大部分人可能都是自定义一个标题的xml文件,然后在需要的地方直接通过include来引用,这比起在每个布局文件中写标题栏已经进化很多了,但仍然不是最简单有效的方法,我们为什么不能自定义一个标题控件呢?今天就带大家自己做一个标题栏控件.效果图如下: 开始啦: 第一步:自定义xml属性 新建一个android项目,在value

Android 自定义UI圆角按钮

Android实际开发中我们一般需要圆角的按钮,一般情况下我们可以让美工做出来相应的按钮图片,然后放上去即可,另外我们可以在布局文件中直接设置,也可以达到一样的效果.下面讲解在布局文件中自定义圆角按钮的小Demo. 代码很简单,实现效果图: 源代码: 源代码: 这里主要是xml布局文件实现: MainActivity: package com.android_drawableresource; import android.app.Activity; import android.os.Bund