3

我正在开发一款类似于最著名的文字游戏。棋盘有 15 x 15 块。瓷砖有 5 种可能的颜色。

棋盘可以放大。也就是说,您可以看到棋盘的全视图,也可以放大 2 倍。

我已经在我的活动中实现了两种绘制板的方法。两者都在我的 Galaxy S 和各种模拟器上测试过。两者似乎都可以在绝大多数设备上正常工作。但是,它们都会给少数用户带来问题(这是我在这里试图解决的问题)。

以下是对 2 种设计的描述:

选项 1:“大图”

描述: 这是最简单的一种。该板是一个独特的ImageView(子类以处理双击缩放和拖动)。图片PNG资源是高分辨率的:大约。最大屏幕尺寸的两倍,以避免放大时放大。

问题: 有时在大屏幕上似乎会出现 OutOfMemory 问题,尤其是在 10" Asus TF101 平板电脑上。

评论: TF101 的测试表明 RAM 使用率是 Galaxy S 的 3 倍。考虑到必须绘制的巨大比例位图,这似乎是合乎逻辑的。

选项 2:重复 5 个小图像

描述: 我试图减少位图使用的 RAM,并利用板只是 5 种小方块的重复这一事实。为了方便调整板视图的大小,我选择将其设为自定义 LinearLayout,其中包含 15 个嵌套的 LinearLayout,每个包含 15 个图像(这当然不是性能方面的最佳选择)。

这是我的 XML 布局对于 4 x 4 板的样子:

        <MyCustomLinearLayout
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:orientation="vertical" >
            <LinearLayout
                android:layout_width="wrap_content"
                android:layout_height="0dp"
                android:layout_weight="1"
                android:orientation="horizontal" >
                <ImageView
                    android:layout_width="0dp"
                    android:layout_height="fill_parent"
                    android:layout_weight="1" >
                </ImageView>

                <ImageView
                    android:layout_width="0dp"
                    android:layout_height="fill_parent"
                    android:layout_weight="1" >
                </ImageView>
            </LinearLayout>

            <LinearLayout
                android:layout_width="wrap_content"
                android:layout_height="0dp"
                android:layout_weight="1"
                android:orientation="horizontal" >
                <ImageView
                    android:layout_width="0dp"
                    android:layout_height="fill_parent"
                    android:layout_weight="1" >
                </ImageView>

                <ImageView
                    android:layout_width="0dp"
                    android:layout_height="fill_parent"
                    android:layout_weight="1" >
                </ImageView>
            </LinearLayout>
        </MyCustomLinearLayout>

问题: 某些用户的一些崩溃或视觉故障。(我仍然没有太多关于这个的信息)

评论: 优点:选项之一是优化了内存占用: 5 个小位图中的每一个只有一个实例保存在内存中。调整板的大小很简单:当我调整 MyCustomLinearLayout 的大小时,Android 会调整位图和嵌套的 LinearLayouts 的大小。

缺点:视图太多,系统必须在每次缩放时重新计算哪些尺寸。

如何改进选项 2 以保持较低的 RAM 占用,同时尊重其他性能良好实践(例如没有数百个视图)?


编辑:最终(?)实施

而不是一个SurfaceView,我去一个简单的自定义View

怕在方法中做大量的位图绘制onDraw()会导致板子的拖拽滞后(因为onDraw()板子移动的时候不断调用)。

事实证明它非常平滑(甚至可能比选项 2 更平滑)。至于 RAM 使用率,它只是比选项 2 重一点(使用 Eclipse Memory Analyzer 进行的比较),因此令人满意。我仍然有一些关于 OutOfMemory 错误的报告(“位图超出最大 VM 堆大小”),但我认为使用位图是不可避免的。

这是最重要的代码,我在其中绘制 15x15 位图(从视图构造函数中的资源初始化)来构建游戏板:

public void drawTileAtCoordsOnCanvas(Bitmap bm, Canvas canvas, int x, int y) {
    _rect.set(x * _sizeOfTile, y * _sizeOfTile, (x + 1) * _sizeOfTile, (y + 1) * _sizeOfTile);
    canvas.drawBitmap(bm, null, _rect, _paint);
}

public void onDraw(Canvas canvas) {
    for (int i = 0; i < _rules.BOARD_SIZE; i++) {
        for (int j = 0; j < _rules.BOARD_SIZE; j++) {
            switch (_rules._boardOfMultiplicators.get(i).get(j)) {
            case NL:
                drawTileAtCoordsOnCanvas(_bitmapNormalTile, canvas, i, j);
                break;
            case DL:
                drawTileAtCoordsOnCanvas(_bitmapDlTile, canvas, i, j);
                break;
            case TL:
                drawTileAtCoordsOnCanvas(_bitmapTlTile, canvas, i, j);
                break;
            case DW:
                drawTileAtCoordsOnCanvas(_bitmapDwTile, canvas, i, j);
                break;
            case TW:
                drawTileAtCoordsOnCanvas(_bitmapTwTile, canvas, i, j);
                break;
            }
        }
    }
    drawTileAtCoordsOnCanvas(_bitmapStarTile, canvas, 7, 7);
}
4

2 回答 2

2

您的第二个选项是最好的(重复 5 个图像),但不是使用 ImageViews,而是直接在自定义视图上绘制会更有效。性能会好很多。

ASurfaceView可能是最好的选择。

于 2012-09-09T10:45:56.973 回答
0

我根本没有 Android 开发经验,所以对此持保留态度,但仅基于查看相关问题和一些谷歌搜索,在我看来,aGridView可能是你想要的。

于 2012-09-09T10:34:38.443 回答