异构网格布局异构网格布局(Heterogeneous GridLayout)

2019-05-16 17:25发布

更新-我的工作的解决方案: https://stackoverflow.com/a/21233824/902172


我想实现下面的布局:

我猜的GridLayout是适合我的需要,但后2小时的奋斗,我不能创造出一个类似的布局。该布局调整错误本身 ,它超过了手机的屏幕 ,它也不会在规定的行和列。

在这里,我选择的按钮,所以你可以看到它超过了界限:

这里是相关的XML代码: https://gist.github.com/2834492

我已经达到了一个类似的布局与嵌套linearlayouts但它无法适当调整大小不同的屏幕大小。


UPDATE -近似的LinearLayout实现:

XML代码: https://gist.github.com/cdoger/2835887然而,问题是它不调整自身正确这里一些截图不同的屏幕配置:


TLDR: 有人告诉我GridLayout的异构布局实现像在第一张照片?

Answer 1:

光盘,

你所面临的问题是由于不恰当地使用了网格布局的。 该网格布局由以显示其子女在网格中您要覆盖,如果没有延长网格布局。 当你想可以用代码来实现(利用为numColumns和columnsize)什么,也不会没有大量的代码赫克是多种屏幕尺寸非常有用。

这将不需要吨黑客的唯一适当的解决方案是明智地使用这两种的LinearLayout和RelativeLayout的的。 的LinearLayout应该它是由掉落在一条线(水平或垂直只)项不专门使用。 当你尝试做底部的四个按钮,这就变得尤为明显。 虽然上面的按钮可以与LinearLayout中完成用很少的努力,RelativeLayout的是您所需要的底部四个按钮。

注:RelativeLayout的可以为那些经验少使用它们有一点点的调皮。 一些缺陷包括:孩子重叠,儿童移动离开屏幕,高度和宽度渲染应用不当。 如果你想一个例子,让我知道,我将编辑我的答案。

最后请注意:我完全利用独特的方式,目前的框架对象,并真正喜欢提供所要求的解决方案。 该解决方案,但是,考虑到这个问题的约束是不可行的。

(修订版)溶液1

一些深思熟虑昨晚之后,这可能与纯LinearLayout中来完成。 虽然我不喜欢这种解决方案,它应该是跨屏和周围要求使用任何工具从我这里。 注意应该有太多的LinearLayouts使用,因为根据谷歌的开发者,它会导致加载速度慢的用户界面,由于layout_weight财产。 当我回家将提供使用RelativeLayout的第二种解决方案。 现在测试这提供了在所有屏幕大小和方向所需的布局参数。

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:orientation="vertical" > 
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:orientation="vertical">
        <LinearLayout 
            android:layout_width="match_parent" 
            android:layout_height="0dp" 
            android:layout_weight="1" 
            android:orientation="horizontal"> 
            <Button 
                android:id="@+id/Button01" 
                android:layout_width="0" 
                android:layout_height="match_parent" 
                android:layout_weight="1" 
                android:text="Button" />     
            <Button 
                android:id="@+id/Button02" 
                android:layout_width="0" 
                android:layout_height="match_parent" 
                android:layout_weight="1" 
                android:text="Button" />     
        </LinearLayout> 
        <Button 
            android:id="@+id/button3" 
            android:layout_width="match_parent" 
            android:layout_height="0dp"
            android:layout_weight="1" 
            android:text="Button" />   
        <LinearLayout 
            android:layout_width="match_parent" 
            android:layout_height="0dp" 
            android:layout_weight="1.00"
            android:orientation="horizontal">  
            <Button 
                android:id="@+id/button1" 
                android:layout_width="0dp" 
                android:layout_height="match_parent" 
                android:layout_weight="1" 
                android:text="Button" />   
            <Button 
                android:id="@+id/button2" 
                android:layout_width="0dp" 
                android:layout_height="match_parent" 
                android:layout_weight="1" 
                android:text="Button" />     
        </LinearLayout>
    </LinearLayout>    
    <LinearLayout 
        android:layout_width="match_parent" 
        android:layout_height="0dp" 
        android:layout_weight="1" 
        android:orientation="horizontal">     
        <LinearLayout 
            android:layout_width="0dp" 
            android:layout_height="match_parent" 
            android:layout_weight="1" 
            android:orientation="vertical" >    
            <Button 
                android:id="@+id/button4" 
                android:layout_width="match_parent" 
                android:layout_height="0dp"
                android:layout_weight="1" 
                android:text="Button" />     
            <Button 
                android:id="@+id/button5" 
                android:layout_width="match_parent" 
                android:layout_height="0dp" 
                android:layout_weight="2" 
                android:text="Button" />     
        </LinearLayout>     
        <LinearLayout 
            android:layout_width="0dp" 
            android:layout_height="match_parent" 
            android:layout_weight="1" 
            android:orientation="vertical" > 
            <Button 
                android:id="@+id/button6" 
                android:layout_width="match_parent" 
                android:layout_height="0dp" 
                android:layout_weight="2" 
                android:text="Button" /> 
            <Button 
                android:id="@+id/button7" 
                android:layout_width="match_parent" 
                android:layout_height="0dp" 
                android:layout_weight="1" 
                android:text="Button" /> 
        </LinearLayout> 
    </LinearLayout> 
