失眠网,内容丰富有趣,生活中的好帮手!
失眠网 > Android自定义View绘制条形统计图

Android自定义View绘制条形统计图

时间:2024-07-15 18:50:42

相关推荐

Android自定义View绘制条形统计图

最终效果

代码实现

package com.example.chartdemo;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.PathEffect;import android.util.AttributeSet;import android.view.View;import androidx.annotation.Nullable;import java.util.List;public class BarChartView extends View {public BarChartView(Context context) {this(context,null);}public BarChartView(Context context, @Nullable AttributeSet attrs) {this(context, attrs,0);}public BarChartView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);}private int widthMode;private int heightMode;private int widthSize;private int heightSize;private List<Integer> xItems;//X轴 轴项private String xUnit;//X轴 刻度单位private List<Integer> yItems;//Y轴 轴项private String yUnit;//Y轴 刻度单位private List<Integer> dataList;//数据private List<Integer> dataList2;//数据2private int xStepDistance;//X轴 步距private int yStepDistance;//Y轴 步距@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {super.onMeasure(widthMeasureSpec, heightMeasureSpec);widthMode = MeasureSpec.getMode(widthMeasureSpec);heightMode = MeasureSpec.getMode(heightMeasureSpec);widthSize = MeasureSpec.getSize(widthMeasureSpec);heightSize = MeasureSpec.getSize(heightMeasureSpec);initPaint();}private Paint linePaint;private Paint linePaint2;private Paint zhouPaint;private Paint gePaint;private Paint zhouTextPaint;private Paint line1DataTextPaint;private Paint line2DataTextPaint;private void initPaint(){linePaint=new Paint();linePaint.setStyle(Paint.Style.FILL_AND_STROKE);//不加这个不显示linePaint.setColor(Color.RED);linePaint.setStrokeWidth(4);linePaint.setAntiAlias(true);//抗锯齿功能linePaint.setARGB(100,255,0,0); //设置:A代表透明度 B代表红 G代表绿 B代表蓝 (范围:0————255)linePaint.setStrokeJoin(Paint.Join.ROUND);//线条连接处样式linePaint.setStrokeCap(Paint.Cap.ROUND);//设置线头模式/*Bitmap bm = BitmapFactory.decodeResource(getResources(), R.drawable._l9_line_back);BitmapShader bitmapShader = new BitmapShader(bm, Shader.TileMode.REPEAT, Shader.TileMode.MIRROR);linePaint.setShader(bitmapShader);*/linePaint2=new Paint();linePaint2.setStyle(Paint.Style.FILL_AND_STROKE);//不加这个不显示linePaint2.setColor(Color.BLUE);linePaint2.setStrokeWidth(4);linePaint2.setAntiAlias(true);//抗锯齿功能linePaint2.setARGB(100,0,0,255);linePaint2.setStrokeJoin(Paint.Join.ROUND);linePaint2.setStrokeCap(Paint.Cap.ROUND);gePaint=new Paint();gePaint.setColor(Color.parseColor("#A3AFB8"));gePaint.setStyle(Paint.Style.STROKE);//不加这个不显示gePaint.setStrokeWidth(0);gePaint.setAntiAlias(true);//抗锯齿功能PathEffect effects = new DashPathEffect(new float[]{5, 10}, 0);//设置绘制虚线gePaint.setPathEffect(effects);zhouPaint=new Paint();zhouPaint.setColor(Color.BLACK);zhouPaint.setStrokeWidth(4);zhouPaint.setAntiAlias(true);//抗锯齿功能zhouTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG);zhouTextPaint.setTextSize(30);line1DataTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG);line1DataTextPaint.setARGB(100,255,0,0);line1DataTextPaint.setTextSize(20);line2DataTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG);line2DataTextPaint.setARGB(100,0,0,255);line2DataTextPaint.setTextSize(20);}@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);//画 X轴=====================================================================================canvas.drawLine(0,heightSize,widthSize, heightSize,zhouPaint);xStepDistance=widthSize/xItems.size();//X轴 步距值for (int a=0;a<xItems.size();a++){//画刻度canvas.drawLine(xStepDistance*a,heightSize,xStepDistance*a, heightSize-10,zhouPaint);//画格子Path gePath=new Path();gePath.moveTo(xStepDistance*a, heightSize);gePath.lineTo(xStepDistance*a, 0);gePath.close();canvas.drawPath(gePath, gePaint);//绘制X轴 刻度文字canvas.drawText(a==xItems.size()-1 ? xItems.get(a)+"("+xUnit+")" : xItems.get(a)+"", xStepDistance*a-10, heightSize-20, zhouTextPaint);}canvas.drawLine(widthSize,heightSize,widthSize-10,heightSize-10,zhouPaint);//画末尾箭头//画 Y轴=====================================================================================canvas.drawLine(0,0,0, heightSize,zhouPaint);yStepDistance=heightSize/yItems.size();//Y轴 步距值for (int a=0;a<yItems.size();a++){//画刻度if (a!=0)canvas.drawLine(0,heightSize-(yStepDistance*a),10, heightSize-(yStepDistance*a),zhouPaint);//画格子Path gePath=new Path();gePath.moveTo(0, heightSize-(yStepDistance*a));gePath.lineTo(widthSize, heightSize-(yStepDistance*a));gePath.close();canvas.drawPath(gePath, gePaint);//绘制Y轴 刻度文字canvas.drawText(a==yItems.size()-2 ? yItems.get(a)+"("+yUnit+")" : yItems.get(a)+"", 10, heightSize-(yStepDistance*(a+1)), zhouTextPaint);}canvas.drawLine(0,0,10,10,zhouPaint);//画末尾箭头//绘制_数据1===================================================================================double yDataPixel=heightSize/100f; //控件高度的像素个数——与——实际数据的对应关系值 (像素点分给100个数据值)for (int k=0;k<dataList.size();k++){//画方形条canvas.drawRect(xStepDistance*k+20,(int)(heightSize-(dataList.get(k)*yDataPixel)),xStepDistance*k+(xStepDistance/2)-30+20,heightSize,linePaint);canvas.drawText(dataList.get(k)+"", xStepDistance*k+20, (int)(heightSize-(dataList.get(k)*yDataPixel))-20, line1DataTextPaint);}//绘制_数据2===================================================================================for (int k=0;k<dataList2.size();k++){//画方形条canvas.drawRect(xStepDistance*k+(xStepDistance/2),(int)(heightSize-(dataList2.get(k)*yDataPixel)),xStepDistance*k+xStepDistance-30,heightSize,linePaint2);canvas.drawText(dataList2.get(k)+"", xStepDistance*k+(xStepDistance/2), (int)(heightSize-(dataList2.get(k)*yDataPixel))-20, line2DataTextPaint);}}/*** 设置曲线1 数据* @param dataList*/public void setData(List<Integer> dataList){this.dataList=dataList;postInvalidate();}/*** 设置曲线2 数据* @param dataList*/public void setData2(List<Integer> dataList){this.dataList2=dataList;postInvalidate();}/*** 设置X轴参数* @param xList* @param unit 刻度单位*/public void setDataScaleX(List<Integer> xList,String unit){xItems=xList;xUnit=unit;postInvalidate();}/*** 设置Y轴参数* @param yList* @param unit 刻度单位*/public void setDataScaleY(List<Integer> yList,String unit){yItems=yList;yUnit=unit;postInvalidate();}}

