UNREFERENCED_PARAMETER(lParam)
switch (message)
{
case WM_INITDIALOG:
return (INT_PTR)TRUE
case WM_COMMAND:
if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
{
EndDialog(hDlg, LOWORD(wParam))
return (INT_PTR)TRUE
}
break
}
return (INT_PTR)FALSE
}
步骤1:将ViewPager与其同一容器内的其它View,使用权重约束。~~~~~未果,效果依然如常态
步骤2:将ViewPager 的高度设置为具体的数值。~~~~~解决问题,但是,偏离了使用wrap_content的初衷。
步骤2:将ViewPager 的 item root view设置固定的高度值。~~~~~未果,效果依然如常态。
步骤3:在Adapter 创建对象的函数中(也就是添加item view的地方),获取到Item root view的子View,并且获取其,宽度、高度,并在此设置 View(instantiateItem 函数 所返回的View) 的宽、高,~~~~~~未果,效果依然如常态
步骤4:此方案类似与“步骤3”,唯一区别的是高亮显示的区域
在Adapter 创建对象的函数中(也就是添加item view的地方),获取到Item root view的子View,并且获取其,宽度、高度,并在此设置 container(instantiateItem 函数 所传递的container ) 的宽、高,~~~~~~得偿所愿,效果实现
Note:注意获取View的高度,需要view.post(new Runnable(){ //get view height }) 在Runnable体内获取高度、宽度
ViewPager高度设置为wrap_content或者具体的高度值无效,是因为ViewPager的onMeasure方法在度量宽高的时候,在方法体的最开始就直接调用了setMeasuredDimension()方法将自身的宽高度量,但是并没有在其onMeasure()计算完其具体的子View的宽高之后,重新度量一次自身的宽高
从这里我们可以看到,ViewPager的宽高会受其父容器的宽高的限制,但是并不会因为自身子View的宽高而影响ViewPager的宽高。
看setMeasuredDimension的源码调用可以看出,当父容器的高度确定时,ViewPager的宽高其实就是父容器的宽高,ViewPager就是在onMeasure方法一进来的时候就直接填充满整个父容器的剩余空间。在计算孩子节点之前,就已经计算好了ViewPager的宽高,在计算完孩子节点之后,并不会再去重新计算ViewPager的宽高。
自定义一个ViewPager,根据子View的宽高重新度量ViewPager的宽高。其实做法就是在自定义onMeasure的super.onMeasure(widthMeasureSpec, heightMeasureSpec)之前重新计算heightMeasureSpec,将原本ViewPager接收的父容器的限定的heightMeasureSpec替换成我们自定义的heightMeasureSpec。
但是这样的做法,会有种问题,即在ViewPager的子View是采用LinearLayout作为根布局的时候,并且给LinearLayout设置了固定的高度值,那么会出现ViewPager动态高度无效的问题
其实具体的做法,就是仿造measureChild的做法,自定义子View的heightMeasureSpec然后度量整个子View,其实子View的宽度也可以这样做。
这里其实是源码层做了限制,在setOffscreenPageLimit中设置了一个默认值,而这个默认值的大小为1
所以从这里可以看出,ViewPager的最小缓存的limit是1,而不能小于1,当小于1的时候就会被强制的设置为1。
而populate()函数就是用来处理ViewPager的缓存的。
populate()的生命周期是与Adapter的生命周期绑定的。
其实在setOffscreenPageLimit()的时候,调用的populate(),而populate()内部调用的
而pupulate(int newCurrentItem)方法在另一处调用的地方就是在setCurrentItem。
其实ViewPager缓存都是基于ItemInfo这个类来进行的,
看下ViewPager.addNewItem的源码
其实ViewPager.addNewItem就是通过调用Adapter.instantiateItem来创建对应的View,并且将View保存到ItemInfo中的object属性,并且判断ViewPager缓存中是否已经有ItemInfo,如果没有,则添加,如果有则做修改替换
从分析FragmentStatePagerAdapter来看,setUserVisibleHint方法会优先于Fragment的生命周期函数 执行。因为在FragmentStatePagerAdapter中提交事务,是在调用finishUpdate方法中进行的,只有提交事务的时候,才会去执行Fragment的生命周期。
FragmentStatePagerAdapter中的instantiateItem和destroyItem都实现了对fragment的事务的添加和删除,而finishUpdate实现了事务的提交,所以在实现FragmentStatePagerAdapter的时候,并不需要重写instantiateItem和destroyItem
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)