本文是引用开源图表库框架 MPAndroIDChart的lineChart
地址:https://github.com/PhilJay/MPAndroidChart
1.需求:
(1)动态添加Radiobutton,点击改变下面的lineChart数据
(2)lineChart绘制价格走势图,只显示最低点的小圆点和VIEw,手指滑动,MarkVIEw数据变化。
(3) 服务端返回端数据,不是每一天端数据,但是x轴显示的必须是每一天的数据,这里是有我自己处理过的。返回里需要显示点的数组,之前的时间点显示的就是第一个点值。
2.实现效果:
最低点显示VIEw和小圆点是自定义的,通过修改 lineChart的源码,下面我们来具体分析代码
3.代码分析
(1)布局的xml
<?xml version="1.0" enCoding="utf-8"?><linearLayout xmlns:androID="http://schemas.androID.com/apk/res/androID" xmlns:app="http://schemas.androID.com/apk/res-auto" xmlns:tools="http://schemas.androID.com/tools" androID:layout_wIDth="match_parent" androID:layout_height="match_parent" androID:orIEntation="vertical"> <RadioGroup androID:ID="@+ID/mRadioGroup" androID:layout_wIDth="wrap_content" androID:layout_height="wrap_content" androID:layout_margintop="30px" androID:orIEntation="horizontal" androID:visibility="gone"> </RadioGroup> <linearLayout androID:layout_wIDth="match_parent" androID:layout_height="200dp" androID:orIEntation="vertical"> <com.github.mikephil.charting.charts.lineChart androID:ID="@+ID/mlineChart" androID:layout_wIDth="match_parent" androID:layout_height="0dp" androID:layout_weight="1" /> <linearLayout androID:layout_wIDth="match_parent" androID:layout_height="wrap_content" androID:orIEntation="horizontal"> <TextVIEw androID:ID="@+ID/detailMinTimeTv" androID:layout_wIDth="wrap_content" androID:layout_height="wrap_content" androID:layout_marginleft="50px" androID:layout_weight="1" androID:textcolor="#B5B5B5" androID:textSize="24px" /> <TextVIEw androID:ID="@+ID/detailMaxTimeTv" androID:layout_wIDth="wrap_content" androID:layout_height="wrap_content" androID:layout_marginRight="30px" androID:layout_weight="1" androID:gravity="right" androID:textcolor="#B5B5B5" androID:textSize="24px" /> </linearLayout> </linearLayout></linearLayout>
这里主要是添加以一个RadioGroup和一个lineChart
接下来是MainActivity.class
private voID addVIEwForGroup(final List<JsonData.HistoricalPrice> List) { for (int i = 0; i < List.size(); i++) { final Radiobutton vIEw = (Radiobutton) LayoutInflater.from(MainActivity.this) .inflate(R.layout.item_gr_add_but_layout,mRadioGroup,false); vIEw.setID(i); vIEw.setText(List.get(i).getTitle()); if (i==0){ vIEw.performClick(); radioGroupTextChange(List.get(0).getData(),List.get(0).getTitle()); mlineCharWidget = new lineChartWidget(MainActivity.this,List.get(0).getData(),mlineChart,setMinPrice(List.get(0).getData())); } mRadioGroup.addVIEw(vIEw); } mRadioGroup.setonCheckedchangelistener(new RadioGroup.OnCheckedchangelistener() { @OverrIDe public voID onCheckedChanged(RadioGroup group,int checkedID) { Radiobutton button = (Radiobutton) findVIEwByID(checkedID); button.setText(List.get(checkedID).getTitle()); for (int i = 0; i < List.size(); i++) { if (button.getText().toString().equals(List.get(i).getTitle())) { radioGroupTextChange(List.get(i).getData(),List.get(i).getTitle()); if (mlineCharWidget == null) { mlineCharWidget = new lineChartWidget(MainActivity.this,List.get(i).getData(),setMinPrice(List.get(i).getData())); } else { mlineCharWidget.updatelineChar(List.get(i).getData(),setMinPrice(List.get(i).getData())); } } } } }); }
注意:这里的lineChartWidget是我自己封装的一个lineChart,包括lineChart初始化,数据的处理,已经手势的一些 *** 作
简单的说一下思路,因为 linechart的x,y都是自定义的,但是我这里只自定义的y轴,是把x隐藏起来的,x轴只显示最开始的点和结束的点,所以我这里有点投机,自己设置点两个textvIEw来显示的
linechart的点一设置都是统一所有点都设置的,但是需求上是得只在最低点显示,并还要绘制一个vIEw先初始化 VIEw,然后解析数据,
JsonData JsonDetail = new Gson().fromJson(JsonStr.toString(),new Typetoken<JsonData>() { }.getType()); if (JsonDetail.getHistorical_price() != null && JsonDetail.getHistorical_price().size() > 0) { setGroupLay(JsonDetail.getHistorical_price()); }
再根据解析的数据动态添加Radiobutton
初始化lineChart
private voID initlineChar() { List<JsonData.HistoricalPrice.HistoricalPriceData.DataList> dataList = removeDuplicteData(mHistoricalPrice.getData_List()); //设置手势滑动事件 mlineChar.setonChartGestureListener(this); //设置数值选择监听 mlineChar.setonChartValueSelectedListener(this); //后台绘制 mlineChar.setDrawGrIDBackground(false); //设置描述文本 mlineChar.getDescription().setEnabled(false); mlineChar.settouchEnabled(true); // 设置是否可以触摸 mlineChar.setDragEnabled(true);// 是否可以拖拽 mlineChar.setScaleXEnabled(true); //是否可以缩放 仅x轴 mlineChar.setScaleYEnabled(true); //是否可以缩放 仅y轴 mlineChar.setPinchZoom(true); //设置x轴和y轴能否同时缩放。默认是否 mlineChar.setDragDecelerationFrictionCoef(0.99f); mlineChar.getAxisRight().setEnabled(false); // 默认动画 mlineChar.animateX(2500); setMakeList(removeDuplicteData(dataList)); initMark(makeList,Long.valueOf(mHistoricalPrice.getStart_time())); initXAxis(dataList.size(),xAxisValuesstr); initYAxis(); initLegend(); setlineCharData(makeList); }
设置markVIEw
private voID setMakeList(List<JsonData.HistoricalPrice.HistoricalPriceData.DataList> dataList) { try { SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); Date dBegin = format.parse(format.format(Long.valueOf(mHistoricalPrice.getStart_time()) * 1000)); Date dEnd = format.parse(format.format(Long.valueOf(mHistoricalPrice.getEnd_time()) * 1000)); float prices = 0; List<Date> ListDate = getDatesBetweenTwoDate(dBegin,dEnd); if (dataList.size() >= ListDate.size()) { makeList.clear(); makeList.addAll(dataList); } else { for (int i = 0; i < ListDate.size(); i++) { JsonData.HistoricalPrice.HistoricalPriceData.DataList data = new JsonData.HistoricalPrice.HistoricalPriceData.DataList(); for (int j = 0; j < dataList.size(); j++) { if (TimetoString(DatetoTimestamp(ListDate.get(i))).equals(TimetoString(Long.valueOf(dataList.get(j).getPrice_drop_time())))) { data.setPrice_drop_time(dataList.get(j).getPrice_drop_time()); data.setPrice_new(dataList.get(j).getPrice_new()); prices = (dataList.get(j).getPrice_new()); } else { data.setPrice_drop_time(DatetoTimestamp(ListDate.get(i)) + ""); data.setPrice_new(prices); } } makeList.add(data); } } } catch (ParseException e) { e.printstacktrace(); } }
这里是设置lineChart里面的数据
private voID setData(ArrayList<Entry> values) { lineDataSet set1 = null; if (mlineChar.getData() != null && mlineChar.getData().getDataSetCount() > 0) { set1 = (lineDataSet) mlineChar.getData().getDataSetByIndex(0); set1.setValues(values); mlineChar.getData().notifyDataChanged(); mlineChar.notifyDataSetChanged(); } else { // 创建一个数据集,并给它一个类型 if (set1 == null) { set1 = new lineDataSet(values,"价格曲线图"); set1.setcolor(color.rgb(27,198,181)); set1.setCirclecolor(color.BLACK); set1.setlinewidth(1f); set1.setCircleRadius(3f); set1.setDrawCircleHole(false); set1.setValueTextSize(9f); set1.setDrawFilled(true); set1.setFormlinewidth(1f); set1.setFormlineDashEffect(new DashPathEffect(new float[]{10f,5f},0f)); set1.setHighlightEnabled(true); //允许突出显示DataSet set1.setDrawHighlightIndicators(false); // 取消点击线上的点展示十字标识 set1.setDrawValues(true); // 不展示线上面点的值 //是否显示小圆点 set1.setDrawCircles(false); //修改源码 自定义的参数,可以显示最低点的VIEw set1.setLowDrawCircles(true); set1.setCirclecolors(color.rgb(27,181));//27,181 //顶点设置值 set1.setDrawValues(false); set1.setFillcolor(color.rgb(203,242,238)); } //修改源码 自定义的参数,可以显示最低点的VIEw set1.setLowNumbers(minData); ArrayList<IlineDataSet> dataSets = new ArrayList<IlineDataSet>(); //添加数据集 dataSets.add(set1); //创建一个数据集的数据对象 lineData data = new lineData(dataSets); //设置数据 mlineChar.setData(data); } }
这里是在源码里新加的地方
//修改源码 自定义的参数,可以显示最低点的VIEw set1.setLowDrawCircles(true); set1.setLowNumbers(minData);
源码修改部分:
1.在lineDataSet添加2个参数,复写IlineDataSet新加的方法
//是否显示最低点的小圆点 private boolean mDrawLowCircle = false; //最低点对应的具体值 private float mLowNumbers = 100f;
2.在IlineDataSet接口中添加2个方法
boolean isLowDrawCirclesEnabled();float getLowNumbers();
3.修改源码lineChartRenderer这个类的 drawValues(Canvas c)方法中,这里是设置最低点显示的VIEw,这个方法中添加判断:
//设置最低点显示的自定义viewif (dataSet.isLowDrawCirclesEnabled()) { if (entry.getY() == dataSet.getYMin()) { //设置在左边 if (x < 100) { locationcode = 1; } else { // 默认在右边 locationcode = 0; } appCustomDrawValue(c,dataSet.getValueFormatter(),entry.getY(),entry,i,x,y - valOffset,color.WHITE); break; }}private int locationcode = 0;//设置最低点显示的text和text的背景框private voID appCustomDrawValue(Canvas c,IValueFormatter formatter,float value,Entry entry,int dataSetIndex,float x,float y,int color) { // Paint.FontMetrics fm = new Paint.FontMetrics(); mValuePaint.setcolor(color.rgb(27,181)); // mValuePaint.getFontMetrics(fm); y = (y + Utils.convertDptopixel(30)); switch (locationcode) { case 0: RectF rectF = new RectF((x - Utils.convertDptopixel(35)),(y - Utils.convertDptopixel(23)),(x + Utils.convertDptopixel(5)),y); c.drawRoundRect(rectF,10,mValuePaint); mValuePaint.setcolor(color); c.drawText("¥" + formatter.getFormattedValue(value,dataSetIndex,mVIEwPortHandler),x - Utils.convertDptopixel(15),y - Utils.convertDptopixel(10),mValuePaint); break; case 1: RectF rectF1 = new RectF(x + Utils.convertDptopixel(5),x + Utils.convertDptopixel(45),y); c.drawRoundRect(rectF1,x + Utils.convertDptopixel(27),mValuePaint); break; } }
在drawCircles(Canvas c)方法中添加判断:则可以显示最低点的小圆点了。
//显示最低点的小圆点if (dataSet.isLowDrawCirclesEnabled()) { if (e.getY() == dataSet.getYMin()) { Bitmap circleBitmap = imageCache.getBitmap(j); c.drawBitmap(circleBitmap,mCirclesBuffer[0] - circleRadius,mCirclesBuffer[1] - circleRadius,null); break; }}
好了,所有功能的关键部分已经讲完了。大家不懂的可以留言提问,或者自己下载源码看看:
github项目地址:https://github.com/Songyan992/LineChartStudy
源码下载地址:LineChartStudy_jb51.rar
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持编程小技巧。
总结以上是内存溢出为你收集整理的Android实现价格走势自定义曲线图全部内容,希望文章能够帮你解决Android实现价格走势自定义曲线图所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)