需要考虑的问题
1.操作系统适配。即适配不同版本的操作系统,需要明确每一个版本API Changed List。
2.厂家型号分类。即适配三星、小米、华为等……这块有两种适配方式,一是公版适配,二是定制开发。
公版适配(大多数app使用),这里指的是只存在一套代码,一个APK,要适配所有的厂商或机型。比较差的方式通常就是在代码中涉及到不同厂商或型号的地方通过if语句利用Build里的厂商标识等进行不同的策略,其结果就是适配得越多,if语句越复杂,越难维护。其实只要利用一个工厂模式就可以做得更灵活一些。
3.硬件兼容。主要是对包括屏幕、CPU、内存、外存、传感器等进行适配,其主要思路也是抽象隔离。
在数据层,最主要的是进行外部存储的适配,即考虑数据存储的位置、格式、易失性等。通常这种持久化的数据存储,都要考虑存储位置及其易失性问题,不要把关键数据保存在易失的外部存储当中,还有Android 5.X开始的外卡的不可访问性,进而,可以根据存储空间和数据特点考虑明文格式还是密文格式,压缩还是不压缩。设备繁多、品牌众多、版本各异,芯片、摄像头、分辨率不统一等等,这些都逐渐成为Android系统发展的障碍,碎片化严重不仅造成Android系统混乱,也导致Android应用隐形开发成本的增多。
最终解决办法:由于android手机的碎片化,没有像ios那样只有固定的机型和尺寸,所以要做到全部适配是不可能,合适的做法是适配市场上流行的机型尺寸、厂商和硬件设备。
版本适配问题
在src目录下建不同版本的values目录
values-v19
values-v21
厂商适配问题
屏幕适配问题(屏幕大小和屏幕密度)
1.尽量使用.9图片来自动适应屏幕;
关于.9图片上下左右四条黑线的含义解释:
(1)上方黑线代表横向拉伸区域。
(2)左边黑线代表纵向拉伸区域。
(3)下方黑线代表横向内容显示区域。
(4)右边黑线代表纵向内容显示区域。
2.尽量使用最少的图片资源,以减少内存的占用。
3.如下
第一种情况:欢迎页面、引导页面等图片需要铺满整个屏幕时,我们至少需要做两套图来满足屏幕的适配(480*800、720*1280)放于对应的文件夹下;
第二种情况:直接切图(480*800)放于对应的文件夹,让其自动适应。
4.在Android系统中,将屏幕大小划分成以下几种
屏幕大小 |
---|
small |
normal |
large |
extra large |
5.常见的密度QVGA(240X320)、HVGA(320X480)、WVGA800(480X800)
屏幕密度 |
---|
low |
medium |
high |
extra high |
1).在android3.0之后出现了一套新的屏幕尺寸适配规则: swXXXdp, wXXXdp, hXXXdp
2).可以控制的程度更细,能够精确适配;可以覆盖指定数值以及更大的尺寸,
swxxxdp :表示屏幕的最短边是xxxdp的屏幕都适配.
wxxxdp:表示平行于地面的边的宽度,在表示的范围内,将会进行布局适配;
屏幕适配相关计算
布局(layout)适配问题
在src目录下建不同分辨率的layout目录
layout-1280x720
layout-800x480
此时,在不同的layout目录下新建有针对性的布局文件,里面的尺寸写死都没有关系。
创建不同的布局(Create Different Layouts)
为了让用户在不同的分辨率的设备上的体验得到优化,我们应该为每一个我们所想支持的屏幕尺寸都创建一个自己的layout XML文件,每个文件都保存在相应的资源目录,例如,如果我们想支持large screens,我们就应该在资源目录res文件夹下创建一个layout-large。android系统会根据屏幕的尺寸大小去自动的加载相应的布局。如下,一个包含这默认的layout和一个供选择的large screen的layout
res/
layout/
main.xml
layout-large/
main.xml
// 需要注意的是,文件名必须相同,但文件里面的内容可以相同,你可以根据不同的屏幕的尺寸制定不同的布局以优化用户的体验
在具体的代码中,没有什么变化,android系统会自动调用不同屏幕尺寸的布局
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
下面是一个关于横屏和竖屏的布局:
MyProject/
res/
layout/
main.xml
layout-land/
main.xml
如果想要提供一个特殊的layout在大屏幕设备横屏的时候,则large和land两个限定符都需要使用。
MyProject/
res/
layout/ # default (portrait)
main.xml
layout-land/ # landscape
main.xml
layout-large/ # large (portrait)
main.xml
layout-large-land/ # large landscape
main.xml
安卓3.2及以上支持定义屏幕尺寸的一种先进方法,允许您指定资源基于最小宽度和高度的屏幕尺寸的密度独立像素。
尺寸(dimens)适配问题
在src目录下建不同分辨率的values目录
values-1280x720
values-800x480
此时,在不同的values目录下新建dimens.xml 文件,在这个dimens文件中就可以针对不同的分辨率定义它的尺寸了。建议将layout中的尺寸数值,放到独立的尺寸资源文件dimens.xml中,这样就可以利用密度、尺寸来进行屏幕尺寸适配而不用创建多个layout.
不要在代码中硬编码尺寸。因为性能和简单要求,Android系统内部均使用像素进行维护,例如在一个设备上执行 View.getWidth()返回10像素,不要将这个数值作为硬编码的常数,因为可能在高密度的设备上,返回的值可能会是15。
使用权重适配
编写xml布局文件时,使用weight来分配屏幕的使用;
java代码动态适配
动态获取屏幕的宽、高 ,然后动态设置布局的尺寸;
国际化适配问题
字符串国际化
只要在 res 文件夹下新建对应语言的 values 文件夹,然后在对应的values文件夹下创建strings.xml即可
中文环境:values-zh
英语环境:values-en
美国英文环境:values-en-rUS
大陆地区中文环境: values-zh-cn
图片资源国际化
在 res 下新建对应语言的 drawable /mipmap文件夹,创建不同的位图(Create Different Bitmaps),Android提供了自动的设备检测功能,能够根据当前设备的一些参数信息,进行动态的资源的加载,从而实现机型适配;
英语环境下的:
drawable-en-ldpi
drawable-en-hdpi
drawable-en-mdpi
中文环境为:
drawable-zh-hdpi
drawable-zh-ldpi
drawable-zh-mdpi
因为需要适配不同屏幕,我们需要提供不同的图片来适配。
dpi分类 | 具体参数 |
---|---|
xhdpi | dpi=320, density=2 |
hdpi | dpi=240, density=1.5 |
mdpi | dpi=160, density=1 (baseline) |
ldpi | dpi=120, density=0.75 |
解析:
以mdpi为基准,进行尺寸的缩放,缩放规则:
mdpi 1 原始尺寸
ldpi 0.75倍尺寸
hdpi 1.5倍尺寸
xhdpi 2倍尺寸
xxhdpi 3倍尺寸
xxxhdpi 4倍尺寸
使用场景:如果我们为xhdpi的设备生成了一张200x200的图片,同时也需要为hdpi的设备生成150x150的图片,为mdpi的设备生成100x100的图片,最后为ldpi的设备生成75x75的图片。
理解:不同设备,其屏幕密度dpi越大,同一个像素尺寸的图片显示的越小;拨不通设备的屏幕密度dpi越小(分辨率越低),同一个图片显示的就大了。高密度手机使用大图片;低密度手机用小图片;
dpi的相关计算 :Android中,定义一套单位dp,以mdpi为标准,进行自动运算的像素数值;
//原理公式
px = dp * (dpi / 160) //已知dp求px
dp = px / (dpi / 160) //已知px 求dp
/**
* 可以把这个当做工具类.
* 实现机型适配,可以指定数值,根据手机屏幕密度
* 生成像素单位,用于代码中的尺寸设置
*/
public static float dp2Px(Context context, int dp) {
DisplayMetrics metrics = new DisplayMetrics();
if (Build.VERSION.SDK_INT >= 17) {
DisplayManager manager = (DisplayManager) context.getSystemService(context.DISPLAY_SERVICE);
manager.getDisplay(0).getMetrics(metrics);
} else {
WindowManager manager = ((WindowManager) context.getSystemService(WINDOW_SERVICE));
manager.getDefaultDisplay().getMetrics(metrics);
}
float px = dp * metrics.density;
return px;
}
采用高清大图进行设计,分辨率低的会自动缩小,图片缩小不会失真.
例如:5dp, 在mdpi的手机上,就是5px,在xhdpi的手机上,就是15px;sp: scalable pixel 可缩放的px, 用于文本的处理.运算规则和dp相似
MyProject/
res/
drawable-xhdpi/
test.png
drawable-hdpi/
test.png
drawable-mdpi/
test.png
drawable-ldpi/
test.png
这样之后,当使用@drawable/test.png,系统都会自动根据当前设备的dpi来选择合适的图片进行显示。
结合Html5和css3优化界面布局和适配。
采用HTML5和CSS3制作界面,然后在WebView视图上进行显示,然后通过JavaScript进行事件的交互。