Android Hexagon Grid

I need to develop an application in which the buttons are hexagons, and they are all located next to each other, creating a grid. Given my little experience with Android, I'm wondering if the GridView approach is the best for this. If so, how do you place hexagons next to each other?

I have it now

enter image description here

Using this layout in main.xml:

<?xml version="1.0" encoding="utf-8"?> <GridView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/gridview" android:layout_width="fill_parent" android:layout_height="fill_parent" android:padding="0dp" android:verticalSpacing="0dp" android:horizontalSpacing="0dp" android:numColumns="4" android:columnWidth="0dp" android:stretchMode="columnWidth" android:gravity="top" /> 

And here is what I am trying to get:

hexagon grid

I will need help to put hexagons attached to each other in a fixed structure. I played with the layout values โ€‹โ€‹without any success. Would a TableView be a better approach? Many thanks

+6
source share
3 answers

Here is the code I used in the application (it is called "Connect3" if you want to play it :)). This is a custom layout class that draws hexagonal images in a grid. The grid can be a triangular or oblique rectangle.

The code calculates the boundaries (in pixels relative to the beginning of the hexagon) of each image, and then calls imageView.layout(left,top,right,bottom) to set the calculated boundaries. Calculations are not so difficult. The main parameter is the radius hexagon. Based on this, the total height, total width, effective height and effective width (image height / width, respectively - the distance between the upper / left borders of two consecutive views). Then it comes down to some simple loops to draw.

To make browsing accessible, simply set onClickListener when creating them. (I made him a member of the class because he simplified the situation).

The onMeasure functions simply calculate the total width and height of the view and call setMeasuredDimension with these values.

The images used for all this are just individual hexagons, as you see them right below the action bar. Note that the images are squares.

  @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,(rl-totalWidth)/2); break; } case 2: {x_offset_row += Math.max(0,(rl-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; } 

hexgrid1hexgrid2

+5
source

Hexgrid is a Github project that implements a hexagonal (hex) grid.

+2
source

You can always work with it as if it were a normal grid. But instead of drawing a square, you draw a hexagon.

http://img811.imageshack.us/img811/9229/uyje.png

But then you move the odd lines half the width of the hexagon so that they match the pairs.

http://img822.imageshack.us/img822/2298/e5cq.png

0
source

Source: https://habr.com/ru/post/905851/


All Articles