自定义viewGroup的常见写法

来源:互联网 发布:被淘宝卖家恐吓 编辑:程序博客网 时间:2024/05/14 21:09
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    // 固定写法 获取宽高的长度和模式
    int wSize = MeasureSpec.getSize(widthMeasureSpec);
    int wMode = MeasureSpec.getMode(widthMeasureSpec);
    int hSize = MeasureSpec.getSize(heightMeasureSpec);
    int hMode = MeasureSpec.getMode(heightMeasureSpec);
    // 得到view真正的宽高,实际的减去内边距 显示内容区域的最大宽度和高度
    int contentW = wSize - getPaddingLeft() - getPaddingRight();
    int contentH = hSize - getPaddingBottom() - getPaddingTop();
    // 获取孩子的总数目
    int count = getChildCount();
    // 遍历所有的view,设置每个view的宽高
    for (int i = 0; i < count; i++) {
        View child = getChildAt(i);
        if (child.getVisibility() == View.GONE) {
            continue;
        }
        int childWidthMeasureSpec;
        int childHeightMeasureSpec;
        // 获取child的设置params
        LayoutParams params = child.getLayoutParams();
        // params.width的值只有三种可能,一种设置dip这种情况,该值大于0
        // patams.width的值小于0,则为LayoutParams.WRAP_CONTENT,LayoutParams.MATCH_PARENT
        if (params.width > 0) {
            childWidthMeasureSpec = MeasureSpec.makeMeasureSpec(params.width,
                    MeasureSpec.EXACTLY);
        }
        else if (params.width == LayoutParams.WRAP_CONTENT) {
            childWidthMeasureSpec = MeasureSpec.makeMeasureSpec(contentW, MeasureSpec.AT_MOST);
        }
        else {
            childWidthMeasureSpec = MeasureSpec.makeMeasureSpec(contentW, MeasureSpec.EXACTLY);
        }


        if (params.height > 0) {
            childHeightMeasureSpec = MeasureSpec.makeMeasureSpec(params.height,
                    MeasureSpec.EXACTLY);
        }
        else if (params.height == LayoutParams.WRAP_CONTENT) {
            childHeightMeasureSpec = MeasureSpec.makeMeasureSpec(contentH, MeasureSpec.AT_MOST);
        }
        else {
            childHeightMeasureSpec = MeasureSpec.makeMeasureSpec(contentH, MeasureSpec.EXACTLY);
        }


        // 测量child
        child.measure(childWidthMeasureSpec, childHeightMeasureSpec);
       }
    //所有的子View都测量完了,设置自身的大小
    setMeasuredDimension(wSize, hSize);
}


@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
    int childW = getPaddingLeft();
    for (int i = 0; i < getChildCount(); i++) {
        View view = getChildAt(i);
        int wide = view.getMeasuredWidth();
        int height = view.getMeasuredHeight();
        //算一下具中
        view.layout(l + childW, mergaH, l + childW + wide, height + mergaH);
    }

}


其他要注意的子view的layout高度是从0开始的,不是指屏幕上的坐标,

画线时线的宽度是在外侧的,计算时要注意

处理文字的常用格式:

public class WayDayView extends View {    private TextPaint mPaint;//测量文字的画笔    private Context mContext;//上下文    private String data;//路线的文字结合    private int tvH;//文字的高    private int tvW;//文字的宽    private int imgW, imgH;//图片的宽高    private int padding;//上下的距离    private Bitmap mBitmap;//文字间的图片    public WayDayView(Context context) {        super(context);        init(context);    }    public WayDayView(Context context,String data) {        super(context);        this.data = data;        init(context);    }    public WayDayView(Context context, AttributeSet attrs) {        super(context, attrs);        init(context);    }    public WayDayView(Context context, AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);        init(context);    }    private void init(Context context) {        this.mContext = context;        padding = ScreenUtils.dip2px(context, 6);        mBitmap = decodeResource(getResources(), R.drawable.icon_allway);        imgW = mBitmap.getWidth();        imgH = mBitmap.getHeight();        tvW = ScreenUtils.dip2px(context, 16);        mPaint = new TextPaint();        mPaint.setTextSize(tvW);        mPaint.setColor(getResources().getColor(R.color.color_666666));        Paint.FontMetrics fontMetrics = mPaint.getFontMetrics();        tvH = (int) (mPaint.getFontMetrics().bottom - mPaint.getFontMetrics().top);        mPaint.clearShadowLayer();    }    public void setData(String data) {        this.data = data;        invalidate();    }    @Override    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        setMeasuredDimension(measureWidth(widthMeasureSpec), measureHeight(heightMeasureSpec));    }    //因为使用match_parent所以是精准型,不需要处理包裹型    private int measureWidth(int measureSpec) {        return ScreenUtils.getWindowWidth(mContext);    }    private int measureHeight(int measureSpec) {        return  Math.min(tvH , imgH)+ padding * 2;    }    private Bitmap decodeResource(Resources resources, int id) {        TypedValue value = new TypedValue();        resources.openRawResource(id, value);        BitmapFactory.Options opts = new BitmapFactory.Options();        opts.inTargetDensity = value.density;        return BitmapFactory.decodeResource(resources, id, opts);    }    @Override    protected void onDraw(Canvas canvas) {        super.onDraw(canvas);        int hight = getHeight();        int nowWidth = padding, textW, topImg, topT;        //文字的高度一定大于图片的        if (!TextUtils.isEmpty(data)) {            if (hight >= tvH) {                topImg = (hight - imgH) / 2;                topT = (hight - tvH) / 2 + tvW;            }            else {                topImg = (tvH - imgH) / 2;                topT = tvW;            }            canvas.drawBitmap(mBitmap, ScreenUtils.dip2px(mContext,15), topImg, null);            canvas.drawText(data, ScreenUtils.dip2px(mContext,25)+imgW, topT, mPaint);        }        else {            //Log.e("LG", "尚未初始化");        }    }}

0 0