欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

android繪制曲線和折線圖的方法

 更新時間:2022年09月13日 16:10:27   作者:會爬樓梯的魚  
這篇文章主要介紹了android繪制曲線和折線圖的方法,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下

本文實例為大家分享了android繪制曲線和折線圖的具體代碼,供大家參考,具體內(nèi)容如下

(曲線)

 (折線)

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;
? ? /**
? ? ?* X軸的數(shù)量,按需調(diào)整
? ? ?*/
? ? private int mLength = 7;
? ? /**
? ? ?* 獲取屏幕的寬度
? ? ?*/
? ? private final int mScreenWidth = getScreenWidth(getContext());
? ? /**
? ? ?* 獲取實際屏幕的寬度
? ? ?*/
? ? private int cScreenWidth = getScreenWidth(getContext());
? ? /**
? ? ?* 整個折線圖的高度=屏幕高度-頂部的狀態(tài)欄高度
? ? ?*/
? ? private final int mHeight = getScreenHeight(getContext()) - dp2px(getContext(), 190);
? ? /**
? ? ?* 節(jié)點外圓的半徑
? ? ?*/
? ? private final int outRadius = dp2px(getContext(), 6);
? ? /**
? ? ?* 節(jié)點內(nèi)圓的半徑
? ? ?*/
? ? private final int inRadius = dp2px(getContext(), 3);
? ? /**
? ? ?* 左右兩邊距邊緣的距離
? ? ?*/
? ? private final float mSideLength = dp2px(getContext(), 20);
? ? /**
? ? ?* X軸底部文字的高度
? ? ?*/
? ? private final int mXTextHeight = dp2px(getContext(), 30);
?
? ? /**
? ? ?* 距離上邊距的高度
? ? ?*/
? ? private final int mPaddingTop = dp2px(getContext(), 10);
?
? ? /**
? ? ?* 獲取間隔距離
? ? ?*/
? ? private int mSpaceLength;
? ? /**
? ? ?* 用戶設(shè)置的數(shù)據(jù)
? ? ?*/
? ? private final List<Pair<String, Float>> dataValue = new ArrayList<>();
? ? /**
? ? ?* 節(jié)點數(shù)據(jù)
? ? ?*/
? ? private final List<Pair<Float, Float>> nodeValue = new ArrayList<>();
? ? /**
? ? ?* 節(jié)點上標(biāo)注的文字
? ? ?*/
? ? 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();
? ? }
?
? ? /**
? ? ?* dp轉(zhuǎn)px
? ? ?*/
? ? 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;
? ? }
?
? ? /*設(shè)置實際內(nèi)容寬度*/
? ? 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;
? ? }
?
? ? /**
? ? ?* 設(shè)置數(shù)據(jù)
? ? ?*/
? ? 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();//初始化節(jié)點內(nèi)圓
? ? ? ? initBrokenLine();//初始化曲線、折線
? ? ? ? initXtext();//初始化X軸標(biāo)簽
? ? ? ? initYtext();//初始化Y軸上數(shù)值
? ? ? ? initShadowPaint();//初始化陰影
? ? }
?
? ? /**
? ? ?* 獲取間隔距離
? ? ?* (屏幕寬度-兩邊的間距)/(x軸數(shù)量-1)
? ? ?*/
? ? 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);
? ? }
?
? ? /**
? ? ?* 初始化底部橫線paint
? ? ?*/
? ? private void initBottomLine() {
? ? ? ? mBottomLinePaint = new Paint();
? ? ? ? mBottomLinePaint.setColor(Color.GRAY);
? ? ? ? mBottomLinePaint.setStrokeWidth(dp2px(getContext(), 0.5f));
? ? ? ? mBottomLinePaint.setStyle(Paint.Style.STROKE);
? ? ? ? mBottomLinePaint.setAntiAlias(true);
? ? }
?
? ? /**
? ? ?* 初始化X軸標(biāo)簽
? ? ?*/
? ? private void initXtext() {
? ? ? ? mXTextPaint = new Paint();
? ? ? ? mXTextPaint.setColor(Color.GRAY);
? ? ? ? mXTextPaint.setTextSize(dp2px(getContext(), 12));
? ? ? ? mXTextPaint.setStyle(Paint.Style.FILL);
? ? ? ? mXTextPaint.setAntiAlias(true);
? ? }
?
? ? /**
? ? ?* 初始化Y軸上數(shù)值
? ? ?*/
? ? private void initYtext() {
? ? ? ? mYTextPaint = new Paint();
? ? ? ? mYTextPaint.setColor(Color.GRAY);
? ? ? ? mYTextPaint.setTextSize(dp2px(getContext(), 12));
? ? ? ? mYTextPaint.setStyle(Paint.Style.FILL);
? ? ? ? mYTextPaint.setAntiAlias(true);
? ? }
?
? ? /**
? ? ?* 初始化節(jié)點內(nèi)圓
? ? ?*/
? ? private void initInCircle() {
? ? ? ? //初始化外圓
? ? ? ? mOutCirclePaint = new Paint();
? ? ? ? mOutCirclePaint.setColor(Color.GREEN);
? ? ? ? mOutCirclePaint.setStyle(Paint.Style.FILL);
? ? ? ? mOutCirclePaint.setAntiAlias(true);
? ? ? ? //內(nèi)框
? ? ? ? mInCirclePaint = new Paint();
? ? ? ? mInCirclePaint.setColor(Color.GRAY);
? ? ? ? mInCirclePaint.setStyle(Paint.Style.STROKE);
? ? ? ? mInCirclePaint.setStrokeWidth(dp2px(getContext(), 2));
? ? ? ? mInCirclePaint.setAntiAlias(true);
? ? ? ? //內(nèi)圓
? ? ? ? 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);
? ? ? ? // 繪制節(jié)點和折線圖
? ? ? ? drawCircleLine(canvas);
? ? ? ? // 繪制Y軸上的數(shù)據(jù)和背景
? ? ? ? drawYtext(canvas);
? ? ? ? // 繪制X軸標(biāo)簽文字
? ? ? ? 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);
? ? ? ? }
? ? }
?
? ? /**
? ? ?* 繪制節(jié)點和曲線或者折線圖
? ? ?*/
? ? private void drawCircleLine(Canvas canvas) {
? ? ? ? nodeValue.clear();
? ? ? ? for (int i = 0; i < dataValue.size(); i++) {
? ? ? ? ? ? Pair<String, Float> pair = dataValue.get(i);
? ? ? ? ? ? // 繪制節(jié)點外圓
? ? ? ? ? ? canvas.drawCircle(mSideLength + mSpaceLength * i, pair.second, outRadius, mOutCirclePaint);
? ? ? ? ? ? // 繪制節(jié)點內(nèi)框
? ? ? ? ? ? canvas.drawCircle(mSideLength + mSpaceLength * i, pair.second, inRadius, mFillCirclePaint);
? ? ? ? ? ? // 繪制節(jié)點內(nèi)圓
? ? ? ? ? ? canvas.drawCircle(mSideLength + mSpaceLength * i, pair.second, inRadius, mInCirclePaint);
? ? ? ? ? ? // 保存圓心坐標(biāo)
? ? ? ? ? ? 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);
? ? ? ? ? ? ? ? //減去文字和指示標(biāo)的高度
? ? ? ? ? ? ? ? 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);
? ? ? ? }
? ? }
?
? ? /**
? ? ?* 獲取坐標(biāo)點
? ? ?*/
? ? 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;
? ? }
?
? ? /**
? ? ?* 繪制底部的X軸線
? ? ?*/
? ? private void drawBottomLine(Canvas canvas) {
? ? ? ? canvas.drawLine(0, mHeight - mXTextHeight, cScreenWidth, mHeight - mXTextHeight, mBottomLinePaint);
? ? }
?
? ? /**
? ? ?* 繪制X軸標(biāo)簽文字
? ? ?*/
? ? private void drawBottomText(Canvas canvas) {
? ? ? ? for (int i = 0; i < dataValue.size(); i++) {
? ? ? ? ? ? String xValue = dataValue.get(i).first;
? ? ? ? ? ? // 獲取Text內(nèi)容寬度
? ? ? ? ? ? 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);
? ? ? ? }
? ? }
?
? ? /**
? ? ?* 繪制Y軸上的數(shù)據(jù)和背景
? ? ?*/
? ? private void drawYtext(Canvas canvas) {
? ? ? ? for (int i = 0; i < dataValue.size(); i++) {
? ? ? ? ? ? Pair<String, Float> pair = dataValue.get(i);
? ? ? ? ? ? // 用Rect計算Text內(nèi)容寬度
? ? ? ? ? ? Rect bounds = new Rect();
? ? ? ? ? ? mYTextPaint.getTextBounds(pair.first, 0, pair.first.length(), bounds);
? ? ? ? ? ? int textWidth = bounds.right - bounds.left;
? ? ? ? ? ? // 繪制節(jié)點上的文字
? ? ? ? ? ? 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);
? ? }
}

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

最新評論