使用安卓Canvas无插件画出简单的条形图

Q:为什么不同MPAndroidChart库来画?
A:别人造的轮子用着不爽,就喜欢自己造轮子(其实是没学懂

开始编码
  • 首先,创建一个Activity,我这里取名为ChartActivity。
  • 在ChartActivity的布局文件中新添加一个ImageView,id名为BarChart
<ImageView
        android:id="@+id/BarChart"
        android:layout_width="400dp"
        android:layout_height="200dp"/>
  • 接下来我们在逻辑代码部分添加画网格的函数(建议复制到IDE里面去看):
private Bitmap drawGrid(){//画网格
        Bitmap bitmap = Bitmap.createBitmap(CanvasWidth,CanvasHeight, Bitmap.Config.ARGB_8888);//创建一个Bitmap(位图)
        Canvas canvas = new Canvas(bitmap);//创建一个画布,在画布上化的东西都会存入bitmap当中
        canvas.drawColor(Color.WHITE);//给画布添加纯白背景色

        Paint paint = new Paint();//创建一个画笔
        paint.setColor(Color.GRAY);

        //画出竖列
        int ColumnCount = 6;//设置总共要画的列数
        for(int i=0;i<=ColumnCount;i++){
            float line_x = (CanvasWidth-Margin_left)*(i/(float)(ColumnCount))+Margin_left-1;
            canvas.drawLine(line_x,0,line_x,CanvasHeight-Margin_bottom,paint);//在canvas上画出竖线
        }

        //画出横排
        int RowCount = 4;//设置总共要画的排数
        for(int i=0;i<=RowCount;i++){
            float line_y = (CanvasHeight-Margin_bottom)*(i/(float)(RowCount))+Margin_bottom+2;
            canvas.drawLine(Margin_left,line_y,CanvasWidth,line_y,paint);//在canvas上画出竖线
        }

        return bitmap;
    }
  • 接着我们利用上面画网格函数drawGrid返回的Bitmap画我们的条形图
    (建议复制到IDE里面去看):
private void drawBarChart(){//画条形图
        ImageView barChart = findViewById(R.id.BarChart);
        Bitmap bitmap = drawGrid();//从drawGrid函数中得到返回的Bitmap
        Canvas canvas = new Canvas(bitmap);
        Paint paint = new Paint();
        paint.setColor(Color.BLUE);//设置竖条颜色
        //准备一下数据
        int yMax = 100;//最大值
        int data[] = {17,24,31,49,57,65,91,85,52,27,46,12};//数据

        float barMargin = 1;
        float barWidth = (CanvasWidth-Margin_left)/(float)data.length;
        float bottom = CanvasHeight-Margin_bottom;
        //开始画条形图
        for(int i=0;i<data.length;i++){
            //使用画矩形的函数画条
            float left = barWidth*i+barMargin+Margin_left;
            float top = (CanvasHeight-Margin_bottom)-((float)(CanvasHeight-Margin_bottom)/yMax)*data[i];
            canvas.drawRect(left,top,left+barWidth-barMargin*2,bottom,paint);
        }




        barChart.setImageBitmap(bitmap);
    }

<- 看看效果

  • 效果基本上已经出来了,我们再给条形图加上刻度和文本(建议复制到IDE里面去看):
private Bitmap drawText(Bitmap bitmap){
        Bitmap baseBitmap = bitmap;
        Canvas canvas = new Canvas(bitmap);
        Paint paint = new Paint();

        //加点文本和刻度数据,这里换成你需要条形图画的样式
        String[] dataType = {"1月","2月","3月","4月","5月","6月","7月","8月","9月","10月","11月","12月"};//横轴上的文本
        String[] dataScale = {"100","75","50","25","0"};//纵轴上的刻度文本

        //先画横轴上的文本
        for(int i=0;i<dataType.length;i++){
            float left = (CanvasWidth-Margin_left)*(i/(float)(dataType.length))+Margin_left;
            canvas.drawText(dataType[i],left,CanvasHeight - Margin_bottom + 20,paint);//在canvas上绘制出文本
        }

        //再画出纵轴上的刻度文本
        for(int i=0;i<dataScale.length;i++){
            float top = CanvasHeight*(i/(float)(dataScale.length))+10;
            canvas.drawText(dataScale[i],5,top,paint);//在canvas上绘制出文本
        }

        return bitmap;
    }
  • 最后在显示条形图的时候调用一下绘制文本的函数:
//将
barChart.setImageBitmap(bitmap);
//改为
barChart.setImageBitmap(drawText(bitmap));
//实在找不到就Ctrl+F搜一下在哪里吧...

<- 看看最终效果

附页面完整代码:

package com.example.challengeapp0601;

import androidx.appcompat.app.AppCompatActivity;

import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.os.Bundle;
import android.widget.ImageView;

public class ChartActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_chart);
        drawBarChart();
    }

