Sto creando una mappa isometrica con tessere semplici e io ’ ve estesa RelativeLayout
per creare un layout che contenga queste tessere. In realtà, solo l'uso di un RelativeLayout
as-is ha funzionato bene finché il mio orientamento corrispondeva all'ordine in cui le tessere venivano scritte nel file XML; tutti i ’ sovrascritti sono i costruttori, dove ho semplicemente chiamato super
e setChildrenDrawingOrderEnabled(true);
insieme con l'impostazione di alcune variabili (altezza e larghezza della griglia), e quindi getChildDrawingOrder
stesso.getChildDrawingOrder chiamato/usato in modo errato?
Il mio codice per getChildDrawingOrder
capisce il nuovo indice per il bambino dato, e imposta anche una stringa nel bambino a i->i'
, dove i
è l'indice originale e i'
è il nuovo indice. I ’ m utilizzando questo per il test; i bambini sono impostati per disegnare questa stringa su se stessi insieme alle loro coordinate.
Sfortunatamente, non funziona correttamente, o meglio funziona in modo irregolare. Delle nove tessere nel mio test case, tre don ’ t sembrano aver chiamato il numero getChildDrawingOrder
: la stringa che ho menzionato sopra è null
. Del resto, almeno uno viene disegnato fuori ordine nonostante venga passato l'indice corretto.
Qui ’ immagine sa (nell'orientamento TOP
):
Si noti che (0,2), (1,2), e (2,1) sono tutti elencati come NULL
, e quindi getChildDrawingOrder
sembra non essere mai stato chiamato per loro. Si noti inoltre che (1,0) è disegnato sopra (1,1), anche se entrambi i numeri i
(3) e i'
(1) sono inferiori a (1,1) ’ s (4 e 4, rispettivamente).
Qui ’ s il codice 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;
}
}
Qualcuno può far luce su ciò che ’ sta succedendo? Perché isn ’ t getChildDrawingOrder
viene chiamato per quelle tre tessere? Perché è (1,0) disegnato nell'ordine errato, anche se getChildDrawingOrder
è chiamato?
Mi sembra che questo abbia bisogno di un po 'più di introduzione. Sono stato lontano da sviluppo Android per anni, quindi dovrei scavare un po 'per entrare in questo codice e capire cosa stava facendo. Senza farlo, non posso nemmeno dire se questa è una buona risposta. Altre spiegazioni su 'getChildDrawingOrder' e su come funziona/su come sono utilizzate potrebbero essere d'aiuto, penso. – KRyan
Aggiungerò alcune immagini per illustrare – petey