Android 横向条形统计图



先看下效果图↑↑


写作思路和网上各种统计图都是一样的。

废话少说上代码:

package com.ustcsoft.yzyx.zxjy.view;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;

import com.ustcsoft.yzyx.zxjy.R;
import com.ustcsoft.yzyx.zxjy.utils.DensityUtil;

import java.util.List;

/**
 * TODO 因为行高和间距都是固定的,所以当统计条数改变时,请在布局文件中设置好高度
 * 水平进度条
 * Created by cuihuihui on 2017/5/5.
 */

public class HorizontalChartView extends View {
    /**
     * 最大值
     */
    private float maxValue ;
    /**
     * 统计项目
     */
    private List
   
   
    
     barList;

    /**
     * 线的宽度
     */
    private int lineStrokeWidth;
    /**
     * 统计条宽度
     */
    private int barWidth;

    /**
     * 两条统计图之间空间
     */
    private int barSpace;

    /**
     * 各画笔
     */
    private Paint barPaint, linePaint, textPaint, scoreTextPaint;

    /**
     * 矩形区域
     */
    private Rect barRect, topRect;

    private Path textPath;

    private int itemNameWidth;

    private int scoreTextHeight;

    /**
     * 项目名和条形图之间的距离
     */
    private int betweenMargin;


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

    /**
     * 初始化设置
     */
    private void init(Context context) {
        barPaint = new Paint();
        barPaint.setColor(getResources().getColor(R.color.score_blue));

        linePaint = new Paint();
        linePaint.setColor(getResources().getColor(R.color.lineColor));
        lineStrokeWidth = DensityUtil.dip2px(context, 0.5f);
        linePaint.setStrokeWidth(lineStrokeWidth);

        textPaint = new Paint();
        textPaint.setColor(getResources().getColor(R.color.text_light_black));
        textPaint.setTextSize(DensityUtil.dip2px(context, 13));
        textPaint.setAntiAlias(true);

        scoreTextPaint = new Paint();
        scoreTextPaint.setTextSize(DensityUtil.dip2px(context, 13));
        scoreTextPaint.setColor(getResources().getColor(R.color.white));

        barRect = new Rect(0, 0, 0, 0);
        textPath = new Path();

        barWidth = DensityUtil.dip2px(context, 18);
        barSpace = DensityUtil.dip2px(context, 20);
        scoreTextHeight = DensityUtil.dip2px(context, 13);
        itemNameWidth = DensityUtil.dip2px(context, 86);
        betweenMargin = scoreTextHeight / 2;

    }

//    @Override
//    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
//        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
//        int width = measureWidth(widthMeasureSpec);
//        int height = measureHeight(heightMeasureSpec);
//        //设置宽高
//        setMeasuredDimension(width, height);
//    }


    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        float lineViewWidth = (float) ((this.getWidth() - itemNameWidth) * 0.8);//线的宽度占总宽度的0.8,剩余的部分显示分数
        float scoreWidth = lineViewWidth / 5;
        int scoreAdd = (int) (maxValue / 5);
        if (isInEditMode()) {
            return;
        }
        for (int i = 0; i < barList.size(); i++) {
            barRect.left = itemNameWidth;
            barRect.top = barSpace * (i + 2) + barWidth * i;
            barRect.right = (int) (lineViewWidth * (barList.get(i).getScore() / maxValue)) + itemNameWidth;
            barRect.bottom = barRect.top + barWidth;
            if ((barList.get(i).getScore() / maxValue) >= 0.6) {
                barPaint.setColor(getResources().getColor(R.color.score_blue));
            } else {
                barPaint.setColor(getResources().getColor(R.color.score_red));
            }

            canvas.drawRect(barRect, barPaint);
            canvas.drawText(barList.get(i).getScore() + "分", barRect.right, barRect.bottom - (barWidth - scoreTextHeight), textPaint);
            canvas.drawText(barList.get(i).getItemName(), itemNameWidth - betweenMargin - textPaint.measureText(barList.get(i).getItemName()), barRect.bottom - (barWidth - scoreTextHeight), textPaint);
            canvas.drawText(String.valueOf(scoreAdd * (i + 1)), itemNameWidth + scoreWidth * (i + 1) - textPaint.measureText(String.valueOf(scoreAdd * (i + 1))) / 2, barSpace, textPaint);
        }
//        canvas.drawText(String.valueOf(maxValue), itemNameWidth + lineViewWidth - textPaint.measureText(String.valueOf(maxValue)) / 2, barSpace, textPaint);
        canvas.drawText("0(分)", itemNameWidth - betweenMargin - textPaint.measureText("0(分)"), barSpace, textPaint);
        canvas.drawLine(itemNameWidth, 0, itemNameWidth, this.getHeight(), linePaint);
    }


    /**
     * 设置统计项目列表
     *
     * @param barList
     */
    public void setBarList(List
    
    
     
      barList) {
        this.barList = barList;
        if (barList == null) {
            throw new RuntimeException("BarChartView.setItems(): the param items cannot be null.");
        }
        if (barList.size() == 0) {
            return;
        }
        maxValue = barList.get(0).getScore();
        for (Bar bar : barList) {
            if (bar.getScore() > maxValue) {
                maxValue = bar.getScore();
            }
        }
        invalidate();

    }

    public static class Bar {
        int score;
        String itemName;

        public Bar(int score, String itemName) {
            this.score = score;
            this.itemName = itemName;
        }

        public int getScore() {
            return score;
        }

        public void setScore(int score) {
            this.score = score;
        }

        public String getItemName() {
            return itemName;
        }

        public void setItemName(String itemName) {
            this.itemName = itemName;
        }
    }

    //根据xml的设定获取宽度
    private int measureWidth(int measureSpec) {
        int specMode = MeasureSpec.getMode(measureSpec);
        int specSize = MeasureSpec.getSize(measureSpec);
        //wrap_content
        if (specMode == MeasureSpec.AT_MOST) {

        }
        //fill_parent或者精确值
        else if (specMode == MeasureSpec.EXACTLY) {

        }
        Log.i("这个控件的宽度----------", "specMode=" + specMode + " specSize=" + specSize);

        return specSize;
    }

    //根据xml的设定获取高度
    private int measureHeight(int measureSpec) {
        int specMode = MeasureSpec.getMode(measureSpec);
        int specSize = MeasureSpec.getSize(measureSpec);
        //wrap_content
        if (specMode == MeasureSpec.AT_MOST) {

        }
        //fill_parent或者精确值
        else if (specMode == MeasureSpec.EXACTLY) {

        }
        Log.i("这个控件的高度----------", "specMode:" + specMode + " specSize:" + specSize);

        return specSize;
    }
}

    
    
   
   


使用也很简单:

在布局文件中手动设置属性;

注意高度是根据统计项目多少来设置的!


<com.ustcsoft.yzyx.zxjy.view.HorizontalChartView
    android:id="@+id/score_checklist"
    android:layout_width="match_parent"
    android:layout_height="230dp"/>
scoreList = (HorizontalChartView) findViewById(R.id.score_checklist);
List<HorizontalChartView.Bar> barList = new ArrayList<>();
barList.add(new HorizontalChartView.Bar(18, "听力"));
barList.add(new HorizontalChartView.Bar(15, "语法"));
barList.add(new HorizontalChartView.Bar(17, "词法"));
barList.add(new HorizontalChartView.Bar(20, "阅读理解"));
barList.add(new HorizontalChartView.Bar(10, "说"));
scoreList.setBarList(barList);
搞定。。。

当然还有很多不完善的地方,大家自己修改下。



  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值