Android APP多屏幕适配
来源:互联网 发布:文泰刻绘2002端口设置 编辑:程序博客网 时间:2024/06/03 23:05
现在的Android手机屏幕越来越多,工作面试的时候很多同学都不是很清楚屏幕适配的问题, 网上其实有很多类似的说明,其实大同小异都是翻译google 官方贵的说明,希望大家有时间多学习官方api,这里我也做一下笔记:
1、基本概念
1.1 屏幕大小(screen size)
屏幕的实际大小,用屏幕对角线长度来衡量(比如3.4寸,3.8寸,4.3寸,5寸,7寸等)。
android把屏幕分为以下4种:small,normal,large,extra large等。
1.2 屏幕密度(Screen Density)
一块实际的屏幕区域有多少个像素,一般用dpi衡量(每英寸有多少个点)。
android把屏幕密度分为4种:low,medium,high,extra high。
手机可以有相同的分辨率,但屏幕尺寸可以不相同,
Diagonal pixel表示对角线的像素值(=),DPI=933/3.7=252
android将实际的屏幕密度分为四个通用尺寸(low,medium,high,and extra high)
一般情况下的普通屏幕:ldpi是120dpi,mdpi是160dpi,hdpi是240dpi,xhdpi是320dpi
对于屏幕来说,dpi越大,屏幕的精细度越高,屏幕看起来就越清楚 。
1.3 屏幕方向(orientation)
屏幕方向分为landscape(横屏)和portrait(竖屏)。
1.4 分辨率(Resolution)
屏幕上的总实际像素数。对屏幕进行适配时,一般不关注它的分辨率,只关注它的屏幕大小和密度。与密度无关的像素(Density-independent pixel,dp或dip) - 为了保证你的UI适合不同的屏幕密度,建议你采用dp来定义程序UI。它的计算方法为:px = dp * (dpi / 160)。
sp(scale-independent pixel)
如何分辨一个屏幕是ldpi、mdpi、hdpi的方法:
2、怎样适配多种屏幕
2.1 支持屏幕类型
在manifest里定义你的程序支持的屏幕类型,相应代码如下:
<supports-screens android:resizeable=["true"| "false"]
android:smallScreens=["true" | "false"] //是否支持小屏
android:normalScreens=["true" | "false"] //是否支持中屏
android:largeScreens=["true" | "false"] //是否支持大屏
android:xlargeScreens=["true" | "false"] //是否支持超大屏
android:anyDensity=["true" | "false"] //是否支持多种不同密度的屏幕
android:requiresSmallestWidthDp=”integer”
android:compatibleWidthLimitDp=”integer”
android:largestWidthLimitDp=”integer”/>
a. 是否支持多种不同密度的屏幕
android:anyDensity=["true" | "false"]
如果android:anyDensity="true"
指应用程序支持不同密度,会根据屏幕的分辨率自动去匹配。
如果android:anyDensity="false"
应用程序支持不同密度,系统自动缩放图片尺寸和这个图片的坐标。具体解释一下系统是如何自动缩放资源的。
例如我们在hdpi,mdpi,ldpi文件夹下拥有同一种资源,那么应用也不会自动地去相应文件夹下寻找资源,这种情况都是出现在高密度,以及低密度的手机上,比如说一部240×320像素的手机,
如果设置android:anyDensity="false",Android系统会将240 x 320(低密度)转换为 320×480(中密度),这样的话,应用就会在小密度手机上加载mdpi文件中的资源。
b. 是否支持大屏幕
android:largeScreens=["true" | "false"]
如果在声明不支持的大屏幕,而这个屏幕尺寸是larger的话,系统使用尺寸为("normal")和密度为("medium)显示, 不过会出现一层黑色的背景。
c. 是否支持小屏幕
android:smallScreens=["true" | "false"]
如果在声明不支持的小屏幕,而当前屏幕尺寸是smaller的话,系统也使用尺寸为("normal")和密度为("medium)显示 .
如果应用程序能在小屏幕上正确缩放(最低是small尺寸或最小宽度320dp),那就不需要用到本属性。否则,就应该为最小屏幕宽度标识符设置本属性
来匹配应用程序所需的最小尺寸。
2.2 对不同大小的屏幕提供不同的layout。
比如,如果需要对大小为large的屏幕提供支持,需要在res目录下新建一个文件夹layout-large/并提供layout。当然,也可以在res目录下建立layout-port和layout-land两个目录,里面分别放置竖屏和横屏两种布局文件,以适应对横屏竖屏自动切换。
res/layout
res/layout-small
res/layout-normal
res/layout-large
res/layout-xlarge
android 新版本支持:
res/layout-mdpi
res/layout-hdpi
res/layout-xhdpi
Android 4.0版本 之后支持layout-mdpi、layout-hdpi 这种写法。
2.3 对不同密度的屏幕提供不同的图片。
1) 应尽量使用点9格式的图片,使用draw9图片则不需要适配,会自动进行拉伸。
2) 使用位图则需要针对不同的屏幕放置合适大小的图,在res目录下建立对应的包,Android有个自动匹配机制去选择对应的布局和图片资源。
3) Android平台中支持一系列你所提供的指定大小(size-specific),指定密度(density-specific)的合适资源。指定大小(size-specific)的合适资源是指small, normal, large, and xlarge。指定密度(density-specific)的合适资源,是指ldpi (low), mdpi (medium), hdpi (high), and xhdpi (extra high).
drawable
drawable-ldpi
drawable-mdpi
drawable-hdpi
drawable-xhdpi
drawable-nodpi
drawable-nodpi-1024×600
drawable-nodpi-1280×800
drawable-nodpi-800×480
4) 图片大小的确定:low:medium:high:extra high比例为3:4:6:8。举例来说,对于中等密度(medium)的屏幕你的图片像素大小为48×48,那么低密度(low)屏幕的图片大小应为36×36,高(high)的为72×72,extra high为96×96。
通常情况下从开发角度讲,应用程序会根据3类Android手机屏幕提供3套UI布局文件,但是相应界面图标也需要提供3套:
Icon Type
Standard Asset Sizes (in Pixels), for Generalized Screen Densities
App
ldpi
mdpi
hdpi
xhdpi
Launcher
36 x 36 px
48 x 48 px
72 x 72 px
96 x96 px
Menu
36 x 36 px
48 x 48 px
72 x 72 px
96 x96 px
Status Bar
24 x 24 px
32x32 px
48 x 48 px
72 x 72 px
Tab
24 x 24 px
32x32 px
48 x 48 px
72 x 72 px
Dialog
24 x 24 px
32x32 px
48 x 48 px
72 x 72 px
List View
24 x 24 px
32x32 px
48 x 48 px
72 x 72 px
3、多屏幕适配的黄金原则
3.1 布局文件配置属性
在layout文件中设置控件尺寸时应采用wrap_content,fill_parent,match_parent和dp。
为了使文字大小更好的适应屏幕应该使用sp来定义文字大小。
layout_weight属性尽量不要嵌套使用。如父节点已经使用了weight属性,则子节点尽量避免使用。
3.2配置文件定义具体值
为了使代码简单,android内部使用pix为单位表示控件的尺寸,但这是基于当前屏幕基础上的。为了适应多种屏幕,android建议开发者不要使用具体的像素来表示控件尺寸。
布局文件中的所有文字大小以及控件大小都必须申明在xml配置文件中,values/dimens.xml,不同的屏幕定义不同的大小,可以很好的适配。
values
values-ldpi
values-mdpi
values-hdpi
values-xhdpi
values-nodpi
values-nodpi-1024×600
values-nodpi-1280×800
values-nodpi-800×480
3.3 布局文件
1)不要使用AbsoluteLayout(android1.5已废弃) 。
2)尽量使用RelativeLayout,如果必须使用权重则可以考虑RelativeLayout和LinearLayout混合使用。
3)需要根据物理尺寸的大小准备多套布局:
layout(放一些通用布局xml文件,比如界面中顶部和底部的布局,不会随着屏幕大小变化。
layout-mdpi (屏幕尺寸小于3.5英寸左右的布局)
layout-hdpi (屏幕尺寸小于4英寸左右)
layout-xhdpi(4.5英寸-7英寸之间)
3.4 对不同的屏幕提供合适大小的图片。见2.3部分。
3.5 根据屏幕大小计算
如果有些时候需要自定义控件,空间大小特别严格的话,可以考虑获取当前屏幕大小进行计算分割。
DisplayMetrics metric = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metric);
int width = metric.widthPixels; // 屏幕宽度(像素)
int height = metric.heightPixels; // 屏幕高度(像素)
float density = metric.density; // 屏幕密度(0.75 / 1.0 / 1.5)
int densityDpi = metric.densityDpi; // 屏幕密度DPI(120 / 160 / 240)
4、横竖屏切换
4.1 禁止切换横屏或竖屏
可以在配置Activity的地方进行如下的配置
android:screenOrientation="portrait"
android:screenOrientation="landscape"
或者 setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
这样就可以保证是竖屏总是竖屏了,或者横屏总是横屏。
4.2 可以切换横屏或竖屏
若要软件在横竖屏之间切换,由于横竖屏的高宽会发生转换,有可能会要求不同的布局。可以通过以下方法来切换布局:
1)layout-land和layout-port
在res目录下建立layout-land(横屏的layout)和layout-port(竖屏的layout)目录,相应的layout文件不变,比如main.xml。其他的不用管,模拟器会自动寻找。
2)onCreate()中判断横竖屏
通过this.getResources().getConfiguration().orientation判断当前是横屏还是竖屏,然后加载相应的xml布局文件。因为当屏幕变为横屏的时候,系统会重新呼叫当前Activity的OnCreate方法,你可以把以下方法放在你的OnCreate中来检查当前的方向,然后可以让你的SetContentView来载入不同的Layout xml.
if (this.getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {
Log.i("info", "landscape");
}
else if (this.getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
Log.i("info", "portrait");
}
4.3 横竖屏切换用onConfigurationChanged
这种方法缺点是动态适应差。比如横竖屏切换时需要你自己写代码来使用不同的layout等resource,语言设置的动态改变等.
首先要在配置Activity的时候进行如下的配置:
<activity android:name=".MyActivity"
android:configChanges="orientation|keyboardHidden|screenSize"
android:label="@string/app_name">
另外需要重写Activity的onConfigurationChanged方法。实现方式如下,不需要做太多的内容:
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
// Checks the orientation of the screen
if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
Toast.makeText(this, "landscape", Toast.LENGTH_SHORT).show();
} else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT){
Toast.makeText(this, "portrait", Toast.LENGTH_SHORT).show();
}
}
关于android应用开发 性能优化的一些建议:
1.http用gzip压缩,设置连接超时时间和响应超时时间
http请求按照业务需求,分为是否可以缓存和不可缓存,那么在无网络的环境中,仍然通过缓存的httpresponse浏览部分数据,实现离线阅读。
2.listview 性能优化
1).复用convertView
在getItemView中,判断convertView是否为空,如果不为空,可复用。如果couvertview中的view需要添加listerner,代码一定要在if(convertView==null){}之外。
2).异步加载图片
item中如果包含有webimage,那么最好异步加载
3).快速滑动时不显示图片
当快速滑动列表时(SCROLL_STATE_FLING),item中的图片或获取需要消耗资源的view,可以不显示出来;而处于其他两种状态(SCROLL_STATE_IDLE和SCROLL_STATE_TOUCH_SCROLL),则将那些view显示出来
3.使用线程池,分为核心线程池和普通线程池,下载图片等耗时任务放置在普通线程池,避免耗时任务阻塞线程池后,导致所有异步任务都必须等待
4.异步任务,分为核心任务和普通任务,只有核心任务中出现的系统级错误才会报错,异步任务的ui操作需要判断原activity是否处于激活状态
5.尽量避免static成员变量引用资源耗费过多的实例,比如Context
6.使用WeakReference代替强引用,弱引用可以让您保持对对象的引用,同时允许GC在必要时释放对象,回收内存。对于那些创建便宜但耗费大量内存的对象,即希望保持该对象,又要在应用程序需要时使用,同时希望GC必要时回收时,可以考虑使用弱引用。
7.超级大胖子Bitmap
及时的销毁(Activity的onDestroy时,将bitmap回收)
设置一定的采样率
巧妙的运用软引用
drawable对应resid的资源,bitmap对应其他资源
8.保证Cursor占用的内存被及时的释放掉,而不是等待GC来处理。并且Android明显是倾向于编 程者手动的将Cursor close掉
9.线程也是造成内存泄露的一个重要的源头。线程产生内存泄露的主要原因在于线程 生命周期的不可控
10.如果ImageView的图片是来自网络,进行异步加载
11.应用开发中自定义View的时候,交互部分,千万不要写成线程不断刷新界面显示,而是根据TouchListener事件主动触发界面的更新
- Android APP多屏幕适配
- Android App 屏幕适配
- Android学习笔记:App屏幕适配相关
- APP UI屏幕适配
- App开发屏幕适配
- Android多屏幕适配
- Android多屏幕适配
- Android多屏幕适配
- Android多屏幕适配
- Android多屏幕适配
- Android多屏幕适配
- Android 多屏幕适配
- Android多屏幕适配
- android多屏幕适配
- Android多屏幕适配
- Android 多屏幕适配
- Android多屏幕适配
- Android多屏幕适配
- PHP中call_user_func_array()函数的用法演示
- 线程池的原理及实现
- 输出编译ota升级包时的打包参数
- TFS发布计划发送到钉钉消息群
- 将小项目部署在Heroku
- Android APP多屏幕适配
- HDU-Delta-wave(C++中的强制转换与sqrt函数的一些小细节)
- 文章标签设计方法,文章Tags数据库设计方法举例
- poj 1679 The Unique MST (裸次小生成树)
- mysql服务已经启动但是无法进行连接(can't connect to mysql 1055)
- iOS中NSLog输出格式大全
- 磁盘重新挂载
- unity消消乐源码
- [BZOJ1089][SCOI2003]严格n元树(递推+高精度)