安卓布局适配的另一种姿势

一:

安卓布局适配一直都是安卓开发者比较头痛的问题,我们不仅需要考虑代码的质量,同时也需要面对数千品种的手机型号而考虑界面适配的工作;

Android屏幕适配全攻略(最权威的官方适配指导)
http://blog.csdn.net/zhaokaiqiang1992/article/details/45419023

这是基于google 官方去适配的一套方案,也是作为安卓工程师必须掌握的一套布局适配的方案。

Android 百分比布局库(percent-support-lib) 解析与扩展http://blog.csdn.net/lmj623565791/article/details/46695347

这是基于Android-percent-support 增强库,实现的百分比布局(详情点击链接查看)

二:

今天我要说的是按照一定的比例(宽高比)去自动适配控件的大小,什么意思呢?请看下幅图:

安卓布局适配的另一种姿势_第1张图片

我们暂且,先把这个控件看作是imageview

这是我公司UI设计师给出的原型设计图,图中选中的控件宽是750px,高是220px。我们普通的做法就是把控件的宽设置为match_parent,高度设置为转换后的dip,然后直接开始布局,这样可以是可以,但是我发现在有些手机上,展现的高度不是很理想;

安卓布局适配的另一种姿势:


    

        


如果我这样布局是不是更加完美呢?
我们已经知道这个控件的宽度是填满整个屏幕,它是个固定值(屏幕有多宽,我就多宽),高度是宽度的0.293333……计算方式:220 / 750 = 0.2933… 这样,无论碰到什么样的情况,他们永远会保持最佳状态。

解释下:

xmlns:auto=”http://schemas.android.com/apk/res-auto” 自定义属性,命名空间
ration :宽高比
anchor:宽度,意思是,根据宽度去自动计算该控件的高度,当然反之,也可以根据高度去自动计算控件的宽度。这里注意,根据什么(宽度或者高度),该值一定要有明确值,不能wrap_content

是不是突然觉得很nice ~

好,那么看它是如何实现的

自定义属性部分:




    
        
        
        
        
            
            
        

    


这里都有备注,应该很容易理解

Autoadapterimageview 实现:

public class AutoAdapterImageView extends ImageView {

//这里都是自定义属性相关的变量
private float ration = 0;
private int anchor;
private final int WIDTH_ANCHOR = 1;
private final int HEIGHT_ANCHOR = 2;

public AutoAdapterImageView(Context context, AttributeSet attrs) {
    super(context, attrs);

//读取自定属性,记得释放资源 recycle()
    TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.AutoAdpaterStyleable);
    ration = typedArray.getFloat(R.styleable.AutoAdpaterStyleable_ratio, ration);
    anchor = typedArray.getInt(R.styleable.AutoAdpaterStyleable_anchor, WIDTH_ANCHOR);
    typedArray.recycle();
}

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
//获取模式,以及大小    mode 下面说明会有   
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
    int widthSize = MeasureSpec.getSize(widthMeasureSpec);
    int heightMode = MeasureSpec.getMode(heightMeasureSpec);
    int heightSize = MeasureSpec.getSize(heightMeasureSpec);

//如果宽高都是精确值,那么我们不处理,交给系统
    if(widthMode == MeasureSpec.EXACTLY && heightMode == MeasureSpec.EXACTLY){
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }
//如果根据宽度自动适配,我们获取到宽度的值 然后计算并设置进去
else if(anchor == WIDTH_ANCHOR && widthMode == MeasureSpec.EXACTLY && ration > 0){
        int height = MeasureSpec.makeMeasureSpec((int) (widthSize * ration + 0.5f), MeasureSpec.EXACTLY);
        super.onMeasure(widthMeasureSpec, height);
    }
//如果根据高度自动适配,我们获取到高度的值 然后计算并设置进去
else if(anchor == HEIGHT_ANCHOR && heightMode == MeasureSpec.EXACTLY && ration > 0){
        int width = MeasureSpec.makeMeasureSpec((int) (heightSize * ration + 0.5f), MeasureSpec.EXACTLY);
        super.onMeasure(width, heightMeasureSpec);
    }
//否则交给系统处理
else{
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }
}
}

MODE的三种情况,
取值分别为MeasureSpec.UNSPECIFIED, MeasureSpec.EXACTLY, MeasureSpec.AT_MOST。

MeasureSpec.EXACTLY是精确尺寸,当我们将控件的layout_width或layout_height指定为具体数值时如andorid:layout_width=”50dip”,或者为FILL_PARENT是,都是控件大小已经确定的情况,都是精确尺寸。

MeasureSpec.AT_MOST是最大尺寸,当控件的layout_width或layout_height指定为WRAP_CONTENT时,控件大小一般随着控件的子空间或内容进行变化,此时控件尺寸只要不超过父控件允许的最大尺寸即可。因此,此时的mode是AT_MOST,size给出了父控件允许的最大尺寸。

MeasureSpec.UNSPECIFIED是未指定尺寸,这种情况不多,一般都是父控件是AdapterView,通过measure方法传入的模式。

Over~

代码不多,如果有什么疑问,请指出,谢谢~

github 简单封装了几个常用的控件,需要的请自行查看

安卓布局适配的另一种姿势_第2张图片

Github 地址 https://github.com/andmizi/AutoAdapterView

你可能感兴趣的:(安卓资料)