ListView、GridView自适应高度wrap-content属性失效问题解决

安卓界面的绘制,需要经过measure、layout、draw三个过程,其中measure决定了控件的大小。需要了解一些MeasureSpec的知识才能理解measure高度的计算。

MeasureSpec的知识

MeasureSpec是一个32位int值,高2位为测量的模式,低30位为测量的大小。测量的模式可以分为以下三种。
1)EXACTLY: 精确值模式,当layout_width或layout_height指定为具体数值,或者为match_parent时,系统使用EXACTLY。
2)AT_MOST:最大值模式,指定为wrap_content时,控件的尺寸不能超过父控件允许的最大尺寸。
3)UNSPECIFIED:不指定测量模式,View想多大就多大,一般不太使用。

android源码中关于三种模式的定义:
EXACTLY:The parent has determined an exact size for the child. The child is going to be given those bounds regardless of how big it wants to be.
AT_MOST:The child can be as large as it wants up to the specified size
UNSPECIFIED:The parent has not imposed any constraint on the child. It can be whatever size it wants

自适应高度的ListView

默认情况下,即时设置了layout_height为“wrap-content”,ListView仍然会充满全屏,效果和"match-parent"一致。
可以通过重写ListView的onMeasure方法来实现wrap-content效果。

package cn.com.example.common.view;

import android.content.Context;
import android.util.AttributeSet;
import android.widget.ListView;

public class WrapContentListView extends ListView {

    public WrapContentListView (Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    public WrapContentListView (Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public WrapContentListView (Context context) {
        super(context);
    }

    public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2,
                MeasureSpec.AT_MOST);
        super.onMeasure(widthMeasureSpec, expandSpec);
    }
}

自适应高度的GridView

与listview的情况类似,代码如下:

package cn.com.example.common.view;

import android.content.Context;
import android.util.AttributeSet;
import android.widget.GridView;

public class WrapContentGridView extends GridView {
    public WrapContentGridView (Context context) {
        super(context);
    }

    public WrapContentGridView (Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2,
                MeasureSpec.AT_MOST);
        super.onMeasure(widthMeasureSpec, expandSpec);
    }
}

你可能感兴趣的:(ListView、GridView自适应高度wrap-content属性失效问题解决)