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

Android Studio:如何填充含百分比参数视图的XML布局

解决复用带百分比参数的CardView到PercentRelativeLayout的问题

我来帮你搞定这个复用CardView的难题——之前尝试失败大概率是布局结构、属性配置或者依赖没搞对,下面给你一步步的可行方案:

第一步:确保依赖正确

首先要确认你的项目已经引入了百分比布局库和CardView库(用AndroidX的话),在Module级别的build.gradle里添加:

dependencies {
    // 百分比布局
    implementation 'androidx.percentlayout:percentlayout:1.0.0'
    // CardView
    implementation 'androidx.cardview:cardview:1.0.0'
}

如果是用旧的Support库,替换成对应的com.android.support:percent:28.0.0com.android.support:cardview-v7:28.0.0就行。

第二步:创建可复用的CardView布局

新建一个reusable_card.xml文件,这里要注意:必须用PercentRelativeLayout作为根容器,这样才能让内部的CardView使用百分比宽高属性。示例代码如下:

<androidx.percentlayout.widget.PercentRelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <androidx.cardview.widget.CardView
        android:id="@+id/card_container"
        android:layout_margin="8dp"
        <!-- 核心:用百分比设置宽高 -->
        app:layout_widthPercent="90%"
        app:layout_heightPercent="25%"
        app:cardElevation="4dp"
        app:cardCornerRadius="8dp">

        <!-- 这里是你需要动态修改的内容,比如标题、图片等 -->
        <TextView
            android:id="@+id/card_title"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="默认标题"
            android:textSize="18sp"
            android:layout_margin="16dp"/>

        <ImageView
            android:id="@+id/card_image"
            android:layout_width="match_parent"
            android:layout_height="120dp"
            android:layout_below="@id/card_title"
            android:scaleType="centerCrop"/>

    </androidx.cardview.widget.CardView>

</androidx.percentlayout.widget.PercentRelativeLayout>

第三步:在主布局中复用CardView

你的主布局里承载视图是PercentRelativeLayout,这里分两种方式复用:

方式1:静态引入(用<include>标签)

直接在主布局的PercentRelativeLayout内部添加<include>,注意给每个复用的视图设置唯一ID,并且添加RelativeLayout的位置规则(避免重叠):

<ScrollView
    android:id="@+id/scrollview"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <androidx.percentlayout.widget.PercentRelativeLayout
        android:id="@+id/main_container"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <!-- 第一个复用的CardView -->
        <include
            layout="@layout/reusable_card"
            android:id="@+id/first_card"
            android:layout_alignParentTop="true"/>

        <!-- 第二个复用的CardView,设置在第一个下面 -->
        <include
            layout="@layout/reusable_card"
            android:id="@+id/second_card"
            android:layout_below="@id/first_card"
            android:layout_marginTop="16dp"/>

        <!-- 可以继续添加更多 -->
        <include
            layout="@layout/reusable_card"
            android:id="@+id/third_card"
            android:layout_below="@id/second_card"
            android:layout_marginTop="16dp"/>

    </androidx.percentlayout.widget.PercentRelativeLayout>

</ScrollView>

方式2:动态添加(代码中Inflate)

如果需要根据数据动态生成多个CardView,在Activity/Fragment里这样做:

// 获取主容器
PercentRelativeLayout mainContainer = findViewById(R.id.main_container);
LayoutInflater inflater = getLayoutInflater();

// 模拟数据,比如3个卡片的标题和图片
List<String> cardTitles = Arrays.asList("动态卡片1", "动态卡片2", "动态卡片3");
List<Integer> cardImages = Arrays.asList(R.drawable.img1, R.drawable.img2, R.drawable.img3);

View lastCard = null;
for (int i = 0; i < cardTitles.size(); i++) {
    // Inflate复用布局
    View cardView = inflater.inflate(R.layout.reusable_card, mainContainer, false);
    // 设置唯一ID(避免冲突)
    cardView.setId(View.generateViewId());

    // 修改卡片内容
    TextView title = cardView.findViewById(R.id.card_title);
    title.setText(cardTitles.get(i));
    ImageView image = cardView.findViewById(R.id.card_image);
    image.setImageResource(cardImages.get(i));

    // 设置布局位置
    PercentRelativeLayout.LayoutParams params = (PercentRelativeLayout.LayoutParams) cardView.getLayoutParams();
    if (lastCard == null) {
        // 第一个卡片贴顶部
        params.addRule(PercentRelativeLayout.ALIGN_PARENT_TOP);
    } else {
        // 后续卡片放在上一个下面
        params.addRule(PercentRelativeLayout.BELOW, lastCard.getId());
        params.topMargin = getResources().getDimensionPixelSize(R.dimen.card_margin_top);
    }

    // 添加到容器
    mainContainer.addView(cardView);
    lastCard = cardView;
}

之前失败的常见原因排查

  • 没加百分比布局依赖:导致app:layout_widthPercent这类属性无法被系统解析,布局直接失效。
  • 复用布局根节点不对:如果直接把CardView作为复用布局的根,没有套PercentRelativeLayout,百分比属性不会生效(因为这些属性是PercentRelativeLayout给子View用的)。
  • 没设置唯一ID和位置规则:多个复用的CardView重叠在一起,看起来像是没添加成功。
  • 属性命名空间错误:百分比属性要用到app:命名空间,不是android:,别写错了。

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

火山引擎 最新活动