【问题标题】:How do I program a Scrollable SurfaceView in Android Java?如何在 Android Java 中编写可滚动的 SurfaceView?
【发布时间】:2014-10-07 08:37:52
【问题描述】:

我正在尝试绘制大于屏幕的图像,并让用户在其周围滚动。该图像是我的代码根据一些数据计算得出的一些图表。 (这是在 Android 中使用 Java)。

我想要的是一个用户可以滚动的视图(实际上是一个 SurfaceView)。我尝试将 SurfaceView 放在 ScrollView 中,但 SurfaceView 绘制的整个图像非常大,因此(a)存在性能问题,因为我的应用程序正在绘制整个 SurfaceView,而它只需要执行视口和 (b) 我的应用程序因“尺寸太大...内存不足”错误而崩溃。

如果 View 可以实现滚动(仅垂直),然后将 y 值传递给我的代码,这样它就可以在视口中绘制我的图像的可见部分,这对我来说是最好的。

或者,我可以捕获“鼠标”事件并自己计算 y 值。

有没有人有任何代码让我可以做到这一点?

更新:我应该澄清一下,图像是由我的程序代码使用 Canvas.drawLine() 等绘制的。我可以计算图像的哪些部分适合我的视口,前提是我将滚动状态作为 y 值,并且我可以通过减去滚动 y 值来计算每个点的绝对 y 坐标。我需要的是可以在用户滚动图像时找到的东西以及生成的 y 值是什么。滚动条也不错。

更新:我正在使用 SurfaceView,以便我可以从另一个线程更新图像,从而提高用户界面性能。

【问题讨论】:

  • 为什么必须有 SurfaceView?你为什么不直接创建一个带有覆盖 onDraw 的自定义视图?
  • 我已编辑问题以解释原因。
  • 好吧,我没有尝试使用 SurfaceView,但这应该与 SurfaceView 扩展视图一样工作:只需使用 View.scrollBy()/View.scrollTo() 以显示视图的某些特定部分
  • 现在我更聪明了,因为我测试了 SurfaceView 和 scrollTo/scrollBy:不幸的是它不起作用,对不起,你需要自己 translate() 你的画布

标签: java android scroll surfaceview


【解决方案1】:

如果你真的只有一个绘图内容......你不需要一个可滚动的客户端那么......

  • 有一个模型(x、y、线条等)
  • 进行平移和缩放
  • 绘制模型的缩放/缩放实例

仅绘制内容(抱歉 - 此解决方案中没有滚动条)

@Override
public boolean onTouchEvent(MotionEvent event) {
    boolean isProcessed = scaleGestureDetector.onTouchEvent(event);

    if (isProcessed) {

        // Handle touch events here...
        switch (event.getAction() & MotionEvent.ACTION_MASK) {

        case MotionEvent.ACTION_DOWN:
            start.set(event.getX(), event.getY());
            tap( event.getX(), event.getY() );
            mode = DRAG_OR_TAP;
            break;
        case MotionEvent.ACTION_POINTER_DOWN:
            break;
        case MotionEvent.ACTION_UP: 
            break;
        case MotionEvent.ACTION_POINTER_UP:
            mode = NONE;
            break;
        case MotionEvent.ACTION_MOVE:
            if (mode == DRAG_OR_TAP) {
                doPan(event.getX() - start.x, event.getY() - start.y);
                start.set(event.getX(), event.getY());
            }
            break;
        }
    }

    myView.scale(currentPan, currentScaleFactor);

    invalidate();
    return true;
}

private void doPan(float panX, float panY) {        
    currentPan.x = currentPan.x + panX;
    currentPan.y = currentPan.y + panY;

}

private void tap(float x, float y) {
    ...
}

最后同样重要的是使用 scaleListener

private class ScaleListener extends
        ScaleGestureDetector.SimpleOnScaleGestureListener {

    @Override
    public boolean onScale(ScaleGestureDetector detector) {

        float value = detector.getScaleFactor();
        currentScaleFactor = currentScaleFactor * value;

        // don't let the object get too small or too large.
        boolean doesntMatch = false;
        if (currentScaleFactor < 1f || currentScaleFactor > 20f){
            currentScaleFactor = Math.max(1f, Math.min(currentScaleFactor, 20f));
            doesntMatch = true;
        }

        if(!doesntMatch){
            //scale the viewport as well
            currentPan.x = currentPan.x*value;
            currentPan.y = currentPan.y*value;

        }
        return true;
    }
}

【讨论】:

  • 我把它作为我代码的基础(我只需要垂直平移,所以我稍微简化了代码)。
  • 老实说 - 这 我的程序的一部分,但我真的必须承认我也复制了从其他人那里剪下的代码(而且我也做了一些调整) ^^ 祝您的应用好运!
【解决方案2】:

您可以简单地使用 WebView 来显示图像

  • 提供泛
  • 提供缩放功能
  • 不需要库
  • 有滚动条

Android: Easiest way to make a WebView display a Bitmap?

我不确定我是否真的遇到了你的问题......

【讨论】:

  • 我没有显示网页。虽然理论上我可以将我的图像显示为 标记,但这将非常低效,因为我一直在更新图像。
猜你喜欢
  • 2010-11-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-06-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多