使用方法

在XML中引用

<com.example.chartdemo.BarChartViewandroid:id="@+id/bar_chart"android:background="#EFEFEF"android:layout_margin="20px"android:layout_width="match_parent"android:layout_height="600px" />

设置参数与数据

List<Integer> dataList=new ArrayList<>();dataList.add(85);dataList.add(90);dataList.add(70);dataList.add(68);dataList.add(50);dataList.add(43);dataList.add(28);dataList.add(21);dataList.add(30);dataList.add(58);dataList.add(70);dataList.add(55);List<Integer> dataList2=new ArrayList<>();dataList2.add(45);dataList2.add(67);dataList2.add(78);dataList2.add(98);dataList2.add(85);dataList2.add(54);dataList2.add(45);dataList2.add(35);dataList2.add(55);dataList2.add(59);dataList2.add(42);dataList2.add(45);List<Integer> xList=new ArrayList<>();xList.add(1);xList.add(2);xList.add(3);xList.add(4);xList.add(5);xList.add(6);xList.add(7);xList.add(8);xList.add(9);xList.add(10);xList.add(11);xList.add(12);List<Integer> yList=new ArrayList<>();yList.add(10);yList.add(20);yList.add(30);yList.add(40);yList.add(50);yList.add(60);yList.add(70);yList.add(80);yList.add(90);yList.add(100);BarChartView bar_chart=(BarChartView) findViewById(R.id.bar_chart);bar_chart.setDataScaleX(xList,"月");bar_chart.setDataScaleY(yList,"件");bar_chart.setData(dataList);bar_chart.setData2(dataList2);//===========动效数据================doBarChartDataList();

东西方法代码

private void doBarChartDataList(){for (int a=0;a<dataList.size();a++){new BarHeartbeat().start(50, a, dataList.get(a), new ActionCallback() {@Overridepublic void toDo(Object o) {List<Integer> list= (List<Integer>) o;dataList.set(list.get(0),list.get(1));bar_chart.setData(dataList);}});}for (int a=0;a<dataList2.size();a++){new BarHeartbeat().start(50, a, dataList2.get(a), new ActionCallback() {@Overridepublic void toDo(Object o) {List<Integer> list= (List<Integer>) o;dataList2.set(list.get(0),list.get(1));bar_chart.setData2(dataList2);}});}}

动效数据辅助类

package com.soface.chartdemo;import android.os.Looper;import android.os.Message;import java.util.ArrayList;import java.util.List;/*** 心跳计时器*/public class BarHeartbeat {//事件标签public final int ACTION_TAG =0xFF;//要回调的接口private ActionCallback thisActionDo;//Handler事件监听器private android.os.Handler mHandler = new android.os.Handler(Looper.getMainLooper()){@Overridepublic void handleMessage(Message msg) {super.handleMessage(msg);switch (msg.what){case ACTION_TAG:List<Integer> list= (List<Integer>) msg.obj;thisActionDo.toDo(list);break;}}};//启动public void start(int countDownTime,int index,int maxNumber,ActionCallback actionDo){thisActionDo=actionDo;for (int a=0;a<=maxNumber;a++){Message msg = mHandler.obtainMessage();msg.what = ACTION_TAG;List<Integer> list=new ArrayList<>();list.add(index);list.add(a);msg.obj=list;mHandler.sendMessageDelayed(msg,countDownTime*a);}};}

package com.soface.chartdemo;public interface ActionCallback {void toDo(Object o);}

如果觉得《Android自定义View绘制条形统计图》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。