下面是一些代碼,我在一個應用程序中使用(它被稱爲「連接3,如果你想發揮它:))。這是一個自定義佈局類,可以在網格中繪製六角形圖像。網格可以是三角形或傾斜的矩形。
該代碼計算每個圖像視圖的邊界(以像素爲單位),然後調用imageView.layout(left,top,right,bottom)
來設置計算的邊界。計算並不困難。主要參數是六邊形的radius
。由此,總高,總寬度,有效高度和有效寬度(imageview的高度/寬度分別是兩個連續視圖的頂部/左邊界之間的距離)。然後歸結爲一些簡單的循環來繪製它們。
要使視圖可點擊,請在創建視圖時設置一個onClickListener
。 (我讓它成爲一個班級成員,因爲它使事情變得更容易)。
onMeasure
函數只計算視圖的總寬度和高度,並用這些值調用setMeasuredDimension
。
用於所有這些的圖像僅僅是您在操作欄下方看到的單個六邊形。請注意,圖像是正方形。
@Override
protected void onLayout(final boolean changed, final int l, final int t, final int r, final int b) {
Log.d(TAG, "board.onlayout called with size "+mSize+" l: "+l+" r: "+r+" t: "+t+" b: "+b);
//If the dimensions of the board haven't changed, a redraw isn't necessary. Just update the images of the views instead by calling invalidate().
if (!changed && !mSizeInvalidated) {
invalidate();
return;
}
int childCount = getChildCount();
//Calculate some useful parameters.
float radius = getResources().getDimension(R.dimen.radius);
float verticalMargin = -radius/4;
float horizontalMargin = ((float) Math.sqrt(3)/2 - 1) * radius;
float height = 2 * radius;
float width = height;
float effectiveHeight = height + 2 * verticalMargin;
float effectiveWidth = width + 2 * horizontalMargin;
float totalHeight=(radius * (3 * mSize + 1))/2;
float totalWidth;
switch (mGameType) {
case Connect3Turn.GAME_TYPE_HEX:
totalWidth = (((float) mSize * 3 - 1)/ 2) * ((float) Math.sqrt(3)) * radius;
break;
case Connect3Turn.GAME_TYPE_Y:
default:
totalWidth = mSize * ((float) Math.sqrt(3)) * radius;
}
LayoutParams layoutParams = new LayoutParams((int) width, (int) height);
//Code to calculate the offsets for horizontal and vertical centering (this is an option in the .xml file)
//The GAME_TYPE_HEX creates a tilted rectangular board and GAME_TYPE_Y creates a triangular board.
float x_offset_row;
switch (mGameType) {
case Connect3Turn.GAME_TYPE_Y:
x_offset_row=(mSize - 1) * effectiveWidth/2 + horizontalMargin;
break;
case Connect3Turn.GAME_TYPE_HEX:
default:
x_offset_row=0;
}
switch (mCenterHorizontal) {
//the left side of the grid should be at non-negative coordinates.
case 1: {
x_offset_row += Math.max(0,(r-l-totalWidth)/2);
break;
}
case 2: {x_offset_row += Math.max(0,(r-l-totalWidth));
break;
}
case 0:
default: {
break;
}
}
//calculate the y_offset for vertical centering.
float y_offset = 0;
switch (mCenterVertical) {
case 1: {
y_offset = Math.max(0, (b - t - totalHeight)/2);
break;
}
case 2: {
y_offset = Math.max(0, (b - t -totalHeight));
break;
}
}
int cell = 0;
for (int row = 0; row < mSize; ++row) {
float x_offset = x_offset_row;
int rowLength;
//The row length depends on the board-type we want to draw.
switch (mGameType){
case Connect3Turn.GAME_TYPE_HEX:
rowLength=mSize;
break;
case Connect3Turn.GAME_TYPE_Y:
default:
rowLength=row+1;
}
Log.d(TAG, "Drawing row "+row+" with "+rowLength+" cells.");
for (int col = 0; col < rowLength; ++col) {
ImageView v;
if (cell < childCount) {
v = (ImageView) getChildAt(cell);
} else {
v = new ImageView(super.getContext());
v.setLayoutParams(layoutParams);
v.setOnClickListener(onClickListener);
addViewInLayout(v, cell, v.getLayoutParams(), true);
}
//Set the image (color) of the cell and put its index in a tag, so we can retrieve the number of the clicked cell in the onClickListener.
v.setImageResource(mImageIds[mImages[cell]]);
v.setTag(cell);
//Set the bounds of the image, which will automatically be cropped in the available space.
v.layout((int) x_offset, (int) y_offset, (int) (x_offset + width), (int) (y_offset + height));
x_offset += effectiveWidth;
++cell;
}
y_offset += effectiveHeight;
//The offset of the next row, relative to this one, again depends on the game type.
switch(mGameType){
case Connect3Turn.GAME_TYPE_Y:
x_offset_row -= effectiveWidth/2;
break;
case Connect3Turn.GAME_TYPE_HEX:
x_offset_row += effectiveWidth/2;
}
}
//We updated all views, so it is not invalidated anymore.
mSizeInvalidated=false;
}
![hexgrid2](https://i.stack.imgur.com/t5Yqc.png)
「HexView」視圖從哪裏來? – theomega 2012-01-14 12:25:32
編輯修正後的問題時,我只是將應用程序的名稱與GridView佈局混淆了。謝謝。 – 2012-01-14 12:56:38
查看[this](http://www.gdreflections。com/2011/02/hexagonal-grid-math.html)非常好的文章,也有不錯的Java樣本。你可以調整他們到Android。 – hypercode 2012-01-12 19:50:57