我正在参加「创意开发 投稿大赛」详情请看:掘金创意开发大赛来了!
重写View的onMeasure方法 在自定义控件的时候,控件的宽高(最终的测量尺寸)由控件本身和其父容器共同决定的,既然是共同决定的我们得知道父容器的“意愿”对吧!
父容器的“意愿”也就三种,在MeasureSpec类中的三个常量表明了其三种意愿:
1、UNSPECIFIED:父容器对控件的大小不在意,你想多大都可以;
2、AT_MOST:父容器给控件的大小设置了一个最大值,表示你大小的取值最好在这个范围内;
3、EXACTLY: 父容器已经给控件计算出了显示的大小,控件就显示这么大得了;
onMeasure方法具体的代码:
int resultWidth;
//获取父容器的意愿
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
int sizeWidth = MeasureSpec.getSize(widthMeasureSpec);
if (widthMode == MeasureSpec.EXACTLY) {
resultWidth = sizeWidth;
} else {
if (widthMode == MeasureSpec.AT_MOST) {
resultWidth = Math.min(screenWidth, sizeWidth);
} else {
resultWidth = screenWidth;
}
}
int resultHeight;
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
int sizeHeight = MeasureSpec.getSize(heightMeasureSpec);
if (heightMode == MeasureSpec.EXACTLY) {
resultHeight = sizeHeight;
} else {
if (heightMode == MeasureSpec.AT_MOST) {
resultHeight = Math.min(screenHeight, sizeHeight);
} else {
resultHeight = screenHeight;
}
}
//设置测量出的宽高
setMeasuredDimension(resultWidth, resultHeight);
理一下画图的顺序 drawTextY(Canvas canvas) //绘制y轴上需要显示的文字 drawTextX(Canvas canvas) //绘制x轴上的文字 drawCoordinate(Canvas canvas) //绘制坐标轴 drawBrokenLine(Canvas canvas) //绘制折线、顶点及顶点文字 差不多就是这个从上到下的顺序! 看到这儿估计有人会说:你特么逗我么,绘制折线图不先画坐标轴? 道友别急,请听我狡辩:绘制折线图有一个关键点是确定点的坐标(特么不是废话么),之所以将坐标轴放到文字之后绘制是因为y上绘制文字的宽度和x轴上文字的高度会对坐标轴的定位有一定影响。因为这两个数据是未知的,所以我们得先确定下来才好进行下一步操作!
private int maxTextWidth;
//y轴每一刻度的高度
private int singleHeight;
//文字的高度
private int textHeight;
//y轴文字list
private List<String> textY;
/**
* draw Y轴上的文字
*
* @param canvas
*/
private void drawTextY(Canvas canvas) {
if (textY == null) return;
// 文字的高度:mTextPaint.descent() - mTextPaint.ascent()
textHeight = (int) (mTextPaint.descent() - mTextPaint.ascent());
singleHeight = (getHeight() - paddingBottom - paddingTop - textHeight - spacing) / (textY.size() - 1);
int xPos = paddingLeft;
int yPos;
for (int i = 0; i < textY.size(); i++) {
//找出文字所需的最大宽度
if (mTextPaint.measureText(textY.get(textY.size() - i - 1)) > maxTextWidth) {
maxTextWidth = (int) mTextPaint.measureText(textY.get(textY.size() - i - 1));
}
yPos = paddingTop + singleHeight * i + textHeight / 2;
canvas.drawText(textY.get(textY.size() - i - 1), xPos, yPos, mTextPaint);
}
}
ok,大概关键代码就这些。
- 效果