MPAndroidChart 自定义 MarkerView
实现思路:
- 继承MarkerView
- getOffsetForDrawingAtPoint() //计算出X Y的偏移值如(超出边界时候XY该如何移动)
- refreshContent() //每次点击需要刷新的图形数据
- draw() //绘制背景等图案
效果:
代码:
package com.example.chart.ChartItme;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.drawable.Drawable;
import android.util.Log;
import android.widget.TextView;
import androidx.annotation.Nullable;
import com.bumptech.glide.Glide;
import com.bumptech.glide.load.DataSource;
import com.bumptech.glide.load.engine.GlideException;
import com.bumptech.glide.request.RequestListener;
import com.bumptech.glide.request.target.Target;
import com.example.chart.R;
import com.github.mikephil.charting.charts.Chart;
import com.github.mikephil.charting.components.MarkerView;
import com.github.mikephil.charting.data.Entry;
import com.github.mikephil.charting.highlight.Highlight;
import com.github.mikephil.charting.utils.MPPointF;
import de.hdodenhof.circleimageview.CircleImageView;
public class myMarkView extends MarkerView {
/**
* Constructor. Sets up the MarkerView with a custom layout resource.
*
* @param context
* @param
*/
String[] im=new String[]{"http://pic1.win4000.com/pic/f/e3/f8a7131cf1.jpg","http://pic1.win4000.com/pic/f/e3/5cb2005713.jpg","http://pic1.win4000.com/pic/f/e3/c10cca6c33.jpg","http://pic1.win4000.com/pic/f/e3/ca0debc52d.jpg"};
CircleImageView img;
TextView tv;
float width;
float height;
int a=-1;
/**
* 需要自己写一个布局
* @param context
*/
public myMarkView(Context context) {
//传入自己的布局文件
super(context, R.layout.marker);
//得到布局中的控件
img=findViewById(R.id.img);
tv=findViewById(R.id.text);
}
/**
* 做偏移计算
* 得到的点是我们点击的点 一般需要做偏移处理
* @param posX
* @param posY
* @return
*/
@Override
public MPPointF getOffsetForDrawingAtPoint(float posX, float posY)
{
MPPointF offset=new MPPointF(posX,posY);
Chart chart=getChartView();
width=getWidth();
height=getHeight();
offset.x=offset.x-(width/2);
offset.y=offset.y-(height)-50;
return offset;
}
/**
* 做刷新操作
* @param e
* @param highlight
*/
@Override
public void refreshContent(Entry e, Highlight highlight) {
super.refreshContent(e, highlight);
Log.i("TAG", "refreshContent: "+e.getX());
//用到图像加载库
Glide.with(this)
.load(im[(int) (e.getX()-1)])
.listener(new RequestListener<Drawable>() {
@Override
public boolean onLoadFailed(@Nullable GlideException e, Object model, Target<Drawable> target, boolean isFirstResource) {
return false;
}
@Override
public boolean onResourceReady(Drawable resource, Object model, Target<Drawable> target, DataSource dataSource, boolean isFirstResource) {
if (resource!=null)
{
if (a!=0)
{
invalidate();
a=0;
}
img.setImageDrawable(resource);
}
return false;
}
})
.into(img);
tv.setText(highlight.getY()+"");
}
/**
* 绘制背景
* @param canvas
* @param posX
* @param posY
*/
@Override
public void draw(Canvas canvas, float posX, float posY) {
//绘制边框 画笔
Paint p=new Paint();
p.setColor(Color.parseColor("#Ac72bd"));
p.setStrokeWidth(2);
// p.setStyle(Paint.Style.FILL_AND_STROKE);
p.setStyle(Paint.Style.STROKE);
//绘制填充画笔
Paint p1=new Paint();
p1.setColor(Color.WHITE);
p1.setStyle(Paint.Style.FILL);
p1.setStrokeWidth(0.5f);
//调用getOffsetForDrawingAtPoint()方法得到偏移后的坐标
MPPointF f=getOffsetForDrawingAtPoint(posX,posY);
//带箭头样式
canvas.drawLine(f.x,f.y,f.x,f.y+height,p);
canvas.drawLine(f.x+width,f.y,f.x+width,f.y+height,p);
canvas.drawLine(f.x,f.y,f.x+width,f.y,p);
canvas.drawLine(f.x,f.y+height,f.x+(width/2)-15,f.y+height,p);
canvas.drawLine(f.x+(width/2)+15,f.y+height,f.x+width,f.y+height,p);
//箭头
canvas.drawLine(f.x+(width/2)-15,f.y+height,f.x+(width/2),f.y+height+30,p);
canvas.drawLine(f.x+(width/2)+15,f.y+height,f.x+(width/2),f.y+height+30,p);
//普通方框样式
// canvas.drawArc();
// RectF rectF=new RectF(f.x,f.y,f.x+width,f.y+height);
// canvas.drawRoundRect(rectF,10,10,p1);
// canvas.drawRoundRect(rectF,10,10,p);
canvas.translate(f.x,f.y);
draw(canvas);
}
}
Activity/Fragment 中代码:
//混合图像
mainView = (CombinedChart) view.findViewById(R.id.mainView);
//设置X轴
initxAxis();
//设置Y轴
inityAxis();
//数据源
CombinedData data=new CombinedData();
//载入数据
data.setData(initLineChart());
data.setData(initBarChart());
mainView.setData(data);
//设置自定义的MarkerView
mainView.setMarker(new myMarkView(getContext()));