天天看点

ScrollView嵌套ViewPager自适应高度

由于项目需要,ScrollView 嵌套ViewPager加载Fragment再包裹RecyclerView等控件来实现一系列功能。在此主要是关于加载数据,ViewPager动态设置高度的问题以及加载数据,滑动不卡顿。做总结。

问题:ViewPager在ScrollView的包裹下,无论高度是设置match_parent,或是wrap_content,都无法加载出fragment中的数据,必须设置确定直才能显示,(500dp),给定确定值以后,数据上拉加载无法实现。因此我们必须要动态计算fragment中RecyclerView的高度,动态的赋高度给ViewPager.

先上图,由于上传不了短视频,没有制作gif,就看图片吧,文章下面,有下载的链接

ScrollView嵌套ViewPager自适应高度

挖坑:动态设置ViewPager高度,最初的实现思路,计算ViewPager当前选中的View(Fragment)的高度。

ViewPager滑动监听的方法中,onPageSelected(intposition),可以获得当前的选中的View的下标位置。

我在重写ViewPager的类中,使用滑动监听传入的下标位置来取得当前的View,的高度。

@Override
public void onPageSelected(int position) {
    viewPager.resetHeight(position);
}      
实践证明,现实和想法还是有差距的,运行切换,指向view为null,打印多遍log,以及查阅资料,才知道      
viewPager只会维持2-3个view,滑动时加载和删除view,然而传入的current,可以是无限的,,,      
解决方法:      
ScrollView嵌套ViewPager自适应高度
遍历ViewPager所有的子View,得到高度,赋值给ViewPager。这样写,是解决了view为null的问题,并且也给ViewPager设置了高度,      
但是,切换页面时,子View的高度与最大的子View的高度不匹配,就会导致,页面下一大片空白部分。      
解决方法:计算当前view的高度,并赋值给viewPager。ViewPager下的Fragment中,包含RecyclerView,的高度,      
于是,我在RecyclerView的适配器中,累加计算item的高度,得到总和后,赋值给ViewPager,解决了页面空白的部分,      
但是,滑动加载到很多页以后,明显感觉屏幕卡顿严重的问题。所以,还是需要思考优化。。。。。      
参考了鸿洋的博客,使用HashMap,根据下标位置,来保存每一个View。具体如下:      
ScrollView嵌套ViewPager自适应高度
ok,到这里为止,核心的代码基本是可以解决了,可以正常取到当前的View,并且获得高度。      
但是还是有一些,微微的卡顿的问题,思考完善之后,在代码中模拟了网络加载数据的情况,进行分析,      
以下几点比较容易遗忘和需要优化的地方。      
ScrollView嵌套ViewPager自适应高度
ScrollView嵌套ViewPager自适应高度
上面代码有没毛病?正常来讲,这样写,还是会实现数据加载,高度计算等。但是你会发现越来越卡,卡到你怀疑人生。      
于是,,,我思考了这几行代码的顺序,,,当前的Fragment的显示的时候,setUserVisibleHint() 方法调用,访问网络数据,      
viewPager监听到onPageSelected(),方法,计算当前页面的高度,此时可能出现网络卡顿,又或者,你得到了返回的网络数据,      
并且关闭了,refresh的刷新方法,但是adapter可能还没加载完数据,所以导致加载卡顿,滑动不流畅等问题。解决如下:      
在Fragment中,没有使用,setUserVisibleHint()方法,来执行getData(),在监听的onPageSelected()方法中,执行getData(),      
保证获取数据,在前,计算高度在后,回到Fragment中,在Handler中,数据加载,填充,刷新,在前,关闭progressDialog,refresh      
在后,确保刷新完数据(与计算高度相关),再关闭。能够很好的提升页面的流程度。      
源码下载