MPAndroidChart LineChart 双击手势控制

MPAndroidChart LineChart Double Tap Gesture Control

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

有什么方法可以获得折线图中单个点的双击监听器控件吗?我最好的猜测是直接获取该点的 View 对象并为其实现一个手势侦听器。如果这是合理的,我怎样才能做到这一点?

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

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

canvas.drawPath(mCirclePathBuffer, mRenderPaint);

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

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

如果有 children 个视图,它们必须可以通过这种方式访问​​。

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

另一种选择是实施 OnChartValueSelectedListener 并使用计时器机制模拟双击。

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

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

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

的 class

马上就能看到有一个方法:

void onChartDoubleTapped(android.view.MotionEvent me);

您必须使用您想要的功能来实现此方法。它可能涉及从 MotionEvent 获取原始像素触摸点并将它们转换为图表上的 x 和 y 值。在 和下面的代码中有关于如何做到这一点的说明:

@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);
}

更多自定义示例 OnChartGestureListenerexample project here

David Rawson 的 is just perfect and answers the question leaving no stones unturned. However, for my situation, I found the by firegloves 更有用。我实际上使用 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 对象。另外,为了方便 fat-finger 点击,我设置了 100 像素的范围,同时双击该点。

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