全网整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:400-708-3566

Android实现价格走势自定义曲线图

本文是引用开源图表库框架 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实现可以滑动的平滑曲线图  # 自定义  # 都是  # 小圆点  # 线上  # 只显示  # 每一天  # 小圆  # 创建一个  # 是在  # 好了  # 第一个  # 是有  # 的说  # 下载地址  # 不懂  # 点了  # 只在  # 一所  # 则可  # 我自 


相关文章: 北京专业网站制作设计师招聘,北京白云观官方网站?  seo网站制作优化,网站SEO优化步骤有哪些?  如何通过建站之星自助学习解决操作问题?  网站网页制作专业公司,怎样制作自己的网页?  如何在香港免费服务器上快速搭建网站?  建站上市公司网站建设方案与SEO优化服务定制指南  C#如何在一个XML文件中查找并替换文本内容  学生网站制作软件,一个12岁的学生写小说,应该去什么样的网站?  JS中使用new Date(str)创建时间对象不兼容firefox和ie的解决方法(两种)  制作旅游网站html,怎样注册旅游网站?  建站之星×万网:智能建站系统+自助建站平台一键生成  ,怎么在广州志愿者网站注册?  开源网站制作软件,开源网站什么意思?  专业商城网站制作公司有哪些,pi商城官网是哪个?  C++如何编写函数模板?(泛型编程入门)  如何制作一个表白网站视频,关于勇敢表白的小标题?  如何在新浪SAE免费搭建个人博客?  网站插件制作软件免费下载,网页视频怎么下到本地插件?  儿童网站界面设计图片,中国少年儿童教育网站-怎么去注册?  建站之星各版本价格是多少?  C++时间戳转换成日期时间的步骤和示例代码  如何做网站制作流程,*游戏网站怎么搭建?  如何续费美橙建站之星域名及服务?  专业企业网站设计制作公司,如何理解商贸企业的统一配送和分销网络建设?  建站主机如何选?高性价比方案全解析  如何在阿里云虚拟机上搭建网站?步骤解析与避坑指南  如何挑选高效建站主机与优质域名?  如何设计高效校园网站?  上海制作企业网站有哪些,上海有哪些网站可以让企业免费发布招聘信息?  Swift开发中switch语句值绑定模式  建站之星如何配置系统实现高效建站?  网站广告牌制作方法,街上的广告牌,横幅,用PS还是其他软件做的?  已有域名建站全流程解析:网站搭建步骤与建站工具选择  建站中国必看指南:CMS建站系统+手机网站搭建核心技巧解析  ,网站推广常用方法?  婚礼视频制作网站,学习*后期制作的网站有哪些?  建站主机是什么?如何选择适合的建站主机?  高配服务器限时抢购:企业级配置与回收服务一站式优惠方案  建站之星价格显示格式升级,你的预算足够吗?  如何通过山东自助建站平台快速注册域名?  阿里云高弹*务器配置方案|支持分布式架构与多节点部署  东莞市网站制作公司有哪些,东莞找工作用什么网站好?  建站主机解析:虚拟主机配置与服务器选择指南  免费的流程图制作网站有哪些,2025年教师初级职称申报网上流程?  建站之星后台管理如何实现高效配置?  网站制作大概要多少钱一个,做一个平台网站大概多少钱?  如何获取上海专业网站定制建站电话?  自助网站制作软件,个人如何自助建网站?  香港服务器网站卡顿?如何解决网络延迟与负载问题?  建站上传速度慢?如何优化加速网站加载效率? 

您的项目需求

*请认真填写需求信息,我们会在24小时内与您取得联系。