You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android GridLayout如何为底部行设置不同列宽?

如何实现多行列宽比例不同的网格布局

其实你遇到的问题是GridLayout的layout_columnWeight特性导致的——它是作用于整个列的全局权重,所以你给上面行设置的1:2比例会被所有行继承,最后一行自然没法变成1:1的等宽。

能不能用GridLayout实现?

可以,但实现起来比较绕,因为GridLayout的列宽度大概率是全局统一的,要让最后一行突破这个限制,需要给底部行的控件单独设置布局属性:

修改后的GridLayout代码示例:

<?xml version="1.0" encoding="utf-8"?>
<android.widget.GridLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:columnCount="2"
    android:rowCount="5"
    tools:context=".MainActivity">

    <!-- 第1-4行:左列1份权重,右列2份权重 -->
    <TextView
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:layout_columnWeight="1"
        android:layout_rowWeight="2"
        android:text="TextView"/>
    <TextView
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:layout_columnWeight="2"
        android:layout_rowWeight="2"
        android:text="TextView"/>

    <TextView
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:layout_columnWeight="1"
        android:layout_rowWeight="2"
        android:text="TextView"/>
    <TextView
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:layout_columnWeight="2"
        android:layout_rowWeight="2"
        android:text="TextView"/>

    <TextView
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:layout_columnWeight="1"
        android:layout_rowWeight="2"
        android:text="TextView"/>
    <TextView
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:layout_columnWeight="2"
        android:layout_rowWeight="2"
        android:text="TextView"/>

    <TextView
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:layout_columnWeight="1"
        android:layout_rowWeight="2"
        android:text="TextView"/>
    <TextView
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:layout_columnWeight="2"
        android:layout_rowWeight="2"
        android:text="TextView"/>

    <!-- 底部行:通过layout_gravity和权重强制等宽 -->
    <Spinner
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:layout_columnWeight="1"
        android:layout_rowWeight="1"
        android:layout_gravity="fill_horizontal"
        android:hint="Spinner"/>
    <Spinner
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:layout_columnWeight="1"
        android:layout_rowWeight="1"
        android:layout_gravity="fill_horizontal"
        android:hint="Spinner"/>

</android.widget.GridLayout>

不过这种方式有时候会因为GridLayout的全局列权重优先级问题,导致底部行的等宽效果不稳定,所以更推荐下面两种更可靠的方案。

更推荐的实现方式

1. LinearLayout嵌套(直观易维护)

这种方式逻辑最清晰,外层用垂直LinearLayout,每一行用水平LinearLayout控制列宽比例,完全避免GridLayout的全局权重限制:

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

    <!-- 第1行:权重2,列宽1:2 -->
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="2"
        android:orientation="horizontal">
        <TextView
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:text="TextView"/>
        <TextView
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="2"
            android:text="TextView"/>
    </LinearLayout>

    <!-- 第2行:权重2,列宽1:2 -->
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="2"
        android:orientation="horizontal">
        <TextView
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:text="TextView"/>
        <TextView
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="2"
            android:text="TextView"/>
    </LinearLayout>

    <!-- 第3行:权重2,列宽1:2 -->
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="2"
        android:orientation="horizontal">
        <TextView
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:text="TextView"/>
        <TextView
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="2"
            android:text="TextView"/>
    </LinearLayout>

    <!-- 第4行:权重2,列宽1:2 -->
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="2"
        android:orientation="horizontal">
        <TextView
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:text="TextView"/>
        <TextView
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="2"
            android:text="TextView"/>
    </LinearLayout>

    <!-- 底部行:权重1,列宽1:1 -->
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:orientation="horizontal">
        <Spinner
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:hint="Spinner"/>
        <Spinner
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:hint="Spinner"/>
    </LinearLayout>

</LinearLayout>

2. ConstraintLayout(灵活扁平化)

