Skip to content Skip to sidebar Skip to footer

Mpandroidchart - Button Click In Markerview

Currently I have a Button in a layout, however an assigned OnClickListener never calls back to the onClick method. Is it possible to intercept the click of a Button in a layout ass

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"