设计兼容不同的屏幕尺寸的Android界面
Android的屏幕类型有几百种不同的尺寸,从小型的手机到大型的电视机。因此要使我们的应用程序兼容不同屏幕尺寸,才可以让我们的应用提供给更多的用户使用。
一、支持不同的屏幕尺寸
1、使用“wrap_content"和”match_parent"
为了确保布局的灵活性,来适应不同尺寸的屏幕,我们应该使用“wrap_content"来匹配组件的最小尺寸和使用”match_parent"来设置某些视图来匹配父视图的大小。这样设置和直接设置视图大小(如48dip)不同的是该视图的空间可以随着屏幕尺寸(父视图的大小)随意扩展。例如如下布局:
<LinearLayout xmlns:android = "http://schemas.android.com/apk/res/android"
android:orientation = "vertical"
android:layout_width = "match_parent"
android:layout_height = "match_parent" >
<LinearLayout android:layout_width = "match_parent"
android:id = "@+id/linearLayout1"
android:gravity = "center"
android:layout_height = "50dp" >
<ImageView android:id = "@+id/imageView1"
android:layout_height = "wrap_content"
android:layout_width = "wrap_content"
android:src = "@drawable/logo"
android:paddingRight = "30dp"
android:layout_gravity = "left"
android:layout_weight = "0" />
<View android:layout_height = "wrap_content"
android:id = "@+id/view1"
android:layout_width = "wrap_content"
android:layout_weight = "1" />
<Button android:id = "@+id/categorybutton"
android:background = "@drawable/button_bg"
android:layout_height = "match_parent"
android:layout_weight = "0"
android:layout_width = "120dp"
style = " @ style / CategoryButtonStyle " />
</LinearLayout> <fragment android:id = "@+id/headlines"
android:layout_height = "fill_parent"
android:name = "com.example.android.newsreader.HeadlinesFragment"
android:layout_width = "match_parent" />
</LinearLayout>
当我们翻转手机屏幕可以看到横向和竖向的屏幕适配如下:
2、使用Relative_layout
我们可以使用LinearLayout通过“wrap_content"和”match_parent"来实现很多复杂的布局,但是LinearLayout擅长控制的是线性的关系,如果是要精确控制平面关系,使用Relative_layout比较合适,它可以指定两个组件之间的空间关系。例如下面代码:
<?xml的version = "1.0" encoding = "utf-8" ?>
<RelativeLayout xmlns:android = "http://schemas.android.com/apk/res/android"
android:layout_width = "match_parent"
android:layout_height = "match_parent" >
<TextView
android:id = "@+id/label"
android:layout_width = "match_parent"
android:layout_height = "wrap_content"
android:text = "Type here:" />
<EditText
android:id = "@+id/entry"
android:layout_width = "match_parent"
android:layout_height = "wrap_content"
android:layout_below = "@id/label" />
<Button
android:id = "@+id/ok"
android:layout_width = "wrap_content"
android:layout_height = "wrap_content"
android:layout_below = "@id/entry"
android:layout_alignParentRight = "true"
android:layout_marginLeft = "10dp"
android:text = "OK" />
<Button
android:layout_width = "wrap_content"
android:layout_height = "wrap_content"
android:layout_toLeftOf = "@id/ok"
android:layout_alignTop = "@id/ok"
android:text = "Cancel" />
</RelativeLayout>
在小屏幕尺寸的QVGA手机上显示如下:
在大屏幕的WSVGA屏幕上显示如下:
3、使用尺寸限定符
上面我们通过“wrap_content"、”match_parent"、“relative_layout"的方法来实现不同屏幕尺寸的视图伸展,有效的解决了屏幕尺寸问题,除了这些方法外我们还可以使用尺寸限定符来针对不同的屏幕来做特殊的界面布局。
第一列是屏幕的特征,有尺寸、密度、方向、长宽比
第二列是限定符的写法(如large,我们就需要建立一个文件夹名称为layout-large)
第三列是相关解释和描述
例如我们现在在我们的res下建立两个文件夹通过不同的限定符文件夹名称来匹配不同尺寸的屏幕
res/layout/main.xml
<LinearLayout xmlns:android = "http://schemas.android.com/apk/res/android"
android:orientation = "vertical"
android:layout_width = "match_parent"
android:layout_height = "match_parent" > <fragment android:id = "@+id/headlines"
android:layout_height = "fill_parent"
android:name = "com.example.android.newsreader.HeadlinesFragment"
android:layout_width = "match_parent" />
</LinearLayout>
res/layout-large/main.xml
<LinearLayout xmlns:android = "http://schemas.android.com/apk/res/android"
android:layout_width = "fill_parent"
android:layout_height = "fill_parent"
android:orientation = "horizontal" >
<fragment android:id = "@+id/headlines"
android:layout_height = "fill_parent"
android:name = "com.example.android.newsreader.HeadlinesFragment"
android:layout_width = "400dp"
android:layout_marginRight = "10dp" />
<fragment android:id = "@+id/article"
android:layout_height = "fill_parent"
android:name = "com.example.android.newsreader.ArticleFragment"
android:layout_width = "fill_parent" />
</LinearLayout>
上面布局中在大屏幕中我们将两个大视图放到了整个屏幕,二小屏幕中我们只放置了一个视图。我们的设备会根据屏幕尺寸来自动寻找自己的布局。
4、使用最小宽度限定符
上面根据屏幕尺寸来匹配不同的布局文件,但是很多时候我们可能在不同的大屏手机中需要分别显示不同的布局(例如Galaxy Tab显示5个还是7个),在Android3.2以后就有了最小宽度限定符来解决这个问题。
假设sw600dp来表示我们的最小宽度,则布局文件就可以有如下表示:
小屏幕手机适配的布局 res/layout/main.xml
<LinearLayout xmlns:android = "http://schemas.android.com/apk/res/android"
android:orientation = "vertical"
android:layout_width = "match_parent"
android:layout_height = "match_parent" > <fragment android:id = "@+id/headlines"
android:layout_height = "fill_parent"
android:name = "com.example.android.newsreader.HeadlinesFragment"
android:layout_width = "match_parent" />
</LinearLayout>
设备宽度大于或等于600dp的布局 res/layout/layout-sw600dp.xml
<LinearLayout xmlns:android = "http://schemas.android.com/apk/res/android"
android:layout_width = "fill_parent"
android:layout_height = "fill_parent"
android:orientation = "horizontal" >
<fragment android:id = "@+id/headlines"
android:layout_height = "fill_parent"
android:name = "com.example.android.newsreader.HeadlinesFragment"
android:layout_width = "400dp"
android:layout_marginRight = "10dp" />
<fragment android:id = "@+id/article"
android:layout_height = "fill_parent"
android:name = "com.example.android.newsreader.ArticleFragment"
android:layout_width = "fill_parent" />
</LinearLayout>
要注意的是这种限定符在3.2以前的版本手机上是不支持的。在3.2之前还必须用尺寸限定符large来代替。
5、使用layout别名
综合上面的分析,如果我们要支持一个包含大屏幕尺寸的设备必须包含例如下面几个布局来匹配
res/layout/main.xml
res/layout/layout-large
res/layout/layout-sw600dp
最后这两个文件的作用是相同的,是为了支持3.2以下和以上版本,为了避免混淆和维护难度,我们可以给这些布局起别名,比如下面的布局名:
res/layout/main.xml 单面板布局
res/layout/main_twopanes.xml 双面板布局
并添加这两个文件
res/values-large/layout.xml
<resources>
<item name="main" type="layout">@layout/main_twopanes</item>
</resources>
res/values-sw600dp/layout.xml
<resources>
<item name="main" type="layout">@layout/main_twopanes</item>
</resources>
可以看到这两个文件的内容相同,他们只是建立起一个main和mian_twospanes的联系,可以通过屏幕尺寸来分别获取不同的value文件下所对应的布局文件别名。
6、使用方向限定符
有的时候我们的应用可能需要翻转手机能获得更好的效果,此时的布局也需要做相应的改变,也可以分别做出对应的布局文件。请参照上面的表格(land 和 port)。
7、使用Nine-Patch图
对于不同的屏幕尺寸通常我们需要使用不同尺寸的图片资源,所以在设计可变大小的组件时,一定要使用Nine-Patch图。
如上图的Nine-Patch图在不同尺寸手机上的拉伸效果如下:
有关Nine-Patch的制作方法请参考我的另一篇博文:http://blog.csdn.net/dawanganban/article/details/17379193
二、支持不同的屏幕密度
我们在设计布局的时候不能使用绝对的像素尺寸,而应该使用dp和sp.不同设备具有不同的屏幕密度,1英寸的不同密度手机上的像素个数是不同的。为了让大家搞清楚这些基本概念,我逐一解释一下:
dpi 像素密度:像素密度,即每英寸屏幕所拥有的像素数,像素密度越大,显示画面细节就越丰富。
我们可以用这个公式表示 1dpi = 1pix / 1in
dp (dip)设备独立像素:在屏幕密度为160的显示屏上,1dip=1px
有了这些概念,我们来算一下,1dip是多长(是多少英寸)
result = in / dip
result = in / px (根据dp的定义)
result = 1 / (px / in)
result = 1 / dpi
result = 1 / 160
从上面的推导可以看出在屏幕密度为160的显示屏上 1dip其实就是 1 / 160 英寸,是一个屏幕尺寸上的绝对单位。
Android中为我们提供了适配不同分辨率的资源包,我们只需要做一套资源就可以自动帮我们换算成相应dpi(分辨率)下的尺寸,放大及缩小比例如上图所示。
三、不同UI的代码逻辑适配
1、确定当前布局
public class NewsReaderActivity extends FragmentActivity {
boolean mIsDualPane ;
@Override
public void onCreate ( Bundle savedInstanceState ) {
super . onCreate ( savedInstanceState );
setContentView ( R . layout . main_layout );
View articleView = findViewById ( R . id . article );
mIsDualPane = articleView != null &&
articleView . getVisibility () == View . VISIBLE ;
}
}
如上面代码,我们可以通过某些View的可见性来判断选用的布局文件。
2、根据不同的布局,做出不同的逻辑
@Override
public void onHeadlineSelected(int index) {
mArtIndex = index;
if (mIsDualPane) {
/* display article on the right pane */
mArticleFragment.displayArticle(mCurrentCat.getArticle(index));
} else {
/* start a separate activity */
Intent intent = new Intent(this, ArticleActivity.class);
intent.putExtra("catIndex", mCatIndex);
intent.putExtra("artIndex", index);
startActivity(intent);
}
}
3、使用代码片段实现重用
<LinearLayout xmlns:android = "http://schemas.android.com/apk/res/android"
android:layout_width = "fill_parent"
android:layout_height = "fill_parent"
android:orientation = "horizontal" >
<fragment android:id = "@+id/headlines"
android:layout_height = "fill_parent"
android:name = "com.example.android.newsreader.HeadlinesFragment"
android:layout_width = "400dp"
android:layout_marginRight = "10dp" />
<fragment android:id = "@+id/article"
android:layout_height = "fill_parent"
android:name = "com.example.android.newsreader.ArticleFragment"
android:layout_width = "fill_parent" />
</LinearLayout>
设计兼容不同的屏幕尺寸的Android界面的更多相关文章
- 创办支持多种屏幕尺寸的Android应用
创建支持多种屏幕尺寸的Android应用 Android涉及各种各样的支持不同屏幕尺寸和密度的设备.对于应用程序,Android系统通过设备和句柄提供了统一的开发环境,大部分工作是校正每一个应用程序的 ...
- android做设计的每一个屏幕尺寸和分辨率(一个)
一个.与分辨率无关 1.使用dp(dpi) Android密度不依赖像素(dp)指定屏幕尺寸,它同意不同的屏幕尺寸和像素密度类似设备通过缩放来达到同样的效果. (不解决不同屏幕尺寸的问题?) 2.的资 ...
- 创建支持多种屏幕尺寸的Android应用
Android涉及各种各样的支持不同屏幕尺寸和密度的设备.对于应用程序,Android系统通过设备和句柄提供了统一的开发环境,大部分工作是校正每一个应用程序的用户界面到它显示的屏上.与此同时,系统提供 ...
- [转]响应式WEB设计学习(1)—判断屏幕尺寸及百分比的使用
原文地址:http://www.jb51.net/web/70360.html 现在移动设备越来越普及,用户使用智能手机.pad上网页越来越普遍.但是传统的fix型的页面在移动终端上无法很好的显示.因 ...
- Android界面设计适配不同屏幕的尺寸和密度解读
Android是运行在各种提供不同的屏幕尺寸和密度的设备.Android系统提供跨设备的统一开发环境和处理大部分的工作,以调整每个应用程序的用户界面,以在其上显示的画面. 同时,该系统提供了API,允 ...
- Android屏幕适配全攻略(最权威的官方适配指导)屏幕尺寸 屏幕分辨率 屏幕像素密度 dpdipdpisppx mdpihdpixdpixxdpi
Android屏幕适配全攻略(最权威的官方适配指导)原创赵凯强 发布于2015-05-19 11:34:17 阅读数 153734 收藏展开 转载请注明出处:http://blog.csdn.net/ ...
- Android平板上开发应用的一点心得——精确适配不同的dpi和屏幕尺寸
一.引言 Android的开源使厂商无需自行研发OS,大大降低了研发.生产的成本,使得Android平板品牌如雨后春笋般爆发,山寨机厂商们似乎又找到了一丝希望.与此同时带来的是广大开发者的苦不堪言,各 ...
- 【文章内容来自《Android 应用程序开发权威指南》(第四版)】如何设计兼容的用户界面的一些建议(有删改)
最近一直在看的一本书是<Android 应用程序开发权威指南>(第四版),十分推荐.书中讲到了一些用户界面设计的规范,对于初学者我认为十分有必要,在这里码给大家,希望对我们都有用. 在我们 ...
- 【转】Android的材料设计兼容库(Design Support Library)
转自:http://www.jcodecraeer.com/a/anzhuokaifa/developer/2015/0531/2958.html?mType=Group Android的材料设计兼容 ...
随机推荐
- 部署OGG时字符集转换问题--oracle to oracle已验证,其他异构环境应当也适用
之前在安装OGG总是遇到字符集问题,尤其是多源端对一个目标端时,源端字符集不同,导致出现字符集问题 无法同步数据,查阅了大量的园子资料,都说要设置复制或抽取进程中SETENV (NLS_LANG=AM ...
- 洛谷 P2128 赤壁之战
P2128 赤壁之战 题目描述 赤壁之战,黄盖率舰满载薪草膏油诈降曹军. 受庞统所授的连环计,曹军战船之间由铁索相连,没有两艘战船在同一位置,也没有铁索两两相交或穿过战船.每艘船都有其一定的战略价值. ...
- jsp页面中自定义标签的小演示
在实习期遇到公司的pg自定义标签了,同事要我自己自学一下 自定义标签是用户定义的JSP语言元素.当JSP页面包含一个自定义标签时将被转化为servlet.JSP标签扩展可以让你创建新的标签并且可以直接 ...
- vs2015发布项目到虚拟主机组策略阻止csc.exe程序问题
这个问题之前碰到过一次,这次又碰到,就记录一下解决方法. 这个问题的产生的原因,据说是虚拟主机没有权限执行exe文件造成的,如果是独立服务器的话发布就不会出现这个问题. 使用VS2015发布web项目 ...
- 转】关于cgi、FastCGI、php-fpm、php-cgi
首先,CGI是干嘛的?CGI是为了保证web server传递过来的数据是标准格式的,方便CGI程序的编写者. web server(比如说nginx)只是内容的分发者.比如,如果请求/index.h ...
- CUDA笔记(十)
下午仔细研究了两个程序,然后搜了一下解决方法 http://blog.sina.com.cn/s/blog_6de28fbd01011cru.html http://blog.csdn.net/che ...
- 使用regasm注册.net com组件出现不是有效的.net程序集的解决办法
作者:朱金灿 来源:http://blog.csdn.net/clever101 在电脑上装有VS 2008和VS 2010.使用VS 2010编写了一个C# com组件:MyCom(基于.net f ...
- SQL Server在用户自定义函数(UDF)中使用临时表
SQL Server在用户自定义函数中UDF使用临时表,这是不允许的. 有时是为了某些特殊的场景, 我们可以这样的实现: CREATE TABLE #temp (id INT) GO INSERT I ...
- mysql优化篇之表分区
当表的数据量达到一定数量时(如单个.myd文件都达到10G,myd 是mysql的数据文件),这时候读取起来必然效率很低. 1.从业务角度可以解决(分表) ...
- 洛谷3857 [TJOI2008]彩灯
题目描述 已知一组彩灯是由一排N个独立的灯泡构成的,并且有M个开关控制它们.从数学的角度看,这一排彩灯的任何一个彩灯只有亮与不亮两个状态,所以共有2N个样式.由于技术上的问题,Peter设计的每个开关 ...