本文实例为大家分享了android自定义圆角柱状图的具体代码,供大家参考,具体内容如下
需求:
画一个圆角柱状图,显示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(); selectindexroles.add(selectindex); invalidate(); // } } } }*/ // } 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; /** * @author chenhuirong * @date 2018/12/10 * @description 统计图 * * */ 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; // } } /* * 获取y轴最大值 */ 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; } /* * 执行动画runnable */ 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(); } /* @override public boolean ontouchevent(motionevent ev) { int x = (int) ev.getx(); int y = (int) ev.gety(); int left = 0; int top = 0; int right = xwidth/ 12; int bottom = yheight; switch (ev.getaction()) { case motionevent.action_down: 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) { listener.getnumber(i, x, y); // isselect=true; // number = i; selectindex = i; selectindexroles.clear(); selectindexroles.add(selectindex); invalidate(); } } } break; case motionevent.action_up: break; } return true; } public void setlistener(getnumberlistener listener) { this.listener = listener; } public interface getnumberlistener { void getnumber(int number, int x, int y); }*/ }
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; /** * @descpription:家庭现状 * @date: 2019/7/17. * @author:chenhuirong */ 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.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(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代表点击,否则代表滑动 /* 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; } 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/*+px2dip(mcontext,70)*/)-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)/*+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; // } 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; } } /** * 将float类型的数据转换成以4位逗号隔开的字符串,并且保留两位有效数字 */ 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; /** * @author chenhuirong * @date 2018/12/10 * @description 柱状图s */ 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; /** * 统计图父类数据类 * created by zqx on 16/6/27. */ 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; } }
注:参考demo时间太久我忘记了,网上可找到
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持www.887551.com。