自定义圆角柱状图

本文介绍如何创建一个具有圆角的柱状图,展示12个月动态分割的Y轴数据。当点击柱状图时,当前月份会变色并显示虚线弹出信息。在滑动过程中,弹框和虚线消失,柱状图恢复原始状态。实现过程中涉及到HistogramRound、ChartYdate、嵌套ScrollView、FamilyStatusActivity、HistogramData和ChartData等关键点。
摘要由CSDN通过智能技术生成

需求:

画一个圆角柱状图,显示12个月的数据,Y轴数据动态分割,如果是当前月,就画出当前月图片;点击柱状图变色,并显示虚线弹出当前月信息,滑动时弹框和虚线消失,柱状图刷新到最初。

 

1.HistogramRound

package com.broker.liming.widget;

import android.annotation.TargetApi;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.DashPathEffect;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Rect;
import android.os.Build;
import android.support.annotation.Nullable;
import android.support.v4.content.ContextCompat;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;

import com.broker.liming.R;
import com.broker.liming.bean.ChartData;
import com.broker.liming.utils.ArithUtil;
import com.broker.liming.utils.LogUtil2;

import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.List;

/**
 * @author chenhuirong
 * @Date 2018/12/10
 * @Description zhu
 */

public class HistogramRound extends ChartYdate {
    private int[] rect_color;
    private int rect_text_color;//矩形文字颜色
    private int rect_big_text_color;//矩形最大文字颜色

    private int rect_text_size;//矩形文字尺寸

    private getNumberListener listener;
    private int selectIndex = -1;
    private int yHeightSelect=0;
    private int leftSelector=0;
    private boolean isScrollow;//true 滑动 false点击

    private List<Integer> selectIndexRoles = new ArrayList<>();
    private List<Object> objects=new ArrayList<>();

    public HistogramRound(Context context) {
        super(context);
    }

    public HistogramRound(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initStyle(context,attrs);
    }

    public HistogramRound(Context context, AttributeSet attrs) {
        super(context, attrs);
        initStyle(context,attrs);
    }
    /*
     * 初始化样式属性
     */
    private void initStyle(Context context,AttributeSet attrs) {
        TypedArray types = context.obtainStyledAttributes(attrs, R.styleable.zqxchart_histogram);
        coordinates_color = types.getColor(R.styleable.zqxchart_histogram_hCoordinatesColor, Color.RED);
        rect_text_color = types.getColor(R.styleable.zqxchart_histogram_rectTextColor,Color.BLACK);
        rect_big_text_color=getResources().getColor(R.color.text_yellow);
        rect_text_size = types.getInteger(R.styleable.zqxchart_histogram_rectTextSize,28);

        x_text_color = types.getColor(R.styleable.zqxchart_histogram_hxTextColor,Color.BLACK);
        y_text_color = types.getColor(R.styleable.zqxchart_histogram_hyTextColor,Color.BLACK);
        x_text_size = types.getInteger(R.styleable.zqxchart_histogram_hxTextSize,30);
        y_text_size = types.getInteger(R.styleable.zqxchart_histogram_hyTextSize,28);
        xpCount = types.getInteger(R.styleable.zqxchart_histogram_hxPointCount,12);
        ypCount = types.getInteger(R.styleable.zqxchart_histogram_hyPointCount,12);
        rect_color = getResources().getIntArray(R.array.histogram_color);
        animType = types.getInteger(R.styleable.zqxchart_histogram_hanimType, Anim.ANIM_NONE);
        types.recycle();
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        if (xData!=null&&yData!=null){
            drawHistogramRound(canvas);
        }

    }

