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,ScrollViewEXACTLY:确切的大小,如:100dp或者march_parentAT_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就会越来越多