View 大小相关
getWidth()
与getMeasuredWidth()
的区别
View 的
width
和height
、measuredWidth
和measuredHeight
的意义,分别的使用场景和赋值时机?
getWidth()
代码:
1 | public final int getWidth() { |
getMeasuredWidth()代码:
1 | public final int getMeasuredWidth() { |
getWidth()
的值在layout(int l, int t, int r, int b)
执行完成后真正确定;getMeasureWidth()
的值是在onMeasure(int widthMeasureSpec, int heightMeasureSpec)
中的setMeasuredDimension(int measureWidth, int measrueHeight)
执行完成后确定的,mMeasureWidth
本身是包含测量模式和测量的具体值的,但在调用getMeasureWidth()
后,进行了掩码操作,将高两位移除了;
结论:子View最终的位置是在onLayout 中确定的,但子View的宽高是在onMeasure中确定的
MeasureSpec
相关
到底是个啥?各种值的含义?mode和size分别代表什么意思?
MeasureSpec
表示的是View的测量结果,用一个int值表示(int值四个字节)其中高两位用来表示mode(测量模式),低30位用来表示size(测量的值),测量模式有三种:
UNSPECIFIED
:不对View大小做限制,如:ListView
,ScrollView
EXACTLY
:确切的大小,如:100dp或者march_parent
AT_MOST
:大小不可超过某数值,如:wrap_content
着重看一下ViewGroup的getChildMeasureSpec(int spec, int padding, int childDimension)
方法
1 | /** |
针对以上ViewGroup的getChildMeasureSpec代码做个小结:
- 不管父View是何模式,若子View有确切数值,则子View大小就是其本身大小,且mode是
EXACTLY
- 若子View是
match_parent
,则模式与父View相同,且大小同父View(若父View是UNSPECIFIED
,则子View大小为0) - 若子View是
wrap_content
,则模式是AT_MOST,大小同父View,表示不可超过父View大小(若父View是UNSPECIFIED
,则子View大小为0)
View的一般绘制流程是什么?
measure->layout->draw
事件分发
事件分发机制(参考一文读懂Android View事件分发机制)
1 | public boolean dispatchTouchEvent(MotionEvent ev) { |
- RecyclerView中嵌套横向的RecyclerView,外层RecyclerView竖直滑动时,内层的不能保持原来的位置
- RecyclerView的PagerSnapHelper的用法
- ViewPager直接调用setCurrentItem,不触发
ViewPager.OnPageChangeListener
的onPageScrollStateChanged
,但触发onPageSelected
- 子View最终的位置是在onLayout 中确定的,但子View的宽高是在onMeasure中确定的
- ViewPager的PageTransform效果在调用Adapter的notifyDataChanged方法后会失效,需要重新setAdapter
- ViewPager中显示单独的View时,调用notifyDataChange时View里面的内容不会更,原因是ViewPager的Adapter被设计成在其显示的Item增加删除时起作用,即
instantiateItem
和destroyItem
两个方法
这个时候可以重写Adapter的getItemPostion方法,让其返回POSITION_NONE(该方法默认放回UNCHANGED,但这个时候需要自己解决显示View列表的缓存问题
如果不解决,那么ViewPager中的View就会越来越多