本文转载自https://blog.csdn.net/liuwan1992/article/details/52734508
直接把完整代码发出来
values的color属性
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="colorPrimary">#008577</color>
<color name="colorPrimaryDark">#00574B</color>
<color name="colorAccent">#D81B60</color>
<color name="color1">#FFFFFF</color>
<color name="color2">#666666</color>
<color name="color3">#D0D0D0</color>
<color name="color11">#59B29C</color>
<color name="color12">#7AD6BF</color>
<color name="color13">#9BECD9</color>
<color name="color14">#D7D1D3</color>
<color name="color15">#F4E161</color>
<color name="color16">#F9974E</color>
</resources>
xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity">
<!-- 标题 -->
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/color11"
android:orientation="horizontal">
<TextView
android:id="@+id/date"
android:layout_width="match_parent"
android:layout_height="40dp"
android:background="@null"
android:gravity="center"
android:text="2016年10月4日"
android:textColor="@color/color1"
android:textSize="16sp" />
</RelativeLayout>
<!-- 柱状图1 -->
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="250dp"
android:background="@null"
android:orientation="vertical"
android:paddingEnd="15dp"
android:paddingStart="15dp">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@null">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="40dp"
android:background="@null"
android:gravity="center"
android:orientation="horizontal">
<ImageView
android:layout_width="20dp"
android:layout_height="20dp"
android:adjustViewBounds="true"
android:scaleType="fitXY"
android:src="@drawable/electric_category" />
<TextView
android:layout_width="wrap_content"
android:layout_height="20dp"
android:layout_marginStart="10dp"
android:gravity="center"
android:text="单柱状图"
android:textColor="@color/color2"
android:textSize="13sp" />
</LinearLayout>
</RelativeLayout>
<LinearLayout
android:id="@+id/customBarChart1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginBottom="10dp"
android:layout_marginTop="40dp"
android:gravity="center"
android:orientation="vertical">
</LinearLayout>
</RelativeLayout>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="@color/color3" />
<!-- 柱状图2 -->
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="250dp"
android:background="@null"
android:orientation="vertical"
android:paddingEnd="15dp"
android:paddingStart="15dp">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@null">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="40dp"
android:layout_marginStart="10dp"
android:baselineAligned="true"
android:gravity="center_vertical"
android:orientation="horizontal">
<TextView
android:layout_width="10dp"
android:layout_height="10dp"
android:background="@color/color14" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="3dp"
android:text="去年"
android:textColor="@color/color2"
android:textSize="12sp" />
<TextView
android:layout_width="10dp"
android:layout_height="10dp"
android:layout_marginStart="10dp"
android:background="@color/color15" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="3dp"
android:text="今年"
android:textColor="@color/color2"
android:textSize="12sp" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="40dp"
android:background="@null"
android:gravity="center"
android:orientation="horizontal">
<ImageView
android:layout_width="20dp"
android:layout_height="20dp"
android:adjustViewBounds="true"
android:scaleType="fitXY"
android:src="@drawable/electric_category" />
<TextView
android:layout_width="wrap_content"
android:layout_height="20dp"
android:layout_marginStart="10dp"
android:gravity="center"
android:text="双柱状图"
android:textColor="@color/color2"
android:textSize="13sp" />
</LinearLayout>
</RelativeLayout>
<LinearLayout
android:id="@+id/customBarChart2"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginBottom="10dp"
android:layout_marginTop="40dp"
android:gravity="center"
android:orientation="vertical">
</LinearLayout>
</RelativeLayout>
</LinearLayout>
自定义柱形图的控件
package com.bwie.administrator.histogram.weight;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.RectF;
import android.support.v4.content.ContextCompat;
import android.util.AttributeSet;
import android.view.View;
import com.bwie.administrator.histogram.R;
import java.util.ArrayList;
import java.util.List;
public class MyView extends View {
//坐标单位
private String[] xLabel;
private String[] yLabel;
//曲线数据
private List<int[]> dataList;
private List<Integer> colorList;
//默认边距
private int margin = 20;
//距离左边的偏移量
private int xmargin = 30;
//原点坐标
private int xPoint;
private int yPoint;
//x与y轴的单位长度
private int xScale;
private int yScale;
//创建画笔 paintAxes:画笔轴
private Paint paintAxes;
//paintCoordinate:画笔坐标
private Paint paintCoordinate;
//paintRectF :画矩形
private Paint paintRectF;
//paintValue :画笔值
private Paint paintValue;
public MyView(Context context, String[] xLabel, String[] yLabel,
List<int[]> dataList, List<Integer> colorList) {
super(context);
this.xLabel = xLabel;
this.yLabel = yLabel;
this.dataList = dataList;
this.colorList = colorList;
}
public MyView(Context context) {
super(context);
}
//初始化数据值和画笔
private void init() {
//原点坐标 y的值 获取高度,然后减掉默认的边距
xPoint = margin + xmargin;
yPoint = this.getHeight() - margin;
//获取x与y的值
xScale = (this.getWidth() - 2 * margin - xmargin) / (xLabel.length - 1);
yScale = (this.getHeight() - 2 * margin) / (yLabel.length - 1);
//画笔轴 STROKE:笔画 setAntiAlias:设置画笔锯齿效果
//setDither设置抖动 setStrokeWidth:设置空心边框的宽度 FILL:装满
paintAxes = new Paint();
paintAxes.setStyle(Paint.Style.STROKE);
paintAxes.setAntiAlias(true);
paintAxes.setDither(true);
paintAxes.setColor(ContextCompat.getColor(getContext(), R.color.colorPrimary));
paintAxes.setStrokeWidth(4);
//画笔坐标设置
paintCoordinate = new Paint();
paintCoordinate.setStyle(Paint.Style.STROKE);
paintCoordinate.setAntiAlias(true);
paintCoordinate.setDither(true);
paintCoordinate.setColor(ContextCompat.getColor(getContext(), R.color.colorPrimary));
paintCoordinate.setTextSize(15);
//设置画笔值
paintRectF = new Paint();
paintRectF.setStyle(Paint.Style.FILL);
paintRectF.setAntiAlias(true);
paintRectF.setDither(true);
paintRectF.setStrokeWidth(1);
//设置画笔值
paintValue = new Paint();
paintValue.setStyle(Paint.Style.STROKE);
paintValue.setDither(true);
paintValue.setAntiAlias(true);
paintValue.setTextAlign(Paint.Align.CENTER);
paintValue.setTextSize(10);
}
@Override
protected void onDraw(Canvas canvas) {
canvas.drawColor(ContextCompat.getColor(getContext(), R.color.colorAccent));
//初始化数据
init();
drawAxesLine(canvas, paintAxes);
drawCoordinate(canvas, paintCoordinate);
//进行判断
if (dataList.size() == 1) {
drawBar(canvas, paintRectF, dataList.get(0), colorList);
drawValue(canvas, paintValue, dataList.get(0), colorList.get(2));
} else if (dataList.size() == 2) {
drawBars(canvas, paintRectF, dataList, colorList);
drawValues(canvas, paintValue, dataList, colorList.get(2));
}
}
private void drawValue(Canvas canvas, Paint paint, int data[], Integer color) {
paint.setColor(ContextCompat.getColor(getContext(), color));
for (int i = 1; i <= (xLabel.length - 1); i++) {
canvas.drawText(data[i - 1] + "w", xPoint + i * xScale, toY(data[i - 1]) - 5, paintValue);
}
}
//绘制单柱形
private void drawBar(Canvas canvas, Paint paint, int data[], List<Integer> colorList) {
for (int i = 1; i <= (xLabel.length - 1); i++) {
int startX = xPoint + i * xScale;
RectF rect = new RectF(startX - 5, toY(data[i - 1]), startX + 5, this.getHeight() - margin - 2);
if (i % 2 == 1) {
paint.setColor(ContextCompat.getColor(getContext(), colorList.get(0)));
} else {
paint.setColor(ContextCompat.getColor(getContext(), colorList.get(1)));
}
canvas.drawRect(rect, paint);
}
}
//绘制双柱形
private void drawBars(Canvas canvas, Paint paint, List<int[]> dataList, List<Integer> colorList) {
for (int i = 1; i <= (xLabel.length - 1); i++) {
int startX = xPoint + i * xScale;
paint.setColor(ContextCompat.getColor(getContext(), colorList.get(0)));
RectF rect1 = new RectF(startX - 20, toY(dataList.get(0)[i - 1]), startX - 10,
this.getHeight() - margin - 2);
canvas.drawRect(rect1, paint);
paint.setColor(ContextCompat.getColor(getContext(), colorList.get(1)));
RectF rect2 = new RectF(startX - 5, toY(dataList.get(1)[i - 1]), startX + 5,
this.getHeight() - margin - 2);
canvas.drawRect(rect2, 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;
}
//绘制刻度
private void drawCoordinate(Canvas canvas, Paint paint) {
//x坐标轴
for (int i = 0; i <= (xLabel.length - 1); i++) {
paint.setTextAlign(Paint.Align.CENTER);
int startX = xPoint + i * xScale;
canvas.drawText(xLabel[i], startX, this.getHeight() - margin / 6, paint);
}
//y坐标轴
for (int i = 0; i <= (yLabel.length - 1); i++) {
paint.setTextAlign(Paint.Align.LEFT);
int startY = yPoint - i * yScale;
int offsetX;
switch (yLabel[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(yLabel[i], margin / 4 + offsetX, startY + offsetY, paint);
}
}
//绘制坐标轴
private void drawAxesLine(Canvas canvas, Paint paint) {
//定义x坐标轴
canvas.drawLine(xPoint, yPoint, this.getWidth() - margin / 6, yPoint, paint);
canvas.drawLine(this.getWidth() - margin / 6, yPoint, this.getWidth() - margin / 2, yPoint - margin / 3, paint);
canvas.drawLine(this.getWidth() - margin / 6, yPoint, this.getWidth() - margin / 2, yPoint + margin / 3, paint);
//定义y坐标轴
canvas.drawLine(xPoint, yPoint, xPoint, margin / 6, paint);
canvas.drawLine(xPoint, margin / 6, xPoint - margin / 3, margin / 2, paint);
canvas.drawLine(xPoint, margin / 6, xPoint + margin / 3, margin / 2, paint);
}
private void drawValues(Canvas canvas, Paint paint, List<int[]> dataList, Integer color) {
paint.setColor(ContextCompat.getColor(getContext(), color));
for (int i = 1; i <= (xLabel.length - 1); i++) {
int startX = xPoint + i * xScale;
int offsetY1 = 5;
int offsetY2 = 5;
if (dataList.get(0)[i - 1] == dataList.get(1)[i - 1]) {
offsetY2 += 10;
}
if (i > 1) {
if ((dataList.get(1)[i - 2] == dataList.get(0)[i - 1])) {
offsetY1 += 10;
}
}
canvas.drawText(dataList.get(0)[i - 1] + "w", startX - 18,
toY(dataList.get(0)[i - 1]) - offsetY1, paintValue);
canvas.drawText(dataList.get(1)[i - 1] + "w", startX + 3,
toY(dataList.get(1)[i - 1]) - offsetY2, paintValue);
}
}
}
最后附上调用方法
package com.bwie.administrator.histogram;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.LinearLayout;
import com.bwie.administrator.histogram.weight.MyView;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity {
private LinearLayout customBarChart1, customBarChart2;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
customBarChart1 = (LinearLayout) findViewById(R.id.customBarChart1);
initBarChart1();
customBarChart2 = (LinearLayout) findViewById(R.id.customBarChart2);
initBarChart2();
}
private void initBarChart2() {
String[] xLabel = {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12"};
String[] yLabel = {"0", "100", "200", "300", "400", "500", "600", "700", "800", "900"};
int[] data1 = {300, 500, 550, 500, 300, 700, 800, 750, 550, 600, 400, 300};
int[] data2 = {400, 600, 500, 700, 300, 500, 550, 500, 300, 700, 800, 750};
List<int[]> data = new ArrayList<>();
data.add(data1);
data.add(data2);
List<Integer> color = new ArrayList<>();
color.add(R.color.color14);
color.add(R.color.color15);
color.add(R.color.color11);
customBarChart2.addView(new MyView(this, xLabel, yLabel, data, color));
}
private void initBarChart1() {
String[] xLabel = {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13",
"14", "15", "16", "17", "18", "19", "20", "21", "22", "23", "24", "25", "26", "27",
"28", "29", "30", "31"};
String[] yLabel = {"0", "100", "200", "300", "400", "500", "600", "700", "800", "900"};
int[] data1 = {300, 500, 550, 500, 300, 700, 800, 750, 550, 600, 400, 300, 400, 600, 500,
700, 300, 500, 550, 500, 300, 700, 800, 750, 550, 600, 400, 300, 400, 600, 500};
List<int[]> data = new ArrayList<>();
data.add(data1);
List<Integer> color = new ArrayList<>();
color.add(R.color.color12);
color.add(R.color.color13);
color.add(R.color.color16);
customBarChart1.addView(new MyView(this, xLabel, yLabel, data, color));
}
}
作者对于自定义里面的部分属性有详细详解,不明白的可以去原博客寻找
以上;