自定义圆角柱状图

 
 
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;

import com.sito.ioammcpv2.utils.Utils;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by Yangzb on 2018/04/04
 * 注释:参考MyChartView原理相
 * 圆角柱状图
 */

public class SingleView extends View {

    private Paint mPaint, mChartPaint, mNumPaint;
    private Rect mBound;
    private int mStartWidth, mHeight, mWidth, mChartWidth, mSize;
    private int lineColor, leftColor, lefrColorBottom, selectLeftColor;
    private List<Float> list = new ArrayList<>();
    private getNumberListener listener;
    private int number = 1000;
    private int selectIndex = -1;
    private List<Integer> selectIndexRoles = new ArrayList<>();
    private String[] mColors = {"#ffffff","#ffffff"};
    private String[] mTags;
    private float mBigNum;

    public void setList(List<Float> list){
        mSize = getWidth() / 25;
        mChartWidth = getWidth() / 4 - mSize / 2;
        mStartWidth = getWidth() / 2-(getWidth() / 4 - mSize / 2);
        invalidate();
    }

    public void setList(List<Float> list,String[] colors,String[] tags) {
        this.list = list;
        if(colors!=null&&colors.length>0){
            mColors = colors;
        }
        if(tags!= null && tags.length>0){
            mTags = tags;
        }
        invalidate();
    }

    /**
     *
     * @param list 源数据
     * @param colors 数据颜色
     * @param tags 底部说明
     * @param num 最大的数据 用来计算柱状图高度
     */
    public void setList(List<Float> list,String[] colors,String[] tags,float num) {
        mSize = getWidth() / 25;
        mChartWidth = getWidth() / 4 - mSize / 2;
        mStartWidth = getWidth() / 2-(getWidth() / 4 - mSize / 2);
        this.list = list;
        if(colors!=null&&colors.length>0){
            mColors = colors;
        }
        if(tags!= null && tags.length>0){
            mTags = tags;
        }
        this.mBigNum = num;
        invalidate();
    }

    public SingleView(Context context) {
        this(context, null);
    }

    public SingleView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public SingleView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
//        TypedArray array = context.getTheme().obtainStyledAttributes(attrs, R.styleable.MyChartView, defStyleAttr, 0);
//        int n = array.getIndexCount();
//        for (int i = 0; i < n; i++) {
//            int attr = array.getIndex(i);
//            switch (attr) {
//                case R.styleable.MyChartView_xyColor:
//                    lineColor = array.getColor(attr, Color.BLACK);
//                    break;
//                case R.styleable.MyChartView_leftColor:
//                    // 默认颜色设置为黑色
//                    leftColor = array.getColor(attr, Color.BLACK);
//                    break;
//                case R.styleable.MyChartView_leftColorBottom:
//                    lefrColorBottom = array.getColor(attr, Color.BLACK);
//                    break;
//                case R.styleable.MyChartView_selectLeftColor:
//                    // 默认颜色设置为黑色
//                    selectLeftColor = array.getColor(attr, Color.BLACK);
//                    break;
//                default:
//                    bringToFront();
//            }
//        }
//        array.recycle();
        init();
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        int width;
        int height;
        int widthSize = MeasureSpec.getSize(widthMeasureSpec);
        int heightSize = MeasureSpec.getSize(heightMeasureSpec);
        int widthMode = MeasureSpec.getMode(widthMeasureSpec);
        int heightMode = MeasureSpec.getMode(heightMeasureSpec);

        if (widthMode == MeasureSpec.EXACTLY) {
            width = widthSize;
        } else {
            width = widthSize * 1 / 2;
        }
        if (heightMode == MeasureSpec.EXACTLY) {
            height = heightSize;
        } else {
            height = heightSize * 1 / 2;
        }

