ScrollView嵌套ListView问题解决

最近在做项目的过程中需要ScrollView嵌套ListView,并且实现ListView的分页加载,筛选框悬浮固定。其中遇到了3个问题,其问题和解决方案分别如下:

1,ListView在ScrollView中无法显示

问题分析:因为ListView是被动态加载进ScrollView中,无法提前设定其长度,导致对应adapter的getView函数没有被调用。
解决方案:自定义ListView,重写其onMeasure方法

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST);
    super.onMeasure(widthMeasureSpec, expandSpec);
}

通过参数MeasureSpec.AT_MOST将ListView的长度设置为最大。

2,ListView和ScrollView产生滑动事件的冲突,无法实现分页加载

问题分析:因为将ListView的高度设置成了最大值,所以在ListView的接口函数onScroll中,firstVisibleItem总是0,visibleItemCount总是ListView总长度,无法有效监听ListView滑动到最底端。

public void onScroll(AbsListView view, int firstVisibleItem,
      int visibleItemCount, int totalItemCount) {
   firstItemIndex = firstVisibleItem;
   mLastItem = firstVisibleItem + visibleItemCount;
}

解决方案:通过监听ScrollView是否滑动到最底端来判断ListView,通过重写ScrollView的onOverScrolled函数,当ScrollView滑动到最底端时, clampedY为true,此时通过自定义接口函数mOnObservableScrollViewListener.moreRefresh() 实现ListView分页加载。

@Override
protected void onOverScrolled(int scrollX, int scrollY, boolean clampedX, boolean clampedY) {
    super.onOverScrolled(scrollX, scrollY, clampedX, clampedY);
    if (scrollY != 0 && mOnObservableScrollViewListener != null && clampedY) {
        // 监听滑动到底部
        mOnObservableScrollViewListener.moreRefresh();
    }
}

3,点击筛选框按钮,实现筛选框在顶部的悬浮固定

解决方案:在顶部定义一个完全一样的筛选框,点发生点击事件时,顶部悬浮框可见,整个ScrollView通过scrollTo函数向上滑动对应距离。

运用上述方法虽然暂时解决了ScrollView嵌套ListView的一些问题,却也带来了致命的性能问题。因为ListView是嵌套在ScrollView中的,所以其高度只能设置为layout_height=”wrap_content”,并且在自定义ListView中重写了onMeasure方法,强行设置AT_MOST来测量子View高度,相当于将listView的所有子项全部展开在ScrollView中。当ListView的长度较少时性能还可以,但是一旦当ListView的数量增多,需要分页加载时,相当于将整个listView重新绘制一遍,比正常情况要多调用好几倍getView,具体分析可参考博客 https://blog.csdn.net/megatronkings/article/details/52752786

因为我的项目涉及到下拉刷新和分页加载,所以不得不抛弃ScrollView嵌套ListView的方案,最终仅用一个ListView来实现所有前端需求,将页面上非ListView的内容通过headerView和footerView来进行加载,最终解决了性能问题。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值