广告
返回顶部
首页 > 资讯 > 移动开发 >android绘制曲线和折线图的方法
  • 828
分享到

android绘制曲线和折线图的方法

2024-04-02 19:04:59 828人浏览 薄情痞子
摘要

本文实例为大家分享了Android绘制曲线和折线图的具体代码,供大家参考,具体内容如下 (曲线)  (折线) 1.CurveView.java package com.

本文实例为大家分享了Android绘制曲线和折线图的具体代码,供大家参考,具体内容如下

(曲线)

 (折线)

1.CurveView.java

package com.package;
 
import android.content.Context;
import android.graphics.canvas;
import android.graphics.Color;
import android.graphics.LinearGradient;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Point;
import android.graphics.PointF;
import android.graphics.Rect;
import android.graphics.Shader;
import android.util.AttributeSet;
import android.util.Pair;
import android.util.TypedValue;
import android.view.View;
import android.view.WindowManager;
 
import androidx.annotation.Nullable;
 
import java.util.ArrayList;
import java.util.List;
 
public class CurveView extends View {
    private Paint mBrokenLinePaint;
    private Paint mInCirclePaint;
    private Paint mFillCirclePaint;
    private Paint mOutCirclePaint;
    private Paint mBottomLinePaint;
    private Paint mXTextPaint;
    private Paint mYLinePaint;
    private Paint mYTextPaint;
    private boolean isCurve;
    
    private int mLength = 7;
    
    private final int mScreenWidth = getScreenWidth(getContext());
    
    private int cScreenWidth = getScreenWidth(getContext());
    
    private final int mHeight = getScreenHeight(getContext()) - dp2px(getContext(), 190);
    
    private final int outRadius = dp2px(getContext(), 6);
    
    private final int inRadius = dp2px(getContext(), 3);
    
    private final float mSideLength = dp2px(getContext(), 20);
    
    private final int mXTextHeight = dp2px(getContext(), 30);
 
    
    private final int mPaddingTop = dp2px(getContext(), 10);
 
    
    private int mSpaceLength;
    
    private final List<Pair<String, Float>> dataValue = new ArrayList<>();
    
    private final List<Pair<Float, Float>> nodeValue = new ArrayList<>();
    
    private final List<String> yValue = new ArrayList<>();
    private Paint mShadowPaint;
 
    public CurveView(Context context) {
        this(context, null);
    }
 
    public CurveView(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }
 
