自定义viewGroup的常见写法

@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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值