【问题标题】:Android: How to position the screen on a part of a view which has bounds greater then the screen?Android:如何将屏幕定位在边界大于屏幕的视图的一部分上?
【发布时间】:2014-02-04 08:01:41
【问题描述】:

我正在使用 aChartEngine GraphicalView 来显示条形图。我没有使用 aChartEngine 的“捏缩放”。行为是图表在第一次点击时放大,然后如果点击图表的一个条形,则会显示该条形的更精细的图表。

对于缩放,我使用的是 aChartEngine 提供的缩放工具。在点击时,我为条形图调用 zoomIn 方法,它运行良好。 (缩放只在X轴上)

我面临的问题是,无论我点击哪里,它总是放大到图表的中心。因此,要在边缘点击一个栏,我必须平移到相应的栏以选择它。我想要做的是,如果用户点击图表的边缘,则图表在放大时应该显示图表的该区域。

例如,如果 x 轴最初显示从 1 到 30 的值。如果用户点击以围绕第 3 条进行缩放,则结果图表会显示从 12 到 18 的条,即使他已经点击了第 3 条。我希望能够显示第 1 到第 6 条,这样他就可以直接看到第 3 条,如果他愿意,他也可以平移到其他条。

附: - aChartEngine 的缩放方法是使用比例来设置范围和内容。设置比例限制在这方面有帮助吗?我无法理解多尺度的基础。

【问题讨论】:

    标签: android achartengine


    【解决方案1】:

    其实没有任何功能可以实现。如果你想实现这一点,你必须编辑库的源代码。

    Zoom.java中创建一个新函数(仅更改centerXcenterY的值)

    public void apply(int zoom_axis,double x,double y) {
        if (mChart instanceof XYChart) {
          int scales = mRenderer.getScalesCount();
          for (int i = 0; i < scales; i++) {
            double[] range = getRange(i);
            checkRange(range, i);
            double[] limits = mRenderer.getZoomLimits();
    
            double centerX = x;
            double centerY = y;
            double newWidth = range[1] - range[0];
            double newHeight = range[3] - range[2];
            double newXMin = centerX - newWidth / 2;
            double newXMax = centerX + newWidth / 2;
            double newYMin = centerY - newHeight / 2;
            double newYMax = centerY + newHeight / 2;
    
            // if already reached last zoom, then it will always set to reached
            if (i == 0) {
              limitsReachedX = limits != null && (newXMin <= limits[0] || newXMax >= limits[1]);
              limitsReachedY = limits != null && (newYMin <= limits[2] || newYMax >= limits[3]);
            }
    
            if (mZoomIn) {
              if (mRenderer.isZoomXEnabled() && (zoom_axis == ZOOM_AXIS_X || zoom_axis == ZOOM_AXIS_XY)) {
                if (limitsReachedX && mZoomRate < 1) {
                  // ignore pinch zoom out once reached X limit
                } else {
                  newWidth /= mZoomRate;
                }
              }
    
              if (mRenderer.isZoomYEnabled() && (zoom_axis == ZOOM_AXIS_Y || zoom_axis == ZOOM_AXIS_XY)) {
                if (limitsReachedY && mZoomRate < 1) {
                } else {
                  newHeight /= mZoomRate;
                }
              }
            } else {
              if (mRenderer.isZoomXEnabled() && !limitsReachedX
                  && (zoom_axis == ZOOM_AXIS_X || zoom_axis == ZOOM_AXIS_XY)) {
                newWidth *= mZoomRate;
              }
    
              if (mRenderer.isZoomYEnabled() && !limitsReachedY
                  && (zoom_axis == ZOOM_AXIS_Y || zoom_axis == ZOOM_AXIS_XY)) {
                newHeight *= mZoomRate;
              }
            }
    
            double minX, minY;
            if (limits != null) {
              minX = Math.min(mRenderer.getZoomInLimitX(), limits[1] - limits[0]);
              minY = Math.min(mRenderer.getZoomInLimitY(), limits[3] - limits[2]);
            } else {
              minX = mRenderer.getZoomInLimitX();
              minY = mRenderer.getZoomInLimitY();
            }
            newWidth = Math.max(newWidth, minX);
            newHeight = Math.max(newHeight, minY);
    
            if (mRenderer.isZoomXEnabled() && (zoom_axis == ZOOM_AXIS_X || zoom_axis == ZOOM_AXIS_XY)) {
              newXMin = centerX - newWidth / 2;
              newXMax = centerX + newWidth / 2;
              setXRange(newXMin, newXMax, i);
            }
            if (mRenderer.isZoomYEnabled() && (zoom_axis == ZOOM_AXIS_Y || zoom_axis == ZOOM_AXIS_XY)) {
              newYMin = centerY - newHeight / 2;
              newYMax = centerY + newHeight / 2;
              setYRange(newYMin, newYMax, i);
            }
          }
        } else {
          DefaultRenderer renderer = ((RoundChart) mChart).getRenderer();
          if (mZoomIn) {
            renderer.setScale(renderer.getScale() * mZoomRate);
          } else {
            renderer.setScale(renderer.getScale() / mZoomRate);
          }
        }
        notifyZoomListeners(new ZoomEvent(mZoomIn, mZoomRate));
      }
    

    同样在GraphicalView.java

    public void zoomIn(double x,double y ) {
        if (mZoomIn != null) {
          mZoomIn.apply(Zoom.ZOOM_AXIS_XY,x,y);
          repaint();
        }
      }
    

    现在在你的onclick() 中使用它

    mChartView.zoomIn(mChartView.toRealPoint(0)[0],mChartView.toRealPoint(0)[1]);
    

    【讨论】:

    • 一直很忙,所以无法回复。我对这个问题做了同样的事情。它运作良好。您必须注意的一件事是平移范围。例如,如果 x 轴上的平移界限为 0,并且我们将图表居中在 0 处,则平移不起作用,因为它位于界限处。因此,您必须确保针对这种边界情况调整图表。我也这样做了。在这种情况下,基本上你将不得不调整中心。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-03-25
    • 2011-02-03
    • 1970-01-01
    • 1970-01-01
    • 2011-06-28
    • 1970-01-01
    • 2018-12-26
    相关资源
    最近更新 更多