其余文章索引:
MPAndroidChart 教程:概述
MPAndroidChart 教程:开始 Getting Started(一)
MPAndroidChart 教程:与图表进行手势交互 Interaction with the Chart(二)
MPAndroidChart 教程:坐标轴,X轴,Y轴,Labels(三)
MPAndroidChart 教程:设置数据,设置颜色(四)
MPAndroidChart 教程:数据格式器 ValueFormatter(五)
MPAndroidChart 教程:图表的具体设置 Specific chart settings(六)
MPAndroidchart 教程:图例 Legend(七)
MPAndroidChart 教程:动态和实时数据 Dynamic & Realtime Data(八)
MPAndroidChart 教程:修改视窗 Modifying the Viewport(九)
MPAndroidChart 教程:动画 Animations(十)
MPAndroidChart 教程:MarkerView(十一)
MPAndroidChart 教程:ChartData类,ChartData子类, DataSet类,DataSet子类(十二)
时间仓促,难免有错误,有的话希望大家在评论中指出,谢谢。
源码:范例代码在线查看或下载
如上图所示,当点击折线图上的点时,会弹出一个View,这就是 Markerview
。
TextView
布局和一个椭圆黑色的 background
TextView
布局和一个 bitmap
的 background
那么这具体是如何实现的呢?
为显示自定义的(弹出的)扩展View并且使得点击的点的值在图表中突出显示,我们可以创建一个类并继承MakerView
抽象类,然后实现该类的构造方法和继承自 MarkerView
类的抽象方法 。
// extend MarkerView
public class YourCustomMarkerView extends MarkerView { ...
MarkerView
类继承自 RelativeLayout
。/**
* View that can be displayed when selecting values in the chart.
* Extend this class to provide custom layouts for your markers.
*/
public abstract class MarkerView extends RelativeLayout {
/**
* Constructor. Sets up the MarkerView with a custom layout resource.
*
* @param context
* @param layoutResource the layout resource to use for the MarkerView
*/
public MarkerView(Context context, int layoutResource) {
super(context);
setupLayoutResource(layoutResource);
}
/**
* Sets the layout resource for a custom MarkerView.
*
* @param layoutResource
*/
private void setupLayoutResource(int layoutResource) {
View inflated = LayoutInflater.from(getContext())
.inflate(layoutResource, this);
inflated.setLayoutParams(
new LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT,
RelativeLayout.LayoutParams.WRAP_CONTENT));
inflated.measure(MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED),
MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
// measure(getWidth(), getHeight());
inflated.layout(0, 0, inflated.getMeasuredWidth(),
inflated.getMeasuredHeight());
}
/**
* Draws the MarkerView on the given position on the screen
* with the given Canvas object.
*
* @param canvas
* @param posx
* @param posy
*/
public void draw(Canvas canvas, float posx, float posy) {
// take offsets into consideration
posx += getXOffset(posx);
posy += getYOffset(posy);
// translate to the correct position and draw
canvas.translate(posx, posy);
draw(canvas);
canvas.translate(-posx, -posy);
}
/**
* This method enables a specified custom MarkerView to
* update it's content everytime the MarkerView is redrawn.
*
* @param e The Entry the MarkerView belongs to. This can
* also be any subclass of Entry, like BarEntry or CandleEntry,
* simply cast it at runtime.
* @param highlight The highlight object contains information
* about the highlighted value such as it's dataset-index, the
* selected range or stack-index (only stacked bar entries).
*/
public abstract void refreshContent(Entry e, Highlight highlight);
/**
* Use this to return the desired offset you wish the MarkerView
* to have on the x-axis. By returning -(getWidth() /
* 2) you will center the MarkerView horizontally.
*
* @param xpos the position on the x-axis in pixels where the marker is drawn
* @return
*/
public abstract int getXOffset(float xpos);
/**
* Use this to return the desired position offset you wish the MarkerView
* to have on the y-axis. By returning
* -getHeight() you will cause the MarkerView to be above the selected value.
*
* @param ypos the position on the y-axis in pixels where the marker is drawn
* @return
*/
public abstract int getYOffset(float ypos);
}
setMarkerView(MarkerView mv)
: 为 chart
设置一个 MarkerView
从而显示选中的值。getMarkerView()
: 获取 chart
已经设置了的 MarkerView
,未设置的话返回 null
。 后面你可以找到一个实现自定义 MarkerView
类的例子。 重要的是,在这个过程中要实现以下从 MarkerView
抽象类继承来的方法:
refreshContent(Entry e, Highlight highlight)
: 每次 MarkerView
重绘此方法都会被调用,并为您提供更新它显示的内容的机会(例如,为一个 TextView
设置文本 ,…)。 它提供了当前突出显示的 Entry
和相应的Highlight对象以获得更多信息。getXOffset(float xpos)
: 在这里,应返回要绘制的 MarkerView
在x轴的偏移位置。 默认情况下,MarkerView
的左上边缘处将绘制在 entry
的位置。 在 xpos
参数表示绘制 MarkerView
的默认位置。getYOffset(float ypos)
: 在这里,应返回要绘制的 MarkerView
在y轴的偏移位置。 默认情况下,MarkerView
的左上边缘处将绘制在 entry
的位置。 在 ypos
参数表示绘制MarkerView
的默认位置。实现自定义 MarkerView
类的例子:
public class CustomMarkerView extends MarkerView {
private TextView tvContent;
public CustomMarkerView (Context context, int layoutResource) {
super(context, layoutResource);
// this markerview only displays a textview
tvContent = (TextView) findViewById(R.id.tvContent);
}
// callbacks everytime the MarkerView is redrawn, can be used to update the
// content (user-interface)
@Override
public void refreshContent(Entry e, Highlight highlight) {
tvContent.setText("" + e.getVal()); // set the entry-value as the display text
}
@Override
public int getXOffset(float xpos) {
// this will center the marker-view horizontally
return -(getWidth() / 2);
}
@Override
public int getYOffset(float ypos) {
// this will cause the marker-view to be above the selected value
return -getHeight();
}
}
MarkerView
类后,需要创建一个 .xml
文件来作为 MarkerView
的布局。 本实例的布局仅是一个有背景图的且内含一个TextView
的 RelativeLayout
,但 你可以创建任何你想要在这里显示的布局。
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="40dp"
android:background="@drawable/markerImage" >
<TextView
android:id="@+id/tvContent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:text=""
android:textSize="12dp"
android:textColor="@android:color/white"
android:ellipsize="end"
android:singleLine="true"
android:textAppearance="?android:attr/textAppearanceSmall" />
RelativeLayout>
MarkerView
。 创建 MarkerView
时请确保你创建的 .xml
文件提供了对应的 layout
资源。 CustomMarkerView mv = new CustomMarkerView(Context,
R.layout.custom_marker_view_layout);
// set the marker to the chart
chart.setMarkerView(mv);
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval">
<solid android:color="@android:color/black"/>
shape>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="72dp"
android:layout_height="48dp"
android:background="@drawable/bg_marker"
android:gravity="center"
android:orientation="vertical">
<TextView
android:id="@+id/tv_content_marker_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="4dp"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textColor="@android:color/white"
android:textSize="18sp"/>
RelativeLayout>
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);
}
@Override
public void refreshContent(Entry e, Highlight highlight) {
mContentTv.setText("" + e.getVal());
}
@Override
public int getXOffset(float xpos) {
return -(getWidth() / 2);
}
@Override
public int getYOffset(float ypos) {
return -getHeight();
}
}
// 设置MarkerView
MarkerView mv = new MyMarkerView(this,R.layout.content_marker_view);
chart.setMarkerView(mv);
本节完。