java - getChildDrawingOrder 调用/使用不正常?

标签 java android drawing

我正在创建一个带有简单图 block 的等距 map ,并且我扩展了 RelativeLayout 以创建一个包含这些图 block 的布局。实际上,只要我的方向与将图 block 写入 XML 文件的顺序相匹配,就可以按原样使用 RelativeLayout;我覆盖的只是构造函数,我只是调用 supersetChildrenDrawingOrderEnabled(true); 以及设置一些变量(网格的高度和宽度),以及然后是 getChildDrawingOrder 本身。

我的 getChildDrawingOrder 代码计算出给定子项的新索引,并将子项中的字符串设置为 i->i',其中 i 是原始索引,i' 是新索引。我正在使用它进行测试; children 被设置为在他们自己身上画这条线以及他们的坐标。

不幸的是,它不能正常工作,或者说工作不稳定。在我的测试用例中的九个图 block 中,三个似乎根本没有调用 getChildDrawingOrder:我上面提到的字符串是 null。在其余部分中,尽管已将正确的索引传递给它,但至少有一个被乱序绘制。

这是一张图片(在 TOP 方向):

Image of getChildDrawingOrder failure

请注意 (0,2)、(1,2) 和 (2,1) 都被列为 NULL,因此 getChildDrawingOrder 似乎从未被要求为他们。还要注意 (1,0) 绘制在 (1,1) 之上,即使它的 i (3) 和 i' (1) 都小于(1,1) 的(分别为 4 和 4)。

这是来自 getChildDrawingOrder 的代码:

@Override
protected int getChildDrawingOrder(int childCount, int i)
{
    TileView ch = (TileView)getChildAt(i);
    ch.order = "Called"; // this string is drawn on my children
    int gx, gy; // the "true" x,y for the current rotation,
                // where 0,0 is the top corner
    switch (rotation)
    {
    case TOP:
        gx = ch.x();
        gy = ch.y();
        break;
    case LEFT:
        gx = (width()-1-ch.x());
        gy = ch.y();
        break;
    case RIGHT:
        gx = ch.x();
        gy = (length()-1-ch.y());
        break;
    case BOTTOM:
        gx = (width()-1-ch.x());
        gy = (length()-1-ch.y());
        break;
    default:
        gx = ch.x();
        gy = ch.y();
    }
    int row = gx+gy; // current row
    if ( row == 0 ) // row 0 is always just the top corner and 0
    {
        ch.order = new String(i+"->0"); // string set to i->i'
        return 0;
    }
    else
    {
        int mx = width()-1, // maximum x value
            my = length()-1, // maximum y value
            mrow = mx+my, // maximum row
            min = Math.min(mx, my), // minor axis length
            maj = Math.max(mx, my), // major axis length
            retn; // for storing the return value
        // inside the top corner
        if ( row <= min )
        {
            // Gauss's formula to get number of cells in previous rows
            // plus the number for which cell in this row this is.
            retn = row*(row+1)/2+gy;
        }
        // in the middle
        else if ( row <= maj )
        {
            // Gauss's formula to get number of cells in top corner
            // plus the number of cells in previous rows of the middle section
            // plus the number for which cell in this row this is.
            retn = min*(min+1)/2+min*(row-min)+gy;
        }
        // bottom corner
        else
        {
            retn = (min+1)*(min+2)/2 // cells in the top corner
                 + min*(maj-min) // cells in the middle
                 + (mrow-maj)*(mrow-maj+1)/2 // total cells in bottom triangle
                 - (mrow-row+1)*(mrow-row+2)/2 // less cells after this one
                 + gy // which cell in this row
                 - (row-maj) // to account for gy not starting at zero
                 ;
        }
        ch.order = new String(i+"->"+retn); // string set to i->i'
        return retn;
    }
}

任何人都可以阐明发生了什么事吗?为什么不为这三个图 block 调用 getChildDrawingOrder?为什么 (1,0) 以错误的顺序绘制,即使调用了 getChildDrawingOrder

最佳答案

好的,通过查看 Android 源代码弄明白了。我有 getChildDrawingOrder 的映射:传递的 i 是“我应该绘制第 i 个 child ?”而不是“我应该什么时候画 child i?” NULL 的原因是因为那些 child 在他们自己的 i 被传递之前被绘制。

我更改了我的代码以在 onMeasure 传递期间找出所有子项的顺序,将其保存在 SparseIntArray 中,然后从 getChildDrawingOrder 返回它。这行得通。

顺便说一下,在 getChildDrawingOrder 函数中反向计算索引是个坏主意,除非您想依赖子项声明的顺序。因为如果不依赖于该顺序,则必须遍历子项列表以找到具有适当 x 和 y 值的子项,这意味着您必须为每个子项遍历子项列表。这是一个 O(n²) 操作(阅读:相当低效)。数学也相当复杂。

关于java - getChildDrawingOrder 调用/使用不正常?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14504649/

相关文章:

android - 将音乐播放器守护进程 (MPD) 移植到 Android

Opengl 像素完美 2D 绘图

android - 如何在 View 上模拟橡皮擦?

Java Spring : mongodb connection issue

java - 多数组列表,尝试用数据存储时间戳

java - Spring :返回@ResponseBody "ResponseEntity<List<JSONObject>>"

java - Android - 如何使用应用程序连接到抽象套接字

java - IDE 想要将我的 Int 转换为 boolean 值?我的方法之一说它不能应用

android - 将位图图像更改为像素数组

android - 未调用自定义 onDraw() 方法