本文是引用开源图表库框架 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(), mLineChart, 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, 198, 181));//27, 198, 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,这个方法中添加判断:
//设置最低点显示的自定义view
if (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, 198, 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, 10, mValuePaint);
mValuePaint.setColor(color);
c.drawText("¥" + formatter.getFormattedValue(value, entry, dataSetIndex, mViewPortHandler), x - Utils.convertDpToPixel(15), y - Utils.convertDpToPixel(10), mValuePaint);
break;
case 1:
RectF rectF1 = new RectF(x + Utils.convertDpToPixel(5), (y - Utils.convertDpToPixel(23)), x + Utils.convertDpToPixel(45), y);
c.drawRoundRect(rectF1, 10, 10, mValuePaint);
mValuePaint.setColor(color);
c.drawText("¥" + formatter.getFormattedValue(value, entry, dataSetIndex, mViewPortHandler), x + Utils.convertDpToPixel(27), y - Utils.convertDpToPixel(10), 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实现自定义曲线图
# Android利用MPAndroidChart绘制曲线图表的基础教程
# Android 曲线图的绘制示例代码
# Android实现简易的柱状图和曲线图表实例代码
# Android 自定义View实现芝麻分曲线图效果
# Android 游戏开发中绘制游戏触摸轨迹的曲线图
# android实现可以滑动的平滑曲线图
# 自定义
# 都是
# 小圆点
# 线上
# 只显示
# 每一天
# 小圆
# 创建一个
# 是在
# 好了
# 第一个
# 是有
# 的说
# 下载地址
# 不懂
# 点了
# 只在
# 一所
# 则可
# 我自
相关文章:
制作表格网站有哪些,线上表格怎么弄?
红河网站制作公司,红河事业单位身份证如何上传?
Android滚轮选择时间控件使用详解
广州网站制作的公司,现在专门做网站的公司有没有哪几家是比较好的,性价比高,模板也多的?
Python lxml的etree和ElementTree有什么区别
网站专业制作公司有哪些,做一个公司网站要多少钱?
建站之星在线版空间:自助建站+智能模板一键生成方案
建站之星如何配置系统实现高效建站?
怀化网站制作公司,怀化新生儿上户网上办理流程?
建站OpenVZ教程与优化策略:配置指南与性能提升
如何快速搭建高效服务器建站系统?
如何高效配置香港服务器实现快速建站?
开心动漫网站制作软件下载,十分开心动画为何停播?
义乌企业网站制作公司,请问义乌比较好的批发小商品的网站是什么?
用v-html解决Vue.js渲染中html标签不被解析的问题
如何通过虚拟主机空间快速建站?
相册网站制作软件,图片上的网址怎么复制?
淘宝制作网站有哪些,淘宝网官网主页?
Python多线程使用规范_线程安全解析【教程】
微信小程序 五星评分(包括半颗星评分)实例代码
贸易公司网站制作流程,出口贸易网站设计怎么做?
手机网站制作与建设方案,手机网站如何建设?
如何彻底卸载建站之星软件?
黑客如何利用漏洞与弱口令入侵网站服务器?
网站制作费用多少钱,一个网站的运营,需要哪些费用?
平台云上自助建站如何快速打造专业网站?
如何用美橙互联一键搭建多站合一网站?
正规网站制作公司有哪些,目前国内哪家网页网站制作设计公司比较专业靠谱?口碑好?
如何通过多用户协作模板快速搭建高效企业网站?
如何通过虚拟主机快速搭建个人网站?
建站之星北京办公室:智能建站系统与小程序生成方案解析
广州网站设计制作一条龙,广州巨网网络科技有限公司是干什么的?
内网网站制作软件,内网的网站如何发布到外网?
七夕网站制作视频,七夕大促活动怎么报名?
成都网站制作公司哪家好,四川省职工服务网是做什么用?
如何正确下载安装西数主机建站助手?
如何配置FTP站点权限与安全设置?
免费ppt制作网站,有没有值得推荐的免费PPT网站?
详解jQuery中基本的动画方法
大连网站制作公司哪家好一点,大连买房网站哪个好?
如何在阿里云服务器自主搭建网站?
如何快速搭建高效WAP手机网站?
如何用好域名打造高点击率的自主建站?
个人网站制作流程图片大全,个人网站如何注销?
如何在IIS中新建站点并配置端口与物理路径?
专业制作网站的公司哪家好,建立一个公司网站的费用.有哪些部分,分别要多少钱?
网站制作需要会哪些技术,建立一个网站要花费多少?
图片制作网站免费软件,有没有免费的网站或软件可以将图片批量转为A4大小的pdf?
车管所网站制作流程,交警当场开简易程序处罚决定书,在交警网站查询不到怎么办?
如何在Tomcat中配置并部署网站项目?
*请认真填写需求信息,我们会在24小时内与您取得联系。