PercentageBar自定义动态柱形图

PercentageBar自定义动态柱形图,
本项目由开发者 阿拉灯神灯提供:https://github.com/nugongshou110/PercentageBar/tree/master
大图实现:通过自定义PercentageBar实现,
部分代码如下:

public class PercentageBar extends View{
//画线的画笔
private Paint mLinePaint;
//画柱状图的画笔
private Paint mBarPaint;
//写字的画笔
private Paint mTextPaint;

//开始X坐标
private int startX;
//开始Y坐标
private int startY;
//结束X坐标
private int stopX;

//测量值 宽度
private int measuredWidth;
//测量值 高度
private int measuredHeight;
//每条柱状图的宽度
private int barWidth;
//设置最大值,用于计算比例
private float max;
//设置每条柱状图的目标值,除以max即为比例
private ArrayList<Float> respTarget;
//设置一共有几条柱状图
private int totalBarNum;
//设置每条柱状图的当前比例
private Float[] currentBarProgress;
//每条竖线的当前比例
private int currentVerticalLineProgress;
//最上面一条横线的比例
private int currentHorizentalLineProgress;
//每条柱状图的名字
private ArrayList<String> respName;
//每条竖线之间的间距
private int deltaX;
//每条柱状图之间的间距
private int deltaY;
//一共有几条竖线
private int verticalLineNum;
//单位
private String unit;
//每条竖线之间相差的值
private float numPerUnit;

public PercentageBar(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init(context);
}

public PercentageBar(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
}

public PercentageBar(Context context) {
super(context);
init(context);
}

private void init(Context context) {
//设开始X坐标为0
startX =0;
//设开始Y坐标为50
startY =50;
//初始化柱状图画笔
mBarPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mBarPaint.setColor(0xff40E0D0);
mBarPaint.setStyle(Style.FILL);
//初始化线的画笔
mLinePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mLinePaint.setStyle(Style.FILL);
mLinePaint.setColor(0xffcdcdcd);
mLinePaint.setStrokeWidth(2);


}

/**
* 测量方法,主要考虑宽和高设置为wrap_content的时候,我们的view的宽高设置为多少
* @param widthMeasureSpec
* @param heightMeasureSpec
*/
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int widthSpecMode = MeasureSpec.getMode(widthMeasureSpec);
int widthSpecSize = MeasureSpec.getSize(widthMeasureSpec);
int heightSpecMode = MeasureSpec.getMode(heightMeasureSpec);
int heightSpecSize = MeasureSpec.getSize(heightMeasureSpec);
//如果宽和高都为wrap_content的时候,我们将宽设置为我们输入的max值,也就是柱状图的最大值
//高度为每条柱状图的宽度加上间距再乘以柱状图条数再加上开始Y值后得到的值
if (widthSpecMode == MeasureSpec.AT_MOST && heightSpecMode == MeasureSpec.AT_MOST) {
setMeasuredDimension((int) max, startY+10+totalBarNum*(barWidth+2*10));
//如果宽度为wrap_content 高度为match_parent或者精确数值的时候
}else if (widthSpecMode == MeasureSpec.AT_MOST) {
//宽度设置为max,高度为父容器高度
setMeasuredDimension((int) max, heightSpecSize);
//如果宽度为match_parent或者精确数值的时候,高度为wrap_content
}else if (heightSpecMode == MeasureSpec.AT_MOST) {
//宽度设置为父容器的宽度,高度为每条柱状图的宽度加上间距再乘以柱状图条数再加上开始Y值后得到的值
setMeasuredDimension(widthSpecSize, startY+10+totalBarNum*(barWidth+2*10));
}


}

@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
//获得测量后的宽度
measuredWidth = getMeasuredWidth();
//获得测量后的高度
measuredHeight = getMeasuredHeight();
//计算结束X的值
stopX = measuredWidth-barWidth;
//计算每条竖线之间的间距
deltaX = (stopX-(startX+7*barWidth/5))/verticalLineNum;
//计算每条柱状图之间的间距
deltaY = (measuredHeight-startY-barWidth*totalBarNum)/totalBarNum;
//计算出每条竖线所代表的数值
numPerUnit = max/verticalLineNum;
//初始化最上面横线的初始进度
currentHorizentalLineProgress = stopX;
}

@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);

