Expandable ListView嵌套SwipeRefreshLayout滑动冲突问题求助
解决ExpandableListView与SwipeRefreshLayout的滚动冲突问题
这个问题我之前做项目时也踩过坑,本质是SwipeRefreshLayout的触摸事件拦截逻辑和ExpandableListView的滚动逻辑撞车了——当你把列表滑到底部后,向上滑动的手势被SwipeRefreshLayout误当成了下拉刷新的触发动作,结果它把事件抢走了,列表自然没法正常向上滚动。下面给你一套亲测有效的解决办法:
核心思路:自定义SwipeRefreshLayout,精准控制事件拦截
我们需要重写SwipeRefreshLayout的onInterceptTouchEvent方法,让它先判断ExpandableListView的滚动状态:如果列表还能向上滚动(没滑到顶部),就不拦截触摸事件,让列表自己处理滚动;只有当列表已经滑到顶部、无法再向上滚动时,才允许SwipeRefreshLayout拦截事件触发下拉刷新。
第一步:编写自定义CustomSwipeRefreshLayout类
import android.content.Context; import android.support.v4.widget.SwipeRefreshLayout; import android.util.AttributeSet; import android.view.MotionEvent; import android.widget.ExpandableListView; public class CustomSwipeRefreshLayout extends SwipeRefreshLayout { private ExpandableListView mExpandableListView; public CustomSwipeRefreshLayout(Context context) { super(context); } public CustomSwipeRefreshLayout(Context context, AttributeSet attrs) { super(context, attrs); } // 关联需要控制的ExpandableListView public void setExpandableListView(ExpandableListView expandableListView) { this.mExpandableListView = expandableListView; } @Override public boolean onInterceptTouchEvent(MotionEvent ev) { if (mExpandableListView != null) { // canScrollVertically(-1):判断列表是否能向上滚动(返回true表示还能向上滑,不在顶部) boolean canScrollUp = mExpandableListView.canScrollVertically(-1); if (canScrollUp) { // 列表还能向上滚动,不拦截事件,交给列表处理 return false; } else { // 列表已经在顶部,允许SwipeRefreshLayout拦截下拉事件 return super.onInterceptTouchEvent(ev); } } return super.onInterceptTouchEvent(ev); } }
第二步:在布局文件中替换为自定义控件
把原来布局里的SwipeRefreshLayout换成我们自定义的控件,注意替换成你自己的包名:
<com.yourprojectpackage.CustomSwipeRefreshLayout android:id="@+id/swipe_refresh" android:layout_width="match_parent" android:layout_height="match_parent"> <ExpandableListView android:id="@+id/expandable_list" android:layout_width="match_parent" android:layout_height="match_parent"/> </com.yourprojectpackage.CustomSwipeRefreshLayout>
第三步:在代码中关联列表与刷新控件
在Activity或Fragment里,找到两个控件并完成关联:
CustomSwipeRefreshLayout swipeRefreshLayout = findViewById(R.id.swipe_refresh); ExpandableListView expandableListView = findViewById(R.id.expandable_list); // 绑定列表和自定义刷新控件,让它能识别列表的滚动状态 swipeRefreshLayout.setExpandableListView(expandableListView); // 正常设置你的刷新逻辑和列表适配器 swipeRefreshLayout.setOnRefreshListener(() -> { // 这里写你的下拉刷新业务逻辑 // 刷新完成后记得调用setRefreshing(false)关闭刷新状态 });
这样修改后,当列表在底部时,向上滑动会正常触发列表滚动;只有当列表滑到顶部,下拉手势才会触发SwipeRefreshLayout的刷新,完美解决冲突问题。
内容的提问来源于stack exchange,提问作者Bomzzn
相关产品推荐
相关产品推荐

