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

求助:多个ExpandableListView在ScrollView中展开时无法撑开高度

问题解决:ScrollView嵌套ExpandableListView展开后高度挤压

核心问题在于ScrollView与ExpandableListView的滚动特性冲突,原生ExpandableListView的wrap_content无法自动计算展开后的总高度,再加上原布局中ConstraintLayout的错误约束(所有列表都绑定了bottom_toBottomOf="parent"),导致展开的子项被挤压在初始高度范围内。

以下是分步解决方案:

1. 重构布局结构

原ConstraintLayout的约束设置会让所有ExpandableListView重叠布局,完全错误。换成垂直LinearLayout实现列表依次排列:

<?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=".screens.home.ui.dailyreportes.DailyReportsDetailsFragment">

    <ScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:fillViewport="true">

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

            <!-- 替换为自定义的ExpandableHeightListView -->
            <com.your.package.ExpandableHeightListView
                android:id="@+id/elv_work_logs"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:divider="@android:color/darker_gray"
                android:dividerHeight="0.5dp" />

            <com.your.package.ExpandableHeightListView
                android:id="@+id/elv_equipment_logs"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:divider="@android:color/darker_gray"
                android:dividerHeight="0.5dp" />

            <com.your.package.ExpandableHeightListView
                android:id="@+id/elv_material_delivery_logs"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:divider="@android:color/darker_gray"
                android:dividerHeight="0.5dp" />

            <com.your.package.ExpandableHeightListView
                android:id="@+id/elv_activity_logs"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:divider="@android:color/darker_gray"
                android:dividerHeight="0.5dp" />

            <com.your.package.ExpandableHeightListView
                android:id="@+id/elv_schedule_delays_logs"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:divider="@android:color/darker_gray"
                android:dividerHeight="0.5dp" />

        </LinearLayout>
    </ScrollView>
</LinearLayout>

2. 自定义ExpandableListView实现高度自适应

原生ExpandableListView不会在组展开/折叠时重新计算总高度,我们需要重写onMeasure方法,手动计算所有可见项(包括展开的子项)的总高度:

public class ExpandableHeightListView extends ExpandableListView {

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

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

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

    @Override
    public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int totalHeight = 0;
        // 遍历所有组项
        for (int i = 0; i < getCount(); i++) {
            View groupView = getChildAt(i);
            if (groupView != null) {
                // 测量组项高度
                groupView.measure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
                totalHeight += groupView.getMeasuredHeight();
                
                // 如果当前组是展开状态,测量所有子项高度
                if (isGroupExpanded(i)) {
                    int childCount = getExpandableListAdapter().getChildrenCount(i);
                    for (int j = 0; j < childCount; j++) {
                        View childView = getExpandableListAdapter().getChildView(i, j, false, null, this);
                        childView.measure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
                        totalHeight += childView.getMeasuredHeight();
                    }
                }
            }
        }
        // 加上分隔线总高度
        totalHeight += getDividerHeight() * (getCount() - 1);

        // 重新设置测量高度
        heightMeasureSpec = MeasureSpec.makeMeasureSpec(totalHeight, MeasureSpec.EXACTLY);
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }
}

注意将com.your.package替换为你自己的项目包名。

3. 代码中添加展开/折叠监听

给每个ExpandableListView设置适配器后,添加组展开/折叠监听,触发布局重新测量:

// 示例:给工作日志列表设置监听
ExpandableHeightListView workLogsListView = findViewById(R.id.elv_work_logs);
workLogsListView.setAdapter(yourWorkLogsAdapter);

workLogsListView.setOnGroupExpandListener(groupPosition -> {
    workLogsListView.requestLayout(); // 展开时重新计算高度
});

workLogsListView.setOnGroupCollapseListener(groupPosition -> {
    workLogsListView.requestLayout(); // 折叠时重新计算高度
});

其他四个列表重复上述监听设置即可。

关键说明

  • ScrollView添加android:fillViewport="true"是为了让内部布局在内容不足时填满屏幕,内容超出时正常滚动。
  • 原布局中android:layout_weight属性在ConstraintLayout中无效,已直接移除,避免布局混乱。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 01:29:54