【问题标题】:Android Hexagon Grid安卓六边形网格
【发布时间】:2015-06-24 16:54:27
【问题描述】:

我需要开发一个应用程序,其中的按钮是六边形,所有按钮都彼此相邻放置,形成一个网格。鉴于我在 Android 方面的一点经验,我想知道 GridView 是否是最好的方法。如果是这样的话,我怎么能把六边形放在一起呢?

我现在有这个

在 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"
/>

这就是我想要得到的:

我需要一些帮助才能将相互连接的六边形放置在一个固定的结构中。我一直在玩弄布局值,但没有成功。 TableView 会是更好的方法吗? 非常感谢

【问题讨论】:

  • 查看 this 非常好的文章,其中也有很好的 Java 示例。你或许可以让它们适应 Android。
  • HexView-View 来自哪里?
  • 我只是在编辑帖子时将应用程序的名称与 GridView 布局混淆了 - 已更正。谢谢。

标签: android gridview


【解决方案1】:

这是我在应用程序中使用的一些代码(如果你想玩的话,它被称为“Connect3 :)”)。它是一个在网格中绘制六边形图像的自定义布局类。网格可以是三角形或倾斜的矩形。

代码计算每个图像视图的边界(以像素为单位,相对于 hexgrid 的原点),然后调用imageView.layout(left,top,right,bottom) 来设置计算的边界。计算并不难。主要参数是六边形的radius。由此,总高度、总宽度、有效高度和有效宽度(图像视图的高度/宽度分别为两个连续视图的上/左边界之间的距离)。然后归结为一些简单的 for 循环来绘制它们。

要使视图可点击,只需在创建视图时设置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;
}

【讨论】:

    【解决方案2】:

    您始终可以像使用普通网格一样使用它。但不是画一个正方形,而是画一个六边形。

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

    但是,您将奇数线移动到六边形宽度的一半,使其与成对线相吻合。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-11-24
      • 1970-01-01
      • 1970-01-01
      • 2012-11-30
      • 1970-01-01
      相关资源
      最近更新 更多