</LinearLayout> 

方案1所说明

到LinearLayouts关键是要定义你迫切需要作为单独的布局和鸟巢的人在他们。 当你施加约束来实现更多维,更LinearLayouts必须添加到封装等。 对于你的,它是有两个家长为了保持比例至关重要。 什么时候应该添加另一个级别的一大指标是,当你利用layout_weight使用除整数值的任何其他。 它只是变得很难正确计算。 从那里,它是相对简单将其拆分成列。

溶液2(失败)

虽然我是能够实现利用的RelativeLayout和“支柱”理想的结果,我只能与人的身高2个按钮倍数布局这样做。 这样的伎俩将是真棒为布局的水平大大降低,所以我会努力在纯XML解决方案并张贴在这里的答案,如果当我实现它。 在此期间,在上述的LinearLayout应该满足您的需求完美。

希望这可以帮助,

FuzzicalLogic



Answer 2:

我读这个线程,并意识到,我想比有线性布局的扁平化的解决方案。 经过一番研究,我结束了让我自己的布局。 它是由一个网格布局的启发,但还是有些不同。

请注意,如果你要复制粘贴代码,就需要改变一些地方包名。

这种布局有小孩使用定位themselves.These是layout_left,layout_top,layout_right,layout_bottom 4个布局参数。 该ICGridLayout本身有两个属性:layout_spacing和列

告诉布局你想要多少列其遏制。 然后,将与相同的高度宽度计算单元的尺寸。 这将是布局的宽度/列。

间距是你要每个孩子之间的空间量。

该layout_left |顶部|右|底部属性是每边的坐标。 布局确实没有计算以避免碰撞或任何东西。 它只是把他们想去的地方是孩子们。

如果你想有较小的正方形,你只需要增加列属性。

请记住,这是一个快速原型,我会继续工作,当我觉得它已经准备好我把它上传到Github上,在这里放了评论。

我所有的代码下面应该产生以下结果:

*****编辑*****增加来衡量孩子的电话,忘记了第一次左右。 编辑完 ICGridLayout.java:

package com.risch.evertsson.iclib.layout;

import android.content.Context;
import android.content.res.TypedArray;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;

import com.risch.evertsson.iclib.R;

/**
 * Created by johanrisch on 6/13/13.
 */
public class ICGridLayout extends ViewGroup {
    private int mColumns = 4;
    private float mSpacing;

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

    public ICGridLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(attrs);
    }

    public ICGridLayout(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        init(attrs);
    }

    private void init(AttributeSet attrs) {
        TypedArray a = getContext().obtainStyledAttributes(
                attrs,
                R.styleable.ICGridLayout_Layout);
        this.mColumns = a.getInt(R.styleable.ICGridLayout_Layout_columns, 3);
        this.mSpacing = a.getDimension(R.styleable.ICGridLayout_Layout_layout_spacing, 0);
        a.recycle();
    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        if (changed) {
            int width = (int) (r - l);
            int side = width / mColumns;
            int children = getChildCount();
            View child = null;
            for (int i = 0; i < children; i++) {
                child = getChildAt(i);
                LayoutParams lp = (LayoutParams) child.getLayoutParams();
                int left = (int) (lp.left * side + mSpacing / 2);
                int right = (int) (lp.right * side - mSpacing / 2);
                int top = (int) (lp.top * side + mSpacing / 2);
                int bottom = (int) (lp.bottom * side - mSpacing / 2);
                child.layout(left, top, right, bottom);
            }
        }
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        measureVertical(widthMeasureSpec, heightMeasureSpec);

    }

    private void measureVertical(int widthMeasureSpec, int heightMeasureSpec) {
        int widthMode = MeasureSpec.getMode(widthMeasureSpec);
        int heightMode = MeasureSpec.getMode(heightMeasureSpec);
        int width = 0;
        int height = 0;


        if (widthMode == MeasureSpec.AT_MOST || widthMode == MeasureSpec.EXACTLY) {
            width = MeasureSpec.getSize(widthMeasureSpec);
        } else {
            throw new RuntimeException("widthMeasureSpec must be AT_MOST or " +
                    "EXACTLY not UNSPECIFIED when orientation == VERTICAL");
        }


        View child = null;
        int row = 0;
        int side = width / mColumns;
        int childCount = getChildCount();
        for (int i = 0; i < childCount; i++) {
            child = getChildAt(i);

            LayoutParams lp = (LayoutParams) child.getLayoutParams();

            if (lp.bottom > row) {
                row = lp.bottom;
            }



            int childHeight = (lp.bottom - lp.top)*side;
            int childWidth = (lp.right-lp.left)*side;
            int heightSpec = MeasureSpec.makeMeasureSpec(childHeight, LayoutParams.MATCH_PARENT);
            int widthSpec = MeasureSpec.makeMeasureSpec(childWidth, LayoutParams.MATCH_PARENT);

            child.measure(widthSpec, heightSpec);
        }
        height = row * side;
        // TODO: Figure out a good way to use the heightMeasureSpec...

        setMeasuredDimension(width, height);
    }

    @Override
    public ViewGroup.LayoutParams generateLayoutParams(AttributeSet attrs) {
        return new ICGridLayout.LayoutParams(getContext(), attrs);
    }

    @Override
    protected boolean checkLayoutParams(ViewGroup.LayoutParams p) {
        return p instanceof ICGridLayout.LayoutParams;
    }

    @Override
    protected ViewGroup.LayoutParams
            generateLayoutParams(ViewGroup.LayoutParams p) {
        return new ICGridLayout.LayoutParams(p);
    }

    @Override
    protected ViewGroup.LayoutParams generateDefaultLayoutParams() {
        return new LayoutParams();
    }

    public static class LayoutParams extends ViewGroup.MarginLayoutParams {
        int right = 1;
        int bottom = 1;
        int top = 0;
        int left = 0;
        int width = -1;
        int height = -1;

        public LayoutParams() {
            super(MATCH_PARENT, MATCH_PARENT);
            top = 0;
            left = 1;
        }

        public LayoutParams(int width, int height) {
            super(width, height);
            top = 0;
            left = 1;
        }

        public LayoutParams(Context context, AttributeSet attrs) {
            super(context, attrs);
            TypedArray a = context.obtainStyledAttributes(
                    attrs,
                    R.styleable.ICGridLayout_Layout);
            left = a.getInt(R.styleable.ICGridLayout_Layout_layout_left, 0);
            top = a.getInt(R.styleable.ICGridLayout_Layout_layout_top, 0);
            right = a.getInt(R.styleable.ICGridLayout_Layout_layout_right, left + 1);
            bottom = a.getInt(R.styleable.ICGridLayout_Layout_layout_bottom, top + 1);
            height = a.getInt(R.styleable.ICGridLayout_Layout_layout_row_span, -1);
            width = a.getInt(R.styleable.ICGridLayout_Layout_layout_col_span, -1);
            if (height != -1) {
                bottom = top + height;
            }
            if (width != -1) {
                right = left + width;
            }

            a.recycle();
        }

        public LayoutParams(ViewGroup.LayoutParams params) {
            super(params);
        }

    }

}

ICGridLayout.java是非常直截了当。 这需要由孩子们提供的值,并奠定了出来。 attrs.xml:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="ICGridLayout_Layout">
        <attr name="columns" format="integer"/>
        <attr name="layout_left" format="integer"/>
        <attr name="layout_top" format="integer"/>
        <attr name="layout_right" format="integer"/>
        <attr name="layout_bottom" format="integer"/>
        <attr name="layout_col_span" format="integer"/>
        <attr name="layout_row_span" format="integer"/>
        <attr name="layout_spacing" format="dimension"/>
    </declare-styleable>

</resources>

example_layout.xml:

<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res/com.rischit.projectlogger"
    android:id="@+id/scroller"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <com.risch.evertsson.iclib.layout.ICGridLayout
        android:id="@+id/ICGridLayout1"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_spacing="4dp"
        app:columns="4" >


        <TextView
            android:id="@+id/textView1"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:layout_bottom="1"
            app:layout_left="0"
            app:layout_right="4"
            app:layout_top="0"
            android:background="#ff0000"
            android:text="TextView" />

        <TextView
            android:id="@+id/textView1"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:layout_bottom="3"
            app:layout_left="3"
            app:layout_right="4"
            app:layout_top="1"
            android:background="#00ff00"
            android:text="TextView" />

        <TextView
            android:id="@+id/textView1"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:layout_bottom="4"
            app:layout_left="0"
            app:layout_right="3"
            app:layout_top="1"
            android:background="#0000ff"
            android:text="TextView" />

        <TextView
            android:id="@+id/textView1"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:layout_bottom="4"
            app:layout_left="3"
            app:layout_right="4"
            app:layout_top="3"
            android:background="#ffff00"
            android:text="TextView" />

        <TextView
            android:id="@+id/textView1"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:layout_bottom="6"
            app:layout_left="0"
            app:layout_right="1"
            app:layout_top="4"
            android:background="#ff00ff"
            android:text="TextView" />

        <TextView
            android:id="@+id/textView1"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:layout_bottom="6"
            app:layout_left="1"
            app:layout_right="4"
            app:layout_top="4"
            android:background="#ffffff"
            android:text="TextView" />
    </com.risch.evertsson.iclib.layout.ICGridLayout>

</ScrollView>

- 约翰·RISCH

PS这是我的第一个长的答案,我一直试图做一个正确的方式。 如果我失败了,请告诉我没有燃烧:) DS



Answer 3:

像这样 ?

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="0.54" >
        <Button
            android:id="@+id/Button01"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1.00"
            android:text="Button" />    
        <Button
            android:id="@+id/Button02"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1.00"
            android:text="Button" />    
    </LinearLayout>
    <Button
        android:id="@+id/button3"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Button" />  
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="99dp" > 
        <Button
            android:id="@+id/button1"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:text="Button" />  
        <Button
            android:id="@+id/button2"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:text="Button" />    
    </LinearLayout>   
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1" >    
        <LinearLayout
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:orientation="vertical" >   
            <Button
                android:id="@+id/button4"
                android:layout_width="match_parent"
                android:layout_height="152dp"
                android:text="Button" />    
            <Button
                android:id="@+id/button5"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="Button" />    
        </LinearLayout>    
        <LinearLayout
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:orientation="vertical" >
            <Button
                android:id="@+id/button6"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="Button" />
            <Button
                android:id="@+id/button7"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:text="Button" />
        </LinearLayout>
    </LinearLayout>

</LinearLayout>


Answer 4:

正如许多人所说,嵌套的线性布局,似乎在这里取胜的唯一途径。 一些解决方案都没有以最灵活的方式使用的布局参数。 下面的代码试图做到这一点,并在某种程度上这是纵横比的变化稳健。 细节中的注释。

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

    <!-- First row. -->

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content" >

        <!-- Equal weights cause two columns of equal width. -->

        <Button
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="A" />

        <Button
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="B" />
    </LinearLayout>

    <!-- Second row. -->

    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="C" />

    <!-- Third row. -->

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content" >

        <!-- Equal weights cause two columns of equal width. -->

        <Button
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="D" />

        <Button
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="E" />
    </LinearLayout>

    <!-- Uneven fourth and fifth rows. -->

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:baselineAligned="false" >

        <!-- Left column. Equal weight with right column gives them equal width. -->

        <LinearLayout
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:orientation="vertical" >

            <!--
                 The use of weights below assigns all extra space to G. There
                 are other choices. LinearLayout computes sizes along its
                     axis as given, then divides the remaining extra space using
                 weights.  If a component doesn't have a weight, it keeps
                 the specified size exactly.
            -->


            <!-- Fill width of layout and use wrap height (because there's no weight). -->

            <Button
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="F" />

            <!-- Fill width of layout and put all the extra space here. -->

            <Button
                android:layout_width="match_parent"
                android:layout_height="0dp"
                android:layout_weight="1"
                android:text="G" />
        </LinearLayout>

        <!-- Right column. Equal weight with left column gives them equal width. -->

        <LinearLayout
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:orientation="vertical" >

            <!-- Same as above except top button gets all the extra space. -->

            <Button
                android:layout_width="match_parent"
                android:layout_height="0dp"
                android:layout_weight="1"
                android:text="H" />

            <Button
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="I" />
        </LinearLayout>
    </LinearLayout>

</LinearLayout>


Answer 5:

因此,这里是我一年后所承诺的解决方案=)它基本上使用ViewTreeObserver获取父布局的尺寸,并相应地创建自定义视图。 由于这个代码是一岁ViewTreeObserver可能不会获得尺寸动态的最佳途径。

你可以在这里找到完整的源代码: https://github.com/cdoger/Android_layout

我分屏幕分成8米相等的宽度和相等6米的高度。 下面是我如何布局意见的快照:

final RelativeLayout mainLayout = (RelativeLayout) findViewById(R.id.main_layout);
ViewTreeObserver vto = mainLayout.getViewTreeObserver();
vto.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
    @Override
    public void onGlobalLayout() {
        final int oneUnitWidth = mainLayout.getMeasuredWidth() / 8;
        final int oneUnitHeight = mainLayout.getMeasuredHeight() / 6;
        /**
         * 1
         ***************************************************************/
        final RelativeLayout.LayoutParams otelParams = new RelativeLayout.LayoutParams(
                oneUnitWidth * 4, oneUnitHeight);
        otelParams.addRule(RelativeLayout.ALIGN_PARENT_TOP);
        otelParams.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
        // otelParams.setMargins(0, 0, 2, 0);
        View1.setLayoutParams(otelParams);
        /***************************************************************/

        /**
         * 2
         ***************************************************************/
        final RelativeLayout.LayoutParams otherParams = new RelativeLayout.LayoutParams(
                oneUnitWidth * 4, oneUnitHeight);
        otherParams.addRule(RelativeLayout.ALIGN_PARENT_TOP);
        otherParams.addRule(RelativeLayout.RIGHT_OF, View1.getId());
        otherParams.setMargins(2, 0, 0, 0);
        View2.setLayoutParams(otherParams);
        /***************************************************************/
//... goes on like this

这里是最后的截图:



Answer 6:

我已经尝试这个政党成员

我在这里阻止:

<?xml version="1.0" encoding="utf-8"?>
<GridLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="center"
    android:columnCount="2"
    android:orientation="horizontal" >

    <Button android:text="1" />

    <Button android:text="2" />

    <Button
        android:layout_columnSpan="2"
        android:layout_gravity="fill"
        android:text="3" />

    <Button android:text="4" />

    <Button android:text="5" />

    <Button
        android:layout_gravity="fill"
        android:layout_rowSpan="2"
        android:text="6" />

    <Button android:text="7" />

    <Button android:text="8" />

    <Button android:text="9" />

</GridLayout>

不可能我扩大了8按钮。 :■

我已经尝试

<Button android:text="8" android:layout_gravity="fill" android:layout_rowSpan="2"/>

但它的ineffec。 :■



Answer 7:

嵌入的LinearLayout您的网格布局如下,并尝试它为我工作。

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

<GridLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:columnCount="2" >

    <Button
        android:layout_column="0"
        android:layout_columnSpan="1"
        android:layout_gravity="start|end"
        android:layout_row="0"
        android:text="ASDFASDF" />

    <Button
        android:layout_column="1"
        android:layout_gravity="start|end"
        android:layout_row="0"
        android:text="SDAVDFBDFB" />

    <Button
        android:layout_column="0"
        android:layout_columnSpan="2"
        android:layout_gravity="fill|center"
        android:layout_row="1"
        android:text="ASDVADFBFDAFEW" />

    <Button
        android:layout_column="0"
        android:layout_columnSpan="1"
        android:layout_gravity="fill|center"
        android:layout_row="2"
        android:text="FWEA AWFWEA" />

    <Button
        android:layout_column="1"
        android:layout_columnSpan="1"
        android:layout_gravity="fill"
        android:layout_row="2"
        android:text="BERWEfasf" />

    <Button
        android:layout_width="94dp"
        android:layout_column="0"
        android:layout_columnSpan="1"
        android:layout_gravity="fill|center"
        android:layout_row="3"
        android:text="SDFVBFAEVSAD" />

    <Button
        android:layout_column="0"
        android:layout_columnSpan="1"
        android:layout_gravity="fill|center"
        android:layout_row="4"
        android:layout_rowSpan="2"
        android:text="GVBAERWEFSD" />

    <Button
        android:layout_column="1"
        android:layout_columnSpan="1"
        android:layout_gravity="fill|center"
        android:layout_row="3"
        android:layout_rowSpan="2"
        android:text="VSDFAVE SDFASDWA SDFASD" />

    <Button
        android:layout_column="1"
        android:layout_columnSpan="1"
        android:layout_gravity="fill|center"
        android:layout_row="5"
        android:text="FWEWEGAWEFWAE"/>
</GridLayout>

    </LinearLayout>


文章来源: Heterogeneous GridLayout