版权声明:转载请标明来自:https://blog.csdn.net/liweipei_gd https://blog.csdn.net/liweipei_gd/article/details/89226515
现在很多优秀的第三方绘表绘图库,但是有时候只需要绘制简单的图表就引用这么庞大的库感觉有点牛刀宰青蛙的感觉。我一般简单的图表都喜欢自定义绘制。
比如现在做一个简单的柱状图,思路很简单,横轴方向分三份,1个做间隔,2个绘柱子。直接上代码:
public class MyBarChart extends View {
int[] value = new int[]{0,0,0,0,0,0}; //数值数组
int max = 100; //图表最大值
int color = R.color.gray; //柱状图颜色
float width; //宽度,方便计算设置float类型
float height; //高度,方便计算设置float类型
float x_unit ; //横向计算单元,2单元为柱状图的宽度,1单元为间隔
float y_unit ; //高度计算单元,跟高度和最大数值挂钩
float margin; //边距间隔
Paint axis_paint; //画轴画笔
Paint title_paint; //横竖轴数值画笔
Paint bg_paint; //画背景柱状图画笔
Paint data_paint; //画数据柱状图画笔
//记录每个柱状图开始结束横坐标,用于点击回调
float[] startX;
float[] stopX;
int select = -1;
public MyBarChart(Context context){
super(context);
}
public MyBarChart(Context context,int[] value,int max,int color,OnItemClickListener onItemClickListener){
super(context);
this.value = value;
this.max = max;
this.color = color;
this.onItemClickListener =onItemClickListener;
init();
}
public void update(int[] value,int max,int color,OnItemClickListener onItemClickListener){
this.value = value;
this.max = max;
this.color = color;
this.onItemClickListener =onItemClickListener;
init();
invalidate();
}
//点击回调监听器
OnItemClickListener onItemClickListener;
public interface OnItemClickListener {
void onTouch(int item,int value);
}
/**
* 数据初始化
* */
private void init() {
axis_paint = new Paint();
axis_paint.setStyle(Paint.Style.STROKE);
axis_paint.setAntiAlias(true);
axis_paint.setDither(true);
axis_paint.setColor(ContextCompat.getColor(getContext(), R.color.black));
axis_paint.setStrokeWidth(1);
title_paint = new Paint(Paint.ANTI_ALIAS_FLAG);//抗锯齿标志
title_paint.setColor(ContextCompat.getColor(getContext(), R.color.black));
if(value.length>25){ //根据数据量调整字体大小,根据自己需求调整
title_paint.setTextSize(18f);
}else if(value.length>10){
title_paint.setTextSize(20f);
}else {
title_paint.setTextSize(30f);
}
bg_paint = new Paint();
bg_paint.setColor(ContextCompat.getColor(getContext(), R.color.gray));
bg_paint.setStyle(Paint.Style.FILL);
bg_paint.setDither(true);
bg_paint.setAntiAlias(true);
data_paint = new Paint();
data_paint.setColor(ContextCompat.getColor(getContext(), color));
data_paint.setStyle(Paint.Style.FILL);
data_paint.setDither(true);
data_paint.setAntiAlias(true);
startX = new float[value.length];
stopX = new float[value.length];
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
calculation();
canvas.drawLine(margin,height+margin/2,width+margin,height+margin/2,axis_paint);// x轴
// canvas.drawLine(margin,height+margin,margin,margin,axis_paint); //y轴
for(int i=0; i<value.length;i++){
float start_x = margin+(1+3*i)*x_unit;
startX[i] = start_x;
float stop_x = margin+(3+3*i)*x_unit;
stopX[i] = stop_x;
float top = margin/2 + height-value[i]*y_unit;
float bottom = margin/2 + height;
canvas.drawRect(start_x,margin,stop_x,bottom,bg_paint);
if(value.length>9){//根据需求绘制横轴坐标数值,这里是每3个绘一个
if(i%3==0){
String t = "";
if(i<9){
t = " "+(i+1);
}else {
t = ""+(i+1);
}
canvas.drawText(t,margin+x_unit*(3*i+1),height+(margin*2/3),title_paint);
}else {
canvas.drawText("",margin+x_unit*(3*i+1),height+(margin*2/3),title_paint);
}
}else {
if(i%3==0){
String t = "";
t = " "+(i+1);
canvas.drawText(t,margin+x_unit*(3*i+1),height+(margin*3/4),title_paint);
}else {
canvas.drawText("",margin+x_unit*(3*i+1),height+(margin*3/4),title_paint);
}
}
if(i==select){
data_paint.setColor(ContextCompat.getColor(getContext(), R.color.text_deep_gray));
}else {
data_paint.setColor(ContextCompat.getColor(getContext(), color));
}
canvas.drawRect(start_x,top,stop_x,bottom,data_paint);
}
}
/**
* 计算边距和间隔
* */
void calculation(){
margin = this.getWidth()/10;
width = this.getWidth()-margin*2;
height = this.getHeight() - margin*2;
x_unit = width/(value.length*3);
y_unit = height/max;
}
//自定义点击监听回调,回调点击的位置和数值,-1表示点在间隔位
@Override
public boolean onTouchEvent(final MotionEvent event) {
final float x = event.getX();
select = -1;
for(int i=0 ;i<startX.length;i++){
if(x>=startX[i]&&x<=stopX[i]){
select = i;
invalidate();
if(onItemClickListener!=null){
if(value[select]>0){//这里是把没数值的柱状图 当成空白间隔回调出去,根据需要调整
onItemClickListener.onTouch(select,value[select]);
}else {
onItemClickListener.onTouch(-1,value[select]);
}
}
break;
}
}
if(select<=0){
if(onItemClickListener!=null)onItemClickListener.onTouch(select,0);
}
return true;
}
}
然后我是在需要的页面使用动态方式放入
MyBarChart myBarChart = new MyBarChart(HistoryActivity.this, new int[]{0, 1, 2, 3, 4, 5, 6, 7, 8}, 20, R.color.text_blue, new MyBarChart.OnItemClickListener() {
@Override
public void onTouch(int item, int value) {
}
});
ll.addView(myBarChart);