Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android - Dragging in MPAndroidChart is unresponsive when contained in ScrollView

I have a LineChart contained within a ScrollView. When the chart is long enough for it to be necessary for a user to scroll to see it in its entirety, the drag features become unresponsive. Drag gestures only register when I hold my finger down for a short period of time in the chart bounds and then drag.

I have tried using the requestDisallowInterceptTouchEvent method that should prevent the chart's parents from intercepting the touch events (but this doesn't solve anything). I've also tried directly passing MotionEvents registered by the ScrollView straight to the chart/translating drag gestures to translateY calls but this doesn't do what I thought it would.

Note: Zooming continues to work perfectly.

Also, this is not an issue when the graph fits in the original window or when it's placed in any view that is not a ScrollView. I have considered getting rid of the ScrollView but it's a pretty necessary feature in my project.

Any ideas on why this could be happening would be appreciated!

Edit: the LineChart has a fixed height

like image 793
Ruthvik Peddawandla Avatar asked Aug 05 '15 23:08

Ruthvik Peddawandla


2 Answers

This question is kind of old but I run into the same problem recently and to solve it, I did the following.

  1. Added a transparent view over the graph on the xml.
  2. Set setOnTouchListener on the view

ex.

     clickInterceptorGraph.setOnTouchListener(new View.OnTouchListener() {
           @Override
           public boolean onTouch(View v, MotionEvent event) {

            return onTouchActionHandler(v, event);

            }
        });
  1. On the MotionEvent Action Down, I'm setting requestDisallowInterceptTouchEvent to true and returning false so the event won't be consumed, so while the user is pressing on the transparent image over the graph requestDisallowInterceptTouchEvent will be true and it will disable the Touch Event on the scrollview which will disable the scroll and when you release the touch the scrollview will work normally again.

ex.

 protected boolean onTouchActionHandler(View v, MotionEvent event){

    int action = event.getAction();
    switch (action) {
        case MotionEvent.ACTION_DOWN:
            // Disallow RecyclerView to intercept touch events.
            scrollView.requestDisallowInterceptTouchEvent(true);
            Log.e(TAG, "onTouchActionHandler: ACTION_DOWN" );
            // Disable touch on transparent view
            return false;
        default:
            return true;
    }
}

*** You could do everything on the setOntouchListener but in my case I need to reuse the requestDisallowInterceptTouchEvent.

like image 130
Ruan_Lopes Avatar answered Oct 23 '22 18:10

Ruan_Lopes


Similar approach as Ruan_Lopes mentioned, you just don't need a transparent overlay view. You can also use chart gesture listener to intercept touches the same way.

lineChart.onChartGestureListener = object : OnChartGestureListener {
    override fun onChartGestureEnd(
        me: MotionEvent?,
        lastPerformedGesture: ChartTouchListener.ChartGesture?
    ) = Unit

    override fun onChartFling(
        me1: MotionEvent?,
        me2: MotionEvent?,
        velocityX: Float,
        velocityY: Float
    ) = Unit

    override fun onChartSingleTapped(me: MotionEvent?) = Unit

    override fun onChartGestureStart(
        e: MotionEvent?,
        lastPerformedGesture: ChartTouchListener.ChartGesture?
    ) = recyclerView.requestDisallowInterceptTouchEvent(true)

    override fun onChartScale(me: MotionEvent?, scaleX: Float, scaleY: Float) = Unit

    override fun onChartLongPressed(me: MotionEvent?) = Unit

    override fun onChartDoubleTapped(me: MotionEvent?) = Unit

    override fun onChartTranslate(me: MotionEvent?, dX: Float, dY: Float) = Unit
}
like image 1
Arūnas Bedžinskas Avatar answered Oct 23 '22 17:10

Arūnas Bedžinskas