成果:无论折线图多大 放在什么位置 折线图可成比例缩放
主要思路:
- 数据处理:
根据数据数量以及布局宽度、坐标 计算点位x、y坐标间隔距离以及相应坐标 - 绘制:
在onDraw方法内进行 需要Path、Paint的对象 path负责绘制折线,Paint负责设置颜色、形状等信息
线的绘制:第一个点位需要使用path.moveTo() 后面用path.lineTo()去实现折线 最后使用canvas.drawPath()将其绘制出来
点位的绘制:直接使用canvas.drawPoint()进行绘制
package com.example.myapplication;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.DashPathEffect;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PointF;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.View;
import androidx.annotation.Nullable;
import java.util.ArrayList;
public class MyLineChartView extends View {
private double[] dataList = {120.0, 130.0, 160.0, 115.0, 180.0};
private ArrayList<PointF> xyList = new ArrayList<PointF>();
private Paint mLinePaint = new Paint();
private double minWeight = Integer.MAX_VALUE;
private double maxWeight = 0;
private Context mContext;
private double spaceX;
private int spaceY;
public MyLineChartView(Context context) {
this(context, null);
this.mContext = context;
}
public MyLineChartView(Context context, @Nullable AttributeSet attrs) {
this(context, attrs, 0);
this.mContext = context;
}
public MyLineChartView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
this.mContext = context;
int a = mContext.getResources().getDisplayMetrics().widthPixels;
// 寻找最大值与最小值
for (int i = 0; i< dataList.length; i++) {
if (dataList[i] < minWeight) {
minWeight = dataList[i];
}
if (dataList[i] > maxWeight) {
maxWeight = dataList[i];
}
}
//折线画笔
mLinePaint.setColor(Color.RED);
mLinePaint.setStrokeWidth(dp2px(5));
mLinePaint.setStyle(Paint.Style.STROKE);
mLinePaint.setAntiAlias(true);
}
@Override
protected void onDraw(Canvas canvas) {
calculationData(getLeft(), getTop(), getRight(), getBottom());
int a = getWidth();
Path path = new Path();
Paint paint= new Paint();
paint.setAntiAlias(true);//去锯齿
paint.setColor(Color.BLACK);//颜色
paint.setStrokeCap(Paint.Cap.ROUND);
paint.setStrokeWidth(40);
for (int i = 0; i < dataList.length; i++) {
if (i == 0) {
path.moveTo(xyList.get(i).x, xyList.get(i).y);
} else {
path.lineTo(xyList.get(i).x, xyList.get(i).y);
}
}
canvas.drawPath(path, mLinePaint);//折线
for (int i = 0; i < dataList.length; i++) {
canvas.drawPoint(xyList.get(i).x, xyList.get(i).y, paint);
}
}
protected float dp2px(float v) {
return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, v, getResources().getDisplayMetrics());
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
}
private void calculationData(int left, int top, int right, int bottom) {
spaceX = (right - left) / (dataList.length + 1);
spaceY = (bottom - top) / 6;
// 设定xy坐标
for (int i = 0; i< dataList.length; i++) {
PointF pointF = new PointF((int) (spaceX * ( i + 1 )), (int) ((1 - ((dataList[i] - minWeight)
/ (maxWeight - minWeight))) * (bottom - top )) );
xyList.add(pointF);
}
}
}
本文介绍了一种自定义的MyLineChartView,能够根据数据大小和屏幕布局动态缩放折线图,通过数据处理计算点位坐标并利用Path和Paint对象绘制折线及点,适用于Android应用中的数据可视化。
467

被折叠的 条评论
为什么被折叠?