/**
* 画柱状图
*/
for(int i = 0 ; i<totalBarNum ; i++){
if (currentBarProgress[i]<(respTarget.get(i)/max)*stopX) {
currentBarProgress[i]+=10;
postInvalidateDelayed(10);
}
canvas.drawText(respName.get(i),startX,startY+deltaY+i*(deltaY+barWidth)+3*barWidth/4, mTextPaint);
canvas.drawRect(startX+7*barWidth/5, startY+deltaY+i*(deltaY+barWidth), currentBarProgress[i], startY+deltaY+i*(deltaY+barWidth)+barWidth, mBarPaint);
}
/**
* 画竖线
*/
for(int i=0 ; i<verticalLineNum ; i++){
if (currentVerticalLineProgress< measuredHeight) {
currentVerticalLineProgress+=3;
postInvalidateDelayed(10);
}
canvas.drawLine((startX+7*barWidth/5)+(i+1)*deltaX, startY, (startX+7*barWidth/5)+(i+1)*deltaX, currentVerticalLineProgress, mLinePaint);
canvas.drawText(numPerUnit*(i+1)+unit, (startX+7*barWidth/5)+(i+1)*deltaX-barWidth, startY-barWidth/5, mTextPaint);
}
/**
* 画最上面的横线
*/
if (currentHorizentalLineProgress>startX+7*barWidth/5) {
currentHorizentalLineProgress-=10;
postInvalidateDelayed(10);
}
canvas.drawLine(stopX, startY, currentHorizentalLineProgress, startY, mLinePaint);
}

/**
* 设置每个柱状图的宽度
* @param width
*/
public void setBarWidth(int width){
this.barWidth = width;
mTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mTextPaint.setTextSize(3*barWidth/5);
mTextPaint.setStrokeWidth(1);
mTextPaint.setColor(0xffababab);

}
/**
* 设置最大值
* @param max
*/
public void setMax(float max){
this.max = max;
}

/**
* 设置一共有几个柱状图
* @param totalNum
*/
public void setTotalBarNum(int totalNum){
this.totalBarNum = totalNum;
currentBarProgress = new Float[totalNum];
for(int i = 0 ; i<totalNum ; i++){
currentBarProgress[i] = 0.0f;
}
}

/**
* 分别设置每个柱状图的目标值
* @param respTarget
*/
public void setRespectTargetNum(ArrayList<Float> respTarget){
this.respTarget = respTarget;

}

/**
* 分别设置每个柱状图的名字
* @param respName
*/
public void setRespectName(ArrayList<String> respName){
this.respName = respName;
}

/**
* 设置单位
* @param unit
*/
public void setUnit(String unit){
this.unit = unit;
}

/**
* 设置有几条竖线
* @param num
*/
public void setVerticalLineNum(int num){
this.verticalLineNum = num;
}

}


调用:
respectTarget = new ArrayList<Float>();
respName = new ArrayList<String>();
respectTarget.add(35.0f);
respectTarget.add(20.0f);
respectTarget.add(18.0f);
respectTarget.add(15.0f);
respectTarget.add(10.0f);
respectTarget.add(8.0f);
respectTarget.add(5.0f);
respName.add("滴滴");
respName.add("小米");
respName.add("京东");
respName.add("美团");
respName.add("魅族");
respName.add("酷派");
respName.add("携程");
mBarGraph = (PercentageBar) findViewById(R.id.bargraph);
mBarGraph.setRespectTargetNum(respectTarget);
mBarGraph.setRespectName(respName);
mBarGraph.setTotalBarNum(7);
mBarGraph.setMax(40);
mBarGraph.setBarWidth(50);
mBarGraph.setVerticalLineNum(4);
mBarGraph.setUnit("亿元");

运行效果:

相关代码

  • PercentageBar自定义动态柱形图

  • Hide-Music-Player 一个完整的音乐播放器

  • FoldableLayout展开效果

  • ProgressRoundButton下载进度按钮变化动画

  • android 过渡动画研究

  • android资讯类软件框架

  • QuickSand图片点击后分裂成几份消失效果

  • MaterialPowerMenu 点击按钮切换页面加载呈现效果

  • PlayNewsStandDemo资讯类新闻客户端框架

  • android加载框效果


更多相关文章

  1. Android(安卓)Intent FLAG介绍
  2. Android(安卓)5.0 CardView+ListView 卡片布局应用
  3. Android(安卓)studio 如何设置字体大小
  4. Android初级教程三个Dialog对话框小案例
  5. android让图片等比例缩放
  6. 设置activity背景图片
  7. 【Android】OpenGL_ES基本用法
  8. Android(安卓)Values文件作用及使用方法
  9. Android中的图片查看器

随机推荐

  1. android与数据库
  2. Porting Wifi driver on Android
  3. Android(安卓)MVP架构搭建
  4. Android之Home键监听封装
  5. Android(安卓)动画绘制移动的小人
  6. Android(安卓)Notification 例子
  7. Android高德地图如何禁止地图在拖动时发
  8. Android应用程序启动过程源代码分析(4)
  9. android 返回 弹出对话框 确认退出
  10. Android实现左右滑动页面