//Write by Pigeon_Ming
    final int CanvasHeight = 200;
    final int CanvasWidth = 400;

    final int Margin_left = 30;//留出左侧和底部边距供纵轴单位和横轴名称使用
    final int Margin_bottom = 30;

    private Bitmap drawGrid(){//画网格
        Bitmap bitmap = Bitmap.createBitmap(CanvasWidth,CanvasHeight, Bitmap.Config.ARGB_8888);//创建一个Bitmap(位图)
        Canvas canvas = new Canvas(bitmap);//创建一个画布,在画布上化的东西都会存入bitmap当中
        canvas.drawColor(Color.WHITE);//给画布添加纯白背景色

        Paint paint = new Paint();//创建一个画笔
        paint.setColor(Color.GRAY);

        //画出竖列
        int ColumnCount = 6;//设置总共要画的列数
        for(int i=0;i<=ColumnCount;i++){
            float line_x = (CanvasWidth-Margin_left)*(i/(float)(ColumnCount))+Margin_left-1;
            canvas.drawLine(line_x,0,line_x,CanvasHeight-Margin_bottom,paint);//在canvas上画出竖线
        }

        //画出横排
        int RowCount = 4;//设置总共要画的排数
        for(int i=0;i<=RowCount;i++){
            float line_y = (CanvasHeight-Margin_bottom)*(i/(float)(RowCount))+Margin_bottom+2;
            canvas.drawLine(Margin_left,line_y,CanvasWidth,line_y,paint);//在canvas上画出竖线
        }

        return bitmap;
    }

    private void drawBarChart(){//画条形图
        ImageView barChart = findViewById(R.id.BarChart);
        Bitmap bitmap = drawGrid();//从drawGrid函数中得到返回的Bitmap
        Canvas canvas = new Canvas(bitmap);
        Paint paint = new Paint();
        paint.setColor(Color.BLUE);//设置竖条颜色
        //准备一下数据
        int yMax = 100;//最大值
        int data[] = {17,24,31,49,57,65,91,85,52,27,46,12};//数据

        float barMargin = 1;
        float barWidth = (CanvasWidth-Margin_left)/(float)data.length;
        float bottom = CanvasHeight-Margin_bottom;
        //开始画条形图
        for(int i=0;i<data.length;i++){
            //使用画矩形的函数画条
            float left = barWidth*i+barMargin+Margin_left;
            float top = (CanvasHeight-Margin_bottom)-((float)(CanvasHeight-Margin_bottom)/yMax)*data[i];
            canvas.drawRect(left,top,left+barWidth-barMargin*2,bottom,paint);
        }




        barChart.setImageBitmap(drawText(bitmap));
    }

    private Bitmap drawText(Bitmap bitmap){
        Bitmap baseBitmap = bitmap;
        Canvas canvas = new Canvas(bitmap);
        Paint paint = new Paint();

        //加点文本和刻度数据,这里换成你需要条形图画的样式
        String[] dataType = {"1月","2月","3月","4月","5月","6月","7月","8月","9月","10月","11月","12月"};//横轴上的文本
        String[] dataScale = {"100","75","50","25","0"};//纵轴上的刻度文本

        //先画横轴上的文本
        for(int i=0;i<dataType.length;i++){
            float left = (CanvasWidth-Margin_left)*(i/(float)(dataType.length))+Margin_left;
            canvas.drawText(dataType[i],left,CanvasHeight - Margin_bottom + 20,paint);//在canvas上绘制出文本
        }

        //再画出纵轴上的刻度文本
        for(int i=0;i<dataScale.length;i++){
            float top = CanvasHeight*(i/(float)(dataScale.length))+10;
            canvas.drawText(dataScale[i],5,top,paint);//在canvas上绘制出文本
        }

        return bitmap;
    }
}

写在最后:

第一次尝试写博客,初来乍到,经验不足,啥也不懂,写得不好还请见谅。
更多的讲解都包含在代码注释里面的,自己研究一下吧。
自己改一改代码说不定能样式更好看。:-)

版权声明:本文由Pigeon_Ming原创,转载请附上原文出处链接及本声明。
原文链接:http://pigeonming.top/?p=121

一条评论

留下评论

您的电子邮箱地址不会被公开。 必填项已用 * 标注