最近项目有用到 MPAndroidChart图表,感觉用起来还是比较复杂的,暂时只需要用到折线图,记录一下。
老规矩,先上图,看看是不是你需要的效果。
数据是动态添加的,像心电图一样。
一次最多50条数据,超过50条则开始向右滑动,默认将焦点一直移至最右侧。
开始
1.添加依赖
repositories {
maven { url 'https://jitpack.io' }
}
dependencies {
implementation 'com.github.PhilJay:MPAndroidChart:v3.1.0'
}
2.布局文件
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"
android:background="#FFFFFF">
android:id="@+id/mLineChar"
android:layout_width="match_parent"
android:layout_height="200dp"/>
3.全局变量
private LineChart mLineChar;
private LineDataSet set1;
// 横坐标 秒
private int i = 1;
// 是否自动向右移动
private boolean isMove = true;
// 记录滑动开始X轴坐标
private double startX;
onCreate () 方法 ,为了方便我就先全写一块啦
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main6);
mLineChar = findViewById(R.id.mLineChar);
// 设置手势滑动事件
mLineChar.setOnChartGestureListener(new OnChartGestureListener() {
@Override
public void onChartGestureStart(MotionEvent me, ChartTouchListener.ChartGesture lastPerformedGesture) {
if(lastPerformedGesture == ChartTouchListener.ChartGesture.DRAG){
startX = me.getX();
Log.i("结果",me.getX()+","+me.getY());
}
}
@Override
public void onChartGestureEnd(MotionEvent me, ChartTouchListener.ChartGesture lastPerformedGesture) {
if(lastPerformedGesture == ChartTouchListener.ChartGesture.DRAG){
if(me.getX() - startX > 20){
Log.i("结果","→");
isMove = false;
Log.i("结果","将不移动焦点");
}else if(startX - me.getX() > -20){
Log.i("结果","←");
isMove = true;
Log.i("结果","将移动焦点");
}
startX = me.getX();
}
}
@Override
public void onChartLongPressed(MotionEvent me) {
}
@Override
public void onChartDoubleTapped(MotionEvent me) {
}
@Override
public void onChartSingleTapped(MotionEvent me) {
}
@Override
public void onChartFling(MotionEvent me1, MotionEvent me2, float velocityX, float velocityY) {
}
@Override
public void onChartScale(MotionEvent me, float scaleX, float scaleY) {
}
@Override
public void onChartTranslate(MotionEvent me, float dX, float dY) {
}
});
// 设置数值选择监听
mLineChar.setOnChartValueSelectedListener(new OnChartValueSelectedListener() {
@Override
public void onValueSelected(Entry e, Highlight h) {
// 点击Toast 当前Entry存储的内容,也就是 秒数+温度 信息。
Toast.makeText(Main6Activity.this,e.toString(),Toast.LENGTH_LONG).show();
}
@Override
public void onNothingSelected() {
}
});
// 后台绘制
mLineChar.setDrawGridBackground(false);
// 设置描述文本
mLineChar.getDescription().setEnabled(false);
// 设置支持触控手势
mLineChar.setTouchEnabled(true);
// 设置缩放
mLineChar.setDragEnabled(true);
// 设置推动
mLineChar.setScaleEnabled(true);
// 如果禁用,扩展可以在x轴和y轴分别完成
mLineChar.setPinchZoom(true);
// 这里我模拟一些数据
ArrayList values = new ArrayList();
// 创建一个数据集,并给它一个类型
set1 = new LineDataSet(values, "温度");
// 在这里设置线
set1.enableDashedLine(10f, 5f, 0f);
set1.enableDashedHighlightLine(10f, 5f, 0f);
set1.setColor(Color.BLACK);
set1.setCircleColor(Color.BLACK);
set1.setLineWidth(1f);
set1.setCircleRadius(1f);
set1.setDrawCircleHole(false);
set1.setValueTextSize(9f);
set1.setDrawFilled(true);
set1.setFormLineWidth(1f);
set1.setFormLineDashEffect(new DashPathEffect(new float[]{10f, 5f}, 0f));
set1.setFormSize(15.f);
// 折线统计图的点不显示具体数值,setVisibleXRangeMaximum (int) 设置的毕竟高的话,最后数量多起来也是密密麻麻的看不清所以就不显示
set1.setDrawValues(false);
// 折线背景填充色
set1.setFillColor(Color.RED);
ArrayList dataSets = new ArrayList<>();
// 添加数据集
dataSets.add(set1);
// 创建一个数据集的数据对象
LineData data = new LineData(dataSets);
// 设置应用数据
mLineChar.setData(data);
// 默认动画
mLineChar.animateX(1000);
// 刷新
mLineChar.invalidate();
// 得到这个文字
Legend l = mLineChar.getLegend();
// 修改文字 ...
l.setForm(Legend.LegendForm.LINE);
//传递数据集
// 开启一个任务,每秒自动添加数据
Timer timer = new Timer();
TimerTask timerTask = new TimerTask() {
@Override
public void run() {
runOnUiThread(new Runnable() {
@Override
public void run() {
// 生成一个最高44,最低36的随机数
int max = 44 ;
int min = 36;
int s = min + (int)(Math.random()*(max-min));
values.add(new Entry(i,s));
set1.setValues(values);
set1.notifyDataSetChanged();
mLineChar.getData().notifyDataChanged();
mLineChar.notifyDataSetChanged();
i++;
// 是否开启移动视图
if(isMove){
// 移动视图
if(values.size() > 2){
mLineChar.moveViewToX(values.size() -1 );
}
}
// 必须要setValues() 方法执行后使用,否则无效,也就是不滑动的情况下最多显示多少条内容
if(values.size() > 10){
mLineChar.setVisibleXRangeMaximum(50);
}
}
});
}
};
timer.schedule(timerTask,1000,1000);
}
以上Ctrl+C 、Ctrl+V 效果应该很快就出来了。
说起来这个 MPAndroidChart 性能还是可以的,8000秒,也就是攒了两个多小时,也不会感觉到卡顿,相信这个时间对绝大部分运行在移动设备的APP来说已经是完全够用了。
模拟器都是默认配置 :
折线图开始时候的资源占用:
CPU:
折线图进行滑动的时候,CPU最高 60 %左右,不滑动的时候基本维持到5%左右。
MEMORY :
内存占用55MB左右,滑动基本没有波动。
折线图攒了8000多条数据的资源占用:
CPU:
触摸滑动的时候CPU最高占用 77%,然后稳定至 50% 左右,不滑动的时候CPU占用基本在 10% 以下。
MEMORY :
内存方面,滑动和不滑动的时候,内存都基本上没有什么波动,占用55MB左右。
有什么不足欢迎指出。