声明:eoe文章著作权属于作者,受法律保护,转载时请务必以超链接形式附带如下信息

原文作者: zhuangyujia

原文地址: http://my.eoe.cn/zhuangyujia/archive/743.html

android屏幕适配

0

作者:zhuangyujia更新于 2013年02月02日访问(1699)评论(0

对于从事android应用开发的朋友来说应该知道,现有android手机的屏幕尺寸从2.7到5.3就有二十多种。光是为了写出来的界面可以适应这么多的屏幕尺寸,就要费不少功夫!
android的屏幕类型如此繁多,大小尺寸,长宽比例都不尽相同,同一个界面在不同分辨率的手机上可能出现布局错乱,控件跑位的现象。做屏幕的适配偶们不可能实现在每种屏幕上显示出的界面效果完全一致。只能靠偶们平时的编程习惯和经验是的界面在不同的屏幕尺寸在不会出现过分的走位,在可遇见范围内控制界面在不同屏幕下的变化,并做出相应调整。
那么偶们应该如何做到屏幕的适配呢?

1,首先从布局考虑

 Android的界面是由布局和组件协同完成的,布局好比是建筑里的框架,而组件则相当于建筑里的砖瓦。组件按照布局的要求依次排列,就组成了用户所看见的界面。Android的五大布局分别是LinearLayout(线性布局)、FrameLayout(单帧布局)、RelativeLayout(相对布局)、AbsoluteLayout(绝对布局)和TableLayout(表格布局)。
每种布局都有其特点,你可能会郁闷无法掌握好每种布局的使用,其实不管一个界面多复杂,偶们只需上述的一两种布局就可以实现,android提供这么多的布局供偶们选择只是为了方便偶们的开发。
本人习惯用LinearLayout,可能由于个人习惯,所以觉得线性布局的条理性更强一点,LinearLayout布局的子控件有一个很重要的属性,android:layout_weight。该属性将会在后面讲到,在这里只是建议大家选择一种自己比较熟悉的布局,自己的条理性强点,在屏幕尺寸发生变化时,能对子控件大小和位置的变化有一定的把握,这样才能做好屏幕适配。

2,px、dp和dip的关系

布局和子控件都有两个重要属性,layout_height和layout_width,用于指定控件的大小。系统还提供了几个属性供偶们使用,
1)fill_parent
设置一个构件的布局为fill_parent将强制性地使构件扩展,以填充布局单元内尽可能多的空间。这跟Windows控件的dockstyle属性大体一致。设置一个顶部布局或控件为fill_parent将强制性让它布满整个屏幕。
2) wrap_content
设置一个视图的尺寸为wrap_content将强制性地使视图扩展以显示全部内容。以TextView和ImageView控件为例,设置为wrap_content将完整显示其内部的文本和图像。布局元素将根据内容更改大小。设置一个视图的尺寸为wrap_content大体等同于设置Windows控件的Autosize属性为True。
3)match_parent
Android2.2中match_parent和fill_parent是一个意思 .两个参数意思一样,match_parent更贴切,于是从2.2开始两个词都可以用。那么如果考虑低版本的使用情况你就需要用fill_parent了。

更多情况下,为了界面可以适应不同屏幕分辨率的手机,偶们需要限制控件的大小,这里就要用到px、dp、dip、sp等等,这里只简单介绍下px和dip,其他在此不做阐述。
px: pixels(像素),不同的设备不同的显示屏显示效果是相同的,这是绝对像素,是多少就永远是多少不会改变。 显然,为了适配不同手机屏幕的显示,使用px来指定控件的大小是不行的。
dip: device independent pixels(设备独立像素). 不同设备有不同的显示效果,这个和设备硬件有关,一般我们为了支持WVGA、HVGA和QVGA 推荐使用这 这个,不依赖像素。
这里要特别注意dip与屏幕密度有关,而屏幕密度又与具体的硬件有关,硬件设置不正确,有可能导致dip不能正常显示。在屏幕密度为160的显示屏上,1dip=1px,有时候可能你的屏幕分辨率很大如480*800,但是屏幕密度没有正确设置比如说还是160,那么这个时候凡是使用dip的都会显示异常,基本都是显示过小。
dip的换算:
dip(value)=(int) (px(value)/1.5 + 0.5)
dp: 很简单,和dip是一样的。