    /*
     * 画柱状图
     */
    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    private void drawHistogramRound(Canvas canvas) {
        //如果没有设置x轴数据
        if (xData == null){
            throw new NullPointerException("x轴数据源不能为空!");
        }
        //如果没有设置y轴数据
        if (yData == null){
            throw new NullPointerException("y轴数据源不能为空!");
        }
        Paint histogramPaint = new Paint();
//        histogramPaint.setAntiAlias(true);
        histogramPaint.setStyle(Paint.Style.FILL);
        histogramPaint.setStrokeWidth((float) 4.0);
        histogramPaint.setStrokeCap(Paint.Cap.ROUND);
        //矩形上具体数据画笔
        Paint textPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
//        tv_mudi.setTextSize(TypedValue.COMPLEX_UNIT_PX,getResources().getDimension(R.dimen.font_13));
//        textPaint.setTextSize(rect_text_size);

        Paint mPaintCircle = new Paint(Paint.ANTI_ALIAS_FLAG);
//        mPaintCircle.setStyle(Paint.Style.ANTI_ALIAS_FLAG);
//
        mPaintCircle.setStrokeWidth(2);
        mPaintCircle.setColor(Color.parseColor("#ff5932"));
        mPaintCircle.setPathEffect(new DashPathEffect(new float[]{4, 4}, 0));
        mPaintCircle.setAntiAlias(true);
        textPaint.setTextSize(getResources().getDimension(R.dimen.font_9));
        DecimalFormat formater = new DecimalFormat("0.000");
        for (int i=0; i<xpCount; i++){
            try {
                histogramPaint.setColor(rect_color == null
                        ? getResources().getColor(R.color.colorPrimary)
                        : rect_color[i]);
            }catch (ArrayIndexOutOfBoundsException e){
                histogramPaint.setColor(getResources().getColor(R.color.colorPrimary));
            }
            int alpha = anims[i].getAlpha();
            textPaint.setAlpha(alpha);
            histogramPaint.setAlpha(alpha);
            //计算执行动画当前y坐标
            float top = anims[i].getCurrentY();
            float left = oX+xCoordinates[i]-xSpacing/5;
            float right = oX+xCoordinates[i]+xSpacing/3;
            String a = formater.format(yData[i]);
            String ydata=a.substring(0,a.indexOf("."));
            int[] textSize = getTextSize(xData[i],textPaint);
            float textY = top - textSize[1]/2;
            LogUtil2.log("yMax-------"+yMax+"--ydata--"+ydata);
            if (Float.valueOf(ydata)>=yMax){
                textPaint.setColor(rect_big_text_color);
            }else {
                textPaint.setColor(rect_text_color);
            }
            LogUtil2.log("yData--------------->ydataY轴上的数据"+ydata);
            //画矩形上文字
//            canvas.drawText(ydata,left+20,textY,textPaint);
            //计算每条柱状图的宽度
//            double tempBarWidth = (((int) mXinterval) >> 1) / mCategoryList.size();
//            mBarPaint.setStrokeWidth((float) tempBarWidth);
            if (selectIndex==i){
                histogramPaint.setColor(ContextCompat.getColor(getContext(), R.color.name_ffa646));
                //draw x 坐标
                yHeightSelect= (int) top/*-getPaddingTop() */- getPaddingBottom()-xTextSurplus-x_text_size;
                yHeightSelect= (int) (/*(oY+75)-(*/top/*+getPaddingTop()/)*/);
                leftSelector= (int) (left+(right-left)/2);
//                canvas.drawLine(oX,top, oX,top-yHeight,mPaintCircle);
                Path path = new Path();
                path.moveTo(oX, oX+xWidth+40);
                path.lineTo(oX, oX+xWidth+40);
//                canvas.drawPath(path, mPaintCircle);
//                canvas.drawLine(oX,top,oX+xWidth+40,top,mPaintCircle);
                if (!isScrollow){

                listener.getNumber(i, (int) oY, leftSelector,yHeightSelect, (int) oX);
                }
                LogUtil2.log("setSelect--画:--getHeight"+getHeight()+"--left--"+left+"--height--"+yHeightSelect+"--top--"+top+"--oy--"+oY);

            }else {
                histogramPaint.setColor(ContextCompat.getColor(getContext(), R.color.color_1FA6FB));

            }

           //画每一个矩形
            if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP){
                //画圆角柱只在5.0以上版本适用,以下版本会闪退
                canvas.drawRoundRect(left,top,right,oY,30,30,histogramPaint);
            }else {
                canvas.drawRect(left,top,right,oY,histogramPaint);
            }

            objects.add(histogramPaint);
        }

    }

    public void setPublicRefresh(){
        selectIndex=-1;
        invalidate();
        for (int i=0;i<objects.size();i++){
            Paint  paint= (Paint) objects.get(i);
            paint.setColor(ContextCompat.getColor(getContext(), R.color.color_1FA6FB));
            LogUtil2.log("柱子--"+paint);
        }
    }
//    public void isScrollow(boolean isScrollowt){
//        this.isScrollow=isScrollowt;
//    };
    /*
     * 设置数据
     */
    @Override
    public void setChartYdateData(ChartData chartData) {
        super.setChartYdateData(chartData);
        HistogramData histogramData = (HistogramData) chartData;
        this.rect_color = histogramData.getRectColor() != null ?
                histogramData.getRectColor() : this.rect_color;
        this.rect_text_size = getFinalValue(this.rect_text_size,histogramData.getRectTextSize());
        this.rect_text_color = getFinalValue(this.rect_text_color,histogramData.getRectTextColor());
    }


    @Override
    public void setOnLongClickListener(@Nullable OnLongClickListener l) {
        super.setOnLongClickListener(l);
        LogUtil2.log("onDraw--getX---弹框的长按事件:" + isScrollow);
    }

    @Override
    protected void onOverScrolled(int scrollX, int scrollY, boolean clampedX, boolean clampedY) {
        super.onOverScrolled(scrollX, scrollY, clampedX, clampedY);
        LogUtil2.log("onDraw--getX---弹框的滑动事件:" + isScrollow);
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        LogUtil2.log("onDraw--getX---弹框的滑动改变事件:" + isScrollow);
    }

    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        int x =0;
        int y =0;
        int left = getPaddingLeft()+yTextSurplus;
        int top = 0;
        int right = xWidth/ 12+getPaddingLeft()+yTextSurplus;
        int bottom = yHeight;
//        int right = getWidth()/ 12;
//        int bottom = yHeight;
        switch (ev.getAction()) {
            case MotionEvent.ACTION_DOWN:
                x = (int) ev.getX();
                y = (int) ev.getY();
                LogUtil2.log("setSelect--666down--x" + x + "--left--" + y + "ev--x" + ev.getX() + "ev--y" + ev.getY());

//                if (isScrollow) {
                  /*  for (int i = 0; i < 12; i++) {
                        Rect rect = new Rect(left, top, right, bottom);
                        left += xWidth / 12;
                        right += xWidth / 12;

                        if (rect.contains(x, y)) {
                            if (listener != null) {
                                LogUtil2.log("setSelect--666down--x" + x + "--left--" + y + "ev--x" + ev.getX() + "ev--y" + ev.getY());

                                //抬起坐标减去放下坐标绝对值小于20代表点击,否则代表滑动
//                            if (Math.abs(ArithUtil.sub(ev.getX(), x)) <= 20 && Math.abs(ArithUtil.sub(ev.getY(), y)) <= 20) {
                                selectIndex = i;
                                selectIndexRoles.clear();
                                se
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值