Mpandroidchart - Button Click In Markerview
Solution 1:
I have finished my app with clickable marker view. My solution is that we'll create a subclass of LineChart (or other chart), then let override onTouchEvent and detect the touch location.
publicclassMyChartextendsLineChart {
@OverridepublicbooleanonTouchEvent(MotionEvent event) {
booleanhandled=true;
// if there is no marker view or drawing marker is disabledif (isShowingMarker() && this.getMarker() instanceof ChartInfoMarkerView){
ChartInfoMarkerViewmarkerView= (ChartInfoMarkerView) this.getMarker();
Rectrect=newRect((int)markerView.drawingPosX,(int)markerView.drawingPosY,(int)markerView.drawingPosX + markerView.getWidth(), (int)markerView.drawingPosY + markerView.getHeight());
if (rect.contains((int) event.getX(),(int) event.getY())) {
// touch on marker -> dispatch touch event in to marker
markerView.dispatchTouchEvent(event);
}else{
handled = super.onTouchEvent(event);
}
}else{
handled = super.onTouchEvent(event);
}
return handled;
}
privatebooleanisShowingMarker(){
return mMarker != null && isDrawMarkersEnabled() && valuesToHighlight();
}
}
publicclassChartInfoMarkerViewextendsMarkerView {
@BindView(R.id.markerContainerView)
LinearLayout markerContainerView;
protectedfloat drawingPosX;
protectedfloat drawingPosY;
privatestaticfinalintMAX_CLICK_DURATION=500;
privatelong startClickTime;
/**
* The constructor
*
* @param context
* @param layoutResource
*/publicChartInfoMarkerView(Context context, int layoutResource) {
super(context, layoutResource);
ButterKnife.bind(this);
markerContainerView.setClickable(true);
markerContainerView.setOnClickListener(newOnClickListener() {
@OverridepublicvoidonClick(View v) {
Log.d("MARKER","click");
}
});
}
@OverridepublicbooleanonTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN: {
startClickTime = Calendar.getInstance().getTimeInMillis();
break;
}
case MotionEvent.ACTION_UP: {
longclickDuration= Calendar.getInstance().getTimeInMillis() - startClickTime;
if(clickDuration < MAX_CLICK_DURATION) {
markerContainerView.performClick();
}
}
}
returnsuper.onTouchEvent(event);
}
@Overridepublicvoiddraw(Canvas canvas, float posX, float posY) {
super.draw(canvas, posX, posY);
MPPointFoffset= getOffsetForDrawingAtPoint(posX, posY);
this.drawingPosX = posX + offset.x;
this.drawingPosY = posY + offset.y;
}
}
Solution 2:
Using the library it appears not to be possible, however a solution of sorts is to show a View or ViewGroup over the chart which has a Button in it. You’ll need to set up an empty layout for the MarkerView and wrap your Chart in a ViewGroup such as a RelativeLayout.
Define a listener such as this in your CustomMarkerView:
publicinterfaceListener {
/**
* A callback with the x,y position of the marker
* @param x the x in pixels
* @param y the y in pixels
*/voidonMarkerViewLayout(int x, int y);
}
Set up some member variables:
private Listener mListener;
privateint mLayoutX;
privateint mLayoutY;
privateint mMarkerVisibility;
In your constructor require a listener:
/**
* Constructor. Sets up the MarkerView with a custom layout resource.
* @param context a context
* @param layoutResource the layout resource to use for the MarkerView
* @param listener listens for the bid now click
*/publicSQUChartMarkerView(Context context, int layoutResource, Listener listener) {
super(context, layoutResource);
mListener = listener;
}
Store the location the marker should be when the values are set:
@OverridepublicintgetXOffset(float xpos) {
mLayoutX = (int) (xpos - (getWidth() / 2));
return -getWidth() / 2;
}
@OverridepublicintgetYOffset(float ypos) {
mLayoutY = (int) (ypos - getWidth());
return -getHeight();
}
Then override onDraw to determine when you should draw your layout:
@Override protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if(mMarkerVisibility == View.VISIBLE) mListener.onMarkerViewLayout(mLayoutX, mLayoutY);
}
I added an option to change the state of the marker:
publicvoidsetMarkerVisibility(int markerVisibility){
mMarkerVisibility = markerVisibility;
}
Where you listen for marker being laid out, get your layout (eg. inflate it or you may have it as a member variable), make sure you measure it, then set the margins. In this case I am using getParent() as the chart and the layout for the marker share the same parent. I have a BarChart so my margins may be different from yours.
@OverridepublicvoidonMarkerViewLayout(int x, int y) {
if(getParent() == null || mChartListener.getAmount() == null) return;
// remove the marker
((ViewGroup) getParent()).removeView(mMarkerLayout);
((ViewGroup) getParent()).addView(mMarkerLayout);
// measure the layout// if this is not done, the first calculation of the layout parameter margins// will be incorrect as the layout at this point has no height or widthintwidthMeasureSpec= View.MeasureSpec.makeMeasureSpec(((ViewGroup) getParent()).getWidth(), View.MeasureSpec.UNSPECIFIED);
intheightMeasureSpec= View.MeasureSpec.makeMeasureSpec(((ViewGroup) getParent()).getHeight(), View.MeasureSpec.UNSPECIFIED);
mMarkerLayout.measure(widthMeasureSpec, heightMeasureSpec);
// set up layout parameters so our marker is in the same position as the mpchart marker would be (based no the x and y)
RelativeLayout.LayoutParamslps= (RelativeLayout.LayoutParams) mMarkerLayout.getLayoutParams();
lps.height = FrameLayout.LayoutParams.WRAP_CONTENT;
lps.width = FrameLayout.LayoutParams.WRAP_CONTENT;
lps.leftMargin = x - mMarkerLayout.getMeasuredWidth() / 2;
lps.topMargin = y - mMarkerLayout.getMeasuredHeight();
}
Hope this helps.
Post a Comment for "Mpandroidchart - Button Click In Markerview"