    public CurveView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }
 
    
    public static int dp2px(Context context, float dp) {
        float px = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, context.getResources().getDisplayMetrics());
        return Math.round(px);
    }
 
    
    public static int getScreenWidth(Context context) {
        WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
        Point size = new Point();
        wm.getDefaultDisplay().getSize(size);
        return size.x;
    }
 
    
    public void setContentWidth(int size) {
        mLength = size + 1;
        cScreenWidth = (mScreenWidth / 7) * size;
    }
 
    
    public static int getScreenHeight(Context context) {
        WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
        Point size = new Point();
        wm.getDefaultDisplay().getSize(size);
        return size.y;
    }
 
    
    public void setData(List<String> xAxis, List<String> yAxis) {
        dataValue.clear();
        yValue.clear();
        float yHeight = mHeight - mXTextHeight;
        for (int i = 0; i < xAxis.size(); i++) {
            yValue.add(yAxis.get(i));
            float value = Float.parseFloat(yAxis.get(i));
            dataValue.add(new Pair<>(xAxis.get(i), (yHeight - value / 200f * yHeight)));
        }
        invalidate();
        requestLayout();
    }
 
    private void init() {
        getSpaceLength();//获取间隔距离
        initYLine();//初始化竖直方向的线条
        initBottomLine();//初始化底部横线paint
        initInCircle();//初始化节点内圆
        initBrokenLine();//初始化曲线、折线
        initXtext();//初始化X轴标签
        initYtext();//初始化Y轴上数值
        initShadowPaint();//初始化阴影
    }
 
    
    private void getSpaceLength() {
        mSpaceLength = (int) (mScreenWidth - mSideLength * 2) / (mLength - 1);
    }
 
    
    private void initYLine() {
        mYLinePaint = new Paint();
        mYLinePaint.setColor(Color.GRAY);
        mYLinePaint.setStrokeWidth(1);
        mYLinePaint.setStyle(Paint.Style.STROKE);
        mYLinePaint.setAntiAlias(true);
    }
 
    
    private void initBottomLine() {
        mBottomLinePaint = new Paint();
        mBottomLinePaint.setColor(Color.GRAY);
        mBottomLinePaint.setStrokeWidth(dp2px(getContext(), 0.5f));
        mBottomLinePaint.setStyle(Paint.Style.STROKE);
        mBottomLinePaint.setAntiAlias(true);
    }
 
    
    private void initXtext() {
        mXTextPaint = new Paint();
        mXTextPaint.setColor(Color.GRAY);
        mXTextPaint.setTextSize(dp2px(getContext(), 12));
        mXTextPaint.setStyle(Paint.Style.FILL);
        mXTextPaint.setAntiAlias(true);
    }
 
    
    private void initYtext() {
        mYTextPaint = new Paint();
        mYTextPaint.setColor(Color.GRAY);
        mYTextPaint.setTextSize(dp2px(getContext(), 12));
        mYTextPaint.setStyle(Paint.Style.FILL);
        mYTextPaint.setAntiAlias(true);
    }
 
    
    private void initInCircle() {
        //初始化外圆
        mOutCirclePaint = new Paint();
        mOutCirclePaint.setColor(Color.GREEN);
        mOutCirclePaint.setStyle(Paint.Style.FILL);
        mOutCirclePaint.setAntiAlias(true);
        //内框
        mInCirclePaint = new Paint();
        mInCirclePaint.setColor(Color.GRAY);
        mInCirclePaint.setStyle(Paint.Style.STROKE);
        mInCirclePaint.setStrokeWidth(dp2px(getContext(), 2));
        mInCirclePaint.setAntiAlias(true);
        //内圆
        mFillCirclePaint = new Paint();
        mFillCirclePaint.setColor(Color.GRAY);
        mFillCirclePaint.setStyle(Paint.Style.FILL);
        mFillCirclePaint.setAntiAlias(true);
    }
 
    
    private void initBrokenLine() {
        mBrokenLinePaint = new Paint();//折线
        mBrokenLinePaint.setColor(Color.GRAY);
        mBrokenLinePaint.setStrokeWidth(dp2px(getContext(), 2f));
        mBrokenLinePaint.setStyle(Paint.Style.STROKE);
        mBrokenLinePaint.setStrokeCap(Paint.Cap.ROUND);
        mBrokenLinePaint.setAntiAlias(true);
    }
 
    
    private void initShadowPaint() {
        mShadowPaint = new Paint();
        mShadowPaint.setStyle(Paint.Style.FILL);
        mShadowPaint.setAntiAlias(true);
        Shader shader = new LinearGradient(getWidth() / 2f, getHeight(), getWidth() / 2f, 0,
                Color.parseColor("#3300FF00"), Color.parseColor("#3300FF00"), Shader.TileMode.MIRROR);
        mShadowPaint.setShader(shader);
    }
 
    
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        drawYLine(canvas);
        // 绘制底部的X轴线
        drawBottomLine(canvas);
        // 绘制节点和折线图
        drawCircleLine(canvas);
        // 绘制Y轴上的数据和背景
        drawYtext(canvas);
        // 绘制X轴标签文字
        drawBottomText(canvas);
        //阴影
        drawShadow(canvas);
    }
 
    
    private void drawYLine(Canvas canvas) {
        for (int i = 0; i < dataValue.size(); i++) {
            canvas.drawLine(mSideLength + mSpaceLength * i, mPaddingTop, mSideLength + mSpaceLength * i, mHeight - mXTextHeight, mYLinePaint);
        }
    }
 
    
    private void drawCircleLine(Canvas canvas) {
        nodeValue.clear();
        for (int i = 0; i < dataValue.size(); i++) {
            Pair<String, Float> pair = dataValue.get(i);
            // 绘制节点外圆
            canvas.drawCircle(mSideLength + mSpaceLength * i, pair.second, outRadius, mOutCirclePaint);
            // 绘制节点内框
            canvas.drawCircle(mSideLength + mSpaceLength * i, pair.second, inRadius, mFillCirclePaint);
            // 绘制节点内圆
            canvas.drawCircle(mSideLength + mSpaceLength * i, pair.second, inRadius, mInCirclePaint);
            // 保存圆心坐标
            Pair<Float, Float> pairs = new Pair<>(mSideLength + mSpaceLength * i, pair.second);
            nodeValue.add(pairs);
        }
        drawScrollLine(canvas);//曲线
        // drawLine(canvas);//折线
    }
 
    
    private void drawScrollLine(Canvas canvas) {
        isCurve = true;
        PointF pStart, pEnd;
        List<PointF> points = getPoints();
        Path path = new Path();
        for (int i = 0; i < points.size() - 1; i++) {
            pStart = points.get(i);
            pEnd = points.get(i + 1);
            PointF point3 = new PointF();
            PointF point4 = new PointF();
            float wd = (pStart.x + pEnd.x) / 2;
            point3.x = wd;
            point3.y = pStart.y;
            point4.x = wd;
            point4.y = pEnd.y;
            path.moveTo(pStart.x, pStart.y);
            path.cubicTo(point3.x, point3.y, point4.x, point4.y, pEnd.x, pEnd.y);
            canvas.drawPath(path, mBrokenLinePaint);
        }
    }
 
    
    private void drawLine(Canvas canvas) {
        isCurve = false;
        for (int i = 0; i < nodeValue.size(); i++) {
            if (i != nodeValue.size() - 1) {
                canvas.drawLine((float) nodeValue.get(i).first,
                        (float) nodeValue.get(i).second,
                        (float) nodeValue.get(i + 1).first,
                        (float) nodeValue.get(i + 1).second, mBrokenLinePaint);
            }
        }
    }
 
    
    private void drawShadow(Canvas canvas) {
        List<PointF> points = getPoints();
        if (isCurve) {//曲线
            PointF pStart, pEnd;
            Path path = new Path();
            for (int i = 0; i < points.size() - 1; i++) {
                pStart = points.get(i);
                pEnd = points.get(i + 1);
                PointF point3 = new PointF();
                PointF point4 = new PointF();
                float wd = (pStart.x + pEnd.x) / 2;
                point3.x = wd;
                point3.y = pStart.y;
                point4.x = wd;
                point4.y = pEnd.y;
                path.moveTo(pStart.x, pStart.y);
                path.cubicTo(point3.x, point3.y, point4.x, point4.y, pEnd.x, pEnd.y);
                //减去文字和指示标的高度
                path.lineTo(pEnd.x, getHeight() - mXTextHeight);
                path.lineTo(pStart.x, getHeight() - mXTextHeight);
            }
            path.close();
            canvas.drawPath(path, mShadowPaint);
        } else {
            Path path = new Path();
            path.moveTo(points.get(0).x, points.get(0).y);
            for (int i = 1; i < points.size(); i++) {
                path.lineTo(points.get(i).x, points.get(i).y);
            }
            //链接最后两个点
            int index = points.size() - 1;
            path.lineTo(points.get(index).x, getHeight() - mXTextHeight);
            path.lineTo(points.get(0).x, getHeight() - mXTextHeight);
            path.close();
            canvas.drawPath(path, mShadowPaint);
        }
    }
 
    
    private List<PointF> getPoints() {
        ArrayList<PointF> points = new ArrayList<>();
        for (Pair<Float, Float> pair : nodeValue) {
            points.add(new PointF((float) pair.first, (float) pair.second));
        }
        return points;
    }
 
    
    private void drawBottomLine(Canvas canvas) {
        canvas.drawLine(0, mHeight - mXTextHeight, cScreenWidth, mHeight - mXTextHeight, mBottomLinePaint);
    }
 
    
    private void drawBottomText(Canvas canvas) {
        for (int i = 0; i < dataValue.size(); i++) {
            String xValue = dataValue.get(i).first;
            // 获取Text内容宽度
            Rect bounds = new Rect();
            mXTextPaint.getTextBounds(xValue, 0, xValue.length(), bounds);
            int width = bounds.right - bounds.left;
            canvas.drawText(xValue, mSideLength - width / 2f + mSpaceLength * i, mHeight - mXTextHeight / 2f, mXTextPaint);
        }
    }
 
    
    private void drawYtext(Canvas canvas) {
        for (int i = 0; i < dataValue.size(); i++) {
            Pair<String, Float> pair = dataValue.get(i);
            // 用Rect计算Text内容宽度
            Rect bounds = new Rect();
            mYTextPaint.getTextBounds(pair.first, 0, pair.first.length(), bounds);
            int textWidth = bounds.right - bounds.left;
            // 绘制节点上的文字
            canvas.drawText(yValue.get(i), mSideLength + mSpaceLength * i - textWidth / 2f, pair.second - 25, mYTextPaint);
        }
    }
}

