请输入关键字
2019-04 25

Android屏幕适配方式

随着支持Android系统的设备(手机、平板、电视、手表)的增多,设备碎片化、品牌碎片化、系统碎片化、传感器碎片化和屏幕碎片化的程度也在不断地加深。而我们今天要探讨的,则是对我们开发影响比较大的——屏幕的碎片化。


Android设备差异化非常大,分辨率不同、屏幕尺寸不同、屏幕长宽比也不同。


分辨率方面,目前主流标准分辨率有720p1080p2k4k等,根据移动观象台数据显示,20164季度,安卓设备前五名分辨率占比75%,前十名占比88%,但排名第100名的分辨率也占到0.01%,这一数据不一定精确,但反映了分辨率千差万别,主流集中的特点,另外有部分手机内置虚拟按键(如华为),会导致屏幕可用分辨率发生变化。


屏幕尺寸方面,可分为穿戴设备、手机、平板和电视等,穿戴设备和电视一般是针对特定硬件开发,我涉及的也不多,这里不讨论,手机的特点是屏幕大小基本与手掌相当,目前一般集中在5-5.5寸,而平板则屏幕大小相差较大,一般7-11寸。


屏幕长宽比不同,这个与分辨率的多样性是相关的,有4:316:9等,不过这个差异一般不是太明显,就拿电视来说,从以前的方形电视,到目前主流偏宽的电视,都是可以观看的,可能稍有拉伸。

 

Android屏幕适配方式;


1 适配方式之 dp

 

    分辨率:eg480*800,1280*720。表示物理屏幕区域内像素点的总和。(切记:跟屏幕适配没有任何关系)

 

因为我们既可以把 1280*720 的分辨率做到 4.0 的手机上面。


我也可以把 1280*720 的分辨率做到 5.0 英寸的手机上面,如果分辨率相同,手机屏幕越小清晰。

 

    px(pix):像素,就是屏幕中最小的一个显示单元

 

    dpi(像素密度):即每英寸屏幕所拥有的像素数,像素密度越大,显示画面细节就越丰富。

 

计算公式:像素密度=√{(长度像素数^2+宽度像素数^2}/ 屏幕尺寸

 

注:屏幕尺寸单位为英寸 例:分辨率为 1280*720 屏幕宽度为 6 英寸 计算所得像素密度约等于 245,屏幕尺寸指屏幕对角线的长度。

 

Android 应用在查找图片资源时会根据其分辨率自动从不同的文件目录下查找(这本身就是 Android 系统的适配策略),如果在低分辨的文件目录中比如 drawable-mdpi 中没有图片资源,其他目录中都有,当我们将该应用部署 mdpi 分辨率的手机上时,那么该应用会查找分辨率较高目录下的资源文件,如果较高分辨率目录下也没有资源则只好找较低目录中的资源了。

 

常见手机屏幕像素及对应分别率级别:

ldpi 320*240

mdpi 480*320

hdpi 800*480

xhdpi 1280*720

xxhdpi 1920*1080

 

dp px 之间的简单换算关系:

ldpi 的手机 1dp=0.75px

mdpi 的手机 1dp=1.0px

hdpi 的手机 1dp=1.5px

xhdpi 的手机 1dp=2.0px

xxhdpi 的手机 1dp=3.0px

 

2 适配方式之 dimens

 

drawable 目录类似的,在 Android 工程的 res 目录下有 values 目录,这个是默认的目录,同时为了适配不同尺寸

 

手机我们可以创建一个 values-1280x720 的文件夹,同时将 dimens.xml 文件拷贝到该目录下。 dimens.xml 中定义一个尺寸。 values-1280x720 目录中的 dimens.xml 中定义同样的尺寸名称,但是使用不同的尺寸。当我们在布局文件中使用长或者宽度单位时,应该使用@dimen/width 来灵活的定义宽度。

 

3,适配方式之 layout

 

values 一样,在 Android 工程目录中 layout 目录也支持类似 values 目录一样的适配,在 layout 中我们可以针对不同手机的分辨率制定不同的布局,

 

4,适配方式之 java 代码适配

 

就是获取屏幕的宽度,根据你的图片的宽高比,通过屏幕的宽度动态的算出图片的高度。通过Android相应api获取当前手机的宽高像素值,按比例分配屏幕中控件的宽高以达到适配效果。

 

public class MainActivity extends Activity {

private static final String tag = null;

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

//去掉 title

requestWindowFeature(Window.FEATURE_NO_TITLE);

setContentView(R.layout.activity_main);

//获取 TextView 控件

TextView tv = (TextView) findViewById(R.id.tv);

//获取封装当前手机屏幕信息对象,用于存放宽高值

DisplayMetrics metrics = new DisplayMetrics();

//给当前 metrics 去设置当前屏幕信息((像素)(像素))(//给当前屏幕设置宽高)

getWindowManager().getDefaultDisplay().getMetrics(metrics);

//获取屏幕的高度和宽度

Constant.srceenHeight = metrics.heightPixels;

Constant.srceenWidth = metrics.widthPixels;

//日志输出屏幕的高度和宽度

Log.i(tag, “Constant.srceenHeight = “+Constant.srceenHeight);

Log.i(tag, “Constant.srceenWidth = “+Constant.srceenWidth);

//宽高各 50%

RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(

//数学角度上 四舍五入

(int)(Constant.srceenWidth*0.5+0.5),

(int)(Constant.srceenHeight*0.5+0.5));

// tv 控件设置布局参数

tv.setLayoutParams(layoutParams);

}

}

其中 Constant 类是一个常量类,很简单,只有两个常量用来记录屏幕的宽和高,其代码清单如下:

public class Constant {

public static int srceenHeight;

public static int srceenWidth;

}

 

5, 适配方式之 weight 权重适配

 

在控件中使用属性 android:layout_weight=”1”可以起到适配效果,但是该属性的使用有如下规则:只能用在线性控件中,比如 LinearLayout竖直方向上使用权重的控件高度必须为 0dpGoogle 官方的推荐用法)水平方向上使用权重的控件宽度必须为 0dpGoogle 官方的推荐用法)。


手机自适应主要分为两种情况:横屏和竖屏的切换,以及分辨率大小的不同。

 

横屏和竖屏的切换:

 

1Android 应用程序支持横竖屏幕的切换,Android 中每次屏幕的切换动会重启 Activity,所以应该在 Activity销毁(执行 onPause()方法和 onDestroy()方法)前保存当前活动的状态;在 Activity 再次创建的时候载入配置,那样,进行中的游戏就不会自动重启了!有的程序适合从竖屏切换到横屏,或者反过来,这个时候怎么办呢?可以在配 Activity 的地方进行如下的配置 android:screenOrientation=”portrait”landscape 是横向,portrait 是纵向)。这样就可以保证是竖屏总是竖屏了。

 

2、而有的程序是适合横竖屏切换的。如何处理呢?首先要在配置 Activity 的时候进行如下的配置:android:configChanges=”keyboardHidden|orientation” , 另 外 需 要 重 写 Activity onConfigurationChanged 方法。实现方式如下:

@Override

public void onConfigurationChanged(Configuration newConfig){

super.onConfigurationChanged(newConfig);

if(this.getResources().getConfiguration().orientation==Configuration.ORIENTATION_

LANDSCAPE){

//TODO

}else

if(this.getResources().getConfiguration().orientation==Configuration.ORIENTATION_

PORTRAIT){

//TODO

}

}