MPAndroidChart LineChart双击手势控制

时间:2017-01-17 10:29:09

标签: android mpandroidchart

我正在使用MPAndroidChart来显示我的应用程序的折线图。我已经拥有的是整个图表的双击监听器。

有没有办法获得折线图中单个点的双击侦听器控制?我最好的猜测是直接获取该点的View对象并为其实现一个手势监听器。如果这是合情合理的,我该如何实现?

如果使用MPAndroidChart无法做到这一点,是否还有其他库可以帮助我解决这个问题?

3 个答案:

答案 0 :(得分:3)

您的解决方案将涉及创建一个实现OnChartGestureListener

的类

您可以立即看到有一种方法:

void onChartDoubleTapped(android.view.MotionEvent me);

您必须使用所需的功能实现此方法。它可能涉及从MotionEvent获取原始像素触摸点并将它们转换为图表上的x和y值。有关如何在this answer和以下代码中执行此操作的说明:

@Override
public void onChartDoubleTapped(MotionEvent me) {
    float tappedX = me.getX();
    float tappedY = me.getY();
    MPPointD point = mChart.getTransformer(YAxis.AxisDependency.LEFT).getValuesByTouchPoint(tappedX, tappedY);
    Log.d(TAG, "tapped at: " + point.x + "," + point.y);
}

自定义OnChartGestureListener的更多示例位于example project here

答案 1 :(得分:2)

David Rawson的answer是完美的,并回答了一个不遗余力的问题。但是,对于我的情况,我发现firegloves的answer更有用。我实际上使用firegloves的解决方案来获取Entry对象以获取值。以下是解决我的问题的代码,但请注意此解决方案是hacky,直到绝对必要时才建议。如果你想要一个干净的解决方案,David Rawson的答案已经涵盖了

mChart.setOnChartValueSelectedListener(new OnChartValueSelectedListener() {
        @Override
        public void onValueSelected(Entry e, Highlight h) {
            final long selectionTime = System.currentTimeMillis();
            final Highlight copyHighlight = h;
            final Entry copyEntry = e;
            final boolean[] isTapped = {false};
            mChart.setOnTouchListener(new View.OnTouchListener() {
                @Override
                public boolean onTouch(View view, MotionEvent motionEvent) {
                    if (!isTapped[0]) {
                        final long doubleTapTime = System.currentTimeMillis();
                        if (doubleTapTime - selectionTime < 300) {
                            if ((motionEvent.getX() <= copyHighlight.getDrawX() + 50
                                    && motionEvent.getX() >= copyHighlight.getDrawX() - 50)
                                    && (motionEvent.getY() <= copyHighlight.getDrawY() + 50
                                    && motionEvent.getY() >= motionEvent.getY() - 50)) {
                                if (copyEntry.getX() == 1.0f && copyEntry.getY() == 1.0f) {
                                    Toast.makeText(MainActivity.this, "1,1", Toast.LENGTH_SHORT).show();
                                } else if (copyEntry.getX() == 2.0f && copyEntry.getY() == 2.0f) {
                                    Toast.makeText(MainActivity.this, "2,2", Toast.LENGTH_SHORT).show();
                                } else if (copyEntry.getX() == 3.0f && copyEntry.getY() == 3.0f) {
                                    Toast.makeText(MainActivity.this, "3,3", Toast.LENGTH_SHORT).show();
                                }
                            }
                        }
                    }
                    isTapped[0] = true;
                    return false;
                }
            });
        }

        @Override
        public void onNothingSelected() {

        }
    });

上面的代码片段让我使用与双击点相关联的Entry对象。此外,我设置了100像素的范围,而点被双击,以方便脂肪手指敲击。

我很想知道是否有一个干净的解决方案,可以在获取Entry数据时双击一个值。

答案 2 :(得分:1)

悄悄进入LineChartRenderer我认为这是不可能的,因为图形渲染是直接在Canvas上绘制的,如下所示:

canvas.drawPath(mCirclePathBuffer, mRenderPaint);

您可以尝试打印所有图形子项以检查我是否错了,例如:

int size =lineChart.getChildCount();
for (int i=0; i<size; i++) {
    View v = lineChart.getChildAt(i);
    Log.i("### LINE", "### INSTANCE OF " + v.getClass());
}

如果有儿童观点,他们必须以这种方式访问​​。

否则,您可以尝试拦截整个LineGraph上的双击,然后您可以尝试检查点击位置是否与映射位置相对应,但我认为您必须自己完成整个工作。

另一个选择可能是实现OnChartValueSelectedListener并使用计时器机制模拟双击。

我认为没有一个支持此功能的库。

如果您找到解决方案,请告诉我