您的位置:首页 > 移动开发 > Android开发

android自定义View,实现折线图(二)

2016-05-18 18:20 459 查看
效果图:



LineChartView类:

public class LineChartView extends View {

private int width;
private int height;
private float maxValue;//传入数据的最大值
private int dataNum;//数据总数

private Paint mPaintBg;//报表背景画笔
private Paint mPaintCoveredBg;//用于画数据覆盖部分
private Paint mPaintChartLine;//用于画报表的网格
private Paint mPaintDataLine;//用于画数据连线
private Paint mPaintTextDate;//用于画日期文本
private Paint mPaintCircle;//用于画空心圆
private Paint mPaintFilledCircle;//用于画实心圆
private Paint mPaintTextValue;//用于画数据访问量值

private Path path;

private HashMap<Integer, PageViewData> dataTotal;//用于得存储传入的总数据
private float mRange[]=new float[3];

//传三个数值范围
public void setRange(float[] range) {
mRange = range;
}

//用一个setPaints()方法,设定所有画笔的属性,增加代码灵活性
public void setPaints(int bgColor, int coveredBgColor, int chartLineColor
, int dataLineColor, int textDateColor, int filledCircleColor, int circleColor, int textValueColor) {

mPaintBg.setColor(bgColor);
mPaintBg.setStyle(Paint.Style.FILL);

mPaintCoveredBg.setColor(coveredBgColor);
mPaintCoveredBg.setStyle(Paint.Style.FILL);

mPaintCircle.setColor(circleColor);
mPaintCircle.setStyle(Paint.Style.STROKE);
mPaintCircle.setStrokeWidth(5);
mPaintCircle.setAntiAlias(true);

mPaintFilledCircle.setColor(filledCircleColor);
mPaintFilledCircle.setStyle(Paint.Style.FILL);
mPaintFilledCircle.setAntiAlias(true);

mPaintChartLine.setColor(chartLineColor);
mPaintChartLine.setStyle(Paint.Style.STROKE);
mPaintChartLine.setAntiAlias(true);

mPaintDataLine.setColor(dataLineColor);
mPaintDataLine.setStyle(Paint.Style.STROKE);
mPaintDataLine.setStrokeWidth(SizeConvert.dip2px(getContext(), 5));
mPaintDataLine.setAntiAlias(true);

mPaintTextDate.setColor(textDateColor);
mPaintTextDate.setTextSize(SizeConvert.dip2px(getContext(), 10));
mPaintTextDate.setTextAlign(Paint.Align.CENTER);
mPaintTextDate.setAntiAlias(true);

mPaintTextValue.setColor(textValueColor);
mPaintTextValue.setTextSize(SizeConvert.dip2px(getContext(), 12));
mPaintTextValue.setTextAlign(Paint.Align.CENTER);
mPaintTextValue.setAntiAlias(true);

//重绘
invalidate();
}

//用于设定传入的总数据
public void setDataTotal(HashMap<Integer, PageViewData> dataTotal) {
this.dataTotal = dataTotal;
invalidate();
}

public LineChartView(Context context) {
super(context);
}

public LineChartView(Context context, AttributeSet attrs) {
super(context, attrs);
mPaintBg = new Paint();
mPaintCoveredBg = new Paint();
mPaintCircle = new Paint();
mPaintChartLine = new Paint();
mPaintDataLine = new Paint();
mPaintTextDate = new Paint();
mPaintTextValue = new Paint();
mPaintFilledCircle = new Paint();
path = new Path();

dataTotal = new HashMap<>();
}

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
//当总数据已经传入,即不为空时,根据总数据中数据个数设定view的总宽
if (dataTotal != null) {
width = (dataTotal.size() - 1) * xAddedNum + chartMarginHorizontal * 2;
getMaxValue(dataTotal);
}
height = getDefaultSize(getSuggestedMinimumHeight(), heightMeasureSpec);
setMeasuredDimension(width, height);
}

/**
*   * 用于得到总数据中最大数据
* @param dataTotal 总数据
*/

private void getMaxValue(HashMap<Integer, PageViewData> dataTotal) {
maxValue = 0;
dataNum = 0;
for (int key : dataTotal.keySet()) {
if (dataTotal.get(key).getPageViewValue() > maxValue) {
maxValue = dataTotal.get(key).getPageViewValue();
}
dataNum++;
}
}

private int mChartHeight;//折线图的高
private int mChartWidth;//折线图的
private int startX = SizeConvert.dip2px(getContext(), 10);//开始绘制的x坐标
private int startY = SizeConvert.dip2px(getContext(), 5);//开始绘制的y坐标
private int chartMarginBottom = SizeConvert.dip2px(getContext(), 30);//折线图距离父控件底部距离
private int chartMarginHorizontal = SizeConvert.dip2px(getContext(), 12);//折线图距离父控件左右的距离
private int valueAlignLeft = SizeConvert.dip2px(getContext(), 0);//value参数文本距离左边距离
private int dateAlignLeft = SizeConvert.dip2px(getContext(), 0);//date参数文本距离左边距离
private int valueAlignBottom = SizeConvert.dip2px(getContext(), 5);//value参数文本距离底部距离
private int dateAlignBottom = SizeConvert.dip2px(getContext(), 10);//date参数文本距离底部距离
private int xAddedNum = SizeConvert.dip2px(getContext(), 60);//绘制折线图时每次移动的x轴距离
private int yAddedNum;//绘制折线图时每次移动的y轴距离
private boolean isDrawFirst;//是否是第一次绘制
private float circleFilledRadius = SizeConvert.dip2px(getContext(), 5);//外圆半径
private float circleRadius = SizeConvert.dip2px(getContext(), 3);//内圆半径

