我想有一个2x2网格内的按钮。这只是ICS,所以我试图使用新的GridLayout给定。

这是我的布局的XML:

 <?xml version="1.0" encoding="utf-8"?>
<GridLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/favorites_grid"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#00ff00"
    android:rowCount="2"
    android:columnCount="2">
  <Button
      android:text="Cell 0"
      android:layout_row="0"
      android:layout_column="0"
      android:textSize="14dip" />
  <Button
      android:text="Cell 1"
      android:layout_row="0"
      android:layout_column="1"
      android:textSize="14dip" />

  <Button
      android:text="Cell 2"
      android:layout_row="1"
      android:layout_column="0"
      android:textSize="14dip" />
  <Button
      android:text="Cell 3"
      android:layout_row="1"
      android:layout_column="1"
      android:textSize="14dip" />
</GridLayout>

问题是我的视图没有为每一行均匀地拉伸。这导致GridLayout的右侧有很多额外的空间。

我尝试设置layout_gravity="fill_horizontal",但这只适用于该行的最后一个视图。这意味着单元格1会一直延伸,为单元格0提供足够的空间。

如何解决这个问题?


当前回答

你可以通过重写ViewGroup onLayout方法来提高速度。 这是我的普遍解决方案:

package your.app.package;

import android.content.Context;
import android.view.ViewGroup;

public class GridLayout extends ViewGroup {

    public GridLayout(Context context) {
        super(context);
    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        final int columns = 2;//edit this if you need different grid
        final int rows = 2;

        int children = getChildCount();
        if (children != columns * rows)
            throw new IllegalStateException("GridLayout must have " + columns * rows + " children");

        int width = getWidth();
        int height = getHeight();


        int viewWidth = width / columns;
        int viewHeight = height / rows;

        int rowIndex = 0;
        int columnIndex = 0;

        for (int i = 0; i < children; i++) {
            getChildAt(i).layout(viewWidth * columnIndex, viewHeight * rowIndex, viewWidth * columnIndex + viewWidth, viewHeight * rowIndex + viewHeight);
            columnIndex++;
            if (columnIndex == columns) {
                columnIndex = 0;
                rowIndex++;
            }
        }
    }

}

编辑: 不要忘记match_parent for children!

android:layout_width="match_parent"
android:layout_height="match_parent"

其他回答

我只是在网格视图中做了简单的网格布局,并在想为什么我以前没有这样做。它很容易实现。(我在示例中使用自定义包装器CSView,但只是将其更改为View)。Ops要求只适用于GridView,所以我把它贴在这里作为答案。为了使拉伸均匀,以numColumns:auto_fit android:numColumns=2为例。

用法:

CSGridLayout(this, R.id.sound_store_grid, SubscriptionUpgradeStoreDialogItem(this),
            PresetUpgradeStoreDialogItem(this), MidiUpgradeStoreDialogItem(this))

实现:

class CSGridLayout(parent: CSActivityView<*>,
                   viewId: Int,
                   vararg items: CSView<*>) : CSView<GridView>(parent, viewId) {

    private val items = list(items)
    private var adapter = Adapter()

    init {
        view.adapter = adapter
        adapter.notifyDataSetChanged()
    }

    inner class Adapter : BaseAdapter() {
        override fun getCount() = items.size
        override fun getViewTypeCount() = 1
        override fun isEnabled(position: Int) = true
        override fun getItem(position: Int) = items[position]
        override fun getItemViewType(position: Int) = 0
        override fun getItemId(position: Int) = position.toLong()
        override fun getView(position: Int, toReuseView: View?, parent: ViewGroup) =
            items[position].view
    }
}

我想有一个居中表,标签右对齐,值左对齐。多余的空间应该在桌子周围。经过多次试验,并没有按照文档的要求去做,我想出了一些可行的方法。以下是我所做的:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:orientation="vertical" >

<GridLayout
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:columnCount="2"
    android:orientation="horizontal"
    android:useDefaultMargins="true" >

    <TextView
        android:layout_gravity="right"
        android:text="Short label:" />

    <TextView
        android:id="@+id/start_time"
        android:layout_gravity="left"
        android:text="Long extended value" />

    <TextView
        android:layout_gravity="right"
        android:text="A very long extended label:" />

    <TextView
        android:id="@+id/elapsed_time"
        android:layout_gravity="left"
        android:text="Short value" />