所以在需要限定控件大小的时候,建议使用dip。

3、layout_weight属性

这个属性其实很好用,一般和android:layout_height="fill_parent"或android:layout_width="fill_parent"一起使用,它用于描述该子元素在剩余空间中占有的大小比例。加入一行只有一个文本框,那么它的默认值就为0,如果一行中有两个等长的文本框,那么他们的android:layout_weight值可以是同为1。如果一行中有两个不等长的文本框,那么他们的android:layout_weight值分别为1和2,那么第一个文本框将占据剩余空间的三分之二,第二个文本框将占据剩余空间中的三分之一。android:layout_weight遵循数值越小,重要度越高的原则。显示效果如下:

android屏幕如此繁多,不可能都是等比例缩放的,所以单纯使用dip来设置控件也是行不通的,与layout_weight属性灵活结合使用,增强界面的适应性。

4、drawable资源

首先:你需要在AndroidManifest.xml文件的元素如下添加子元素

  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  1. <supports-screens android:largeScreens="true"
  2. android:normalScreens="true" android:anyDensity="true"
  3. android:smallScreens="true"></supports-screens>
  4.  
  5. 名如其意,以上是为我们的屏幕设置多分辨率支持(更准确的说是适配大、中、小三种密度)。android:anyDensity="true" ,这一句对整个的屏幕都起着十分重要的作用,值为true,我们的应用程序当安装在不同密度的手机上时,程序会分别加载hdpi,mdpi,ldpi文件夹中的资源。

相反,如果值设置为false,即使我们在hdpi,mdpi,ldpi文件夹下拥有同一种资源,那么应用也不会自动地去相应文件夹下寻找资源,这种情况都是出现在高密度,以及低密度的手机上,比如说一部240×320像素的手机,如果设置android:anyDensity="false",Android系统会将240 x 320(低密度)转换为 320×480(中密度),这样的话,应用就会在小密度手机上加载mdpi文件中的资源。
细心的人会发现自android2.0开始之后drawable文件被三个文件夹drawable-hdpi,drawable-mdpi,drawable-ldpi三个文件夹所取代,有些编程人员为了让应用程序默认地加载某些图片,他们会特意地去在android2.0之后的应用程序中重新创建drawable文件夹,其实这样做完全没有必要,通过第一段的分析我们得知,android:anyDensity="false",则应用会将大小密度转变成中密度,从而去加载mdpi中的资源。这里同样,当android:anyDensity="false",则应用会去加载mdpi中的资源。

总结一下:
第一:android:anyDensity="true",系统会依据屏幕密度,自动去找对应的文件夹
第二:android:anyDensity="false",
(1)如果drawable-hdpi,drawable-mdpi,drawable-ldpi三个文件夹中有同一张图片资源的不同密度表示,那么系统会去加载drawable_mdpi文件夹中的资源
(2)如果drawable-hpdi中有高密度图片,其它两个文件夹中没有对应图片资源,那么系统会去加载drawable-hdpi中的资源。
(3)如果drawable-hdpi,drawable-mdpi中有图片资源,drawable-ldpi中没有对应的图片资源,那么系统会加载drawable-mdpi文件夹中的资源

注意上图各种文件夹的不同表示。
drawable-hdpi 该图片即适用于横屏,也适用于竖屏
drawable-land-hdpi,当屏幕为横屏,且为高密度时,加载此文件夹中的资源
drawable-port-hdpi,当屏幕为竖屏,且为高密度时,加载此文件夹中的资源

5、draw9patch工具

android SDK包的tools目录下为偶们提供了这么一个图片处理工具。有时候偶们需要图片资源自适应且不失真,无论横屏还是竖屏,高分辨率还是低分辨率,都能自动填充满,而且不失真等等背景问题。 Android针对这种情况,专门制作了一种.9.PNG格式来解决这个问题。draw9patch就是帮助偶们制作.9.PNG格式资源的一个小工具。
*.9.PNG就标准的PNG格式,只是在最外面一圈额外增加1px的边框,这个1px的边框就是用来定义图片中可扩展的和静态不变的区域。特别说明,left(左)和top(上)边框中交叉部分是可拉伸部分,未选中部分是静态区域部分。right和bottom(下和右)边框中交叉部分则是内容部分。

