前言:
各位同学大家好,有段时间没有给大家更新文章了,具体多久我也记不清楚了。最近重新复习了一下原生安卓的知识点,写了一个安卓原生自定义折线图的效果,就想着分享给大家。希望帮助到各位学习和工作,那份废话不多说我们正式开始。
效果图:
具体实现
自定义 :BrokenView
private Context mContext;
private int bWidth,bHeight; // 左边距 除去下边距的距离
private int totalValue, pJValue; // Y的刻度 Y的总值
private String xStr="x",yStr="y";
private HashMap<Double, Double>map=new HashMap<>();
private boolean isShow;
private int marginB;
private List<Double> dlk=new ArrayList<>();
private List<Integer>xList=new ArrayList<>();
private Point []mPoints;
public BrokenView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
mContext=context;
}
对外方法
public void setView(HashMap<Double,Double>map,int totalValue,int pJValue,
boolean isShow,int marginB){
this.map=map;
this.totalValue=totalValue;
this.pJValue=pJValue;
this.isShow=isShow;
this.marginB=marginB;
}
重写ondraw 方法
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
// 把x 坐标从小到大进行排列 保存在一个集合里面
dlk=Tools.getintformap(map);
int height=getHeight();
int width=getWidth();
bWidth=50;
bHeight=height-marginB;
int jSzie=totalValue/pJValue;
Paint paint=new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setColor(Color.GRAY); //设置画笔颜色
paint.setStrokeWidth(1);
paint.setStyle(Paint.Style.STROKE);
// 画横轴
for (int i = 0; i < jSzie+1; i++) {
canvas.drawLine(bWidth,bHeight-(bHeight/jSzie)*i+20,width,bHeight-(bHeight/jSzie)*i+20,paint);
// 画Y的刻度
drawText(pJValue*i+yStr,bWidth/2,bHeight-(bHeight/jSzie)*i+20,canvas);
}
// 画竖轴
for (int i = 0; i <dlk.size(); i++) {
// 把相对于view的x的坐标值找到
xList.add(bWidth+(int)((width-bWidth)/dlk.size()*dlk.get(i)));
if(isShow){
canvas.drawLine(bWidth+(width-bWidth)/dlk.size()*i,20,
bWidth+(width-bWidth)/dlk.size()*i,bHeight,paint);
}
drawText(1+xStr,bWidth+(width-bWidth)/dlk.size()*i,bHeight-20,canvas);
}
// 把所有的点相对于View的集合找到
mPoints=getPotins(dlk,map,totalValue,canvas,xList);
paint.setColor(Color.GREEN);
paint.setStyle(Paint.Style.STROKE);
drawPoints(mPoints,canvas ,paint);
paint.setColor(Color.RED);
paint.setStyle(Paint.Style.FILL);
for (int i = 0; i <mPoints.length ; i++) {
canvas.drawRect(paintRect(mPoints[i]),paint);
}
}
- ####画横轴
// 画横轴
for (int i = 0; i < jSzie+1; i++) {
canvas.drawLine(bWidth,bHeight-(bHeight/jSzie)*i+20,width,bHeight-(bHeight/jSzie)*i+20,paint);
// 画Y的刻度
drawText(pJValue*i+yStr,bWidth/2,bHeight-(bHeight/jSzie)*i+20,canvas);
}
- ####画数轴
// 画竖轴
for (int i = 0; i <dlk.size(); i++) {
// 把相对于view的x的坐标值找到
xList.add(bWidth+(int)((width-bWidth)/dlk.size()*dlk.get(i)));
if(isShow){
canvas.drawLine(bWidth+(width-bWidth)/dlk.size()*i,20,
bWidth+(width-bWidth)/dlk.size()*i,bHeight,paint);
}
drawText(1+xStr,bWidth+(width-bWidth)/dlk.size()*i,bHeight-20,canvas);
}
获得相对于View 所有的点的集合
// 获得相对于View 所有的点的集合
private Point []getPotins(List<Double> dlk2, HashMap<Double, Double> map2, int totalValue2,
Canvas canvas, List<Integer> xList2) {
Point [] points=new Point[dlk2.size()];
for (int i = 0; i <points.length ; i++) {
int ph=bHeight-(int) (bHeight*(map.get(dlk.get(i))/totalValue2));
points[i]=new Point(xList2.get(i),ph+20);
}
return points;
}
绘制刻度方法
private void drawText(String str,int i , int j, Canvas canvas){
Paint paint=new Paint();
paint.setAlpha(0X0000FF);
paint.setTextSize(20);
paint.setColor(Color.GRAY);
Typeface typeface=Typeface.create("宋体",Typeface.ITALIC);
paint.setTypeface(typeface);
paint.setTextAlign(Paint.Align.CENTER);
canvas.drawText(str,i ,j,paint);
}
Tools 工具类
将 HashMap 排序然后添加在list里面并返回
package com.app.broken_demo;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
public class Tools {
public static ArrayList<Double>getintformap(HashMap<Double,Double>map){
ArrayList<Double>dlk=new ArrayList<>();
@SuppressWarnings("rawtypes")
Set set=map.entrySet();
@SuppressWarnings("rawtypes")
Iterator iterator=set.iterator();
while (iterator.hasNext()){
@SuppressWarnings("rawtypes")
Map.Entry mapentry= (Map.Entry) iterator.next();
dlk.add((Double) mapentry.getKey());
}
Collections.sort(dlk);
return dlk;
}
}
mainactivity测试
package com.app.broken_demo;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.Button;
import java.util.HashMap;
public class MainActivity extends AppCompatActivity {
private HashMap<Double,Double>map=new HashMap<>();
private BrokenView brokenView;
private Button button;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
brokenView=findViewById(R.id.menulist);
button=findViewById(R.id.btn_add);
map.put(0.0,0.0);
map.put(1.5,(double) 0);
map.put(2.0,25.0);
map.put(3.0,20.0);
map.put(4.0,32.0);
map.put(5.0,41.0);
map.put(6.0,16.0);
map.put(7.0,36.0);
map.put(8.0,26.0);
brokenView.setView(map,50,10,false,50);
}
}
最后总结
自定义折线图主要是对于要绘制的 点的坐标的处理 然后依次画出横轴刻度 以及数轴刻度。最后将获取到的现在画出线即可 。最后希望我的文章能帮助到各位解决问题 ,以后我还会贡献更多有用的代码分享给大家。各位同学如果觉得文章还不错 ,麻烦给关注和star,小弟在这里谢过啦!
项目地址:
码云 :https://gitee.com/qiuyu123/brokendemo