private float firstX;//第一个点的x轴坐标
private float firstY;//第一个点的y轴坐标

@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
isDrawFirst = true;
mChartHeight = height - chartMarginBottom;
yAddedNum = mChartHeight / 4;
mChartWidth = width - chartMarginHorizontal * 2;

canvas.drawRect(startX, startY, startX + mChartWidth, startY + mChartHeight, mPaintBg);
for (int key : dataTotal.keySet()) {
float value = dataTotal.get(key).getPageViewValue();
if (isDrawFirst) {
//当第一次绘制时得到第一个点的横纵坐标
firstX = startX;
firstY = startY + (1f - value / ((int) maxValue * 1.5f)) * mChartHeight;
path.moveTo(firstX, firstY);
isDrawFirst = false;
}
//每循环一次,将path线性相位一次
path.lineTo(startX, startY + (1f - value / ((int) maxValue * 1.5f)) * mChartHeight);
startX += xAddedNum;
}
//重新给startX赋值
startX = SizeConvert.dip2px(getContext(), 10);
//画出折线
canvas.drawPath(path, mPaintDataLine);
//画出折线以下部分的颜色
path.lineTo(startX + mChartWidth, startY + mChartHeight);
path.lineTo(startX, startY + mChartHeight);
path.lineTo(firstX, firstY);
canvas.drawPath(path, mPaintCoveredBg);

//画出每个点的圆圈,和对应的文本
for (int key : dataTotal.keySet()) {
String date = dataTotal.get(key).getDate();
float value = dataTotal.get(key).getPageViewValue();

if(value <= mRange[0]){
mPaintCircle.setColor(Color.parseColor("#FF0000"));
}else if(value >= mRange[2]) {
mPaintCircle.setColor(Color.parseColor("#FBAD5F"));
}else{
mPaintCircle.setColor(Color.parseColor("#C8E1A8"));
}
canvas.drawCircle(startX, startY + (1f - value / ((int) maxValue * 1.5f)) * mChartHeight, circleFilledRadius, mPaintFilledCircle);
canvas.drawCircle(startX, startY + (1f - value / ((int) maxValue * 1.5f)) * mChartHeight, circleRadius, mPaintCircle);
canvas.drawText(date + "", startX + dateAlignLeft, height - dateAlignBottom, mPaintTextDate);
canvas.drawText(value + "", startX + valueAlignLeft, startY + (1f - value / ((int) maxValue * 1.5f)) * mChartHeight - valueAlignBottom, mPaintTextValue);

startX += xAddedNum;
}

//在次使startX回到初始值
startX = SizeConvert.dip2px(getContext(), 10);

/**
* 画出网格
*/

//竖线
for (int i = 0; i < dataNum; i++) {
canvas.drawLine(startX + i * xAddedNum, startY, startX + i * xAddedNum, startY + mChartHeight, mPaintChartLine);
}

//横线
for (int i = 0; i < 5; i++) {
canvas.drawLine(startX, startY + i * yAddedNum, startX + mChartWidth, startY + i * yAddedNum, mPaintChartLine);
}

path.reset();

}
}


xml文件:

<HorizontalScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scrollbars="none">
<com.xx.xx.LineChartView
android:id="@+id/line_chart_view_item"
android:layout_width="wrap_content"
android:layout_height="160dp"/>
</HorizontalScrollView>


MainActivity:

public class MainActivity extends Activity {
private LineChartView mLineChartView;
private HashMap<Integer,PageViewData> mDataPageView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mLineChartView = (LineChartView) findViewById(R.id.line_chart_view_item);
initDataPageView();
}
private void initDataPageView() {
mDataPageView = new HashMap<>();
mDataPageView.put(1,new PageViewData(1,"5/1",4.0f));
mDataPageView.put(2,new PageViewData(2,"5/2",8.5f));
mDataPageView.put(3,new PageViewData(3,"5/3",5.4f));
mDataPageView.put(4,new PageViewData(4,"5/4",4.6f));
mDataPageView.put(5,new PageViewData(5,"5/5",6.2f));
mDataPageView.put(6,new PageViewData(6,"5/6",4.2f));
mDataPageView.put(7,new PageViewData(7,"5/7",10.4f));
mDataPageView.put(8,new PageViewData(8,"5/8",4.4f));
mDataPageView.put(9,new PageViewData(9,"5/9",5.5f));
mDataPageView.put(10,new PageViewData(10,"5/10",6.0f));
mDataPageView.put(11,new PageViewData(11,"5/11",5.4f));
mDataPageView.put(12,new PageViewData(12,"5/12",3.9f));
mDataPageView.put(13,new PageViewData(13,"5/13",4.2f));
mDataPageView.put(14,new PageViewData(14,"5/14",8.0f));
mDataPageView.put(15,new PageViewData(15,"5/15",11.4f));
mLineChartView.setDataTotal(mDataPageView);
mLineChartView.setRange(new float[]{4.4f,7f,10f});//范围
mLineChartView.setPaints(Color.argb(255,225, 250, 250),
Color.argb(255,234, 234, 250), Color.argb(255,74,208, 204),
Color.argb(255,105, 210, 249),Color.argb(255,203, 203, 203)
,Color.argb(255,255, 255, 255),Color.argb(255,105, 210, 249),Color.argb(255,105, 210, 249));
}


下载资源传送门入口:

点击打开链接
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: