文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

Android如何自定义圆角柱状图

2023-06-29 04:01

关注

这篇文章主要为大家展示了“Android如何自定义圆角柱状图”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“Android如何自定义圆角柱状图”这篇文章吧。

具体内容如下

需求:

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

Android如何自定义圆角柱状图

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;  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- getPaddingBottom()-xTextSurplus-x_text_size;                yHeightSelect= (int) (top);                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) {                  //                }                break;            case MotionEvent.ACTION_MOVE:                isScrollow=true;                LogUtil2.log("setSelect--666Move--x" + x + "--left--" + y + "ev--x" + ev.getX() + "ev--y" + ev.getY());                 break;            case MotionEvent.ACTION_UP:                isScrollow=false;                x = (int) ev.getX();                y = (int) ev.getY();                LogUtil2.log("setSelect--666UP--x" + x + "--left--" + y + "ev--x" + ev.getX() + "ev--y" + ev.getY());                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) {                             //抬起坐标减去放下坐标绝对值小于20代表点击,否则代表滑动//                            if (Math.abs(ArithUtil.sub(ev.getX(), x)) <= 20 && Math.abs(ArithUtil.sub(ev.getY(), y)) <= 20) {                            selectIndex = i;                            selectIndexRoles.clear();                            selectIndexRoles.add(selectIndex);                            invalidate();//                            }                        }                    }                }                break;        }        return true;    }      public void setListener(getNumberListener listener) {        this.listener = listener;    }     public interface getNumberListener {        void getNumber(int number, int x, int y,int HeightSelect,int ox);    }}

2.ChartYdate

package com.broker.liming.widget; import android.content.Context;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.graphics.Canvas;import android.graphics.Paint;import android.graphics.Rect;import android.graphics.RectF;import android.support.v4.content.ContextCompat;import android.util.AttributeSet;import android.view.MotionEvent;import android.view.View; import com.broker.liming.R;import com.broker.liming.bean.ChartData;import com.broker.liming.utils.DensityUtil;import com.broker.liming.utils.DoubleUtils;import com.broker.liming.utils.LogUtil2; import java.math.BigDecimal;import java.text.DecimalFormat;import java.text.SimpleDateFormat;import java.util.ArrayList;import java.util.Date;import java.util.List; public class ChartYdate extends View {     protected final int xSurplus = 0;//x轴留余    protected final int ySurplus = 20;//y轴留余    protected final int xTextSurplus = 150;//x轴文字留余    protected final int yTextSurplus = 100;//y轴文字留余    protected float oX;//原点x    protected float oY;//原点y    protected int xWidth;//x轴宽度    protected int yHeight;//y轴高度    protected int xSpacing;//x轴坐标间距    protected int ySpacing;//y轴坐标间距    protected int xpCount = 7;//x轴坐标点数    protected int ypCount = 7;//y轴坐标点数    protected int[] xCoordinates;//x轴坐标点    protected int[] yCoordinates;//y轴坐标点    protected float yMax = 0f;//y轴最大刻度值    protected String[] xData;//x轴数据    protected float[] yData;//y轴数据    protected int coordinates_color;//坐标系颜色    protected int x_text_size;//x轴文字尺寸    protected int y_text_size;//y轴文字尺寸    protected int x_text_color;//x轴文字颜色    protected int y_text_color;//y轴文字颜色     protected boolean isAnim = true;    protected Anim[] anims;//动画数组    protected long interval = 100;//动画执行间隔    protected int animType = -2;//动画    private Paint mTableValuePaint;//    private getNumberListener listener;//    private int selectIndex = -1;//    private List<Integer> selectIndexRoles = new ArrayList<>();     public ChartYdate(Context context) {        super(context);    }     public ChartYdate(Context context, AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);    }     public ChartYdate(Context context, AttributeSet attrs) {        super(context, attrs);    }     @Override    protected void onDraw(Canvas canvas) {        LogUtil2.log("yData--------------->onDraw画布"+ypCount);        initChartYdateProp();        initCoordinateSystem(canvas);        //开始动画        if (isAnim){            initAnims();            post(animator);            isAnim = false;        }    }        private void initChartYdateProp() {        //x轴宽度        xWidth = getWidth() - getPaddingLeft() - getPaddingRight() - yTextSurplus;        //y轴宽度        yHeight = getHeight() - getPaddingTop() - getPaddingBottom() - xTextSurplus;        //x轴每个刻度的间距        xSpacing = (xWidth-xSurplus-xWidth%xpCount)/xpCount;        //y轴每个刻度的间距        ySpacing = (yHeight-ySurplus-yHeight%ypCount)/ypCount;        //坐标系原点x        oX = getPaddingLeft()+yTextSurplus;        //坐标系原点y  减70为了画出当月图片        oY = getPaddingTop()+yHeight+xTextSurplus/2-70;        //x轴各刻度点位置        xCoordinates = new int[xpCount];        //y轴各刻度点位置        yCoordinates = new int[ypCount];        //记录x轴刻度点位置  修改柱形图离坐标原点的距离        for (int i=0; i<xpCount; i++){            xCoordinates[i] = (i+1) * xSpacing- 30;        }        LogUtil2.log("yData--------------->ypCount记录y轴刻度点位置"+ypCount);        //记录y轴刻度点位置        for (int j=0; j<ypCount; j++){            yCoordinates[j] = (j+1) * ySpacing;            LogUtil2.log("yData--------------->henghe"+yCoordinates[j]);        }        LogUtil2.log("yData--------------->yCoordinates记录y轴刻度点位置"+yCoordinates.length);    }        private void initCoordinateSystem(Canvas canvas){        Paint mainPaint = new Paint();        mainPaint.setColor(coordinates_color);        mainPaint.setAntiAlias(true);        //draw x 坐标//        canvas.drawLine(oX,oY, oX,oY-yHeight,mainPaint);        //draw y 坐标//        canvas.drawLine(oX,oY,oX+xWidth+40,oY,mainPaint);        //刻度值画笔        Paint textPaint = new Paint(Paint.ANTI_ALIAS_FLAG);        textPaint.setColor(getResources().getColor(R.color.transparent));        mTableValuePaint = new Paint();        mTableValuePaint.setStrokeWidth(DensityUtil.dip2px(getContext(), 0.04f));        mTableValuePaint.setStyle(Paint.Style.FILL);        mTableValuePaint.setColor(ContextCompat.getColor(getContext(), R.color.text_666666));        mTableValuePaint.setAntiAlias(true);        mTableValuePaint.setTextSize(DensityUtil.dip2px(getContext(), 13));        //draw x 刻度        for (int i=0; i<xCoordinates.length; i++){            //更改文字大小//            textPaint.setTextSize(x_text_size);            textPaint.setTextSize(getResources().getDimension(R.dimen.font_9));            //更改文字颜色            textPaint.setColor(x_text_color);            //x轴刻度线//            canvas.drawLine(oX+xCoordinates[i],oY,oX+xCoordinates[i],oY-5,mainPaint);            //获取x轴文字宽高            if (xData!=null&&xData.length>0){                int[] textSize = getTextSize(xData[i],textPaint);                //计算x轴文字x,y坐标偏移量                int textX = textSize[0]/2;                int textY = xTextSurplus/2 - textSize[1]/2;                //画x轴文字                canvas.drawText(xData[i],oX+xCoordinates[i]-textX,oY+textY,textPaint);                String[] strNow = new SimpleDateFormat("yyyy-MM-dd").format(new Date()).toString().split("-");                Integer year = Integer.parseInt(strNow[0]);                Integer month = Integer.parseInt(strNow[1]);                //画当前月图片 + DensityUtil.dip2px(mContext, 6)                if (month == Integer.parseInt(xData[i])) {                    Bitmap arrow = BitmapFactory.decodeResource(getResources(), R.mipmap.current_month);                    RectF rectF = new RectF((float) (oX+xCoordinates[i]-textX - DensityUtil.dip2px(getContext(), 10)),                            (float) (oY+textY+60 - DensityUtil.dip2px(getContext(), 15)),                            (float) (oX+xCoordinates[i]-textX + DensityUtil.dip2px(getContext(), 20)),                            (float) (oY+textY+70 - DensityUtil.dip2px(getContext(), 3)));                    canvas.drawBitmap(arrow, null, rectF, textPaint);                }            }        }        if(yMax == 0f){            yMax = getYMax();        }        if(getYMax()==0){            yMax=1.0f;        }         //draw y 刻度        for (int j=0; j<ypCount; j++){            //更改文字大小            textPaint.setTextSize(y_text_size);             //y轴刻度线//            canvas.drawLine(oX,oY-yCoordinates[j],oX+5,oY-yCoordinates[j],mainPaint);            //y轴刻度值            int iYMax = (int)yMax;            String datay;            if (yMax - iYMax == 0){                datay = (int)(yMax/ypCount*(j+1))+"";            }else {                datay = new DecimalFormat("0.000").format(yMax/ypCount*(j+1));            }            //平均分成4份//            Double mMaxDiv = DoubleUtils.getLargerInterger(yMax, 7);//            datay= String.valueOf((new BigDecimal((j + 1) * mMaxDiv).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue()));              int att=(int) Math.floor(yMax);            String mBigst=String.valueOf(att);//            String mBigst=String.valueOf(yMax).substring(0, String.valueOf(yMax).indexOf("."));            int maxLength=mBigst.length();            int baseMax= att+1;            if (maxLength>=2){                baseMax= Integer.valueOf(mBigst.substring(0, 2))+1;            }            boolean isBreak=false;            int margCount=0;             String  ii="";//画y轴最大值            String aa="";//间隔            for (int i=baseMax;i<baseMax+100;i++){                for (int a=100;a>0;a--){                    if (i%a==0&&i/a<=6&&i/a>=4){                        margCount=i/a;                        ii= String.valueOf(i);                        aa=String .valueOf(a);                        isBreak=true;                        break;                    }                }                if (isBreak)                    break;            }            for (int y=0;y<maxLength-2;y++){                aa=aa+"0";                ii=ii+"0";            }//            double mm=formatTosepara2(Double.valueOf(aa));//            int mm+=Integer.parseInt(aa)*j;            //String.valueOf(Integer.parseInt(aa)*(j+1))            datay= formatTosepara2(Double.valueOf(Integer.parseInt(aa)*(j+1)));//            LogUtil2.log("ydate---+++"+datay+"---"+ii);            //获取文字宽高            int[] textSize = getTextSize(datay,textPaint);            //计算画文字的坐标偏移量            int textX = yTextSurplus/2 + textSize[0]/2;            int textY = textSize[1]/2;            //画y轴文字            textPaint.setColor(y_text_color);            if (j==0){                canvas.drawText("0",oX-textX,oY,textPaint);            }            canvas.drawText(datay,oX-textX,oY-yCoordinates[j]+textY,textPaint);        }        LogUtil2.log("ydate---+++"+yData.toString());     }    public String formatTosepara2(double data) {        int length = String.valueOf(data).split("\\.")[0].length();        if (length < 4) {            return String.format("%.2f", data);        }        DecimalFormat df = new DecimalFormat("##,###");        return df.format(data);    }        private void initAnims() {        anims = new Anim[xpCount];//        switch (animType){//            case Anim.ANIM_TRANSLATE://                for (int i=0;i<xpCount;i++){//                    float dataX = oX+xCoordinates[i];//                    float dataY = oY-yData[i]/yMax*yCoordinates[yCoordinates.length-1];//                    Anim anim = new Anim(dataX,dataY,dataX,oY);//                    anim.setAnimation(new TranslateAnim());//                    anim.setVelocity(interval*2);//                    anims[i] = anim;//                }//                break;//            case Anim.ANIM_ALPHA://                for (int i=0;i<xpCount;i++){//                    float dataX = oX+xCoordinates[i];//                    float dataY = oY-yData[i]/yMax*yCoordinates[yCoordinates.length-1];//                    Anim anim = new Anim(dataX,dataY,dataX,dataY);//                    anim.setAnimation(new AlphaAnim());//                    anim.setAlpha(0);//                    anim.setVelocity(interval * 3/2);//                    anims[i] = anim;//                }//                break;//            default://        for (int i=0;i<xpCount;i++){//            float dataX = oX+xCoordinates[i];//            float dataY = oY-yData[i]/yMax*yCoordinates[yCoordinates.length-1];//            Anim anim = new Anim(dataX,dataY,dataX,dataY);//            anim.setAnimation(new TranslateAnim());//            anim.setVelocity(interval);//            anims[i] = anim;//        }        for (int i=0;i<xpCount;i++){            float dataX = oX+xCoordinates[i];            LogUtil2.log("yData----------dataX"+oX+xCoordinates[i]);            LogUtil2.log("yData----------yData"+yData.length);            LogUtil2.log("yData----------xpCount"+xpCount);            LogUtil2.log("yData----------yCoordinates"+yCoordinates.length);            //平均分成4份            Double mMaxDi = DoubleUtils.getLargerInterger(yMax, 7);            //设置Y轴分值            float total=0;//            float total= (float) new BigDecimal((7) * mMaxDi).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();            LogUtil2.log("最大值--"+yMax);            int att=(int) Math.floor(yMax);            String mBigst=String.valueOf(att);//            String mBigst=String.valueOf((int) Math.floor(yMax));            LogUtil2.log("最大值--"+yMax+"---"+mBigst);//            String mBigst=String.valueOf(yMax).substring(0, String.valueOf(yMax).indexOf("."));            int maxLength=mBigst.length();            int baseMax= att+1;            if (maxLength>=2){                baseMax= Integer.valueOf(mBigst.substring(0, 2))+1;            }            boolean isBreak=false;            String aa="";//间隔值            String ii="";//y轴最大            int margCount=0;//分多少份,动态设置            for (int j=baseMax;j<baseMax+100;j++){                for (int a=100;a>0;a--){                    if (j%a==0&&j/a<=6&&j/a>=4){                        margCount=j/a;                        aa=String.valueOf(a);                        ii=String.valueOf(j);                        isBreak=true;                        break;                    }                }                if (isBreak)                    break;            }             for (int y=0;y<maxLength-2;y++){                aa=aa+"0";                ii=ii+"0";//                total= Float.parseFloat(String.valueOf(baseMax)+"0");            }            LogUtil2.log("total"+total);            total= Float.parseFloat(ii);            LogUtil2.log("aa--"+aa+"--total"+total);            float dataY = oY-yData[i]/total*yCoordinates[yCoordinates.length-1];            LogUtil2.log("yData----------dataY"+dataY);            Anim anim = new Anim(dataX,dataY,dataX,dataY);            anim.setAnimation(new TranslateAnim());            anim.setVelocity(interval);            anims[i] = anim;            LogUtil2.log("yData----------anims"+anims);        }//                break;//        }    }         protected float getYMax(){        if (yData == null || yData.length == 0){            yData = new float[ypCount];        }        float max =0;        for (int i=0; i<yData.length; i++){            if (max < yData[i]){                max = yData[i];            }        }        return max;    }         protected int[] getTextSize(String str,Paint paint){        //计算文字所在矩形,可以得到宽高        Rect rect = new Rect();        paint.getTextBounds(str, 0, str.length(), rect);        int w = rect.width();        int h = rect.height();        return new int[]{w,h};    }        public void setChartYdateData(ChartData chartData) {        if (chartData == null){            throw new NullPointerException("折线图数据不能为空!");        }        this.xData = chartData.getXdata();        this.yData = chartData.getYdata();        this.xpCount = getFinalValue(this.xpCount,chartData.getXpCount());        this.ypCount = getFinalValue(this.ypCount,chartData.getYpCount());        this.coordinates_color = getFinalValue(this.coordinates_color,chartData.getCoordinatesColor());        this.x_text_size = getFinalValue(this.x_text_size,chartData.getxTextSize());        this.y_text_size = getFinalValue(this.y_text_size,chartData.getyTextSize());        this.x_text_color = getFinalValue(this.x_text_color,chartData.getxTextColor());        this.y_text_color = getFinalValue(this.y_text_color,chartData.getyTextColor());        this.interval = getFinalValue((int) this.interval,chartData.getInterval());//        this.animType = chartData.getAnimType() != -2 ? chartData.getAnimType()//                : this.animType;        this.yMax = chartData.getyMax() != 0f ? chartData.getyMax() : this.yMax;    }        protected int getFinalValue(int old,int news){        old = news != 0 ? news : old;        return old;    }        private Runnable animator = new Runnable() {        @Override        public void run() {            LogUtil2.log("yData----------anims循环"+anims);            LogUtil2.log("yData----------anims长多"+anims.length);            for(Anim a : anims){                LogUtil2.log("yData----------anims循环2"+a.isOver());                if(!a.isOver()){                    a.refresh();                    postDelayed(this, interval);                    invalidate();                    return;                }            }        }    };        public void update(ChartData chartData){        yMax = 0;        setChartYdateData(chartData);        isAnim = true;        invalidate();    }   }

3.布局 activity_family_status嵌套在Scrollowview中

 <android.support.v4.widget.NestedScrollView        android:id="@+id/scrollowview"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:fillViewport="true"        android:layout_marginBottom="@dimen/lay_10"        >        <LinearLayout            android:layout_width="match_parent"            android:layout_height="wrap_content"            android:orientation="vertical"            >                          <com.broker.liming.widget.HistogramRound                    android:id="@+id/histogramchart"                    android:layout_width="@dimen/lay_320"                    android:layout_height="220dp"                    android:layout_marginLeft="@dimen/lay_12"                    chart:hCoordinatesColor="@color/text_999999"                    chart:hxTextColor="@color/color_6a6a6a"                    chart:hyTextColor="@color/color_1FA6FB"                    />            <LinearLayout/><android.support.v4.widget.NestedScrollView/>

4.运用FamilyStatusActivity

package com.broker.liming.activity; import android.content.Context;import android.content.Intent; import android.support.annotation.RequiresApi;import android.support.v4.widget.NestedScrollView;import android.support.v7.widget.LinearLayoutManager;import com.broker.liming.utils.ArithUtil;import com.broker.liming.utils.BarUtils;import com.broker.liming.utils.GsonUtils;import com.broker.liming.utils.LogUtil2;import com.broker.liming.utils.UIHelper;import com.broker.liming.widget.HistogramData;import com.broker.liming.widget.HistogramRound;import com.broker.liming.widget.TitleBar; import org.json.JSONException; import java.text.DecimalFormat;import java.text.SimpleDateFormat;import java.util.ArrayList;import java.util.Arrays;import java.util.Date;import java.util.List; import butterknife.BindView; import static com.sobot.chat.utils.ScreenUtils.dip2px;import static com.sobot.chat.utils.ScreenUtils.px2dip;  public class FamilyStatusActivity extends BaseActivity{       @BindView(R.id.histogramchart)    HistogramRound histogramChart;     @BindView(R.id.scrollowview)    NestedScrollView scrollowview;    private FamilyStatusAdapter adapter;    private FamilyStatusRateAdapter rateAdapter;    private  HistogramData histogramData;    //柱状图//    @BindView(R.id.my_single_chart_view)//    SingleView mMySingleChartView;    @BindView(R.id.rl_single)    RelativeLayout rlSingle;    private List<Float> singlelist;    private LinearLayout llSingle;    private double mMax = 44;    private List<FamilyPremiumArrayBean> listData = new ArrayList<>();    private String monthBack;      float[] ydata = new float[12];    private String[] xdata= new String[12] ;    private String[] xdataShow= new String[12] ;//仅为显示    private boolean isScrollow=true;    private boolean isFresh=false;    int margCount=0;//共分多少份    private LinearLayout line;    private String name;    public static void actionStart(Context context, String familyUuid,String names) {        Intent intent = new Intent(context, FamilyStatusActivity.class);        intent.putExtra("familyUuid", familyUuid);        intent.putExtra("name",names);        context.startActivity(intent);    }    @Override    protected void initTitleBar() {        TitleBar titleBar = (TitleBar) findViewById(R.id.title_bar);        assert titleBar != null;                titleBar.setLeftBackground(R.mipmap.order_back);         titleBar.setTitle(name+"的家庭数据分析");        titleBar.setTitleColor(R.color.text_000000);         titleBar.setTitleBarBg(getResources().getColor(R.color.white));        titleBar.setLeftClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                finish();            }        });    }     @Override    protected int getContentView() {        return R.layout.activity_family_status;    }    @Override    protected boolean initBundle(Bundle bundle) {           }      @Override    public void initData() {        super.initData();     }     @Override    protected void onResume() {        super.onResume();             getPieDate(familyUuid);    }     public void getHomeData() {        try {            UserBean query = UserBeanDao.query();            requestServerPostForm(false, 100, HttpParams.getFamilyStatus(query, familyUuid));         } catch (JSONException e) {            e.printStackTrace();        }    }     @Override    public void initView() {        xdata=new String[]{"1","2","3","4","5","6","7","8","9","10","11","12"};        xdataShow=new String[]{"01","02","03","04","05","06","07","08","09","10","11","12"};         initSingle();         scrollowview.setOnTouchListener(new View.OnTouchListener() {            @Override            public boolean onTouch(View v, MotionEvent event) {                LogUtil2.log("onDraw--getX---isScrollow" +isScrollow);                float x=0;                float y=0;                switch (event.getAction()) {                    case MotionEvent.ACTION_DOWN:                        x = event.getX();                        y = event.getY();                         LogUtil2.log("onDraw--getX---down" + event.getX() + "---" + y);                        break;                    case MotionEvent.ACTION_MOVE:                        LogUtil2.log("onDraw--getX---move:" + event.getX() + "---");//                        isFresh=true;                        //在此刷新柱状图,防止多次刷新,多次重绘                        if (isScrollow){                            rlSingle.removeView(llSingle);                            rlSingle.removeView(line);                            histogramChart.setPublicRefresh();//                            histogramChart.isScrollow(isFresh);                            isScrollow=false;                        }                        break;                    case MotionEvent.ACTION_CANCEL:                    case MotionEvent.ACTION_UP://                        //允许ScrollView截断点击事件,ScrollView可滑动                        LogUtil2.log("onDraw--getX---up" + event.getX() + "mLastWownY:" + event.getY()+"x差值:"+Math.abs(ArithUtil.sub(event.getX(), x))+"--y差值:"+ Math.abs(ArithUtil.sub(event.getY(), y))  );                         //抬起坐标减去放下坐标绝对值小于20代表点击,否则代表滑动                                               break;                }                 return false;            }        });        changeStatusBarTextColor(true);        BarUtils.setColorNoTranslucent(this, getResources().getColor(R.color.white));    }          private void initSingle(){        rlSingle = (RelativeLayout) findViewById(R.id.rl_single);        singlelist = new ArrayList<>();        rlSingle.removeView(llSingle);        rlSingle.removeView(line);         histogramChart.setOnLongClickListener(new View.OnLongClickListener() {            @Override            public boolean onLongClick(View v) {                LogUtil2.log("onDraw--getX---弹框的长按事件:" + isScrollow);                return false;            }        });          histogramChart.setListener(new HistogramRound.getNumberListener() {            @Override            public void getNumber(int index, int height, int left,int selectorHeight,int ox) {//                rlSingle.removeAllViews();                LogUtil2.log("onDraw--getX---弹框:" + isScrollow);                isScrollow=true;//                if(!isFresh){                     rlSingle.removeView(llSingle);                    rlSingle.removeView(line);                    line= (LinearLayout) LayoutInflater.from(FamilyStatusActivity.this).inflate(R.layout.layout_dash_line, null); //                TextView view=new TextView(mContext);//              view.setBackground(mContext.getResources().getDrawable(R.drawable.shape_dash_line));                    RelativeLayout.LayoutParams viewParam=new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.WRAP_CONTENT);viewParam. topMargin=height-selectorHeight;                    viewParam.topMargin=selectorHeight-5;                    viewParam.leftMargin=dip2px(mContext,40);                    viewParam.rightMargin=dip2px(mContext,30);                    line.setLayoutParams(viewParam);                    rlSingle.addView(line);                     llSingle = (LinearLayout) LayoutInflater.from(FamilyStatusActivity.this).inflate(R.layout.layout_pro_expense, null);                    LinearLayout ll_back=(LinearLayout)llSingle.findViewById(R.id.ll_back);                    TextView tvMoney = (TextView) llSingle.findViewById(R.id.tv_month);                    TextView tv_money=(TextView) llSingle.findViewById(R.id.tv_money);                    if (singlelist!=null&&singlelist.size()>0){                        tv_money.setText(formatTosepara2(singlelist.get(index))+"");                    }else {                        tv_money.setText("0");                    }                    String[] strNow = new SimpleDateFormat("yyyy-MM-dd").format(new Date()).toString().split("-");                    String year = strNow[0];                    tvMoney.setText(year+"-"+xdataShow[index]);                    RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT,                            RelativeLayout.LayoutParams.WRAP_CONTENT);                     LogUtil2.log("setSelect--callback--"+height+"--left---"+left+"---"+selectorHeight+"弹框高--"+dip2px(mContext,60)+"--差值--"+(height-(height-selectorHeight)-dip2px(mContext,60)));                    LogUtil2.log("----宽-----+++"+params.width);                    LogUtil2.log("setSelect--转换"+px2dip(mContext,height)+"--left---"+px2dip(mContext,left)+"---"+dip2px(mContext,selectorHeight));                    int topmargin=0;                    int leftmargin=0;                    LogUtil2.log("setSelect--差距"+px2dip(mContext,height-selectorHeight));                    if (index+1>6){                        if (height-(height-selectorHeight)-dip2px(mContext,60)-dip2px(mContext,5)>0){                            ll_back.setBackground(mContext.getResources().getDrawable(R.mipmap.right_bottom));                            topmargin=height-(height-selectorHeight)-dip2px(mContext,60)-dip2px(mContext,5);                        }else {                            topmargin= height-(height-selectorHeight)+dip2px(mContext,5);                            ll_back.setBackground(mContext.getResources().getDrawable(R.mipmap.right_top));                        }//                        leftmargin=left-dip2px(mContext,150)+dip2px(mContext,40);                    }else {                        if (height-(height-selectorHeight)-dip2px(mContext,60)-dip2px(mContext,5)>0){                            ll_back.setBackground(mContext.getResources().getDrawable(R.mipmap.left_bottom));                            topmargin=height-(height-selectorHeight)-dip2px(mContext,60)-dip2px(mContext,5);                        }else {                            ll_back.setBackground(mContext.getResources().getDrawable(R.mipmap.left_top));                            topmargin=height-(height-selectorHeight)+dip2px(mContext,5);                        }                        leftmargin=left;                    }                    params.leftMargin = leftmargin;                    //相当于总布局的上方,需要减去家庭保费和保费距离                    params.topMargin=topmargin;//                LogUtil2.log("setSelect--callback--"+histogramChart.getHeight()+"---"+selectorHeight+"---left"+ params.topMargin);//                if (x - 100 < 0) {//                    params.leftMargin = 0;//                } else if (x - 100 > relativeLayout.getWidth() - llSingle.getMeasuredWidth()) {//                    params.leftMargin = relativeLayout.getWidth() - llSingle.getMeasuredWidth();//                }                     llSingle.setLayoutParams(params);                    rlSingle.addView(llSingle);//                }            }        });    }     private void changeStatusBarTextColor(boolean isBlack) {        if (Build.VERSION.SDK_INT > Build.VERSION_CODES.M) {            if (isBlack) {                getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);//设置状态栏黑色字体            }else {                getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_VISIBLE);//恢复状态栏白色字体            }        }    }      private void setDate(FamilyYearCheakBean yearCheakBean) {         if (yearCheakBean != null) {            if (yearCheakBean.familyPremiumTotal != null && !yearCheakBean.familyPremiumTotal.equals("")) {                tv_total_money.setText("合计年缴"+formatTosepara(Double.valueOf(String.valueOf(yearCheakBean.familyPremiumTotal))) + "元");            }else {                tv_total_money.setText("合计年缴0.00元");             }             String[] strNow = new SimpleDateFormat("yyyy-MM-dd").format(new Date()).toString().split("-");            Integer year = Integer.parseInt(strNow[0]);            Integer month = Integer.parseInt(strNow[1]);            listData = yearCheakBean.familyPremiumArray;            List<Double> list = new ArrayList<>();            ArrayList<DotVo> temp = new ArrayList();             for (int i = 0; i < listData.size(); i++) {                FamilyPremiumArrayBean bean = listData.get(i);                String yearback = bean.MONTH.substring(0, bean.MONTH.indexOf("-"));                monthBack = bean.MONTH.substring(bean.MONTH.lastIndexOf("-") + 1);//                mXdots[i] = yearback + "年\n" + monthBack + "月";                list.add(Double.valueOf(bean.premium));                double premium = 0;                if (bean.premium != null && !bean.premium.equals("")) {                    premium = Double.valueOf(bean.premium);                    list.add(Double.valueOf(bean.premium));                    singlelist.add(Float.valueOf(bean.premium));                    ydata[i]=Float.valueOf(bean.premium);                 }                DotVo tempDotVo = new DotVo(monthBack, premium);                temp.add(tempDotVo);             }             Double[] toBeStored = list.toArray(new Double[list.size()]);            mMax = checkMax(toBeStored);         }        //向下取整        int att=(int) Math.floor(mMax);        String mBigst=String.valueOf(att);        int maxLength=mBigst.length();        int baseMax= att+1;        if (maxLength>=2){            baseMax= Integer.valueOf(mBigst.substring(0, 2))+1;        }        boolean isBreak=false;         for (int i=baseMax;i<baseMax+100;i++){            for (int a=100;a>0;a--){                if (i%a==0&&i/a<=6&&i/a>=4){                    margCount=i/a;                    isBreak=true;                    break;                }            }            if (isBreak)                break;        }        for (int i=0;i<maxLength-2;i++){         }        LogUtil2.log("ydata---设置数据"+ydata.toString()+"--最大分数--"+margCount);        histogramData = HistogramData.builder()                .setXdata(xdata)                .setYdata(ydata)                .setYpCount(margCount)//                .setAnimType(Anim.ANIM_ALPHA)                .build();        histogramChart.setChartYdateData(histogramData);        histogramChart.update(histogramData);     }    public double checkMax(Double[] args) {        double max = 0;        for (int i = 0; i < args.length; i++) {            if (args[i] > max) {                max = args[i];            }        }        return max;    }    @Override    protected void onSuccess(String response, int id) {        super.onSuccess(response, id);         switch (id){                      case 200:                yearCheakBean= GsonUtils.toObject(response,FamilyYearCheakBean.class);                             setDate(yearCheakBean);                              break;         }     }          public String formatTosepara(double data) {        int length = String.valueOf(data).split("\\.")[0].length();        if (length < 4) {            return String.format("%.2f", data);        }        DecimalFormat df = new DecimalFormat("#,####.00");        return df.format(data);    }    public String formatTosepara2(double data) {        int length = String.valueOf(data).split("\\.")[0].length();        if (length < 4) {            return String.format("%.2f", data);        }        DecimalFormat df = new DecimalFormat("##,###");        return df.format(data);    } }

5.HistogramData

package com.broker.liming.widget; import com.broker.liming.bean.ChartData;  public class HistogramData extends ChartData {    private int[] rectColor;    private int rectTextColor;    private int rectTextSize;     private HistogramData(Builder builder) {        setXdata(builder.xdata);        setYdata(builder.ydata);        setXpCount(builder.xpCount);        setYpCount(builder.ypCount);        setCoordinatesColor(builder.coordinatesColor);        setxTextSize(builder.xTextSize);        setyTextSize(builder.yTextSize);        setxTextColor(builder.xTextColor);        setyTextColor(builder.yTextColor);        setyMax(builder.yMax);        setInterval(builder.interval);        setAnimType(builder.animType);        setRectColor(builder.rectColor);        setRectTextColor(builder.rectTextColor);        setRectTextSize(builder.rectTextSize);    }     public static Builder builder() {        return new Builder();    }     public int[] getRectColor() {        return rectColor;    }     public void setRectColor(int[] rectColor) {        this.rectColor = rectColor;    }     public int getRectTextColor() {        return rectTextColor;    }     public void setRectTextColor(int rectTextColor) {        this.rectTextColor = rectTextColor;    }     public int getRectTextSize() {        return rectTextSize;    }     public void setRectTextSize(int rectTextSize) {        this.rectTextSize = rectTextSize;    }     public static final class Builder{        private int rectTextSize;        private int rectTextColor;        private int[] rectColor;        private int animType;        private int interval;        private int yMax;        private int yTextColor;        private int xTextColor;        private int yTextSize;        private int xTextSize;        private int coordinatesColor;        private int ypCount;        private int xpCount;        private float[] ydata;        private String[] xdata;         private Builder(){}         public Builder setRectTextSize(int val) {            rectTextSize = val;            return this;        }         public Builder setRectTextColor(int val) {            rectTextColor = val;            return this;        }         public Builder setRectColor(int[] val) {            rectColor = val;            return this;        }         public Builder setAnimType(int val) {            animType = val;            return this;        }         public Builder setInterval(int val) {            interval = val;            return this;        }         public Builder setYMax(int val) {            yMax = val;            return this;        }         public Builder setYTextColor(int val) {            yTextColor = val;            return this;        }         public Builder setXTextColor(int val) {            xTextColor = val;            return this;        }         public Builder setYTextSize(int val) {            yTextSize = val;            return this;        }         public Builder setXTextSize(int val) {            xTextSize = val;            return this;        }         public Builder setCoordinatesColor(int val) {            coordinatesColor = val;            return this;        }         public Builder setYpCount(int val) {            ypCount = val;            return this;        }         public Builder setXpCount(int val) {            xpCount = val;            return this;        }         public Builder setYdata(float[] val) {            ydata = val;            return this;        }         public Builder setXdata(String[] val) {            xdata = val;            return this;        }         public HistogramData build() {            return new HistogramData(this);        }    }}

6.ChartData

package com.broker.liming.bean; public class ChartData {    protected String[] xdata;    protected float[] ydata;    protected int xpCount;    protected int ypCount;    protected int coordinatesColor;    protected int xTextSize;    protected int yTextSize;    protected int xTextColor;    protected int yTextColor;    protected int yMax;    protected int interval;    protected int animType = -2;     protected ChartData(){}     public String[] getXdata() {        return xdata;    }     public void setXdata(String[] xdata) {        this.xdata = xdata;    }     public float[] getYdata() {        return ydata;    }     public void setYdata(float[] ydata) {        this.ydata = ydata;    }     public int getXpCount() {        return xpCount;    }     public void setXpCount(int xpCount) {        this.xpCount = xpCount;    }     public int getYpCount() {        return ypCount;    }     public void setYpCount(int ypCount) {        this.ypCount = ypCount;    }     public int getCoordinatesColor() {        return coordinatesColor;    }     public void setCoordinatesColor(int coordinatesColor) {        this.coordinatesColor = coordinatesColor;    }     public int getxTextSize() {        return xTextSize;    }     public void setxTextSize(int xTextSize) {        this.xTextSize = xTextSize;    }     public int getyTextSize() {        return yTextSize;    }     public void setyTextSize(int yTextSize) {        this.yTextSize = yTextSize;    }     public int getxTextColor() {        return xTextColor;    }     public void setxTextColor(int xTextColor) {        this.xTextColor = xTextColor;    }     public int getyTextColor() {        return yTextColor;    }     public void setyTextColor(int yTextColor) {        this.yTextColor = yTextColor;    }     public int getyMax() {        return yMax;    }     public void setyMax(int yMax) {        this.yMax = yMax;    }     public int getInterval() {        return interval;    }     public void setInterval(int interval) {        this.interval = interval;    }     public int getAnimType() {        return animType;    }     public void setAnimType(int animType) {        this.animType = animType;    }}

以上是“Android如何自定义圆角柱状图”这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注编程网行业资讯频道!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