public class GeographicProfileViewV1 extends View { public Paint profilePaint,RadiusPaint; public Path profilePath; public Paint waterLinePaint; public Paint waterFillPaint; // 新增的水位填充颜色 public static final int PROFILE_COLOR = Color.parseColor("#967C57"); public static final int WATER_LINE_COLOR = Color.parseColor("#6699CC"); public static final int SEA_LEVEL_COLOR = Color.GRAY; public static final int AXIS_COLOR = Color.parseColor("#49B6FF"); public static final int AXIS_COLOR1 = Color.parseColor("#1FDCD5"); public static final int TEXT_COLOR = Color.WHITE; public int scale=20; // 在你的类中定义一个缩放因子,初始值为1.0 public float scaleFactor = 1f; // 地理数据 public double[] elevationData = {}; public double[] xData = {}; public List<Double> YList=new ArrayList<>(); public List<Double> XList=new ArrayList<>(); // 水位高度 public double waterLevel = 8; // 你可以根据需要调整水位高度 public double waveAmplitude = 2; // 水波纹振幅 public double waveFrequency = 200; // 水波纹频率 public double wavePhase = 10; // 水波纹相位 public float circleRadius = 3; // 小圆点的半径 public List<CircleModel> listCircle; public double minElevation; public double maxElevation; public float drawingHeight; public int viewWidth; public Matrix matrix = new Matrix(); public int maxLane=81; public double verticalLine=8; private int currentDataIndex = 0; private Paint axisPaint; public GeographicProfileViewV1(Context context) { super(context); init(); } public GeographicProfileViewV1(Context context, AttributeSet attrs) { super(context, attrs); init(); } public void init() { axisPaint = new Paint(); axisPaint.setColor(TEXT_COLOR); // 设置文本颜色 axisPaint.setStrokeWidth(4); // 设置文本笔触宽度 axisPaint.setTextSize(14); // 设置文本大小 XyModel xyModel = new Gson().fromJson("{\n" + " \"clist\":[\n" + " [\n" + " 0,\n" + " 12.224\n" + " ],\n" + " [\n" + " 0,\n" + " 12.224\n" + " ],\n" + " [\n" + " 0,\n" + " 12.224\n" + " ],\n" + " [\n" + " 0.77,\n" + " 12.258\n" + " ],\n" + " [\n" + " 4.78,\n" + " 9.999\n" + " ],\n" + " [\n" + " 6.79,\n" + " 9.348\n" + " ],\n" + " [\n" + " 6.79,\n" + " 9.348\n" + " ],\n" + " [\n" + " 9.59,\n" + " 9.183\n" + " ],\n" + " [\n" + " 10.75,\n" + " 8.851\n" + " ],\n" + " [\n" + " 15.64,\n" + " 8.306\n" + " ],\n" + " [\n" + " 21.61,\n" + " 7.889\n" + " ],\n" + " [\n" + " 21.61,\n" + " 7.889\n" + " ],\n" + " [\n" + " 21.61,\n" + " 7.889\n" + " ],\n" + " [\n" + " 21.61,\n" + " 7.889\n" + " ],\n" + " [\n" + " 21.61,\n" + " 7.889\n" + " ],\n" + " [\n" + " 26.98,\n" + " 7.599\n" + " ],\n" + " [\n" + " 27.78,\n" + " 7.379\n" + " ],\n" + " [\n" + " 29.02,\n" + " 7.379\n" + " ],\n" + " [\n" + " 29.37,\n" + " 7.629\n" + " ],\n" + " [\n" + " 33.38,\n" + " 7.599\n" + " ],\n" + " [\n" + " 34.07,\n" + " 7.429\n" + " ],\n" + " [\n" + " 35.07,\n" + " 7.489\n" + " ],\n" + " [\n" + " 37.13,\n" + " 7.379\n" + " ],\n" + " [\n" + " 40.54,\n" + " 7.539\n" + " ],\n" + " [\n" + " 41.21,\n" + " 7.539\n" + " ],\n" + " [\n" + " 41.47,\n" + " 7.299\n" + " ],\n" + " [\n" + " 44.09,\n" + " 7.279\n" + " ],\n" + " [\n" + " 47.03,\n" + " 7.299\n" + " ],\n" + " [\n" + " 47.2,\n" + " 7.549\n" + " ],\n" + " [\n" + " 50.38,\n" + " 7.339\n" + " ],\n" + " [\n" + " 52.62,\n" + " 6.979\n" + " ],\n" + " [\n" + " 54.47,\n" + " 7.159\n" + " ],\n" + " [\n" + " 55.01,\n" + " 7.449\n" + " ],\n" + " [\n" + " 56.1,\n" + " 7.469\n" + " ],\n" + " [\n" + " 56.64,\n" + " 7.329\n" + " ],\n" + " [\n" + " 56.88,\n" + " 7.169\n" + " ],\n" + " [\n" + " 58.64,\n" + " 7.189\n" + " ],\n" + " [\n" + " 59.26,\n" + " 7.279\n" + " ],\n" + " [\n" + " 59.51,\n" + " 7.339\n" + " ],\n" + " [\n" + " 59.78,\n" + " 7.379\n" + " ],\n" + " [\n" + " 60.27,\n" + " 7.419\n" + " ],\n" + " [\n" + " 60.6,\n" + " 7.279\n" + " ],\n" + " [\n" + " 61.74,\n" + " 7.289\n" + " ],\n" + " [\n" + " 66.35,\n" + " 7.889\n" + " ],\n" + " [\n" + " 66.35,\n" + " 7.889\n" + " ],\n" + " [\n" + " 66.35,\n" + " 7.889\n" + " ],\n" + " [\n" + " 66.35,\n" + " 7.889\n" + " ],\n" + " [\n" + " 66.35,\n" + " 7.889\n" + " ],\n" + " [\n" + " 68.32,\n" + " 8.259\n" + " ],\n" + " [\n" + " 70.17,\n" + " 8.596\n" + " ],\n" + " [\n" + " 72.28,\n" + " 9.099\n" + " ],\n" + " [\n" + " 74.21,\n" + " 9.643\n" + " ],\n" + " [\n" + " 76.06,\n" + " 10.017\n" + " ],\n" + " [\n" + " 77.61,\n" + " 10.077\n" + " ],\n" + " [\n" + " 81.11,\n" + " 10.349\n" + " ]\n" + " ],\n" + " \"plist\":[\n" + " [\n" + " 21.61,\n" + " 7.889\n" + " ],\n" + " [\n" + " 66.35,\n" + " 7.889\n" + " ],\n" + " [\n" + " 26.98,\n" + " 7.599\n" + " ],\n" + " [\n" + " 27.78,\n" + " 7.379\n" + " ],\n" + " [\n" + " 29.02,\n" + " 7.379\n" + " ],\n" + " [\n" + " 29.37,\n" + " 7.629\n" + " ],\n" + " [\n" + " 33.38,\n" + " 7.599\n" + " ],\n" + " [\n" + " 34.07,\n" + " 7.429\n" + " ],\n" + " [\n" + " 35.07,\n" + " 7.489\n" + " ],\n" + " [\n" + " 37.13,\n" + " 7.379\n" + " ],\n" + " [\n" + " 40.54,\n" + " 7.539\n" + " ],\n" + " [\n" + " 41.21,\n" + " 7.539\n" + " ],\n" + " [\n" + " 41.47,\n" + " 7.299\n" + " ],\n" + " [\n" + " 44.09,\n" + " 7.279\n" + " ],\n" + " [\n" + " 47.03,\n" + " 7.299\n" + " ],\n" + " [\n" + " 47.2,\n" + " 7.549\n" + " ],\n" + " [\n" + " 50.38,\n" + " 7.339\n" + " ],\n" + " [\n" + " 52.62,\n" + " 6.979\n" + " ],\n" + " [\n" + " 54.47,\n" + " 7.159\n" + " ],\n" + " [\n" + " 55.01,\n" + " 7.449\n" + " ],\n" + " [\n" + " 56.1,\n" + " 7.469\n" + " ],\n" + " [\n" + " 56.64,\n" + " 7.329\n" + " ],\n" + " [\n" + " 56.88,\n" + " 7.169\n" + " ],\n" + " [\n" + " 58.64,\n" + " 7.189\n" + " ],\n" + " [\n" + " 59.26,\n" + " 7.279\n" + " ],\n" + " [\n" + " 59.51,\n" + " 7.339\n" + " ],\n" + " [\n" + " 59.78,\n" + " 7.379\n" + " ],\n" + " [\n" + " 60.27,\n" + " 7.419\n" + " ],\n" + " [\n" + " 60.6,\n" + " 7.279\n" + " ],\n" + " [\n" + " 61.74,\n" + " 7.289\n" + " ]\n" + " ]\n" + "}", XyModel.class); List<List<Double>> clist = xyModel.getClist(); List<Double> list =new ArrayList<>(); list.add(90.0); list.add(0.0); clist.add(list); List<Double> list1 =new ArrayList<>(); list1.add(100.0); list1.add(15.0); clist.add(list1); for (int i = 0; i <clist.size() ; i++) { List<Double> integers = clist.get(i); Double y = integers.get(0); Double x = integers.get(1); YList.add(x); XList.add(y); } elevationData = new double[YList.size()]; for (int i = 0; i < YList.size(); i++) { elevationData[i] = YList.get(i); } xData = new double[XList.size()]; for (int i = 0; i < XList.size(); i++) { xData[i] = XList.get(i); } minElevation = Double.MAX_VALUE; maxElevation = -Double.MAX_VALUE; // 找到最小和最大高程值 for (double elevation : elevationData) { if (elevation < minElevation) { minElevation = elevation; } if (elevation > maxElevation) { maxElevation = elevation; } } drawingHeight = (float) (maxElevation - minElevation); profilePaint = new Paint(); profilePaint.setColor(PROFILE_COLOR); profilePaint.setStrokeWidth(4); profilePaint.setStyle(Paint.Style.STROKE); profilePath = new Path(); waterLinePaint = new Paint(); waterLinePaint.setColor(WATER_LINE_COLOR); // waterLinePaint.setStrokeWidth(2); waterFillPaint = new Paint(); Shader shader = new LinearGradient(10, 20, 50, 18, AXIS_COLOR1, AXIS_COLOR, Shader.TileMode.CLAMP); waterFillPaint.setShader(shader); waterFillPaint.setStyle(Paint.Style.FILL); RadiusPaint = new Paint(); RadiusPaint.setColor(AXIS_COLOR); RadiusPaint.setStrokeWidth(2); RadiusPaint.setStyle(Paint.Style.FILL); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); int viewWidth = getWidth(); int viewHeight = getHeight(); // 应用缩放变换 matrix.reset(); matrix.setScale(scaleFactor, scaleFactor); // 将缩放变换的锚点设置为左下角 matrix.postTranslate(0, viewHeight * (1 - scaleFactor)); // 将缩放变换应用到画布 canvas.concat(matrix); drawWater(canvas); drawElevationData(canvas); // 绘制海平面虚线 drawSeaLevelLine(canvas, viewWidth, viewHeight); // 在缩放后绘制内容 drawAxis(canvas, viewWidth, viewHeight); // 更新水波纹相位以实现波动效果 wavePhase += 0.1; drawCircles(canvas); getData(); // 数据发生变化后,调用 invalidate() 触发重新绘制 } private void drawWater(Canvas canvas) { int width = getWidth(); int height = getHeight(); // 计算水位线高度,加入正弦波动态效果 float waterLineY = height - (float) ((waterLevel - minElevation) * (height / drawingHeight)); waterLineY += (float) (waveAmplitude * Math.sin(2 * Math.PI * waveFrequency + wavePhase)); // 绘制水位填充颜色 canvas.drawRect(0, waterLineY, width, height, waterFillPaint); // 绘制水位线 canvas.drawLine(0, waterLineY, width, waterLineY, waterLinePaint); } private void drawElevationData(Canvas canvas) { int width = getWidth(); int height = getHeight(); float intervalX = 0; // 计算绘制的线条间隔 float screenPixelWidth = getWidth(); // 获取屏幕宽度 float xDataRange = maxLane; // x 轴数据的范围 要跟最大的距离做换算 intervalX = screenPixelWidth / xDataRange; // 计算间隔,确保 x 数据能够适应屏幕宽度 // 找到最小和最大高程值 double minElevation = Double.MAX_VALUE; double maxElevation = -Double.MAX_VALUE; for (double elevation : elevationData) { if (elevation < minElevation) { minElevation = elevation; } if (elevation > maxElevation) { maxElevation = elevation; } } // 计算绘图区域的高度 float drawingHeight = (float) maxElevation - (float) minElevation; profilePath.reset(); // 移动到起始点 profilePath.moveTo(0, height); listCircle = new ArrayList<>(); for (int i = 0; i < elevationData.length; i++) { float x = (float) (xData[i] * intervalX); float y = (float) ((elevationData[i] - minElevation) * (height / drawingHeight)); profilePath.lineTo(x, height - y); // 在每个关键点位置绘制小圆点 if (elevationData[i]<waterLevel){ listCircle.add(new CircleModel(x, height - y,false)); }else { listCircle.add(new CircleModel(x, height - y,true)); } } // 封闭路径 profilePath.lineTo(width, height); profilePath.close(); // 绘制填充颜色 profilePaint.setStyle(Paint.Style.FILL); profilePaint.setColor(PROFILE_COLOR); // 填充颜色 canvas.drawPath(profilePath, profilePaint); // 绘制地理断面线 profilePaint.setStyle(Paint.Style.STROKE); profilePaint.setColor(Color.parseColor("#494B55")); // 地理断面线颜色 canvas.drawPath(profilePath, profilePaint); // 绘制海平面线 float seaLevelY = height - (float) (minElevation - minElevation) * (height / drawingHeight); canvas.drawLine(0, seaLevelY, width, seaLevelY, waterLinePaint); } private void drawSeaLevelLine(Canvas canvas, int width, int height) { float seaLevelY = height - (float) (0 * (height / scale)); // 将海平面高程值0映射到视图高度 Paint seaLevelPaint = new Paint(); seaLevelPaint.setColor(Color.GRAY); // 设置虚线颜色 seaLevelPaint.setStyle(Paint.Style.STROKE); // 创建虚线效果 DashPathEffect dashPathEffect = new DashPathEffect(new float[]{10, 10}, 0); seaLevelPaint.setPathEffect(dashPathEffect); seaLevelPaint.setStrokeWidth(2); // 设置虚线宽度 Path seaLevelPath = new Path(); seaLevelPath.moveTo(0, seaLevelY); seaLevelPath.lineTo(width, seaLevelY); canvas.drawPath(seaLevelPath, seaLevelPaint); } private void drawAxis(Canvas canvas, int width, int height) { Paint axisPaint = new Paint(); axisPaint.setColor(TEXT_COLOR); axisPaint.setStrokeWidth(4); axisPaint.setTextSize(14); // 绘制X轴 #456079 // canvas.drawLine(0, height, width, height, axisPaint); // 绘制Y轴 canvas.drawLine(0, 0, 0, height, axisPaint); axisPaint.setColor(Color.WHITE); int myX= width/maxLane; //这里的100是揽道最大宽度 axisPaint.setTextSize(30); // for (int i = 0; i <=maxLane ; i++) { // if (i % 10 == 0) { // float x = i * width / (maxLane - 1); // canvas.drawLine(x, height, x, height - 10, axisPaint); // canvas.drawText(i+"",myX*i, height - 30, axisPaint); // } // // } // 添加Y轴刻度标注axisPaint int minY = (int) Math.floor(minElevation); int maxY = (int) Math.ceil(maxElevation); // 添加Y轴刻度标注,只绘制每隔10个刻度一个刻度文字 if (minY>0){ minY=0; } for (int i = 0; i <= maxY; i++) { if (i % 2 == 0) { float y = height - (float) ((i - minElevation) * (height / drawingHeight)); // 添加Y轴刻度文字 String label = String.valueOf(i); Double aDouble = Double.valueOf(label); if (verticalLine==aDouble){ axisPaint.setColor(Color.parseColor("#49B6FF")); }else { axisPaint.setColor(Color.parseColor("#FFFFFF")); } canvas.drawLine(5, y, 10, y, axisPaint); canvas.drawText(label, 25, y + 5, axisPaint); } } } private void drawCircles(Canvas canvas) { for (CircleModel circle : listCircle) { if (!circle.isColor()){ RadiusPaint = new Paint(); RadiusPaint.setColor(AXIS_COLOR); RadiusPaint.setStrokeWidth(2); RadiusPaint.setStyle(Paint.Style.FILL); }else { RadiusPaint = new Paint(); RadiusPaint.setColor(TEXT_COLOR); RadiusPaint.setStrokeWidth(2); RadiusPaint.setStyle(Paint.Style.FILL); } canvas.drawCircle(circle.getX(), circle.getY(), circleRadius, RadiusPaint); } } public void getData(){ // 添加Y轴刻度标注axisPaint int height = getHeight(); float y=0; y = height - (float) ((verticalLine - minElevation) * (height / drawingHeight)); setDataY.getY(minElevation,height,drawingHeight); } public setDataY setDataY; public void setSetDataY(GeographicProfileViewV1.setDataY setDataY) { this.setDataY = setDataY; } public interface setDataY{ void getY(double minElevation,int height,double drawingHeight); } }
public class HomeView extends View { private Paint profilePaint,profilePaintV1; private int maxLane=81; private float tower1X, tower1Y; // 塔1底部坐标 private float tower2X, tower2Y; // 塔2底部坐标 private float towerHeight = 80; // 塔身高度 private float towerWidth = 80; // 塔身宽度 double drawingHeight; double minElevation; int heightView; /** * 垂线 */ private List<GondolaModel> LineList=new ArrayList<>(); /** * 吊舱 */ private List<GondolaModel> ListGondola=new ArrayList<>(); /** * 维修区域 */ private List<RepairAreaModel> RepairArea=new ArrayList<>(); private Paint towerPaint; private int width; private int height; /** * 动画 */ private float currentX; private float maxX; // 最大 X 坐标值 public HomeView(Context context) { super(context); init(); } public HomeView(Context context, @Nullable AttributeSet attrs) { super(context, attrs); init(); } public HomeView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(); } private void init() { profilePaint = new Paint(); profilePaint.setColor(Color.parseColor("#6CEBA2")); profilePaint.setStrokeWidth(2); profilePaint.setStyle(Paint.Style.FILL_AND_STROKE); profilePaintV1 = new Paint(); profilePaintV1.setColor(Color.parseColor("#FFFFFF")); profilePaintV1.setStrokeWidth(2); profilePaintV1.setStyle(Paint.Style.FILL_AND_STROKE); towerPaint = new Paint(); towerPaint.setColor(Color.parseColor("#6CEBA2")); towerPaint.setStyle(Paint.Style.FILL); tower1X=150; tower1Y=600; LineList.add(new GondolaModel("垂线8m",8,10)); LineList.add(new GondolaModel("垂线12m",12,22)); ListGondola.add(new GondolaModel("1吊舱35m",10,35)); ListGondola.add(new GondolaModel("2吊舱50m",12,50)); RepairArea.add(new RepairAreaModel(5,15,25)); RepairArea.add(new RepairAreaModel(60,14,75)); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); width = getWidth(); height = getHeight(); int myX= width /maxLane; //这里的100是揽道最大宽度 profilePaint.setColor(Color.WHITE); //添加第一条揽线两边的圆 //添加第一条揽线 canvas.drawCircle(50, 10, 10, profilePaint); canvas.drawCircle(getWidth()-50, 10, 10, profilePaint); canvas.drawLine(50, 10, getWidth()-50, 10, profilePaint); profilePaint.setColor(Color.parseColor("#6BDC2E")); canvas.drawCircle(50, (getHeight()/2)/2, 10, profilePaint); canvas.drawCircle(getWidth()-50, (getHeight()/2)/2, 10, profilePaint); canvas.drawLine(50, (getHeight()/2)/2, getWidth()-50, (getHeight()/2)/2, profilePaint); profilePaintV1.setPathEffect(new DashPathEffect(new float[]{10, 10}, 0)); /** * 画垂线 */ addLine(canvas,myX); /** * 画吊舱 */ addGondola(canvas,myX); /** * 画维修发车区域 */ addMaintenance(canvas,myX); } private void addMaintenance(Canvas canvas, int myX) { for (int i = 0; i <RepairArea.size() ; i++) { RepairAreaModel repairAreaModel = RepairArea.get(i); float l = repairAreaModel.getL(); float r = repairAreaModel.getR(); float h = repairAreaModel.getH(); float cornerRadius = 15; // 圆角半径 float left1 = myX*l; float top1 = 10; float right1 = myX*r; float Myy = heightView - (float) (((h) - minElevation) * (heightView / drawingHeight)); float bottom1 =Myy+(getHeight()/2); RectF rectF = new RectF(left1, top1, right1, bottom1); Paint backgroundPaint = new Paint(); backgroundPaint.setColor(Color.parseColor("#BBBDC8FC")); // 设置背景颜色 backgroundPaint.setPathEffect(new DashPathEffect(new float[]{10, 10}, 0)); backgroundPaint.setStyle(Paint.Style.STROKE); canvas.drawRoundRect(rectF, cornerRadius, cornerRadius, backgroundPaint); float textX = (left1 + right1) / 2; backgroundPaint.setColor(Color.WHITE); backgroundPaint.setTextSize(20); backgroundPaint.setStyle(Paint.Style.FILL_AND_STROKE); canvas.drawText("发车/维护点", textX-50,bottom1-20 , backgroundPaint); } } /** * 添加吊舱 * @param canvas */ private void addGondola(Canvas canvas,int myx) { float Myy=0; Paint axisPaint = new Paint(); axisPaint.setColor(Color.WHITE); // 文本颜色 axisPaint.setTextSize(30); // 文本大小 axisPaint.setStyle(Paint.Style.FILL); // 填充样式 for (int i = 0; i <ListGondola.size() ; i++) { float x = ListGondola.get(i).getX(); float y = ListGondola.get(i).getY(); Myy = heightView - (float) (((y+1) - minElevation) * (heightView / drawingHeight)); // 计算矩形的左上角和右下角坐标 float left = myx*x; // 以X轴中心点为中心,向左偏移 45 个单位 float top =(getHeight()/2)+Myy; // 矩形顶部位置,你可以自行调整 float right = left + 45; // 以X轴中心点为中心,向右偏移 45 个单位 float bottom = top+10; // 矩形底部位置,你可以自行调整 // 创建一个Paint对象,设置矩形的颜色和样式 profilePaintV1.setPathEffect(null); // 取消虚线效果,使线条成为实线 profilePaintV1.setColor(Color.parseColor("#808080")); canvas.drawLine(left+22, (getHeight()/2)/2, left+22, top+10, profilePaintV1); Paint rectPaint = new Paint(); rectPaint.setColor(Color.parseColor("#808080")); // 设置颜色,这里使用红色 rectPaint.setStyle(Paint.Style.FILL); // 填充样式 // 绘制矩形 canvas.drawRect(left+10, top, right-10, bottom, rectPaint); canvas.drawRect(left, (getHeight()/2)/2, right, (getHeight()/2)/2+20, rectPaint); canvas.drawRect(left-20, (getHeight()/2)/2-10, right+20, (getHeight()/2)/2+10, rectPaint); rectPaint.setColor(Color.parseColor("#FFFFFF")); // 设置颜色,这里使用红色 String s = ListGondola.get(i).getName(); int x1 = (int) (myx*x); // X坐标 int y1 = ((getHeight() / 2) / 2) - 60; // Y坐标 float textWidth = axisPaint.measureText(s); // 获取文本的宽度 float padding = 10; // 背景色的填充 float cornerRadius = 15; // 圆角半径 float left1 = x1 - padding-50; float top1 = y1 - axisPaint.getTextSize() - padding; float right1 = x1 + textWidth + padding-50; float bottom1 = y1 + padding+5; RectF rectF = new RectF(left1, top1, right1, bottom1); Paint backgroundPaint = new Paint(); backgroundPaint.setColor(Color.parseColor("#383549")); // 设置背景颜色 canvas.drawRoundRect(rectF, cornerRadius, cornerRadius, backgroundPaint); canvas.drawText(s, x1-50, y1, axisPaint); } } private void addLine(Canvas canvas,int myX) { Paint axisPaint = new Paint(); axisPaint.setColor(Color.WHITE); // 文本颜色 axisPaint.setTextSize(30); // 文本大小 axisPaint.setStyle(Paint.Style.FILL); // 填充样式 for (int i = 0; i <LineList.size() ; i++) { String name = LineList.get(i).getName(); float x = LineList.get(i).getX(); float y = LineList.get(i).getY(); float Myy=0; Myy = heightView - (float) ((y - minElevation) * (heightView / drawingHeight)); profilePaintV1.setColor(Color.parseColor("#6BDC2E")); canvas.drawLine((myX*x), (getHeight()/2)/2, (myX*x), (getHeight()/2)+Myy, profilePaintV1); addCircle(canvas, myX*x); String s = LineList.get(i).getName(); int x1 = (int) (myX*x); // X坐标 int y1 = ((getHeight() / 2) / 2) - 25; // Y坐标 float textWidth = axisPaint.measureText(s); // 获取文本的宽度 float padding = 10; // 背景色的填充 float cornerRadius = 15; // 圆角半径 float left = x1 - padding-50; float top = y1 - axisPaint.getTextSize() - padding; float right = x1 + textWidth + padding-50; float bottom = y1 + padding+5; RectF rectF = new RectF(left, top, right, bottom); Paint backgroundPaint = new Paint(); backgroundPaint.setColor(Color.parseColor("#383549")); // 设置背景颜色 canvas.drawRoundRect(rectF, cornerRadius, cornerRadius, backgroundPaint); canvas.drawText(s, x1-50, y1, axisPaint); } } private void addCircle(Canvas canvas,float myX) { float centerX = (myX); int centerY = (getHeight() / 2) / 2; int radius = 10; int strokeWidth = 2; // 边框的宽度 // 绘制白色的圆(边框) Paint borderPaint = new Paint(); borderPaint.setStyle(Paint.Style.STROKE); // 设置为描边模式 borderPaint.setStrokeWidth(strokeWidth); // 设置边框宽度 borderPaint.setColor(Color.WHITE); // 设置边框颜色 canvas.drawCircle(centerX, centerY, radius, borderPaint); // 绘制黑色的圆(内部填充) Paint fillPaint = new Paint(); fillPaint.setStyle(Paint.Style.FILL); // 设置为填充模式 fillPaint.setColor(Color.BLACK); // 设置填充颜色 canvas.drawCircle(centerX, centerY, radius - strokeWidth, fillPaint); } public void setmYY(double minElevation,int height,double drawingHeight) { this.heightView=height; this.minElevation=minElevation; this.drawingHeight=drawingHeight; //y = height - (float) ((verticalLine - minElevation) * (height / drawingHeight)); invalidate(); } }
public class MyRuler extends View { private static final int AXIS_COLOR = Color.parseColor("#FFFFFF"); private int maxLane=81; public MyRuler(Context context) { super(context); init(); } private void init() { } public MyRuler(Context context, @Nullable AttributeSet attrs) { super(context, attrs); init(); } public MyRuler(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); int width = getWidth(); int height = getHeight(); Paint axisPaint = new Paint(); axisPaint.setColor(AXIS_COLOR); axisPaint.setStrokeWidth(4); axisPaint.setTextSize(20); int myX= width/maxLane; //这里的100是揽道最大宽度 canvas.drawLine(0, height, width, height, axisPaint); for (int i = 0; i <=maxLane ; i++) { if (i % 10 == 0) { float x = i * width / (maxLane - 1); canvas.drawLine(x, height, x, height - 10, axisPaint); canvas.drawText(i+"",myX*i, height - 30, axisPaint); } } } }
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout 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:background="#080229" tools:context=".MainActivity"> <LinearLayout android:layout_marginLeft="10dp" android:layout_marginRight="10dp" android:layout_alignParentBottom="true" android:orientation="vertical" android:layout_width="wrap_content" android:layout_height="wrap_content"> <RelativeLayout android:id="@+id/lane_view" android:layout_width="500dp" android:layout_height="250dp"> <ImageView android:layout_marginLeft="10dp" android:layout_marginBottom="90dp" android:layout_alignParentBottom="true" android:layout_width="wrap_content" android:layout_height="155dp" android:background="@mipmap/tashen"/> <ImageView android:layout_alignParentRight="true" android:layout_marginRight="8dp" android:layout_marginBottom="90dp" android:layout_alignParentBottom="true" android:layout_width="wrap_content" android:layout_height="155dp" android:background="@mipmap/tashen"/> <com.iec.cableway.myview.GeographicProfileViewV1 android:layout_alignParentBottom="true" android:id="@+id/geographic_profile_view" android:layout_width="500dp" android:layout_height="125dp" /> <com.iec.cableway.myview.HomeView android:id="@+id/home_view" android:layout_alignParentBottom="true" android:layout_width="500dp" android:layout_height="250dp"/> </RelativeLayout> <com.iec.cableway.myview.MyRuler android:background="#080229" android:layout_width="500dp" android:layout_height="20dp"/> </LinearLayout> </RelativeLayout>