You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何实现占满屏幕宽度的2x2正方形CardView网格布局?

实现2x2网格中CardView的正方形布局

要解决CardView被拉伸、无法保持正方形的问题,有几种简单可靠的方案,根据你的布局结构选择即可:

方案一:自定义SquareCardView(最通用)

这种方法不管你用GridLayout、RecyclerView还是其他布局都能生效,核心是让CardView的高度强制等于宽度:

  1. 创建自定义CardView类:
import android.content.Context
import android.util.AttributeSet
import androidx.cardview.widget.CardView

class SquareCardView @JvmOverloads constructor(
    context: Context,
    attrs: AttributeSet? = null,
    defStyleAttr: Int = 0
) : CardView(context, attrs, defStyleAttr) {

    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
        // 让高度测量规格和宽度一致,实现正方形
        super.onMeasure(widthMeasureSpec, widthMeasureSpec)
    }
}
  1. 在XML布局中替换原CardView为这个自定义View:
    假设你的GridLayout是2列布局,给每个SquareCardView设置layout_width="0dp"layout_columnWeight="1"(让每列平分父容器宽度),高度设为wrap_content即可:
<GridLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:columnCount="2"
    android:rowCount="2">

    <com.your.package.name.SquareCardView
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_columnWeight="1"
        android:layout_margin="8dp"
        app:cardCornerRadius="8dp"
        app:cardElevation="4dp"/>

    <!-- 重复另外3个SquareCardView -->

</GridLayout>

方案二:用ConstraintLayout设置宽高比(无需自定义View)

如果你的布局可以改用ConstraintLayout实现2x2网格,或者给每个CardView套一层ConstraintLayout,直接通过属性设置宽高比为1:1:

<androidx.constraintlayout.widget.ConstraintLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <!-- 第一个CardView -->
    <androidx.cardview.widget.CardView
        android:id="@+id/card1"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:layout_margin="8dp"
        app:cardCornerRadius="8dp"
        app:cardElevation="4dp"
        app:layout_constraintWidth_percent="0.45"
        app:layout_constraintHeight_toEqualWidth="true"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"/>

    <!-- 第二个CardView -->
    <androidx.cardview.widget.CardView
        android:id="@+id/card2"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:layout_margin="8dp"
        app:cardCornerRadius="8dp"
        app:cardElevation="4dp"
        app:layout_constraintWidth_percent="0.45"
        app:layout_constraintHeight_toEqualWidth="true"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toTopOf="parent"/>

    <!-- 第三个和第四个同理,设置顶部约束为card1/card2的底部 -->

</androidx.constraintlayout.widget.ConstraintLayout>

这里用layout_constraintWidth_percent="0.45"让每个CardView占父宽度的45%(留出门距),再通过layout_constraintHeight_toEqualWidth="true"强制高度等于宽度,完美实现正方形。

方案三:RecyclerView + GridLayoutManager(适合动态数据)

如果你的2x2网格是动态生成的(比如从数据源加载),用RecyclerView配合GridLayoutManager更合适:

  1. 设置RecyclerView的LayoutManager:
recyclerView.layoutManager = GridLayoutManager(context, 2)
  1. 在Item布局中,给CardView套一层ConstraintLayout,设置宽高比1:1:
<androidx.constraintlayout.widget.ConstraintLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <androidx.cardview.widget.CardView
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:layout_margin="8dp"
        app:cardCornerRadius="8dp"
        app:cardElevation="4dp"
        app:layout_constraintWidth_toMatchParent="true"
        app:layout_constraintHeight_toEqualWidth="true"/>

</androidx.constraintlayout.widget.ConstraintLayout>

这样每个Item的CardView会自动保持正方形,宽度平分RecyclerView的宽度。


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

火山引擎 最新活动