【问题标题】:How to scroll "infinitely" wide view in Android?如何在 Android 中滚动“无限”宽视图?
【发布时间】:2009-10-17 14:39:34
【问题描述】:

我正在考虑如何在 android 中滚动“无限”、类似比例的控件。简单的想法是在每次滚动运动时重绘整个视图,但不知何故,这似乎不是正确的方法。可以预先绘制内容,但我不知道首先应该使视图有多宽,以及当用户滚动到视图末尾时会发生什么?我想我需要将视野扩大到那个方向。

我是否应该以编程方式向线性布局添加(和删除)视图块?很高兴听到关于绘制这种长滚动自定义控件的经验。

谢谢 /埃里克

【问题讨论】:

标签: android scroll custom-view custom-scrolling


【解决方案1】:

如果您正在使用列表/网格或任何使用适配器的数据,您可以使用由 CommonsWare 编写的最优秀的类,可在此处获得:

http://github.com/commonsguy/cwac-endless

它是专门为此目的的

【讨论】:

  • 这看起来很有希望,但我还没有研究过组件的细节。该演示似乎在检索其他视图时暂停并显示进度。我想通过在实际需要之前一段时间渲染可能在屏幕上滚动的视图来使控件感觉更加流畅。你知道这个组件是否可以做到这一点。文档有点简短。
【解决方案2】:

使用控件大小的屏幕外缓冲区。

首先做简单的方法。绘制滚动到正确位置的整个 offscreenbuffer。准备好后将其传送到实际屏幕。

如果这太慢,请尝试通过不重绘整个屏幕外缓冲区而是进行垂直分割来优化它:(我现在只讨论水平滚动移动,以便更容易理解这个概念。但是这个方法也适用于 8 向滚动)

这实现起来有些棘手(这就是我首先建议使用简单方法的原因),但请尝试想象一张上面有图片的纸,然后将左侧环绕并将其粘贴到右侧(这样您会得到一个管子)。这样您就可以无限期地滚动纸张(通过围绕它的 y 轴旋转管子)。

类似地,您可以对屏幕外缓冲区执行相同的操作。通过在屏幕外缓冲区上绘制完整内容来准备屏幕外缓冲区。

现在向右滚动,您基本上将屏幕外缓冲区拆分为 2(通过这种垂直拆分(就像胶水示例中的纸张一样))。假设您向右滚动 10 个像素,您所做的是:

  • 将分割的右侧(位于像素 10)复制到控件的像素 0。 (所以整个区域从 (10, 0) - (width - height) 到:(0,0)
  • 然后将分割的左侧复制:像素 0 到 10 到像素宽度 10。所以:(0,0)-(10,height) 到 (width-10, 0)

在您执行此操作之前,仅重绘要更改的像素(在本例中为 10 像素,因为我们滚动了 10 像素)。所有其他像素仍然相同,不需要重绘。

你必须自己在纸上画出来才能真正理解它。在资源有限的平台(手机等)上进行游戏开发是一种非常常见的技术。

附言可以以完全相同的方式实现向所有方向滚动(虽然更难做到正确);^)

【讨论】:

  • 感谢这个漂亮的算法。似乎可以将其调整为我想要的行为,但它似乎也需要比 Reflog 建议的组件更详细的开发。因此,我将给出答案。
【解决方案3】:

聚会有点晚了,但我想我会告诉你一个更简单的方法: 您只需要背景所在视图的屏幕尺寸或大小,然后调用以下代码(假设您正在扩展视图并覆盖 onDraw):

 private void drawEndlessBackground(Canvas canvas, float left, float top) {

    float modLeft = left % screenWidth;

    canvas.drawBitmap(backgroundImage, modLeft, top, null);

    if (left < 0) {

        canvas.drawBitmap(backgroundImage, modLeft + screenWidth, top, null);

    } else {

        canvas.drawBitmap(backgroundImage, modLeft - screenWidth, top, null);

    }



}

【讨论】:

    【解决方案4】:

    在 XML 中怎么样? private void drawEndlessBackground(Canvas canvas, 向左浮动, 向上浮动) {

    float modLeft = left % screenWidth;
    
    canvas.drawBitmap(backgroundImage, modLeft, top, null);
    
    if (left < 0) {
    
        canvas.drawBitmap(backgroundImage, modLeft + screenWidth, top, null);
    
    } else {
    
        canvas.drawBitmap(backgroundImage, modLeft - screenWidth, top, null);
    
    }
    

    【讨论】:

      猜你喜欢
      • 2013-10-28
      • 2020-06-22
      • 2014-12-12
      • 2012-08-05
      • 1970-01-01
      • 2010-12-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多