就是上面的这个折线图,加载的时候有揭露动画,gif图就不录制了,直接上代码,代码注释写的很详细了,自定义属性没有加,为了方便直接拿来用
package com.oneweone.momocamera.widget;
import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.view.View;
/**
* Created by fanday on 2017/11/1.
*/
public class LineChart extends View {
//圆点的数据
private float[] dots = {1.2f,2.4f,3.2f,0.9f,1.1f,2.3f,4.0f};
//数据对应的日期
private String[] days = {"21","22","23","24","25","26","27"};
//圆点的半径
private float circleRadius = 12f;
//每段线在x轴上的投影
private float lineLen = 0f;
//y轴对应的分度值
private float hAverage = 0f;
//下方文字的总高度
private float textHeight = 60;
public LineChart(Context context) {
this(context,null,0);
}
public LineChart(Context context, @Nullable AttributeSet attrs) {
this(context, attrs,0);
}
public LineChart(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
private Paint paint;
private Paint bgPaint;
private Paint circlePaint;
private Paint vLinePaint;
private Paint textPaint;
//距离最左边的偏移量 防止圆点和文字过于靠左
private float xOffset = 20;
//初始化各种画笔
private void init() {
paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setColor(Color.BLACK);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(4);
bgPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
bgPaint.setColor(Color.GRAY);
bgPaint.setStyle(Paint.Style.FILL);
bgPaint.setStrokeWidth(0.0f);
circlePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
circlePaint.setColor(Color.WHITE);
circlePaint.setStyle(Paint.Style.FILL);
circlePaint.setStrokeWidth(0.0f);
vLinePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
vLinePaint.setColor(Color.RED);
vLinePaint.setStyle(Paint.Style.STROKE);
vLinePaint.setStrokeWidth(2.0f);
textPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
textPaint.setColor(Color.BLACK);
textPaint.setStyle(Paint.Style.STROKE);
textPaint.setTextSize(30);
textPaint.setStrokeWidth(2.0f);
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
lineLen = (w - dots.length*2*circleRadius-circleRadius-xOffset)*1.0f/6;
float maxH = getMaxHPoint();
hAverage = (h-circleRadius-textHeight-2)*1.0f/maxH;
}
/**
* 拿到数据中的最大值 以便于计算y轴的分度值
* @return
*/
private float getMaxHPoint() {
float max = 0f;
for (Float f :dots){
max = max>f?max:f;
}
return max;
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//画垂直x轴的线段
drawVLine(canvas);
//画折线图
drawChart(canvas);
//画日期文字
drawText(canvas);
}
private void drawText(Canvas canvas) {
for (int i = 0;i
代码中调用
LineChart view = (LineChart) findViewById(R.id.line);
view.anim();
package com.oneweone.momocamera.widget;
import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.DashPathEffect;
import android.graphics.Paint;
import android.graphics.RectF;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.view.View;
/**
* Created by fanday on 2017/11/2.
*/
public class CompassView extends View {
public CompassView(Context context) {
super(context);
init();
}
public CompassView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
init();
}
public CompassView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
private Paint dashPaint;
private Paint outerPaint;
private Paint grayDashPaint;
private Paint grayOuterPaint;
private Paint pointPaint;
//边缘的距离 防止绘制圆球超出
private float outOffset = 20f;
//两个圆弧之间的距离
private float outInnerOffset = 40f;
//当前的动画加载到的角度
private float currentRadius = 120f;
//小圆点的半径
private float circleRadius = 15f;
//内圆弧的宽度
private float innerPaintWidth = 6.0f;
//外圆弧的宽度
private float outerPaintWidth = 8.0f;
//内指示器的宽度
private float pointPaintWidth = 2f;
private void init() {
dashPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
dashPaint.setColor(Color.WHITE);
dashPaint.setStyle(Paint.Style.STROKE);
dashPaint.setStrokeWidth(innerPaintWidth);
dashPaint.setPathEffect(new DashPathEffect(new float[] {15, 15}, 0));
outerPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
outerPaint.setColor(Color.WHITE);
outerPaint.setStyle(Paint.Style.STROKE);
outerPaint.setStrokeWidth(outerPaintWidth);
grayDashPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
grayDashPaint.setColor(Color.GRAY);
grayDashPaint.setStyle(Paint.Style.STROKE);
grayDashPaint.setStrokeWidth(innerPaintWidth);
grayDashPaint.setPathEffect(new DashPathEffect(new float[] {15, 15}, 0));
grayOuterPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
grayOuterPaint.setColor(Color.GRAY);
grayOuterPaint.setStyle(Paint.Style.STROKE);
grayOuterPaint.setStrokeWidth(outerPaintWidth);
pointPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
pointPaint.setColor(Color.WHITE);
pointPaint.setStyle(Paint.Style.FILL);
pointPaint.setStrokeWidth(pointPaintWidth);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//关闭硬件加速
setLayerType(LAYER_TYPE_SOFTWARE, null);
drawCircle(canvas);
drawPoint(canvas);
}
private void drawPoint(Canvas canvas) {
//旋转画布让指示器和和圆点始终在y轴上面
canvas.save();
canvas.translate(getWidth()/2,getHeight()/2);
canvas.rotate(60f,0,0);
canvas.rotate(currentRadius,0,0);
float cx = 0;
float cy = getWidth()/2-outOffset-4;
canvas.drawCircle(cx,cy,circleRadius,pointPaint);
float y1 = getWidth()/2-outOffset-outInnerOffset-outerPaintWidth-innerPaintWidth-5;
float y2 = getWidth()/2-outOffset-outInnerOffset-outerPaintWidth-innerPaintWidth-55;
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setStrokeWidth(14);
paint.setColor(Color.WHITE);
canvas.drawLine(0,y1,0,y2,paint);
canvas.restore();
}
private void drawCircle(Canvas canvas) {
RectF rect = new RectF(outOffset+outInnerOffset,outOffset+outInnerOffset,
getWidth()-outOffset-outInnerOffset,getHeight()-outOffset-outInnerOffset);
RectF outRect = new RectF(outOffset,outOffset,getWidth()-outOffset,
getHeight()-outOffset);
//灰色带圆弧
canvas.drawArc(rect,-210,240f,false,grayDashPaint);
canvas.drawArc(outRect,-210,240,false,grayOuterPaint);
//动画控制的
canvas.drawArc(rect,-210,currentRadius,false,dashPaint);
canvas.drawArc(outRect,-210,currentRadius,false,outerPaint);
}
public void start(){
ValueAnimator va = ValueAnimator.ofFloat(0,180);
va.setDuration(2000);
va.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
currentRadius = (float) animation.getAnimatedValue();
invalidate();
}
});
va.start();
}
}
布局使用
代码中启动
final CompassView campassView = (CompassView) findViewById(R.id.compass);
campassView.postDelayed(new Runnable() {
@Override
public void run() {
campassView.start();
}
},100);