        setMeasuredDimension(width, height);
    }

    @Override
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
        super.onLayout(changed, left, top, right, bottom);
        mWidth = getWidth();
        mHeight = getHeight();
        mSize = mWidth / 8;
        mChartWidth = getWidth() / 4 - mSize / 2;
        mStartWidth = getWidth() / 2-(getWidth() / 4 - mSize / 2);
    }

    private void init() {
        mPaint = new Paint();
        mPaint.setAntiAlias(true);
        mBound = new Rect();
        mChartPaint = new Paint();
        mChartPaint.setAntiAlias(true);
        mNumPaint = new Paint();
        mNumPaint.setAntiAlias(true);
    }

    @Override
    public void onWindowFocusChanged(boolean hasWindowFocus) {
        super.onWindowFocusChanged(hasWindowFocus);
        if (hasWindowFocus) {

        }
    }

    @Override
    protected void onWindowVisibilityChanged(int visibility) {
        super.onWindowVisibilityChanged(visibility);
        if (visibility == VISIBLE) {
            mSize = getWidth() / 25;
            mChartWidth = getWidth() / 4 - mSize / 2;
            mStartWidth = getWidth() / 2-(getWidth() / 4 - mSize / 2);
        }
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
//        String[] strings = mTags;
        String[] colors = mColors;
        mStartWidth = getWidth() / 2-(getWidth() / 4 - mSize / 2);
//        int temp = (int)(mBigNum*1.6);
//        int size = temp == 0 ? 0:mHeight / temp;
        float size = mBigNum == 0?0:(mHeight-100-mBound.height()/2-mChartWidth)/mBigNum;
//        mHeight = (int)(1-(mHeight)*size);
        for (int i = 0; i < 2; i++) {
            mChartPaint.setStyle(Paint.Style.FILL);
            mChartPaint.setColor(Color.parseColor(colors[i]));
            if (list.size() > 0) {
                //画柱状图
                RectF rectF = new RectF();
                rectF.left = mStartWidth;
                rectF.right = mStartWidth + mChartWidth/2;
                if(mTags != null && mTags.length>0){//有底部描述
                    rectF.bottom = mHeight-100;
                    rectF.top = mHeight - 100 -list.get(i)*size;
                }else {
                    rectF.bottom = mHeight-40;
                    rectF.top = mHeight - 40 -list.get(i)*size;
                }
                canvas.drawRoundRect(rectF, 20, 20, mChartPaint);

                //画顶部数字
                mNumPaint.setColor(Color.parseColor(colors[i]));
                mNumPaint.setTextSize(25);
                mNumPaint.setTextAlign(Paint.Align.CENTER);
                mNumPaint.getTextBounds(String.valueOf(i + 1) + "", 0, String.valueOf(i).length(), mBound);
                float n = list.get(i);
                canvas.drawText(String.valueOf(Integer.valueOf((int)n)), mStartWidth+mChartWidth/4,
                        rectF.top - mBound.height() * 1 / 2, mNumPaint);

                if(mTags != null && mTags.length>0){
                    //画底部标注
                    mPaint.setColor(Color.parseColor(colors[i]));
                    mPaint.setTextSize(Utils.dip2px(getContext(),10));
                    mPaint.setTextAlign(Paint.Align.CENTER);
                    mPaint.getTextBounds(String.valueOf(i + 1) + "", 0, String.valueOf(i).length(), mBound);
                    canvas.drawText(mTags[i], mStartWidth+mChartWidth/4,
                            rectF.bottom + mChartWidth, mPaint);
                }
                mStartWidth += getWidth() / 4;
            }
        }
    }

    @Override
    public boolean onTouchEvent(MotionEvent ev) {

        int x = (int) ev.getX();
        int y = (int) ev.getY();
        int left = 0;
        int top = 0;
        int right = mWidth / 12;
        int bottom = mHeight - 100;
        switch (ev.getAction()) {
            case MotionEvent.ACTION_DOWN:
                for (int i = 0; i < 12; i++) {
                    Rect rect = new Rect(left, top, right, bottom);
                    left += mWidth / 12;
                    right += mWidth / 12;
                    if (rect.contains(x, y)) {
                        if (listener != null) {
                            listener.getNumber(i, x, y);
                            number = i;
                            selectIndex = i;
                            selectIndexRoles.clear();
                            selectIndexRoles.add(selectIndex);
                            invalidate();
                        }
                    }
                }
                break;
            case MotionEvent.ACTION_UP:

                break;
        }
        return true;
    }

    public void setListener(getNumberListener listener) {
        this.listener = listener;
    }

    public interface getNumberListener {
        void getNumber(int number, int x, int y);
    }
}


猜你喜欢

转载自blog.csdn.net/yangzongbin/article/details/79814706