【问题标题】:MPAndroidChart LineChart Double Tap Gesture ControlMPAndroidChart LineChart 双击手势控制
【发布时间】:2017-01-17 10:29:08
【问题描述】:

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

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

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

【问题讨论】:

    标签: android mpandroidchart


    【解决方案1】:

    您的解决方案将涉及创建一个实现 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

    【讨论】:

      【解决方案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() {
      
              }
          });
      

      上面的代码 sn-p 让我可以使用与双击的点相关联的 Entry 对象。另外,我设置了 100 像素的范围,同时点按两次以方便胖手指点击。

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

      【讨论】:

        【解决方案3】:

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

        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 并使用计时器机制模拟双击。

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

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

        【讨论】:

        • 或者更好的是你可以使用 Android Studio -> Tools -> Android -> Layout Inspector
        • 感谢您的解决方案,我会在试用后回复您。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多