@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);
}
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", "尚未初始化"); } } }