如果你的布局需要更复杂的交互或者想避免嵌套,ConstraintLayout是最佳选择,通过指引线(Guideline)可以轻松实现不同行的列宽比例:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"  
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent" 
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <!-- 上面4行的垂直指引线(1:2分割) -->
    <androidx.constraintlayout.widget.Guideline
        android:id="@+id/above_rows_guideline"
        android:layout_width="wrap_content"  
 android:layout_height="wrap_content"
        android:orientation="vertical"
        app:layout_constraintGuide_percent="0.333"/>

    <!-- 底部行的垂直指引I线(1:1分害) -->
    <androidx.constraintlayout.widget.Guideline  
        android:id="@+id/bottom_row_guideline"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        app:layout_constraintGuide_percent="0.5"/>

    <!-- 米平把引线,设置行高比例:上面4行行占2份,底部行占1份 -->
    <androidx.constraintlayout.widget.Guideline
        android:id="@+id/row1_bottom"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        app:layout_constraintGuide_percent="0.222"/>
    <androidx.constraintlayout.widget.Guideline
        android:id="@+id/row2_bottom"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        app:layout_constraintGuide_percent="0.444"/>
    <androidx.constraintlayout.widget.Guideline
        android:id="@+id/row3_bottom"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        app:layout_constraintGuide_percent="0.666"/>
    <androidx.constraintlayout.widget.Guideline
        android:id="@+id/row4_bottom"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        app:layout_constraintGuide_percent="0.888"/>

    <!-- 第1行左 -->
    <TextView
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:text="TextView"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toLeftOf="@id/above_rows_guideline"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toTopOf="@id/row1_bottom"/>

    <!-- 第1行右 -->
    <TextView
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:text="TextView"
        app:layout_constraintLeft_toRightOf="@id/above_rows_guideline"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toTopOf="@id/row1_bottom"/>

    <!-- 第2行左 -->
    <TextView
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:text="TextView"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toLeftOf="@id/above_rows_guideline"
        app:layout_constraintTop_toBottomOf="@id/row1_bottom"
        app:layout_constraintBottom_toTopOf="@id/row2_bottom"/>

    <!-- 第2行右 -->
    <TextView
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:text="TextView"
        app:layout_constraintLeft_toRightOf="@id/above_rows_guideline"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toBottomOf="@id/row1_bottom"
        app:layout_constraintBottom_toTopOf="@id/row2_bottom"/>

    <!-- 第3行左 -->
    <TextView
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:text="TextView"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toLeftOf="@id/above_rows_guideline"
        app:layout_constraintTop_toBottomOf="@id/row2_bottom"
        app:layout_constraintBottom_toTopOf="@id/row3_bottom"/>

    <!-- 第3行右 -->
    <TextView
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:text="TextView"
        app:layout_constraintLeft_toRightOf="@id/above_rows_guideline"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toBottomOf="@id/row2_bottom"
        app:layout_constraintBottom_toTopOf="@id/row3_bottom"/>

    <!-- 第4行左 -->
    <TextView
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:text="TextView"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toLeftOf="@id/above_rows_guideline"
        app:layout_constraintTop_toBottomOf="@id/row3_bottom"
        app:layout_constraintBottom_toTopOf="@id/row4_bottom"/>

    <!-- 第4行右 -->
    <TextView
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:text="TextView"
        app:layout_constraintLeft_toRightOf="@id/above_rows_guideline"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toBottomOf="@id/row3_bottom"
        app:layout_constraintBottom_toTopOf="@id/row4_bottom"/>

    <!-- 底部行左Spinner -->
    <Spinner
        android:id="@+id/sp1"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:hint="Spinner"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toLeftOf="@id/bottom_row_guideline"
        app:layout_constraintTop_toBottomOf="@id/row4_bottom"
        app:layout_constraintBottom_toBottomOf="parent"/>

    <!-- 底部行右Spinner -->
    <Spinner
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:hint="Spinner"
        app:layout_constraintLeft_toRightOf="@id/bottom_row_guideline"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="@id/sp1"
        app:layout_constraintBottom_toBottomOf="@id/sp1"/>

</androidx.constraintlayout.widget.ConstraintLayout>

总的来说,GridLayout可以实现你的需求,但不够灵活和直观;LinearLayout嵌套是最容易上手和维护的方案;ConstraintLayout则适合追求布局扁平化和复杂交互的场景,你可以根据自己的需求选择。

内容的提问来源于stack exchange,提问作者coray8

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 07:31:21