2.xml里引入

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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"
    tools:context=".MainActivity">
 
    <com.package.line.CurveView
        android:id="@+id/curveView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="#f2f2f2"/>
 
</androidx.constraintlayout.widget.ConstraintLayout>

3.activity中使用

package com.package;
 
import androidx.appcompat.app.AppCompatActivity;
 
import android.os.Bundle;
 
import com.package.line.CurveView;
 
import java.util.Arrays;
import java.util.List;
 
public class MainActivity extends AppCompatActivity {
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        CurveView curveView = findViewById(R.id.curveView);
          List<String> xList = Arrays.asList("1","2","3","4","5","6","7");
        List<String> yList = Arrays.asList("0","50","55","51","53","56","59");
        curveView.setData(xList, yList);
    }
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持编程网。

--结束END--

本文标题: android绘制曲线和折线图的方法

本文链接: https://www.lsjlt.com/news/167442.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • android绘制曲线和折线图的方法
    本文实例为大家分享了android绘制曲线和折线图的具体代码,供大家参考,具体内容如下 (曲线)  (折线) 1.CurveView.java package com....
    99+
    2022-11-13
  • Android绘制双折线图的方法
    本文实例为大家分享了Android绘制双折线图的具体代码,供大家参考,具体内容如下 自定义View实现双折线图,可点击,点击后带标签描述,暂未实现拖动的功能,实现效果如下: 代码如...
    99+
    2022-11-13
  • python绘制折线图和条形图的方法
    本文实例为大家分享了python绘制折线图和条形图的具体代码,供大家参考,具体内容如下 最近开始写小论文啦,中间不免要作各种各样的图,学习后自己作了个小笔记,供小伙伴一起学习哦。 折...
    99+
    2022-11-10
  • python绘制散点图和折线图的方法
    本文实例为大家分享了python绘制散点图和折线图的具体代码,供大家参考,具体内容如下 #散点图,一般和相关分析、回归分析结合使用 import pandas import ...
    99+
    2022-11-10
  • C#绘制柱状图和折线图的方法
    本文实例为大家分享了C#绘制柱状图和折线图的具体代码,供大家参考,具体内容如下 运行效果如下图: 设计上面的柱状图和折线图其实并没有什么难度,主要是各个坐标的计算,完全是精细活。...
    99+
    2022-11-13
  • Flutter怎么绘制曲线,折线图及波浪动效
    这篇文章主要介绍了Flutter怎么绘制曲线,折线图及波浪动效,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。简介之前用 Flutter 的 Canvas 画点有趣的图形我们介...
    99+
    2023-06-29
  • Android怎么绘制双折线图
    本篇内容主要讲解“Android怎么绘制双折线图”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Android怎么绘制双折线图”吧!自定义View实现双折线图,可点击,点击后带标签描述,暂未实现拖...
    99+
    2023-06-29
  • Android图表库HelloChart绘制多折线图
    本文实例为大家分享了Android图表库HelloChart绘制多折线图的具体代码,供大家参考,具体内容如下 一、效果图 二、实现步骤 1.添加依赖库 compile 'com.g...
    99+
    2022-11-13
  • 详解Flutter如何绘制曲线,折线图及波浪动效
    目录正弦曲线绘制波浪动效曲线绘制折线图其他说明总结简介 上一篇用 Flutter 的 Canvas 画点有趣的图形我们介绍了使用 CustomPaint 绘制自定义形状,可以看到有了...
    99+
    2022-11-13
  • C#绘制实时曲线图的方法详解
    在终端机器上的曲线显示本打算用控件,可控件折腾好长时间也没弄顺,还是自己写的好使,记录下来后面再改进。 //绘图部分的定义 Int32 Draw_To...
    99+
    2022-11-13
  • 怎么使用Android LineChart绘制折线图
    这篇文章主要介绍“怎么使用Android LineChart绘制折线图”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“怎么使用Android LineChart绘制折线图”文章能帮...
    99+
    2023-07-05
  • Android 使用MPAndroidChart:v3.1.0绘制动态折线图
    工作需要绘制一张可动态添加的折线图,经过筛选,选择MPAndroidChart:v3.1.0。 **使用方法:** 1、添加bui...
    99+
    2022-06-06
    折线图 mpandroidchart 动态 Android
  • Android实现绘制折线图APP代码
    目录一.总体设计二.具体模块实现三.效果展示四.功能展望总结一.总体设计 1.寻找规律,公式化的生成坐标系。 2.将生成坐标系的关键参数设置为可自定义,从而可变的可以生成自己想要的坐...
    99+
    2022-11-13
  • 怎么用Android的HelloChart绘制多折线图
    本文小编为大家详细介绍“怎么用Android的HelloChart绘制多折线图”,内容详细,步骤清晰,细节处理妥当,希望这篇“怎么用Android的HelloChart绘制多折线图”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来...
    99+
    2023-06-29
  • Android LineChart绘制折线图的示例详解
    1.首先在 build.gradle 里导入包 implementation 'com.github.PhilJay:MPAndroidChart:v3.1.0'&n...
    99+
    2023-03-24
    Android LineChart绘制折线图 Android LineChart折线图 Android LineChart
  • C#绘制实时曲线的方法
    本文实例为大家分享了C#绘制实时曲线的具体代码,供大家参考,具体内容如下 1.要做一个调试工具,采集传感器数据并显示。绘制曲线注意坐标反转,线条的张力即可。项目中的曲线是从右往左显示...
    99+
    2022-11-13
  • QtQChart实现折线图的绘制
    目录前言1.使用2.效果如下3.具体实现如下4.刷新QChart5.PCL 点排序前言 QChart  是常用的图表;我这里做了一个 default 和 custom 1....
    99+
    2023-05-17
    Qt QChart绘制折线图 Qt QChart折线图 Qt QChart
  • Android自定义View绘制贝塞尔曲线的方法
    本文实例为大家分享了Android自定义View绘制贝塞尔曲线的具体代码,供大家参考,具体内容如下 在平面内任选 3 个不共线的点,依次用线段连接。 在第一条线段上任选一个点 D。计...
    99+
    2022-11-13
  • python怎么绘制折线图和条形图
    今天小编给大家分享一下python怎么绘制折线图和条形图的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。折线图import&n...
    99+
    2023-06-30
  • C#如何绘制柱状图和折线图
    这篇文章给大家分享的是有关C#如何绘制柱状图和折线图的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。具体内容如下运行效果如下图:设计上面的柱状图和折线图其实并没有什么难度,主要是各个坐标的计算,完全是精细活。首先在...
    99+
    2023-06-29
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作