关于屏幕适配

  即使android提供了像素无关密度(dp),但是由于不同设备的dpi,也不能实现不同设备上的一致效果。从初始的角度上是看,dp的初衷并不是让显示的效果在不同屏幕上一致,google 官方也是推荐尽量使用match-parent、weight、加以以dp为单位的边距来进行布局,然而,这对于某些工程来说,也没有达到完美适配的目的。所以邪教的适配方式也层出不穷。
例如:

  采用比例兑换的对应分辨率下的sp,产生了大量了values文件,据说优酷客户端就是这样干的。

  android借鉴了CSS的精髓,提供了一个百分比布局support库[com.android.support:percent],但依赖于替换原有的布局标签,同样,你如果想让一个view支持百分比,就必须在外面嵌套一个百分比布局。
  android设备可谓百花齐放,然而并不是所有的设备都和Google Api设备一样,所以适配成了日常开发过程中必须要踩的坑。所谓适配,适配大致分为ROM适配,设备适配、屏幕适配。这里来记录下最近比较火的国产AndroidAutoLayout适配方案。

原理

  其实整个实现的代码也比较简单,总的说来就是算的过程。花了大概半个小时看完。
主包也只有三个,分别是:attr存放布局属性,config存放配置实现了初始化读取manifest、屏幕参数,utils定义了AutoLayoutHelper辅助布局进行参数重绘,算是这个项目的核心所在、AutoUtils实现了属性参数换算、ScreenUtils测量屏幕分辨率。
整理实现思路大致如下:
  通过AutoLayoutActivityonCreateView方法获得根布局属性,替换为Auto***Layout,layout在onMesure时候调用AutoLayoutHelper的adjustChildren()方法重新调整布局属性,遍历子控件,运算重写布局间距参数。

使用

1.加入依赖

dependencies {
compile 'com.zhy:autolayout:1.3.4'
}

2.在manifest里面加入稿纸尺寸,即参考屏幕的宽高像素

<meta-data android:name="design_width" android:value="720">
</meta-data>
<meta-data android:name="design_height" android:value="1280">
</meta-data>

3.把需要自适应宽高的Activity继承于AutoLayoutActivity.或者覆写自定义的ActivityonCreateView(String name, Context context, AttributeSet attrs)方法

@Override
public View onCreateView(String name, Context context, AttributeSet attrs)
{
View view = null;
if (name.equals(LAYOUT_FRAMELAYOUT))
{
view = new AutoFrameLayout(context, attrs);
}
if (name.equals(LAYOUT_LINEARLAYOUT))
{
view = new AutoLinearLayout(context, attrs);
}
if (name.equals(LAYOUT_RELATIVELAYOUT))
{
view = new AutoRelativeLayout(context, attrs);
}
if (view != null) return view;
return super.onCreateView(name, context, attrs);
}

扩展的方法

  对于一些继承自基础布局的的布局控件,可以复写generateLayoutParams(AttributeSet attrs)onMeasure(int widthMeasureSpec, int heightMeasureSpec)方法让其支持布局自动调整

@Override
public AutoFrameLayout.LayoutParams generateLayoutParams(AttributeSet attrs)
{
return new AutoFrameLayout.LayoutParams(getContext(), attrs);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
{
if (!isInEditMode())
{
new AutoLayoutHelper(this).adjustChildren();
}
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}

后记

1.ListView类因为外层布局是ListView所以要在获得view的时候调用AutoUtils.autoSize(View view)方法达到自适应的效果。

2.看issue据说Bitmap有OMM情况,这个我没验证。

3.作者提供了

app:layout_auto_basewidth="height",代表height上编写的像素值参考宽度。
app:layout_auto_baseheight="width",代表width上编写的像素值参考高度。

  这两个方法实现了布局“高度与宽度相等”、“宽度与高度相等”在解决一些图片空间确实有一定作用。
4.关于性能
  理论上,整个适配过程只是一个修改宽高参数的过程,并未对控件进行重绘,理论上损失的只是计算参数时的性能。