我见过最简单,方便的屏幕适配

转载地址:http://blog.csdn.net/zhengjingle/article/details/51742839

一、吩咐美工UI做的事情

设计图都用一个尺寸(分辨率)设计,例如是1280x720。

所有控件,或要发生交互的地方,标注上:

1、坐标,以设计图的左上角为原点,离左边和顶部的PX距离。

2、宽度和高度,也是PX为单位。

例如下图,这是我项目里的一个页面,尺寸:1280x720


对于列表item,即是RecyclerView、ListView等等里的item,坐标原点是以item的左上角为标准,例如下图:


我这个APP是全屏,如果你的APP要有状态栏,我也建议设计图用全屏,下面第二部分会介绍状态栏的问题。


对于那些需要变化的图片,当然要让美工切出来。


至此,美工的工作就完成了。


你看,我这种项目用上AutoLayout这种自适配方法岂不是很爽。

那些控件放上去就行了,基本不用嵌套。美工也很爽,少切很多图。


二、使用AutoLayout

1、编写xml布局,调出与你设计图相同尺寸的视图:

在此尺寸设置好布局就可以,不用理其他分辨率的。

root布局设上一张背景图,然后把控件放上去,按照美工给的坐标和宽高,设置好leftMargin和topMargin,宽layout_width,高layout_height。

(1)对于那些宽高不定的控件,例如TextView,当然是wrap_content,有些需要match_parent的地方就match_parent。

(2)对于图片ImageView,一定要设置fitXY,因为如果屏幕拉伸了,而你的图片没有拉伸,就对不齐。在你的设计尺寸中,无论ScaleType是哪种类型,效果看起来都是一样的。除非你的ImageView有特殊需求,例如程序要放大缩小图片,那么你另行设置。另外要注意,同上,设置ImageView的宽高值,不要以为图片放上xml布局就宽高适合而疏忽了。

2、在程序代码中:初始化

在你的Activity中设置:

AutoUtils.setSize(this, false, 720, 1280);

//第一个参数this,是Activity对象。

//第二个参数false,是boolean变量,表示没有状态栏。如果你的APP要有状态栏,就设置为true。

//第三个参数720,是int变量,是设计尺寸的宽度。

//第四个参数1280,是int变量,是设计尺寸的高度。


如果你的APP屏幕的显示方式没有变化,你设置一次就可以。

如果有需要,你可以随时重新设置,它是灵活的。例如你有需求切换为横屏播放视频,那么你就把设计图的宽高值换一下传进去,当然你切换回竖屏时要记得重新设置回来。


(1)对于状态栏(StatusBar),如果你需要全屏,第二个参数就设置false;如果你需要有,就设置true。

其实这里有两种方案:第一种是美工的设计图都是按全屏设计,然后true或false控制有无状态栏。第二种是美工的设计图已经包含有无状态栏,然后一律用false。因为美工的设计图的状态栏高度可能不标准,所以我建议用第一种方案。

(2)对于虚拟按键(NavigationBar),有些机,例如华为有这个。我看到张鸿洋的博客有人问这个怎么处理,在我这里是自动适配的,你完全不需要理。

3、在程序代码中:自动适配

在setContentView()之后,在页面真正绘图之前:

AutoUtils.auto(this);

//参数this,是Activity对象。


就是这么简单。

(1)对于TextView的字体大小,我作了一定的缩放处理,不过正如张鸿洋所说的“灵活应对这个问题”,因为这个字体的情况有些复杂。

(2)对于那些动态布局,在代码中生成控件,或者像平移的动画效果,先处理一下它实际显示的宽高值:

int width=AutoUtils.getDisplayWidthValue(designWidthValue);//designWidthValue,是int变量,设计的宽度
int height=AutoUtils.getDisplayHeightValue(designHeightValue);//designHeightValue,是int变量,设计的高度

像动态控件的宽高,margin值,平移动画,在设置数值前调用这两个方法转换一下就可以了。

也可以整个控件按设计尺寸设置完,再AutoUtils.auto(view)一下,如下。


4、在程序代码中:列表item的处理

像RecyclerView、ListView这些,item的xml布局大部分与上面说的一致。

有一点要注意的是:item的背景图要拿出来独立用一个ImageView显示,不要在root view中设置background,因为在列表中它的拉伸不对。

然后在你的ViewHolder构造方法中:

AutoUtils.auto(view);

//参数view,是View对象。

凡是需要inflate导入view的地方,用这个方法处理一下就可以。


在张鸿洋的方法中,你inflate导入item布局时,需要传入parent(ViewGroup布局);在我这里,你传null也可以。

我开始用张鸿洋的方法时,在root view中设置background,然后AutoUtils.autoSize(convertView);在非设计尺寸的手机上就发现有问题了,首先背景图对不齐,然后那些margin也不对。我看他只是autoSize()。估计是他没有遇到有背景图的情况,所以他的item效果看起来还好。

至此,对于一般的item,高度固定的item,就完结了。


但我遇到更棘手的需求,请看下图:

我需要在红色方框中显示评论,评论长度是不定的,因此整个item的高度是不定的。


我是这样解决的,用draw9patch设置红色方框部分可拉伸,然后背景图的ImageView的layout_alignBottom属性设置为那个评论的TextView,使ImageView一同拉伸。但是评论的TextView并没有触及底部,于是我又用LinearLayout嵌套评论的TextView与另一个TextView,使ImageView的layout_alignBottom属性设置为那个LinearLayout。并且设置评论的TextView最小行数minLines,免得评论短时过分缩小。这样我成功的解决了问题。具体可以查看我的demo代码。


最后,请看下我demo的效果图,这是从我项目中抽取的页面做成的:

我的设计尺寸大小是:720x1280

左图尺寸是:768x1280,有虚拟按键

右图尺寸是:1080x1920,有虚拟按键



详细项目:

https://github.com/zhengjingle/Autolayout


猜你喜欢

转载自blog.csdn.net/qq_33756493/article/details/62892221