如何实现ExpandableListView嵌套ViewPager?附实测结果
更新 - 已添加实验结果
我尝试将ViewPager作为ExpandableListView的子视图,但它无法显示:( 我也尝试将其放在ScrollView下,结果依旧,所以我认为这是滚动视图嵌套的问题?但移除ScrollView后它就显示出来了。我该怎么做才能让它们共存?
目标效果

实际实现效果
注:这只是样例,尚未完成。我有3个子项,布局也重复显示了三次,每个子项都包含在内
嘿,我之前也踩过滚动视图嵌套的坑,ExpandableListView和ViewPager搭在一起确实容易出现显示异常或者滚动冲突的问题,给你几个亲测有效的解决方案:
1. 自定义ExpandableListView,解决滚动拦截冲突
当用户在ViewPager区域横向滑动时,让ExpandableListView别抢触摸事件,把事件传递给ViewPager。你可以写个自定义子类:
public class CustomExpandableListView extends ExpandableListView { private float startX, startY; // 滑动阈值,判断是横向还是纵向滑动 private static final int SCROLL_THRESHOLD = 10; public CustomExpandableListView(Context context) { super(context); } public CustomExpandableListView(Context context, AttributeSet attrs) { super(context, attrs); } @Override public boolean onInterceptTouchEvent(MotionEvent ev) { switch (ev.getAction()) { case MotionEvent.ACTION_DOWN: // 记录触摸起始点 startX = ev.getX(); startY = ev.getY(); break; case MotionEvent.ACTION_MOVE: float dx = Math.abs(ev.getX() - startX); float dy = Math.abs(ev.getY() - startY); // 如果是横向滑动(超过阈值),不拦截事件,交给ViewPager处理 if (dx > dy && dx > SCROLL_THRESHOLD) { return false; } break; } return super.onInterceptTouchEvent(ev); } }
然后把布局里的原生ExpandableListView换成这个自定义的就行。
2. 让ViewPager自适应内容高度
很多时候ViewPager不显示是因为嵌套在滚动容器里时,无法正确测量自身高度。可以自定义一个能自适应高度的ViewPager:
public class WrapContentHeightViewPager extends ViewPager { public WrapContentHeightViewPager(Context context) { super(context); } public WrapContentHeightViewPager(Context context, AttributeSet attrs) { super(context, attrs); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int height = 0; // 遍历所有子页面,取最高的高度作为ViewPager的高度 for (int i = 0; i < getChildCount(); i++) { View child = getChildAt(i); child.measure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED)); int childHeight = child.getMeasuredHeight(); if (childHeight > height) { height = childHeight; } } // 重新设置高度测量规则 heightMeasureSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY); super.onMeasure(widthMeasureSpec, heightMeasureSpec); } }
这样ViewPager就能根据内部内容自动调整高度,不会因为高度为0而隐身了。
3. 别嵌套ScrollView!
你已经发现移除ScrollView后ViewPager能显示,那尽量别把ExpandableListView再套进ScrollView里——毕竟ExpandableListView本身就是滚动容器,嵌套会导致双重滚动冲突,还会搞乱布局测量。如果页面顶部有需要滚动的内容,直接用expandableListView.addHeaderView()把这些内容加进去,整个页面的滚动交给ExpandableListView统一管理,就不会有问题了。
先试试这几个方法,应该能解决你的显示问题。如果还有细节卡壳,可以把相关的布局代码或者Adapter代码贴出来,再帮你排查~
内容的提问来源于stack exchange,提问作者jace

