自定義view

測量,賦值,繪製

  1. 測量:父view調用子view的onMeasure()方法,首先看子view是一個view還是viewgroup, 如果子view是一個view,直接調用它的onMeasure方法去測量,並把測量結果返回給父view。如果子view是一個viewgroup, 分別測量每個子view,保存每個子view的尺寸,並且計算並保存自己的尺寸。
    1.測量已有view的尺寸
public class MyImageView extends android.support.v7.widget.AppCompatImageView {
    public MyImageView(Context context) {
        super(context);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        int width = getMeasuredWidth();
        int height = getMeasuredHeight();

        if (width > height) {
            width = height;
        } else {
            height = width;
        }

        setMeasuredDimension(width, height);

    }
}

2.測量自定義view的尺寸

public class CustomView extends ViewGroup {

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

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        
        int width = getMeasuredWidth();
        int height = getMeasuredHeight();
        
        width = resolveSize(width, widthMeasureSpec);
        height = resolveSize(height, heightMeasureSpec);
        
        setMeasuredDimension(width, height);
        
    }

    public static int resolveSizeAndState(int size, int measureSpec, int childMeasuredState) {
        final int specMode = MeasureSpec.getMode(measureSpec);
        final int specSize = MeasureSpec.getSize(measureSpec);
        final int result;
        switch (specMode) {
            case MeasureSpec.AT_MOST:
                if (specSize < size) {
                    result = specSize | MEASURED_STATE_TOO_SMALL;
                } else {
                    result = size;
                }
                break;
            case MeasureSpec.EXACTLY:
                result = specSize;
                break;
            case MeasureSpec.UNSPECIFIED:
            default:
                result = size;
        }
        return result | (childMeasuredState & MEASURED_STATE_MASK);
    }
    
    

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        
    }
}

3.測量與佈局自定義view

public class MyView extends ViewGroup {


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


    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        
        int viewCount = getChildCount();

        int widthMode = MeasureSpec.getMode(widthMeasureSpec);
        int widthSize = MeasureSpec.getSize(widthMeasureSpec);

        int heightMode = MeasureSpec.getMode(heightMeasureSpec);
        int heightSize = MeasureSpec.getSize(heightMeasureSpec);

        for (int i = 0; i < viewCount; i++) {

            View view = getChildAt(i);
            LayoutParams lp = view.getLayoutParams();
            int childMeasureSpec;
            switch (lp.width) {
                case LayoutParams.MATCH_PARENT:
                    if(widthMode == MeasureSpec.EXACTLY || widthMode == MeasureSpec.AT_MOST){
                        childMeasureSpec = MeasureSpec.makeMeasureSpec(widthSize - 10, MeasureSpec.EXACTLY);
                    }else {
                        childMeasureSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
                    }
                    break;
                case LayoutParams.WRAP_CONTENT:
                    if(widthMode == MeasureSpec.EXACTLY || widthMode == MeasureSpec.AT_MOST){
                        childMeasureSpec = MeasureSpec.makeMeasureSpec(widthSize- 10 , MeasureSpec.AT_MOST);
                    }else{
                        childMeasureSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
                    }
                default:
                    childMeasureSpec = MeasureSpec.makeMeasureSpec(lp.width, MeasureSpec.EXACTLY);
                    break;
            }

        }

    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        int viewCount = getChildCount();
        for(int i=0; i<viewCount; i++){
            View view = getChildAt(i);
            view.layout(getLeft(), getTop(), getRight(), getBottom());
        }
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章