如上图《也就是说,在手机里。无论上面那张图怎么放大,四周的圆角都是不会被放大的!只有left(左)和top(上)边框内才会伸缩!
在Android中以9.PNG格式的图片未背景,则能够自定义拉伸而不失真,比如系统的Button就是一个典型的例子。其实呢,无论是left和top,还是right和bottom都是把图片分成9块 (边角四块是不能缩放的,其他的四块则是允许缩放的),所以叫做9.PNG。
关于draw9patch工具的使用在此不做阐述,需要的可以参考一下博文:draw9patch教程

6、Layout资源

有时候可能由于屏幕布局过于复杂,同一个布局文件很难适应所有的屏幕分辨率。可以像drawable资源一样,在工程的res文件夹下建立多个相应的layout文件夹,为相应分辨率的屏幕编写相应的layout文件。
文件夹的命名规范是这样的:layout-分辨率
例如:layout-320x240 , layout-480x320等等。
系统就会根据运行环境的分辨率优先加载相应的文件夹下的layout布局文件。

7、代码动态添加

使用过swing的都知道如何代码动态添加控件,android也是一样的,当然代码动态添加远远没有xml布局文件方便,也不易于管理。但他的好处就是偶们可以在代码里获得运行环境的屏幕尺寸,通过计算构建相应的界面。虽然代码编写界面确实繁琐,但他的适配性也是不可否认的。
获取屏幕的大小可以有两种方法:
// 方法一:
WindowManager manager = getWindowManager();
int width = manager.getDefaultDisplay().getWidth();
int height = manager.getDefaultDisplay().getHeight();
// 方法二:
DisplayMetrics dMetrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(dMetrics);
int screenWidth = dMetrics.widthPixels;
int screenHeight = dMetrics.heightPixels;

8、其他
除了xml文件和代码编写界面外,还可以用webview加载相应的html文件,界面内容由html完成。本人见过别人用html5编写界面也非常美观,屏幕的适应性也非常强。由于本人对html5不是很了解,在此就不细谈,有兴趣的朋友可以去了解下。
有时候可能由于屏幕实在太小,要显示的内容又实在太多,一屏实在挤不下去。可以适当的使用ScrollView控件使界面更加完整,确保用户体验。

如何将一个应用程序适配在不同的手机上,虽然这不算是一个技术问题,但是对于刚刚做屏幕的开发人员来说,还真不是一件多么简单的事情。
以上只是本人学习android开发以来的一点拙见和总结,欢迎热爱编程的朋友们一起来探讨和学习!

