当前位置: 代码迷 >> 综合 >> 安卓日记:周月年视图的单击事件+mpandroidchart+Markview实现动态图表
  详细解决方案

安卓日记:周月年视图的单击事件+mpandroidchart+Markview实现动态图表

热度:87   发布时间:2023-11-10 15:00:44.0

效果图:

因为只是为了做出效果,没有加数据库什么的,数据都是静态的直接从数组取出来的。单击事件也是比较容易理解的,所以源码放出来给大家,本人作为安卓初学者,烦请大家请品评指正。

在xml中引用linechart

<com.github.mikephil.charting.charts.LineChartandroid:id="@+id/line_chart"android:layout_width="match_parent"android:layout_height="160dp" ></com.github.mikephil.charting.charts.LineChart>

activity的代码:

package com.andyidea.drivers.activity;import com.andyidea.drivers.util.LineChartManager;
import com.andyidea.tabdemo.R;
import com.github.mikephil.charting.charts.LineChart;
import com.github.mikephil.charting.data.LineData;import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.Window;
import android.widget.Button;public class LiShi_TiZhongActivity extends Activity {private LineChart  lineChart2;private LineData lineData;private Button btn_zhou;private Button btn_yue;private Button btn_nian;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);requestWindowFeature(Window.FEATURE_NO_TITLE);setContentView(R.layout.lishi_tizhong);btn_zhou=(Button) findViewById(R.id.btn_tizhong_zhou);btn_yue=(Button) findViewById(R.id.btn_tizhong_yue);btn_nian=(Button) findViewById(R.id.btn_tizhong_nian);OnClickListener cl=new OnClickListener() {			@Overridepublic void onClick(View v) {if(v.getId()==R.id.btn_tizhong_nian){btn_nian.setBackgroundResource(R.drawable.btn_choose_onclick_04);btn_yue.setBackgroundResource(R.drawable.btn_choose_unclick_03);btn_zhou.setBackgroundResource(R.drawable.btn_choose_unclick_02);initNianChart();}else if(v.getId()==R.id.btn_tizhong_yue){btn_yue.setBackgroundResource(R.drawable.btn_choose_onclick_03);btn_nian.setBackgroundResource(R.drawable.btn_choose_unclick_04);btn_zhou.setBackgroundResource(R.drawable.btn_choose_unclick_02);initYueChart();}else if(v.getId()==R.id.btn_tizhong_zhou){btn_zhou.setBackgroundResource(R.drawable.btn_choose_onclick_02);btn_nian.setBackgroundResource(R.drawable.btn_choose_unclick_04);btn_yue.setBackgroundResource(R.drawable.btn_choose_unclick_03);initZhouChart();}else{btn_nian.setBackgroundResource(R.drawable.btn_choose_unclick_04);btn_yue.setBackgroundResource(R.drawable.btn_choose_unclick_03);btn_zhou.setBackgroundResource(R.drawable.btn_choose_unclick_02);}}};initZhouChart();btn_zhou.setBackgroundResource(R.drawable.btn_choose_onclick_02);btn_nian.setOnClickListener(cl);btn_yue.setOnClickListener(cl);btn_zhou.setOnClickListener(cl);}private void initZhouChart() {lineChart2 = (LineChart) findViewById(R.id.line_chart);// 设置图表的描述lineChart2.setDescription("体温数据");// 设置x轴的数据int numX = 7;// 设置y轴的数据//体温float[] datas1 = { 52.3f, 51f, 50f, 48f,49f,48f,46f,50f,50f,50f,50f,50f,52.3f, 51f, 50f, 48f,49f,48f,46f,50f,50f,52.3f, 51f, 50f, 48f,49f,48f,46f,50f,50f};// 数据// 设置折线的名称// LineChartManager.setLineName("体温数据");// 创建折线的图表lineData = LineChartManager.initZhouLineChart(this, lineChart2, numX, datas1);LineChartManager.initDataStyle(lineChart2, lineData, this);lineChart2.setDragEnabled(true);}private void initYueChart() {lineChart2 = (LineChart) findViewById(R.id.line_chart);// 设置图表的描述lineChart2.setDescription("体温数据");// 设置x轴的数据int numyue=30;// 设置y轴的数据//体温//float[] datas2 = { 37.5f, 37.1f, 37.3f, 36.7f, 36.5f, 36.7f, 37.5f, 37.1f, 37.3f, 36.7f, 36.5f, 36.7f,37.5f, 37.1f, 37.3f, 36.7f, 36.5f, 36.7f, 37.5f };// 数据float[] datas1 = { 52.3f, 51f, 50f, 48f,49f,48f,46f,50f,50f,50f,50f,50f,52.3f, 51f, 50f, 48f,49f,48f,46f,50f,50f,52.3f, 51f, 50f, 48f,49f,48f,46f,50f,50f};// 数据// 设置折线的名称// LineChartManager.setLineName("体温数据");// 创建折线的图表//lineData = LineChartManager.initZhouLineChart(this, lineChart2, numX, datas1);lineData = LineChartManager.initYueLineChart(this, lineChart2, numyue, datas1);LineChartManager.initDataStyle(lineChart2, lineData, this);lineChart2.setDragEnabled(true);}private void initNianChart() {lineChart2 = (LineChart) findViewById(R.id.line_chart);// 设置图表的描述lineChart2.setDescription("体温数据");// 设置x轴的数据int numX = 12;// 设置y轴的数据//体温//float[] datas2 = { 37.5f, 37.1f, 37.3f, 36.7f, 36.5f, 36.7f, 37.5f, 37.1f, 37.3f, 36.7f, 36.5f, 36.7f,37.5f, 37.1f, 37.3f, 36.7f, 36.5f, 36.7f, 37.5f };// 数据float[] datas1 = { 52.3f, 51f, 50f, 48f,49f,48f,46f,50f,50f,50f,50f,50f,52.3f, 51f, 50f, 48f,49f,48f,46f,50f,50f,52.3f, 51f, 50f, 48f,49f,48f,46f,50f,50f};// 数据// 设置折线的名称// LineChartManager.setLineName("体温数据");// 创建折线的图表//lineData = LineChartManager.initZhouLineChart(this, lineChart2, numX, datas1);lineData = LineChartManager.initNianLineChart(this, lineChart2, numX, datas1);LineChartManager.initDataStyle(lineChart2, lineData, this);lineChart2.setDragEnabled(true);}}

工具类:linechartmanager

package com.andyidea.drivers.util;import java.util.ArrayList;import com.andyidea.tabdemo.R;
import com.github.mikephil.charting.animation.Easing;
import com.github.mikephil.charting.charts.LineChart;
import com.github.mikephil.charting.components.Legend;
import com.github.mikephil.charting.components.LimitLine;
import com.github.mikephil.charting.components.MarkerView;
import com.github.mikephil.charting.components.XAxis;
import com.github.mikephil.charting.components.YAxis;
import com.github.mikephil.charting.data.Entry;
import com.github.mikephil.charting.data.LineData;
import com.github.mikephil.charting.data.LineDataSet;import android.content.Context;
import android.graphics.Color;public class LineChartManager {private static String lineName = null;/*** 创建一条折线* * @param context*            上下文* @param mLineChart*            对象* @param count*            X轴的数据* @param datas*            Y轴的数据* @return LineData*/public static LineData initZhouLineChart(Context context, LineChart mLineChart, int count, float[] datas) {ArrayList<String> xValues = new ArrayList<String>();for (int i = 1; i <= count; i++) {// x轴显示的数据,这里默认使用数字下标显示String s;switch (i) {case 1:s = "一";break;case 2:s = "二";break;case 3:s = "三";break;case 4:s = "四";break;case 5:s = "五";break;case 6:s = "六";break;case 7:s = "日";break;default:s = "null";break;}xValues.add("星期" + s);}// y轴的数据ArrayList<Entry> yValues = new ArrayList<Entry>();for (int i = 0; i < count; i++) {yValues.add(new Entry(datas[i], i));}// 设置折线的样式LineDataSet dataSet = new LineDataSet(yValues, lineName);// 用y轴的集合来设置参数dataSet.setLineWidth(2f); // 线宽dataSet.setCircleSize(4f);// 显示的圆形大小dataSet.setColor(Color.rgb(89, 194, 230));// 折线显示颜色dataSet.setCircleColor(Color.rgb(89, 194, 230));// 圆形折点的颜色dataSet.setHighLightColor(Color.GREEN); // 高亮的线的颜色dataSet.setHighlightEnabled(true);dataSet.setValueTextColor(Color.rgb(89, 194, 230)); // 数值显示的颜色dataSet.setValueTextSize(10f); // 数值显示的大小dataSet.setDrawValues(false);// 设置y轴的数字不显示ArrayList<LineDataSet> dataSets = new ArrayList<LineDataSet>();dataSets.add(dataSet);// 构建一个LineData 将dataSets放入LineData lineData = new LineData(xValues, dataSets);return lineData;}public static LineData initYueLineChart(Context context, LineChart mLineChart, int count, float[] datas) {ArrayList<String> xValues = new ArrayList<String>();for (int i = 1; i <= count; i++) {// x轴显示的数据xValues.add(i + "日");}// y轴的数据ArrayList<Entry> yValues = new ArrayList<Entry>();for (int i = 0; i < count; i++) {yValues.add(new Entry(datas[i], i));}// 设置折线的样式LineDataSet dataSet = new LineDataSet(yValues, lineName);// 用y轴的集合来设置参数dataSet.setLineWidth(2f); // 线宽dataSet.setCircleSize(4f);// 显示的圆形大小dataSet.setColor(Color.rgb(89, 194, 230));// 折线显示颜色dataSet.setCircleColor(Color.rgb(89, 194, 230));// 圆形折点的颜色dataSet.setHighLightColor(Color.GREEN); // 高亮的线的颜色dataSet.setHighlightEnabled(true);dataSet.setValueTextColor(Color.rgb(89, 194, 230)); // 数值显示的颜色dataSet.setValueTextSize(10f); // 数值显示的大小dataSet.setDrawValues(false);// 设置y轴的数字不显示ArrayList<LineDataSet> dataSets = new ArrayList<LineDataSet>();dataSets.add(dataSet);// 构建一个LineData 将dataSets放入LineData lineData = new LineData(xValues, dataSets);return lineData;}public static LineData initNianLineChart(Context context, LineChart mLineChart, int count, float[] datas) {ArrayList<String> xValues = new ArrayList<String>();for (int i = 1; i <= count; i++) {// x轴显示的数据xValues.add(i + "月");}// y轴的数据ArrayList<Entry> yValues = new ArrayList<Entry>();for (int i = 0; i < count; i++) {yValues.add(new Entry(datas[i], i));}// 设置折线的样式LineDataSet dataSet = new LineDataSet(yValues, lineName);// 用y轴的集合来设置参数dataSet.setLineWidth(2f); // 线宽dataSet.setCircleSize(4f);// 显示的圆形大小dataSet.setColor(Color.rgb(89, 194, 230));// 折线显示颜色dataSet.setCircleColor(Color.rgb(89, 194, 230));// 圆形折点的颜色dataSet.setHighLightColor(Color.GREEN); // 高亮的线的颜色dataSet.setHighlightEnabled(true);dataSet.setValueTextColor(Color.rgb(89, 194, 230)); // 数值显示的颜色dataSet.setValueTextSize(10f); // 数值显示的大小dataSet.setDrawValues(false);// 设置y轴的数字不显示ArrayList<LineDataSet> dataSets = new ArrayList<LineDataSet>();dataSets.add(dataSet);// 构建一个LineData 将dataSets放入LineData lineData = new LineData(xValues, dataSets);return lineData;}/*** @Description:初始化图表的样式*/public static void initDataStyle(LineChart lineChart, LineData lineData, Context context) {// 设置点击折线点时,显示其数值MarkerView mv = new MyMarkerView(context,R.layout.content_marker_view);lineChart.setMarkerView(mv);lineChart.setDrawBorders(false); // 在折线图上添加边框// lineChart.setDescription("时间/数据"); //数据描述lineChart.setNoDataText("暂无数据");// 没有数据的时候lineChart.setDrawGridBackground(false); // 表格颜色lineChart.setGridBackgroundColor(Color.GRAY & 0x70FFFFFF); // 表格的颜色,设置一个透明度lineChart.setTouchEnabled(true); // 启用/禁用与图表的所有可能的触摸交互。lineChart.setDragEnabled(true); // 可拖拽lineChart.setScaleEnabled(false); // 可缩放lineChart.setPinchZoom(true);// 如果设置为true,捏缩放功能。 如果false,x轴和y轴可分别放大。lineChart.setBackgroundColor(Color.WHITE); // 设置背景颜色lineChart.setVisibleXRangeMaximum(12);// x轴底部最多显示几个lineChart.setVisibleXRangeMinimum(7);// setViewPortOffsets(float left, float top, float right, float bottom)// : 设置当前视图的偏移量(实际图表窗口的两侧偏移量)。 设置这个,将阻止图表自动计算它的偏移量。// 使用 resetViewPortOffsets() 撤消此设置。lineChart.setViewPortOffsets(80f, 50f, 80f, 50f);Legend legend = lineChart.getLegend();legend.setEnabled(false);// 设置Legend启用或禁用。 如果禁用, Legend 将不会被绘制。lineChart.setData(lineData);Legend mLegend = lineChart.getLegend(); // 设置标示,就是那个一组y的value的mLegend.setForm(Legend.LegendForm.SQUARE); // 样式mLegend.setFormSize(6f); // 字体mLegend.setTextColor(Color.GRAY); // 颜色lineChart.setVisibleXRange(1, 15); // x轴可显示的坐标范围XAxis xAxis = lineChart.getXAxis(); // x轴的标示xAxis.setPosition(XAxis.XAxisPosition.BOTTOM); // x轴位置xAxis.setTextColor(Color.GRAY); // 字体的颜色xAxis.setTextSize(10f); // 字体大小xAxis.setGridColor(Color.GRAY);// 网格线颜色xAxis.setDrawGridLines(false); // 不显示网格线xAxis.setAxisLineWidth(1f);// 设置x轴的直线宽度YAxis axisLeft = lineChart.getAxisLeft(); // y轴左边标示YAxis axisRight = lineChart.getAxisRight(); // y轴右边标示axisLeft.setTextColor(Color.GRAY); // 字体颜色axisLeft.setTextSize(10f); // 字体大小// axisLeft.setAxisMaxValue(800f); //最大值axisLeft.setLabelCount(5, true); // 显示格数axisLeft.setGridColor(Color.GRAY); // 网格线颜色// 设置y轴初始数据不是零axisLeft.setStartAtZero(false);axisLeft.setAxisMinValue(40f);axisLeft.setAxisMaxValue(60f);axisRight.setDrawAxisLine(false);axisRight.setDrawGridLines(false);axisRight.setDrawLabels(false);// 设置动画效果/** lineChart.animateY(1500); lineChart.animateX(1500);*/// lineChart.invalidate();lineChart.animateXY(1000, 1000);// lineChart.animateX(2000); //立即执行动画}/*** @param name* @Description:设置折线的名称*/public static void setLineName(String name) {lineName = name;}}

最后是markview的效果,需要一个背景文件bg_mark,一个markview的xml布局文件,以及markview类

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">android:shape="rectangle"><solid android:color="@color/text_color_fc" /><corners android:radius="30dp" /><solid android:color="@color/text_color_fc"/>
</shape>



<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="35dp"android:layout_height="25dp"android:background="@drawable/bg_marker"android:gravity="center"android:orientation="vertical"><TextViewandroid:id="@+id/tv_content_marker_view"android:layout_width="wrap_content"android:layout_height="wrap_content"android:padding="2dp"android:textAppearance="?android:attr/textAppearanceSmall"android:textColor="@android:color/white"android:textSize="12sp"/>
</RelativeLayout>


package com.andyidea.drivers.util;import com.andyidea.tabdemo.R;
import com.github.mikephil.charting.components.MarkerView;
import com.github.mikephil.charting.data.Entry;
import com.github.mikephil.charting.highlight.Highlight;import android.content.Context;
import android.widget.TextView;public class MyMarkerView extends MarkerView {private TextView mContentTv;public MyMarkerView(Context context, int layoutResource) {super(context, layoutResource);mContentTv = (TextView) findViewById(R.id.tv_content_marker_view);}@Overridepublic void refreshContent(Entry e, Highlight highlight) {mContentTv.setText("" + e.getVal());}@Overridepublic int getXOffset(float xpos) {return -(getWidth() / 2);}@Overridepublic int getYOffset(float ypos) {return -getHeight();}
}

在引用markview的时候,直接在activity文件中写入:

// 设置点击折线点时,显示其数值MarkerView mv = new MyMarkerView(context,R.layout.content_marker_view);lineChart.setMarkerView(mv);
写在结尾:也从网上找了十来篇案例,都下载下来在手机调试一遍,又不断地修改,钻研,才勉强做出了自己想要的效果。自觉代码好像还可以从各个方面进行优化,但没有好的思路。希望大家批评指正哈~