android自定义柱形图绘制
思路:1、定义一个布局容器用来做画布;2、定义一个 View类 用 Paint 将要绘制的图像都绘制出来;3、在调用的类里定义一个方法插入需要的数据以此绘图。视图效果:点击按钮时调用绘图方法将图绘制出来,也可以直接在界面上绘制详解:1、定义一个布局容器用来做画布;我的布局定义在了 activity_column.xml 里面,如下:<Buttonandroid:id="@+
思路:
1、定义一个布局容器用来做画布;
2、定义一个 View类 用 Paint 将要绘制的图像都绘制出来;
3、在调用的类里定义一个方法插入需要的数据以此绘图。
视图效果:
点击按钮时调用绘图方法将图绘制出来,也可以直接在界面上绘制
详解:
1、定义一个布局容器用来做画布;
我的布局定义在了 activity_column.xml 里面,如下:
<Button android:id="@+id/start" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="开始绘制柱状图"/> <!--柱状图绘制的地方--> <RelativeLayout android:layout_width="match_parent" android:layout_height="180dp" android:orientation="vertical" android:background="#00000000" android:paddingEnd="15dp" android:paddingStart="15dp"> <LinearLayout android:id="@+id/column" android:background="#00000000" android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center" android:orientation="vertical"> </LinearLayout> </RelativeLayout>
在这个布局中,将要绘制的柱形图会根据 id--column 绘制在 LinearLyout 里面
2、定义一个 View类 用 Paint 将要绘制的图像都绘制出来;
这里才是重点,这里需要自己获取布局的大小坐标,根据画布坐标绘制图形
import android.content.Context; import android.graphics.Canvas; import android.graphics.Paint; import android.graphics.RectF; import android.support.v4.content.ContextCompat; import android.view.View; import java.util.List; /** * Created by Administrator on 2018/3/14 0014. * 柱状图的绘制 */ public class ColumnView extends View { private String[] transverse; //横列的刻度值数组 private String[] vertical; //竖列的刻度值数组 private List<Integer> colors; //画笔颜色集合 private int[] high; //柱状图高度数值数组 //整个画布的宽、高 private int width; private int height; // X,Y轴的单位长度 (类似网格切割) private int xScale; private int yScale; // 默认边距 private int margin = 20; // 距离左边偏移量 private int marginX = 30; // 原点坐标 private int xPoint; private int yPoint; // 画笔 private Paint paintAxes; //画轴 private Paint paintCoordinate; //画坐标(文字或数值) private Paint paintRectF; //画矩形 public ColumnView(Context context) { super(context); } //在构造方法中传入横列的刻度值数组、竖列的刻度值数组、画笔颜色集合、柱状图高度数值数组 public ColumnView(Context context, String[] transverse, String[] vertical, List<Integer> colors, int[] high) { super(context); this.transverse = transverse; this.vertical = vertical; this.colors = colors; this.high = high; } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); init(); drawAxesLine(canvas, paintAxes); //绘制横、竖轴 drawCoordinate(canvas, paintCoordinate); //绘制坐标(文字或数值) drawColumn(canvas, paintRectF, high);//画柱形图 } //初始化数据值和画笔 public void init(){ //计算原点坐标和单位长度 xPoint = margin + marginX; yPoint = this.getHeight() - margin; xScale = (this.getWidth() - 2 * margin - marginX) / (transverse.length - 1); yScale = (this.getHeight() - 2 * margin) / (vertical.length - 1); paintAxes = new Paint(); //画轴(横轴和竖轴) paintAxes.setStyle(Paint.Style.STROKE); paintAxes.setAntiAlias(true); paintAxes.setDither(true); paintAxes.setColor(ContextCompat.getColor(getContext(), colors.get(0))); paintAxes.setStrokeWidth(1); paintCoordinate = new Paint(Paint.ANTI_ALIAS_FLAG); //画坐标(文字或数值) paintCoordinate.setColor(ContextCompat.getColor(getContext(), colors.get(1))); paintCoordinate.setTextSize(22f); paintRectF = new Paint(); //画矩形 paintRectF.setColor(ContextCompat.getColor(getContext(), colors.get(2))); paintRectF.setStyle(Paint.Style.FILL); paintRectF.setDither(true); paintRectF.setAntiAlias(true); } // 绘制坐标轴 private void drawAxesLine(Canvas canvas, Paint paint) { // 画 X 轴 canvas.drawLine(xPoint + 20, yPoint - 20, this.getWidth() - margin / 6 + 20, yPoint - 20, paint); // 画 Y 轴 canvas.drawLine(xPoint + 20, yPoint - 20, xPoint + 20, margin / 6 - 20, paint); } // 绘制坐标刻度 (可以根据自己需要进行微调) private void drawCoordinate(Canvas canvas, Paint paint) { // X轴坐标 for (int i = 0; i <= (transverse.length - 1); i++) { paint.setTextAlign(Paint.Align.CENTER); int startX = xPoint + i * xScale; canvas.drawText(transverse[i], startX - 10, this.getHeight() - margin / 6, paint); } // Y轴坐标 for (int i = 0; i <= (vertical.length - 1); i++) { paint.setTextAlign(Paint.Align.LEFT); int startY = yPoint - i * yScale; int offsetX; switch (vertical[i].length()) { case 1: offsetX = 28; break; case 2: offsetX = 20; break; case 3: offsetX = 12; break; case 4: offsetX = 5; break; default: offsetX = 0; break; } int offsetY; if (i == 0) { offsetY = 0; } else { offsetY = margin / 5; } canvas.drawText(vertical[i], margin / 4 + offsetX - 10, startY + offsetY - 5, paint); } } // 绘制单柱形 private void drawColumn(Canvas canvas, Paint paint, int data[]) { for (int i = 1; i <= (transverse.length - 1); i++) { int startX = xPoint + i * xScale; RectF rect = new RectF(startX - 20, toY(data[i - 1]), startX + 5, this.getHeight() - margin*2); canvas.drawRect(rect, paint); } } //数据按比例转换坐标(可以根据需要自己设置转换比例) private float toY(int num) { float y; try { float a = (float) num / 100.0f; y = yPoint - a * yScale; } catch (Exception e) { return 0; } return y; } }
在这个 ColumnView 类中,需要继承 View ;
在 ColumnView 的构造方法中传入绘图所需要的一些数据,包括 :
在构造方法中传入横列的刻度值数组、竖列的刻度值数组、画笔颜色集合、柱状图高度数值数组
接下来就是在 onDraw()中绘制图形了:
首先:在 init() 中初始化数值、定义画笔样式等
接下来:drawAxesLine(Canvas canvas, Paint paint) 定义画 X、Y 轴的方法
drawCoordinate(Canvas canvas, Paint paint) 画坐标(横竖的文字)
drawColumn(Canvas canvas, Paint paint, int data[])画柱状图
最后:调用这些方法
当然了,有的时候传进来的数值与画布里的数值不同,就需要用 toY() 方法 自定义的按比例转换
3、在调用的类里定义一个方法插入需要的数据以此绘图。
上面将关键的事都做完了,接下来就是调用了
import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.view.View; import android.widget.Button; import android.widget.LinearLayout; import com.win.customview.R; import java.util.ArrayList; import java.util.List; //自定义绘制柱状图 public class ColumnActivity extends AppCompatActivity { private Button start;//开始绘制 private LinearLayout column;//柱状图绘制的地方 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_column); start = (Button)findViewById(R.id.start); column = (LinearLayout) findViewById(R.id.column); start.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { //这里调用绘制方法 (也可以直接调用显示的) barChart(); } }); } // 初始化柱状图数据(可以根据自己需要插入数据) private void barChart() { //第一个为空,它需要占一个位置 String[] transverse = {"","周一","周二","周三","周四","周五","周六","周日"}; String[] vertical = {"0", "2h", "4h", "8h", "10h"}; //这里的数据是根据你横列有几个来设的,如上面的横列星期有周一到周日,所以这里设置七个数据 int[] data = {420 , 380, 340, 300, 260, 220, 180}; //这里的颜色就对应线条、文字和柱状图(可以根据自己的需要到color里设置) List<Integer> color = new ArrayList<>(); color.add(R.color.colorAccent); color.add(R.color.colorPrimary); color.add(R.color.green); column.addView(new ColumnView(this, transverse, vertical, color, data)); } }
这里可以看到,点击按钮后,主要是调用了 barChart() 方法
在这个方法中我们向 ColumnView 的构造方法中传入了四个数组,
用 addView() 方法将绘制的图形放入了 coiumn 中(上面定义的一个布局)
这样就大功告成了
提示:如果需要绘制其他的图形也可以根据这个模式一步步的添加图形,最后达到想要的效果
图形的颜色可以自己随意更改!!!
源码:https://github.com/iscopy/CustomView
在 column 包中
更多推荐
所有评论(0)