(转)android屏幕适配的更多相关文章

  1. Android屏幕适配全攻略 (转载)

    http://blog.csdn.net/jdsjlzx/article/details/45891551 https://github.com/hongyangAndroid/AndroidAuto ...

  2. 【收藏】Android屏幕适配全攻略(最权威的Google官方适配指导)

    来源:http://blog.csdn.net/zhaokaiqiang1992 更多:Android AutoLayout全新的适配方式, 堪称适配终结者 Android的屏幕适配一直以来都在折磨着 ...

  3. Android屏幕适配全攻略(最权威的官方适配指导)(转),共大家分享。

    Android的屏幕适配一直以来都在折磨着我们这些开发者,本篇文章以Google的官方文档为基础,全面而深入的讲解了Android屏幕适配的原因.重要概念.解决方案及最佳实践,我相信如果你能认真的学习 ...

  4. Android屏幕适配全攻略(最权威的官方适配指导) (转)

    招聘信息: Cocos2d-X 前端主程 [新浪微博]手机客户端iOS研发工程师 20k-40k iOS 开发工程师 iOS高级开发工程师(中国排名第一的企业级移动互联网云计算公司 和创科技 红圈营销 ...

  5. 腾讯优测| 让Android屏幕适配开发更简单-Google百分比布

    文/腾讯优测工程师 吴宇焕 腾讯优测优社区干货精选~ 相信开发同学都被安卓设备碎片化的问题折磨过,市面上安卓手机的主流屏幕尺寸种类繁多,给适配造成很大的困难.就算搞定了屏幕尺寸问题,各种分辨率又让人眼 ...

  6. Android 屏幕适配(一)百分比布局库(percent-support-lib) 解析与扩展

    转载请标明出处: http://blog.csdn.net/lmj623565791/article/details/46695347: 本文出自:[张鸿洋的博客] 一.概述 周末游戏打得过猛,于是周 ...

  7. Android重写getResources规避用户调整系统字体大小影响Android屏幕适配

    Android屏幕适配一直是一个头疼的问题.除此之外还要考虑APP在实际应用场景中,用户千奇百怪的设置,最常见的用户设置行为就是设置手机的字体大小,比如把字体设置成超大或者超小,这对屏幕适配又带来额外 ...

  8. 【转】Android屏幕适配全攻略(最权威的官方适配指导)

    原文网址:http://blog.csdn.net/jdsjlzx/article/details/45891551 Android的屏幕适配一直以来都在折磨着我们这些开发者,本篇文章以Google的 ...

  9. Android开发——自动生成Android屏幕适配的dimens.xml文件

    使用dimens.xml解决屏幕适配问题是Android官方解决方案,本文主要讲述了如何自动生成Android屏幕适配的dimens.xml,减少了工作量,在维护dimens.xml文件时更加省时省力 ...

随机推荐

  1. ViewPager+Fragment实现滑动显示,且Fragment里面又放Fragment+viewPager

    思路:新建一个Activity,且这个Activity要继承FragementActivity,在Activity的布局文件中放入了一个viewPager,为了效果好看,还做了个导航,使得ViewPa ...

  2. 无法在 Android 模拟器上访问本机的Web服务的解决办法

    我在本地跑了一个 Tomcat ,我想在 Android 模拟器中直接通过下面的 url 地址访问 Tomcat 上的服务 http://192.168.0.20:8080/getweather 但是 ...

  3. 基于swift语言iOS8的蓝牙连接(初步)

    看过一些蓝牙App的事例,大体上对蓝牙的连接过程进行了了解.但是开始真正自己写一个小的BLE程序的时候就举步维艰了.那些模棱两可的概念在头脑中瞬间就蒸发了,所以还是决定从最基本的蓝牙连接过程进行.这里 ...

  4. 51nod 1109 01组成的N的倍数

    用01 组成 N的最小倍数 这个BFS搜索就好. 类似这道:  ZOJ Problem Set - 1530 每次 要么是0 要么是1, 记入余数,和前驱. #include<bits/stdc ...

  5. Differences Between Xcode Project Templates for iOS Apps

    Differences Between Xcode Project Templates for iOS Apps When you create a new iOS app project in Xc ...

  6. 如何在Report Builder中使用fnd_profile.value

    在EBS的Report开发中,需要根据客户化的一个Profile来控制用户可以访问的数据,可是在开发的过程中发现一直取不到该Profile的值,后来百度才找到了原因. 解决方法: 1.添加用户参数p_ ...

  7. Careercup - Google面试题 - 5661939564806144

    2014-05-06 01:40 题目链接 原题: Give a N*N matrix, print it out diagonally. Follow up, if it is a M*N matr ...

  8. Window 添加定时任务

    简单任务 右键点击 我的电脑->管理->任务计划程序库->创建基本任务 然后选择任务类型,触发时间,触发程序就可以了,可以精确到秒 带参数的计划任务 如果执行程序是cmd 可选参数那 ...

  9. 关于Google+以及Facebook第三方登录实现的一点总结

    简述 最近项目中有关于第三方登陆的需求,第三方Facebook以及Google +登录. 正好这几天把这个需求做得差不多了,收个尾,作为一个这方面之前基本从未涉及的小白,总结下开发流程以及过程中遇到的 ...

  10. dp--poj1458最长公共子序列

    很水的一题 输入串a与串b: Dp[i][j]表示a串中1~i与b串中1~j的子串的最长公共子序列. Max{dp[i-1][j], dp[i][j-1]}       (a[i]!=b[j]) Dp ...