近来公司事前较少,再来找几个有意思的View练练手,下面是原生华为天气预报界面:
下面是仿的UI交互效果:
**思路:
1.平移画布到View中心,先绘制一个圆弧,绘制中间文字
2.旋转画布,绘制小短线,同时绘制中间的温度和下边的图片
3.确定0摄氏度的位置,确定每日温差之间共覆盖多少角度
4.算出最小温度的起始角,根据cos,sin计算坐标,绘制温度数字。
5.算出最小温度的短线索引,加粗变色绘制。**
1.首先在onMeasure中保证View宽高。
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int wrap_Len = 600;
int width = measureDimension(wrap_Len, widthMeasureSpec);
int height = measureDimension(wrap_Len, heightMeasureSpec);
int len=Math.min(width,height);
//保证是一个正方形
setMeasuredDimension(len,len);
}
public int measureDimension(int defaultSize, int measureSpec){
int result;
int specMode = MeasureSpec.getMode(measureSpec);
int specSize = MeasureSpec.getSize(measureSpec);
if(specMode == MeasureSpec.EXACTLY){
result = specSize;
}else{
result = defaultSize; //UNSPECIFIED
if(specMode == MeasureSpec.AT_MOST){
result = Math.min(result, specSize);
}
}
return result;
}
然后开始平移画布,绘制一个圆弧
mWidth=getWidth();
mHeight=getHeight();
radius=(mWidth-getPaddingLeft()-getPaddingRight())/2;//半径
canvas.translate(mWidth/2,mHeight/2);
private void drawArcView(Canvas canvas) {
RectF mRect=new RectF(-radius,-radius,radius,radius);
//canvas.drawRect(mRect,mArcPaint);
canvas.drawArc(mRect,startAngle,sweepAngle,false,mArcPaint);
}
效果如图:
2.旋转画布,绘制小短线
以一定的角度旋转画布,循环画出短线
private void drawLine(Canvas canvas) {
canvas.save();
float angle = (float)sweepAngle/count;//刻度间隔
canvas.rotate(-270+startAngle);//将起始刻度点旋转到正上方
for(int i=0;i<=count;i++){
if(i==0 || i==count){
mLinePaint.setStrokeWidth(1);
mLinePaint.setColor(Color.WHITE);
canvas.drawLine(0,-radius,0,-radius+40,mLinePaint);
}else if(i>=getStartLineIndex(minTemp,maxTemp) && i<=getEndLineIndex(minTemp,maxTemp)){
mLinePaint.setStrokeWidth(3);
mLinePaint.setColor(getRealColor(minTemp,maxTemp));
canvas.drawLine(0,-radius,0,-radius+30,mLinePaint);
}else {
mLinePaint.setStrokeWidth(2);
mLinePaint.setColor(Color.WHITE);
canvas.drawLine(0,-radius,0,-radius+30,mLinePaint);
}
canvas.rotate(angle);//逆时针旋转
}
canvas.restore();
}
效果如图:
然后绘制中间的温度和下边的图片,并注释掉绘制圆环的方法
private void drawTextBitmapView(Canvas canvas) {
mTextPaint.setTextSize(144);
canvas.drawText(currentTemp+"°",0,0+getTextPaintOffset(mTextPaint),mTextPaint);
canvas.drawBitmap(bitmap,0-bitmap.getWidth()/2,radius-bitmap.getHeight()/2-30,null);
}
其中getTextPaintOffset()函数改变文字的Y坐标偏移量
public float getTextPaintOffset(Paint paint){
Paint.FontMetricsInt fontMetrics = paint.getFontMetricsInt();
return -fontMetrics.descent+(fontMetrics.bottom-fontMetrics.top)/2;
}
效果如图: