我正在创建一个带有简单图 block 的等距 map ,并且我扩展了 RelativeLayout
以创建一个包含这些图 block 的布局。实际上,只要我的方向与将图 block 写入 XML 文件的顺序相匹配,就可以按原样使用 RelativeLayout
;我覆盖的只是构造函数,我只是调用 super
和 setChildrenDrawingOrderEnabled(true);
以及设置一些变量(网格的高度和宽度),以及然后是 getChildDrawingOrder
本身。
我的 getChildDrawingOrder
代码计算出给定子项的新索引,并将子项中的字符串设置为 i->i'
,其中 i
是原始索引,i'
是新索引。我正在使用它进行测试; children 被设置为在他们自己身上画这条线以及他们的坐标。
不幸的是,它不能正常工作,或者说工作不稳定。在我的测试用例中的九个图 block 中,三个似乎根本没有调用 getChildDrawingOrder
:我上面提到的字符串是 null
。在其余部分中,尽管已将正确的索引传递给它,但至少有一个被乱序绘制。
这是一张图片(在 TOP
方向):
请注意 (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/