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);
    }
}
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容