高度自适应的ViewPager--SelfAdaptingViewPager
来源:互联网 发布:数据采集流程图 编辑:程序博客网 时间:2024/05/17 23:41
之前项目遇到了一个需求,需要scrollview里面嵌套一个viewpager,而且要做到切换viewpager的时候恰好完全展示对应的page。
在网上搜索了很久,只看到某位大神提供的CustomViewPager,代码如下:
public class CustomViewPager extends ViewPager { public CustomViewPager(Context context) { super(context); } public CustomViewPager(Context context, AttributeSet attrs) { super(context, attrs); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int height = 0; for (int i = 0; i < getChildCount(); i++) { View child = getChildAt(i); child.measure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED)); int h = child.getMeasuredHeight(); if (h > height) height = h; } heightMeasureSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY); super.onMeasure(widthMeasureSpec, heightMeasureSpec); } }
研究一番后发现,onMeasure方法中最后记录的是所有page多次测量后高度中的最大值,这样两个高度不一的page虽然都能完全展示,但是高度矮的那个就会有留白,不符合我们恰好展示的需求。
于是我对代码进行了修改,有了SelfAdaptingViewPager,代码如下:
public class SelfAdaptingViewPager extends ViewPager { private Map<Integer, Integer> map = new HashMap<>(2); private int currentPosition = 0; private MarginLayoutParams params; public SelfAdaptingViewPager(Context context) { super(context); } public SelfAdaptingViewPager(Context context, AttributeSet attrs) { super(context, attrs); } //在View的绘制过程中此方法会被多次调用,每次都会测量出新的数据,我们用最新的数据替换旧的数据 @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { for (int i = 0; i < getChildCount(); i++) { View child = getChildAt(i); child.measure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED)); int h = child.getMeasuredHeight(); Log.d("SelfAdaptingViewPager", "measuredHeight=" + h); Log.d("SelfAdaptingViewPager", "getChildCount=" + getChildCount()); Log.d("SelfAdaptingViewPager", "getChildAt(i)=" + i); /* Log.d("SelfAdaptingViewPager", "getChildAt(i).getId())=" + getChildAt(i).getId()); if (Build.VERSION.SDK_INT > 19) { map.put(Math.abs(i - 1), h); } else {*/ map.put(i, h); // } } int height = 0; //onMeasure第一次被调用的时候,遍历不到child(View的绘制流程只是了解最基本的,我就不解释了) height = map.get(currentPosition) == null ? 0 : map.get(currentPosition); Log.d("SelfAdaptingViewPager", "height=" + height); heightMeasureSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY); super.onMeasure(widthMeasureSpec, heightMeasureSpec); } //在切换tab的时候,重置ViewPager的高度 public void resetHeight(int currentPosition) { this.currentPosition = currentPosition; params = (MarginLayoutParams) getLayoutParams(); if (params == null) { params = new MarginLayoutParams(LayoutParams.MATCH_PARENT, map.get(currentPosition)); } else { params.height = map.get(currentPosition); } setLayoutParams(params); }}
但是我在用android4.4的机型测试时发现了问题,一个page留白,一个page不能完全展示,显然两个page所展示的高度正好弄反了。
后来发现是和手机的android版本有关,使用android版本4.4及以下的机型都有这个问题。遍历viewpager的儿子,得到的第一个儿子是第二个page对应的view,得到的第二儿子是第一个page对应的view。
这次周末在家我想再研究一下这个问题,结果自己写的demo在任何机型上并不会出现这样的问题。
最终发现问题的出现和依赖的v7包有关系,我在工作项目中依赖的是com.android.support:appcompat-v7:23.4.0,demo中依赖的是com.android.support:appcompat-v7:23.1.1,所以可能是不同版本的v7包所包含的v4包中ViewPager对于getChildAt的实现有区别吧,以后有时间和基础了我想我会进一步研究的。
下面是demo的截图:
demo的代码地址:https://github.com/tingshuonitiao/AndroidStudy
- 高度自适应的ViewPager--SelfAdaptingViewPager
- 设置viewPager的高度为自适应
- 设置viewPager的高度为自适应
- 自适应子View高度的viewPager
- ViewPager高度自适应
- ViewPager高度自适应
- ViewPager高度自适应
- ViewPager自适应高度问题
- ViewPager的高度根据item的高度自适应
- ViewPager的高度根据item的高度自适应
- 关于ViewPager高度自适应(随着pager页的高度改变Viewpager的高度)
- 关于ViewPager高度自适应(随着pager页的高度改变Viewpager的高度)
- 关于ViewPager高度自适应(随着pager页的高度改变Viewpager的高度)
- 关于ViewPager高度自适应(随着页面高度改变Viewpager的高度)
- Android中viewpager自适应高度
- ViewPager自适应高度和宽度
- 仿小红书顶部自适应高度viewpager
- ViewPager 嵌套多个不同高度的Fragment,ViewPager 高度自适应
- 策略模式
- My SQL
- SVN的使用
- Hybrid 开发:JsBridge
- springboot js 函数变量 字符串拼接
- 高度自适应的ViewPager--SelfAdaptingViewPager
- yii2 activefrom常用input框样式
- 15个良好的编程习惯
- Datatlble常用小例子
- jqgrid总结,使用过程中的一些配置信息的记录
- cmsis dap的实现, 改为无线通信方式
- ReadMoreTextView
- Windows下编译运行DPM(Discriminatively trained deformable part models)
- msql库操作用户权限连接数据库