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

具体内容如下

需求:

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

1.HistogramRound

packagecom.broker.liming.widget;importandroid.annotation.TargetApi;importandroid.content.Context;importandroid.content.res.TypedArray;importandroid.graphics.Canvas;importandroid.graphics.Color;importandroid.graphics.DashPathEffect;importandroid.graphics.Paint;importandroid.graphics.Path;importandroid.graphics.Rect;importandroid.os.Build;importandroid.support.annotation.Nullable;importandroid.support.v4.content.ContextCompat;importandroid.util.AttributeSet;importandroid.view.MotionEvent;importandroid.view.View;importandroid.view.ViewConfiguration;importcom.broker.liming.R;importcom.broker.liming.bean.ChartData;importcom.broker.liming.utils.ArithUtil;importcom.broker.liming.utils.LogUtil2;importjava.text.DecimalFormat;importjava.util.ArrayList;importjava.util.List;/***@authorchenhuirong*@Date2018/12/10*@Descriptionzhu*/publicclassHistogramRoundextendsChartYdate{privateint[]rect_color;privateintrect_text_color;//矩形文字颜色privateintrect_big_text_color;//矩形最大文字颜色privateintrect_text_size;//矩形文字尺寸privategetNumberListenerlistener;privateintselectIndex=-1;privateintyHeightSelect=0;privateintleftSelector=0;privatebooleanisScrollow;//true滑动false点击privateList<Integer>selectIndexRoles=newArrayList<>();privateList<Object>objects=newArrayList<>();publicHistogramRound(Contextcontext){super(context);}publicHistogramRound(Contextcontext,AttributeSetattrs,intdefStyleAttr){super(context,attrs,defStyleAttr);initStyle(context,attrs);}publicHistogramRound(Contextcontext,AttributeSetattrs){super(context,attrs);initStyle(context,attrs);}/**初始化样式属性*/privatevoidinitStyle(Contextcontext,AttributeSetattrs){TypedArraytypes=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();}@OverrideprotectedvoidonDraw(Canvascanvas){super.onDraw(canvas);if(xData!=null&&yData!=null){drawHistogramRound(canvas);}}/**画柱状图*/@TargetApi(Build.VERSION_CODES.LOLLIPOP)privatevoiddrawHistogramRound(Canvascanvas){//如果没有设置x轴数据if(xData==null){thrownewNullPointerException("x轴数据源不能为空!");}//如果没有设置y轴数据if(yData==null){thrownewNullPointerException("y轴数据源不能为空!");}PainthistogramPaint=newPaint();//histogramPaint.setAntiAlias(true);histogramPaint.setStyle(Paint.Style.FILL);histogramPaint.setStrokeWidth((float)4.0);histogramPaint.setStrokeCap(Paint.Cap.ROUND);//矩形上具体数据画笔PainttextPaint=newPaint(Paint.ANTI_ALIAS_FLAG);//tv_mudi.setTextSize(TypedValue.COMPLEX_UNIT_PX,getResources().getDimension(R.dimen.font_13));//textPaint.setTextSize(rect_text_size);PaintmPaintCircle=newPaint(Paint.ANTI_ALIAS_FLAG);//mPaintCircle.setStyle(Paint.Style.ANTI_ALIAS_FLAG);//mPaintCircle.setStrokeWidth(2);mPaintCircle.setColor(Color.parseColor("#ff5932"));mPaintCircle.setPathEffect(newDashPathEffect(newfloat[]{4,4},0));mPaintCircle.setAntiAlias(true);textPaint.setTextSize(getResources().getDimension(R.dimen.font_9));DecimalFormatformater=newDecimalFormat("0.000");for(inti=0;i<xpCount;i++){try{histogramPaint.setColor(rect_color==null?getResources().getColor(R.color.colorPrimary):rect_color[i]);}catch(ArrayIndexOutOfBoundsExceptione){histogramPaint.setColor(getResources().getColor(R.color.colorPrimary));}intalpha=anims[i].getAlpha();textPaint.setAlpha(alpha);histogramPaint.setAlpha(alpha);//计算执行动画当前y坐标floattop=anims[i].getCurrentY();floatleft=oX+xCoordinates[i]-xSpacing/5;floatright=oX+xCoordinates[i]+xSpacing/3;Stringa=formater.format(yData[i]);Stringydata=a.substring(0,a.indexOf("."));int[]textSize=getTextSize(xData[i],textPaint);floattextY=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);//计算每条柱状图的宽度//doubletempBarWidth=(((int)mXinterval)>>1)/mCategoryList.size();//mBarPaint.setStrokeWidth((float)tempBarWidth);if(selectIndex==i){histogramPaint.setColor(ContextCompat.getColor(getContext(),R.color.name_ffa646));//drawx坐标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);Pathpath=newPath();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);}}publicvoidsetPublicRefresh(){selectIndex=-1;invalidate();for(inti=0;i<objects.size();i++){Paintpaint=(Paint)objects.get(i);paint.setColor(ContextCompat.getColor(getContext(),R.color.color_1FA6FB));LogUtil2.log("柱子--"+paint);}}//publicvoidisScrollow(booleanisScrollowt){//this.isScrollow=isScrollowt;//};/**设置数据*/@OverridepublicvoidsetChartYdateData(ChartDatachartData){super.setChartYdateData(chartData);HistogramDatahistogramData=(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());}@OverridepublicvoidsetOnLongClickListener(@NullableOnLongClickListenerl){super.setOnLongClickListener(l);LogUtil2.log("onDraw--getX---弹框的长按事件:"+isScrollow);}@OverrideprotectedvoidonOverScrolled(intscrollX,intscrollY,booleanclampedX,booleanclampedY){super.onOverScrolled(scrollX,scrollY,clampedX,clampedY);LogUtil2.log("onDraw--getX---弹框的滑动事件:"+isScrollow);}@OverrideprotectedvoidonSizeChanged(intw,inth,intoldw,intoldh){super.onSizeChanged(w,h,oldw,oldh);LogUtil2.log("onDraw--getX---弹框的滑动改变事件:"+isScrollow);}@OverridepublicbooleanonTouchEvent(MotionEventev){intx=0;inty=0;intleft=getPaddingLeft()+yTextSurplus;inttop=0;intright=xWidth/12+getPaddingLeft()+yTextSurplus;intbottom=yHeight;//intright=getWidth()/12;//intbottom=yHeight;switch(ev.getAction()){caseMotionEvent.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(inti=0;i<12;i++){Rectrect=newRect(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();selectIndexRoles.add(selectIndex);invalidate();//}}}}*///}break;caseMotionEvent.ACTION_MOVE:isScrollow=true;LogUtil2.log("setSelect--666Move--x"+x+"--left--"+y+"ev--x"+ev.getX()+"ev--y"+ev.getY());break;caseMotionEvent.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(inti=0;i<12;i++){Rectrect=newRect(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;}returntrue;}publicvoidsetListener(getNumberListenerlistener){this.listener=listener;}publicinterfacegetNumberListener{voidgetNumber(intnumber,intx,inty,intHeightSelect,intox);}}

2.ChartYdate

packagecom.broker.liming.widget;importandroid.content.Context;importandroid.graphics.Bitmap;importandroid.graphics.BitmapFactory;importandroid.graphics.Canvas;importandroid.graphics.Paint;importandroid.graphics.Rect;importandroid.graphics.RectF;importandroid.support.v4.content.ContextCompat;importandroid.util.AttributeSet;importandroid.view.MotionEvent;importandroid.view.View;importcom.broker.liming.R;importcom.broker.liming.bean.ChartData;importcom.broker.liming.utils.DensityUtil;importcom.broker.liming.utils.DoubleUtils;importcom.broker.liming.utils.LogUtil2;importjava.math.BigDecimal;importjava.text.DecimalFormat;importjava.text.SimpleDateFormat;importjava.util.ArrayList;importjava.util.Date;importjava.util.List;/***@authorchenhuirong*@Date2018/12/10*@Description统计图***/publicclassChartYdateextendsView{protectedfinalintxSurplus=0;//x轴留余protectedfinalintySurplus=20;//y轴留余protectedfinalintxTextSurplus=150;//x轴文字留余protectedfinalintyTextSurplus=100;//y轴文字留余protectedfloatoX;//原点xprotectedfloatoY;//原点yprotectedintxWidth;//x轴宽度protectedintyHeight;//y轴高度protectedintxSpacing;//x轴坐标间距protectedintySpacing;//y轴坐标间距protectedintxpCount=7;//x轴坐标点数protectedintypCount=7;//y轴坐标点数protectedint[]xCoordinates;//x轴坐标点protectedint[]yCoordinates;//y轴坐标点protectedfloatyMax=0f;//y轴最大刻度值protectedString[]xData;//x轴数据protectedfloat[]yData;//y轴数据protectedintcoordinates_color;//坐标系颜色protectedintx_text_size;//x轴文字尺寸protectedinty_text_size;//y轴文字尺寸protectedintx_text_color;//x轴文字颜色protectedinty_text_color;//y轴文字颜色protectedbooleanisAnim=true;protectedAnim[]anims;//动画数组protectedlonginterval=100;//动画执行间隔protectedintanimType=-2;//动画privatePaintmTableValuePaint;//privategetNumberListenerlistener;//privateintselectIndex=-1;//privateList<Integer>selectIndexRoles=newArrayList<>();publicChartYdate(Contextcontext){super(context);}publicChartYdate(Contextcontext,AttributeSetattrs,intdefStyleAttr){super(context,attrs,defStyleAttr);}publicChartYdate(Contextcontext,AttributeSetattrs){super(context,attrs);}@OverrideprotectedvoidonDraw(Canvascanvas){LogUtil2.log("yData--------------->onDraw画布"+ypCount);initChartYdateProp();initCoordinateSystem(canvas);//开始动画if(isAnim){initAnims();post(animator);isAnim=false;}}/**初始化统计图属性*/privatevoidinitChartYdateProp(){//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;//坐标系原点xoX=getPaddingLeft()+yTextSurplus;//坐标系原点y减70为了画出当月图片oY=getPaddingTop()+yHeight+xTextSurplus/2-70;//x轴各刻度点位置xCoordinates=newint[xpCount];//y轴各刻度点位置yCoordinates=newint[ypCount];//记录x轴刻度点位置修改柱形图离坐标原点的距离for(inti=0;i<xpCount;i++){xCoordinates[i]=(i+1)*xSpacing-30;}LogUtil2.log("yData--------------->ypCount记录y轴刻度点位置"+ypCount);//记录y轴刻度点位置for(intj=0;j<ypCount;j++){yCoordinates[j]=(j+1)*ySpacing;LogUtil2.log("yData--------------->henghe"+yCoordinates[j]);}LogUtil2.log("yData--------------->yCoordinates记录y轴刻度点位置"+yCoordinates.length);}/**初始化坐标系*/privatevoidinitCoordinateSystem(Canvascanvas){PaintmainPaint=newPaint();mainPaint.setColor(coordinates_color);mainPaint.setAntiAlias(true);//drawx坐标//canvas.drawLine(oX,oY,oX,oY-yHeight,mainPaint);//drawy坐标//canvas.drawLine(oX,oY,oX+xWidth+40,oY,mainPaint);//刻度值画笔PainttextPaint=newPaint(Paint.ANTI_ALIAS_FLAG);textPaint.setColor(getResources().getColor(R.color.transparent));mTableValuePaint=newPaint();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));//drawx刻度for(inti=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坐标偏移量inttextX=textSize[0]/2;inttextY=xTextSurplus/2-textSize[1]/2;//画x轴文字canvas.drawText(xData[i],oX+xCoordinates[i]-textX,oY+textY,textPaint);String[]strNow=newSimpleDateFormat("yyyy-MM-dd").format(newDate()).toString().split("-");Integeryear=Integer.parseInt(strNow[0]);Integermonth=Integer.parseInt(strNow[1]);//画当前月图片+DensityUtil.dip2px(mContext,6)if(month==Integer.parseInt(xData[i])){Bitmaparrow=BitmapFactory.decodeResource(getResources(),R.mipmap.current_month);RectFrectF=newRectF((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;}//drawy刻度for(intj=0;j<ypCount;j++){//更改文字大小textPaint.setTextSize(y_text_size);//y轴刻度线//canvas.drawLine(oX,oY-yCoordinates[j],oX+5,oY-yCoordinates[j],mainPaint);//y轴刻度值intiYMax=(int)yMax;Stringdatay;if(yMax-iYMax==0){datay=(int)(yMax/ypCount*(j+1))+"";}else{datay=newDecimalFormat("0.000").format(yMax/ypCount*(j+1));}//平均分成4份//DoublemMaxDiv=DoubleUtils.getLargerInterger(yMax,7);//datay=String.valueOf((newBigDecimal((j+1)*mMaxDiv).setScale(2,BigDecimal.ROUND_HALF_UP).doubleValue()));intatt=(int)Math.floor(yMax);StringmBigst=String.valueOf(att);//StringmBigst=String.valueOf(yMax).substring(0,String.valueOf(yMax).indexOf("."));intmaxLength=mBigst.length();intbaseMax=att+1;if(maxLength>=2){baseMax=Integer.valueOf(mBigst.substring(0,2))+1;}booleanisBreak=false;intmargCount=0;Stringii="";//画y轴最大值Stringaa="";//间隔for(inti=baseMax;i<baseMax+100;i++){for(inta=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(inty=0;y<maxLength-2;y++){aa=aa+"0";ii=ii+"0";}//doublemm=formatTosepara2(Double.valueOf(aa));//intmm+=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);//计算画文字的坐标偏移量inttextX=yTextSurplus/2+textSize[0]/2;inttextY=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());}publicStringformatTosepara2(doubledata){intlength=String.valueOf(data).split("\\.")[0].length();if(length<4){returnString.format("%.2f",data);}DecimalFormatdf=newDecimalFormat("##,###");returndf.format(data);}/**准备动画*/privatevoidinitAnims(){anims=newAnim[xpCount];//switch(animType){//caseAnim.ANIM_TRANSLATE://for(inti=0;i<xpCount;i++){//floatdataX=oX+xCoordinates[i];//floatdataY=oY-yData[i]/yMax*yCoordinates[yCoordinates.length-1];//Animanim=newAnim(dataX,dataY,dataX,oY);//anim.setAnimation(newTranslateAnim());//anim.setVelocity(interval*2);//anims[i]=anim;//}//break;//caseAnim.ANIM_ALPHA://for(inti=0;i<xpCount;i++){//floatdataX=oX+xCoordinates[i];//floatdataY=oY-yData[i]/yMax*yCoordinates[yCoordinates.length-1];//Animanim=newAnim(dataX,dataY,dataX,dataY);//anim.setAnimation(newAlphaAnim());//anim.setAlpha(0);//anim.setVelocity(interval*3/2);//anims[i]=anim;//}//break;//default://for(inti=0;i<xpCount;i++){//floatdataX=oX+xCoordinates[i];//floatdataY=oY-yData[i]/yMax*yCoordinates[yCoordinates.length-1];//Animanim=newAnim(dataX,dataY,dataX,dataY);//anim.setAnimation(newTranslateAnim());//anim.setVelocity(interval);//anims[i]=anim;//}for(inti=0;i<xpCount;i++){floatdataX=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份DoublemMaxDi=DoubleUtils.getLargerInterger(yMax,7);//设置Y轴分值floattotal=0;//floattotal=(float)newBigDecimal((7)*mMaxDi).setScale(2,BigDecimal.ROUND_HALF_UP).doubleValue();LogUtil2.log("最大值--"+yMax);intatt=(int)Math.floor(yMax);StringmBigst=String.valueOf(att);//StringmBigst=String.valueOf((int)Math.floor(yMax));LogUtil2.log("最大值--"+yMax+"---"+mBigst);//StringmBigst=String.valueOf(yMax).substring(0,String.valueOf(yMax).indexOf("."));intmaxLength=mBigst.length();intbaseMax=att+1;if(maxLength>=2){baseMax=Integer.valueOf(mBigst.substring(0,2))+1;}booleanisBreak=false;Stringaa="";//间隔值Stringii="";//y轴最大intmargCount=0;//分多少份,动态设置for(intj=baseMax;j<baseMax+100;j++){for(inta=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(inty=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);floatdataY=oY-yData[i]/total*yCoordinates[yCoordinates.length-1];LogUtil2.log("yData----------dataY"+dataY);Animanim=newAnim(dataX,dataY,dataX,dataY);anim.setAnimation(newTranslateAnim());anim.setVelocity(interval);anims[i]=anim;LogUtil2.log("yData----------anims"+anims);}//break;//}}/**获取y轴最大值*/protectedfloatgetYMax(){if(yData==null||yData.length==0){yData=newfloat[ypCount];}floatmax=0;for(inti=0;i<yData.length;i++){if(max<yData[i]){max=yData[i];}}returnmax;}/**获取文字宽高*/protectedint[]getTextSize(Stringstr,Paintpaint){//计算文字所在矩形,可以得到宽高Rectrect=newRect();paint.getTextBounds(str,0,str.length(),rect);intw=rect.width();inth=rect.height();returnnewint[]{w,h};}/**设置统计图属性*/publicvoidsetChartYdateData(ChartDatachartData){if(chartData==null){thrownewNullPointerException("折线图数据不能为空!");}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;}/**设置正确属性值*/protectedintgetFinalValue(intold,intnews){old=news!=0?news:old;returnold;}/**执行动画runnable*/privateRunnableanimator=newRunnable(){@Overridepublicvoidrun(){LogUtil2.log("yData----------anims循环"+anims);LogUtil2.log("yData----------anims长多"+anims.length);for(Anima:anims){LogUtil2.log("yData----------anims循环2"+a.isOver());if(!a.isOver()){a.refresh();postDelayed(this,interval);invalidate();return;}}}};/**更新数据并重绘*/publicvoidupdate(ChartDatachartData){yMax=0;setChartYdateData(chartData);isAnim=true;invalidate();}/*@OverridepublicbooleanonTouchEvent(MotionEventev){intx=(int)ev.getX();inty=(int)ev.getY();intleft=0;inttop=0;intright=xWidth/12;intbottom=yHeight;switch(ev.getAction()){caseMotionEvent.ACTION_DOWN:for(inti=0;i<12;i++){Rectrect=newRect(left,top,right,bottom);left+=xWidth/12;right+=xWidth/12;if(rect.contains(x,y)){if(listener!=null){listener.getNumber(i,x,y);//isSelect=true;//number=i;selectIndex=i;selectIndexRoles.clear();selectIndexRoles.add(selectIndex);invalidate();}}}break;caseMotionEvent.ACTION_UP:break;}returntrue;}publicvoidsetListener(getNumberListenerlistener){this.listener=listener;}publicinterfacegetNumberListener{voidgetNumber(intnumber,intx,inty);}*/}

3.布局 activity_family_status嵌套在Scrollowview中

<android.support.v4.widget.NestedScrollViewandroid:id="@+id/scrollowview"android:layout_width="match_parent"android:layout_height="wrap_content"android:fillViewport="true"android:layout_marginBottom="@dimen/lay_10"><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="vertical"><com.broker.liming.widget.HistogramRoundandroid: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

packagecom.broker.liming.activity;importandroid.content.Context;importandroid.content.Intent;importandroid.support.annotation.RequiresApi;importandroid.support.v4.widget.NestedScrollView;importandroid.support.v7.widget.LinearLayoutManager;importcom.broker.liming.utils.ArithUtil;importcom.broker.liming.utils.BarUtils;importcom.broker.liming.utils.GsonUtils;importcom.broker.liming.utils.LogUtil2;importcom.broker.liming.utils.UIHelper;importcom.broker.liming.widget.HistogramData;importcom.broker.liming.widget.HistogramRound;importcom.broker.liming.widget.TitleBar;importorg.json.JSONException;importjava.text.DecimalFormat;importjava.text.SimpleDateFormat;importjava.util.ArrayList;importjava.util.Arrays;importjava.util.Date;importjava.util.List;importbutterknife.BindView;importstaticcom.sobot.chat.utils.ScreenUtils.dip2px;importstaticcom.sobot.chat.utils.ScreenUtils.px2dip;/***@Descpription:家庭现状*@Date:2019/7/17.*@author:chenhuirong*/publicclassFamilyStatusActivityextendsBaseActivity{@BindView(R.id.histogramchart)HistogramRoundhistogramChart;@BindView(R.id.scrollowview)NestedScrollViewscrollowview;privateFamilyStatusAdapteradapter;privateFamilyStatusRateAdapterrateAdapter;privateHistogramDatahistogramData;//柱状图//@BindView(R.id.my_single_chart_view)//SingleViewmMySingleChartView;@BindView(R.id.rl_single)RelativeLayoutrlSingle;privateList<Float>singlelist;privateLinearLayoutllSingle;privatedoublemMax=44;privateList<FamilyPremiumArrayBean>listData=newArrayList<>();privateStringmonthBack;float[]ydata=newfloat[12];privateString[]xdata=newString[12];privateString[]xdataShow=newString[12];//仅为显示privatebooleanisScrollow=true;privatebooleanisFresh=false;intmargCount=0;//共分多少份privateLinearLayoutline;privateStringname;publicstaticvoidactionStart(Contextcontext,StringfamilyUuid,Stringnames){Intentintent=newIntent(context,FamilyStatusActivity.class);intent.putExtra("familyUuid",familyUuid);intent.putExtra("name",names);context.startActivity(intent);}@OverrideprotectedvoidinitTitleBar(){TitleBartitleBar=(TitleBar)findViewById(R.id.title_bar);asserttitleBar!=null;/*titleBar.setLeftBackground(R.mipmap.back);*/titleBar.setLeftBackground(R.mipmap.order_back);titleBar.setTitle(name+"的家庭数据分析");titleBar.setTitleColor(R.color.text_000000);titleBar.setTitleBarBg(getResources().getColor(R.color.white));titleBar.setLeftClickListener(newView.OnClickListener(){@OverridepublicvoidonClick(Viewv){finish();}});}@OverrideprotectedintgetContentView(){returnR.layout.activity_family_status;}@OverrideprotectedbooleaninitBundle(Bundlebundle){}@OverridepublicvoidinitData(){super.initData();}@OverrideprotectedvoidonResume(){super.onResume();getPieDate(familyUuid);}publicvoidgetHomeData(){try{UserBeanquery=UserBeanDao.query();requestServerPostForm(false,100,HttpParams.getFamilyStatus(query,familyUuid));}catch(JSONExceptione){e.printStackTrace();}}@OverridepublicvoidinitView(){xdata=newString[]{"1","2","3","4","5","6","7","8","9","10","11","12"};xdataShow=newString[]{"01","02","03","04","05","06","07","08","09","10","11","12"};initSingle();scrollowview.setOnTouchListener(newView.OnTouchListener(){@OverridepublicbooleanonTouch(Viewv,MotionEventevent){LogUtil2.log("onDraw--getX---isScrollow"+isScrollow);floatx=0;floaty=0;switch(event.getAction()){caseMotionEvent.ACTION_DOWN:x=event.getX();y=event.getY();LogUtil2.log("onDraw--getX---down"+event.getX()+"---"+y);break;caseMotionEvent.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;caseMotionEvent.ACTION_CANCEL:caseMotionEvent.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代表点击,否则代表滑动/*if(Math.abs(ArithUtil.sub(event.getX(),x))<=20&&Math.abs(ArithUtil.sub(event.getY(),y))<=20){//isScrollow=false;isCheck=true;}else{//isScrollow=true;isCheck=false;histogramChart.isScrollow(false);rlSingle.removeView(llSingle);rlSingle.removeView(line);if(isScrollow){histogramChart.setPublicRefresh();isScrollow=false;}}*/break;}returnfalse;}});changeStatusBarTextColor(true);BarUtils.setColorNoTranslucent(this,getResources().getColor(R.color.white));}/***弹出弹框*/privatevoidinitSingle(){rlSingle=(RelativeLayout)findViewById(R.id.rl_single);singlelist=newArrayList<>();rlSingle.removeView(llSingle);rlSingle.removeView(line);histogramChart.setOnLongClickListener(newView.OnLongClickListener(){@OverridepublicbooleanonLongClick(Viewv){LogUtil2.log("onDraw--getX---弹框的长按事件:"+isScrollow);returnfalse;}});histogramChart.setListener(newHistogramRound.getNumberListener(){@OverridepublicvoidgetNumber(intindex,intheight,intleft,intselectorHeight,intox){//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);//TextViewview=newTextView(mContext);//view.setBackground(mContext.getResources().getDrawable(R.drawable.shape_dash_line));RelativeLayout.LayoutParamsviewParam=newRelativeLayout.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);LinearLayoutll_back=(LinearLayout)llSingle.findViewById(R.id.ll_back);TextViewtvMoney=(TextView)llSingle.findViewById(R.id.tv_month);TextViewtv_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=newSimpleDateFormat("yyyy-MM-dd").format(newDate()).toString().split("-");Stringyear=strNow[0];tvMoney.setText(year+"-"+xdataShow[index]);RelativeLayout.LayoutParamsparams=newRelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT,RelativeLayout.LayoutParams.WRAP_CONTENT);LogUtil2.log("setSelect--callback--"+height+"--left---"+left+"---"+selectorHeight+"弹框高--"+dip2px(mContext,60)+"--差值--"+(height-(height-selectorHeight/*+px2dip(mContext,70)*/)-dip2px(mContext,60)));LogUtil2.log("----宽-----+++"+params.width);LogUtil2.log("setSelect--转换"+px2dip(mContext,height)+"--left---"+px2dip(mContext,left)+"---"+dip2px(mContext,selectorHeight));inttopmargin=0;intleftmargin=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)/*+dip2px(mContext,70)*/;}else{topmargin=height-(height-selectorHeight)+dip2px(mContext,5)/*+dip2px(mContext,70)*/;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/*selectorHeight+px2dip(mContext,64)*/;//LogUtil2.log("setSelect--callback--"+histogramChart.getHeight()+"---"+selectorHeight+"---left"+params.topMargin);//if(x-100<0){//params.leftMargin=0;//}elseif(x-100>relativeLayout.getWidth()-llSingle.getMeasuredWidth()){//params.leftMargin=relativeLayout.getWidth()-llSingle.getMeasuredWidth();//}llSingle.setLayoutParams(params);rlSingle.addView(llSingle);//}}});}privatevoidchangeStatusBarTextColor(booleanisBlack){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);//恢复状态栏白色字体}}}privatevoidsetDate(FamilyYearCheakBeanyearCheakBean){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=newSimpleDateFormat("yyyy-MM-dd").format(newDate()).toString().split("-");Integeryear=Integer.parseInt(strNow[0]);Integermonth=Integer.parseInt(strNow[1]);listData=yearCheakBean.familyPremiumArray;List<Double>list=newArrayList<>();ArrayList<DotVo>temp=newArrayList();for(inti=0;i<listData.size();i++){FamilyPremiumArrayBeanbean=listData.get(i);Stringyearback=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));doublepremium=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);}DotVotempDotVo=newDotVo(monthBack,premium);temp.add(tempDotVo);}Double[]toBeStored=list.toArray(newDouble[list.size()]);mMax=checkMax(toBeStored);}//向下取整intatt=(int)Math.floor(mMax);StringmBigst=String.valueOf(att);intmaxLength=mBigst.length();intbaseMax=att+1;if(maxLength>=2){baseMax=Integer.valueOf(mBigst.substring(0,2))+1;}booleanisBreak=false;for(inti=baseMax;i<baseMax+100;i++){for(inta=100;a>0;a--){if(i%a==0&&i/a<=6&&i/a>=4){margCount=i/a;isBreak=true;break;}}if(isBreak)break;}for(inti=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);}publicdoublecheckMax(Double[]args){doublemax=0;for(inti=0;i<args.length;i++){if(args[i]>max){max=args[i];}}returnmax;}@OverrideprotectedvoidonSuccess(Stringresponse,intid){super.onSuccess(response,id);switch(id){case200:yearCheakBean=GsonUtils.toObject(response,FamilyYearCheakBean.class);setDate(yearCheakBean);break;}}/***将float类型的数据转换成以4位逗号隔开的字符串,并且保留两位有效数字*/publicStringformatTosepara(doubledata){intlength=String.valueOf(data).split("\\.")[0].length();if(length<4){returnString.format("%.2f",data);}DecimalFormatdf=newDecimalFormat("#,####.00");returndf.format(data);}publicStringformatTosepara2(doubledata){intlength=String.valueOf(data).split("\\.")[0].length();if(length<4){returnString.format("%.2f",data);}DecimalFormatdf=newDecimalFormat("##,###");returndf.format(data);}}

5.HistogramData

packagecom.broker.liming.widget;importcom.broker.liming.bean.ChartData;/***@authorchenhuirong*@Date2018/12/10*@Description柱状图s*/publicclassHistogramDataextendsChartData{privateint[]rectColor;privateintrectTextColor;privateintrectTextSize;privateHistogramData(Builderbuilder){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);}publicstaticBuilderbuilder(){returnnewBuilder();}publicint[]getRectColor(){returnrectColor;}publicvoidsetRectColor(int[]rectColor){this.rectColor=rectColor;}publicintgetRectTextColor(){returnrectTextColor;}publicvoidsetRectTextColor(intrectTextColor){this.rectTextColor=rectTextColor;}publicintgetRectTextSize(){returnrectTextSize;}publicvoidsetRectTextSize(intrectTextSize){this.rectTextSize=rectTextSize;}publicstaticfinalclassBuilder{privateintrectTextSize;privateintrectTextColor;privateint[]rectColor;privateintanimType;privateintinterval;privateintyMax;privateintyTextColor;privateintxTextColor;privateintyTextSize;privateintxTextSize;privateintcoordinatesColor;privateintypCount;privateintxpCount;privatefloat[]ydata;privateString[]xdata;privateBuilder(){}publicBuildersetRectTextSize(intval){rectTextSize=val;returnthis;}publicBuildersetRectTextColor(intval){rectTextColor=val;returnthis;}publicBuildersetRectColor(int[]val){rectColor=val;returnthis;}publicBuildersetAnimType(intval){animType=val;returnthis;}publicBuildersetInterval(intval){interval=val;returnthis;}publicBuildersetYMax(intval){yMax=val;returnthis;}publicBuildersetYTextColor(intval){yTextColor=val;returnthis;}publicBuildersetXTextColor(intval){xTextColor=val;returnthis;}publicBuildersetYTextSize(intval){yTextSize=val;returnthis;}publicBuildersetXTextSize(intval){xTextSize=val;returnthis;}publicBuildersetCoordinatesColor(intval){coordinatesColor=val;returnthis;}publicBuildersetYpCount(intval){ypCount=val;returnthis;}publicBuildersetXpCount(intval){xpCount=val;returnthis;}publicBuildersetYdata(float[]val){ydata=val;returnthis;}publicBuildersetXdata(String[]val){xdata=val;returnthis;}publicHistogramDatabuild(){returnnewHistogramData(this);}}}

6.ChartData

packagecom.broker.liming.bean;/***统计图父类数据类*Createdbyzqxon16/6/27.*/publicclassChartData{protectedString[]xdata;protectedfloat[]ydata;protectedintxpCount;protectedintypCount;protectedintcoordinatesColor;protectedintxTextSize;protectedintyTextSize;protectedintxTextColor;protectedintyTextColor;protectedintyMax;protectedintinterval;protectedintanimType=-2;protectedChartData(){}publicString[]getXdata(){returnxdata;}publicvoidsetXdata(String[]xdata){this.xdata=xdata;}publicfloat[]getYdata(){returnydata;}publicvoidsetYdata(float[]ydata){this.ydata=ydata;}publicintgetXpCount(){returnxpCount;}publicvoidsetXpCount(intxpCount){this.xpCount=xpCount;}publicintgetYpCount(){returnypCount;}publicvoidsetYpCount(intypCount){this.ypCount=ypCount;}publicintgetCoordinatesColor(){returncoordinatesColor;}publicvoidsetCoordinatesColor(intcoordinatesColor){this.coordinatesColor=coordinatesColor;}publicintgetxTextSize(){returnxTextSize;}publicvoidsetxTextSize(intxTextSize){this.xTextSize=xTextSize;}publicintgetyTextSize(){returnyTextSize;}publicvoidsetyTextSize(intyTextSize){this.yTextSize=yTextSize;}publicintgetxTextColor(){returnxTextColor;}publicvoidsetxTextColor(intxTextColor){this.xTextColor=xTextColor;}publicintgetyTextColor(){returnyTextColor;}publicvoidsetyTextColor(intyTextColor){this.yTextColor=yTextColor;}publicintgetyMax(){returnyMax;}publicvoidsetyMax(intyMax){this.yMax=yMax;}publicintgetInterval(){returninterval;}publicvoidsetInterval(intinterval){this.interval=interval;}publicintgetAnimType(){returnanimType;}publicvoidsetAnimType(intanimType){this.animType=animType;}}

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