使用GridView的中心方形棋盘

时间:2015-01-06 10:25:36

标签: android android-layout gridview border

这似乎已被问过很多次了,我已经阅读了很多问题和答案,但没有一个能适合我的问题:

我的情况:

  • 在我的活动中,在一堆其他东西之下,你应该看到一个棋盘。对于小/短智能手机,棋盘的剩余空间(正方形)可能不是太多。因此我不能简单地说棋盘的大小由剩余的宽度决定。如果剩余高度较低,则高度决定了尺寸。
  • 广场数量在游戏中有所不同。棋盘将始终是一个正方形,但它的尺寸从3x3到8x8不等。
  • 我希望我的棋盘(使用GridView实现)有一个黑色边框(大约2pd)。
  • 如果棋盘的正方形可以是真正的正方形,那就太好了。但我希望即使列数变化也能修复棋盘的大小。因此,我不能有一个恒定的边框粗细和正方形,因为棋盘的大小(减去边框厚度)不能保证可以被列数整除。

我看到两种可能的解决方案来解决这个问题,但我无法让它们正常工作:

  1. 为了拥有一个漂亮的方形棋盘,我使用了下面的xml:

    <GridView android:id="@+id/chessboard_gridview" android:layout_width="match_parent" android:layout_height="match_parent" android:padding="2dp" android:layout_margin="10dp" android:background="@color/black" android:layout_gravity="center" android:gravity="center" > </GridView>

    并在onCreate()我的活动中的以下代码:

    gridView.setNumColumns(board.getColumns());
    gridView.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener(){
    
        @Override
        public void onGlobalLayout() {
    
            int size = Math.min(gridView.getWidth(), gridView.getHeight());
    
            ViewGroup.LayoutParams params = gridView.getLayoutParams();
            params.width = size;
            params.height = size;
            gridView.setLayoutParams(params);
    
            gridView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
        }});
    

    为了将完美的正方形作为正方形,我找到了以下我自定义适配器使用的ImageViews解决方案:

    public class SquareView extends ImageView{
    
        public SquareView(Context context){
            super(context);
        }
    
        @Override
        public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
            super.onMeasure(widthMeasureSpec, widthMeasureSpec);
        }
    }
    

    但如果我查看结果,我可以看到边界线的厚度不同,因为棋盘不能被列数整除:

    border line varies in thickness

    我很好,如果我以某种方式设法将所有方块都放在GridView中心。然后边界比2dp厚,并且可能一边比另一边厚一个像素,但我不在乎。

    问题:如何使方块居中,使边框厚度不会发生变化?

  2. 另一种方法是拥有一个恰好2 dp的漂亮边框,但方块不是真正的正方形。使边框在右侧和底部变厚的剩余空间可以或多或少均匀地分布在正方形上。例如:如果剩余3个像素,则将每个像素的宽度增加为2,4和6列,将2,4和6行放得更高。

    问题:我怎样才能完美地将所有GridView空间用于我的方块,即使这意味着我的方块不再是真正的方块,但有些方块略宽或更高?

    我原本以为GridView会自动拉伸它们但是如果我使用简单的ImageView而不是我的SquareView用于方块我有一个黑棋盘,如果我不自己设置每个方块的大小。如果我手动为方块设置方形大小,则会为所有stretchModes获得不同的错误结果。

2 个答案:

答案 0 :(得分:0)

希望我正在读你的问题吧。问题可能是由于大小不能被board.getColumns整除。因此,我们可以选择一个newSize,它对于给定的电路板列可以被平分。

gridView.setNumColumns(board.getColumns());
gridView.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener(){
@Override
public void onGlobalLayout() {
    int size = Math.min(gridView.getWidth(), gridView.getHeight());
    int newsize = (size/board.getColumns()) * board.getColumns(); // computing new size

    ViewGroup.LayoutParams params = gridView.getLayoutParams();
    params.width = newsize; //assigning new size
    params.height = newsize; //assigning new size
    gridView.setLayoutParams(params);

    gridView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
}});

答案 1 :(得分:0)

我刚才问过这个问题,并决定最后写下我如何解决我的问题。最后,我并不关心在更改行数和列数时棋盘大小可能会有所不同。请注意,可能会有更新的答案。这是一个在2015年对我有用的解决方案。

我的GridView:

<GridView
    android:id="@+id/chessboard_gridview"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_gravity="center"
    android:background="@color/black"
    android:gravity="center"
    android:padding="2dp">
</GridView>

在活动onCreate中初始化:

this.gridView = (GridView) findViewById(R.id.chessboard_gridview);

同一个Activity使用棋盘的自定义适配器:

ChessboardViewAdapter adapter = new ChessboardViewAdapter(numRows, numCols, ...);       
gridView.setAdapter(adapter);

ChessboardViewAdapter然后(除其他外)确定正方形的正确大小。请注意,SquareView是一个自定义类,不再覆盖onMeasure,就像在原始问题的代码中一样。

public class ChessboardViewAdapter extends BaseAdapter{
    ...
    @Override
    public View getView(int position, View convertView, ViewGroup parent){

        View view = convertView;
        if(view == null){
            view = new SquareView(context);
        }

        // Adjust each square's size to look like a square
        int parentPadding = 2 * parent.getPaddingTop(); // equal paddings
        int newSize = (parent.getWidth() - parentPadding) / this.columns;
        view.setLayoutParams(new GridView.LayoutParams(newSize, newSize));
        view.setPadding(10, 10, 10, 10); // hard coded offsets for the black border
        ...
    }
}