</GridLayout>

这似乎工作,但GridLayout显示的消息:

这个GridLayout布局或者它的LinearLayout父布局是无用的

当它对我有效时,不知道为什么它是“无用的”。

我不知道为什么这是一个好主意,但如果你尝试一下,可以提供一个更好的想法,小的改进或解释为什么它是(或不工作),我很感激反馈。

谢谢。

结果:

试试这样做:

    final int MAX_COLUMN = gridView.getColumnCount(); //5
    final int MAX_ROW = gridView.getRowCount(); //7
    final int itemsCount = MAX_ROW * MAX_COLUMN; //35

    int row = 0, column = 0;

    for (int i = 0; i < itemsCount; i++) {
        ImageView view = new ImageView(this);

        //Just to provide alternate colors
        if (i % 2 == 0) {
            view.setBackgroundColor(Color.RED);
        } else {
            view.setBackgroundColor(Color.GREEN);
        }

        GridLayout.LayoutParams params = new GridLayout.LayoutParams(GridLayout.spec(row, 1F), GridLayout.spec(column, 1F));
        view.setLayoutParams(params);
        gridView.addView(view);

        column++;

        if (column >= MAX_COLUMN) {
            column = 0;
            row++;
        }
    }

如果你想要单元格的特定宽度和高度,那么使用:

     params.width = 100; // Your width
     params.height = 100; //your height

我终于找到了解决办法。就像Rotemmiz说的,你必须在之后动态地做。这段代码拉伸按钮以水平填充视图,但同样可以用于垂直填充视图。

public void fillview(android.support.v7.widget.GridLayout gl)
{
    Button buttontemp;

    //Stretch buttons
    int idealChildWidth = (int) ((gl.getWidth()-20*gl.getColumnCount())/gl.getColumnCount());
    for( int i=0; i< gl.getChildCount();i++)
    {
        buttontemp = (Button) gl.getChildAt(i);
        buttontemp.setWidth(idealChildWidth);
    }
}

(20是内部和外部的填充和空白。这可以更普遍地做,但这个要干净得多)

然后可以这样调用:

    android.support.v7.widget.GridLayout gl = (android.support.v7.widget.GridLayout)findViewById(R.id.buttongrid);
    ViewTreeObserver vto = gl.getViewTreeObserver();
    vto.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {@Override public void onGlobalLayout() 
    {

            android.support.v7.widget.GridLayout gl = (android.support.v7.widget.GridLayout) findViewById(R.id.buttongrid);
            fillview(gl);

            ViewTreeObserver obs = gl.getViewTreeObserver();
            obs.removeGlobalOnLayoutListener(this);
    }});

它必须用一个观察者来完成,因为我们需要在调用视图之前等待视图被绘制。

从没有v7支持库的API 21开始使用ScrollView:

XML:

<?xml version="1.0" encoding="utf-8"?>
<ScrollView
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    >

    <GridLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:columnCount="2"
            >

        <TextView
            android:layout_width="0dp"
            android:layout_height="100dp"
            android:layout_columnWeight="1"
            android:gravity="center"
            android:layout_gravity="fill_horizontal"
            android:background="@color/colorAccent"
            android:text="Tile1" />

        <TextView
            android:layout_width="0dp"
            android:layout_height="100dp"
            android:layout_columnWeight="1"
            android:gravity="center"
            android:layout_gravity="fill_horizontal"
            android:background="@color/colorPrimaryDark"
            android:text="Tile2" />

        <TextView
            android:layout_width="0dp"
            android:layout_height="100dp"
            android:layout_columnWeight="1"
            android:gravity="center"
            android:layout_gravity="fill_horizontal"
            android:background="@color/colorPrimary"
            android:text="Tile3" />

        <TextView
            android:layout_width="0dp"
            android:layout_height="100dp"
            android:layout_columnWeight="1"
            android:gravity="center"
            android:layout_gravity="fill_horizontal"
            android:background="@color/colorAccent"
            android:text="Tile4" />

    </GridLayout>
</ScrollView>