开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第8天,点击查看活动详情
dispatchDraw
- 第一段
final int childrenCount = mChildrenCount;
final View[] children = mChildren;
int flags = mGroupFlags;
首先初始化一些局部变量
-
那mChildrenCount在哪里赋值的呢。我们在ViewGroup里面搜索后发现是在addInArray执行了加1操作。addInArray的执行是由于addView的执行。 那谁调用了addView呢?只能用debug看一下mChildrenCount表示子view个数
看了debug知道是由于inflate的执行调用的addView。而view也正是在inflate中创建的。(inflate会先创建根view,然后再创建子类view,这样一个layout就会inflate完毕)
-
mChildren数组也是在addview过程赋值的
扩容规则:mChildren数组如果满了,就会在当前大小基础上再增加12个大小。
-
mGroupFlags
viewGroup的内部标志值,viewgroup在创建时会有一些默认值
initViewGroup会在构造函数里面调用。
private void initViewGroup() {
if (!isShowingLayoutBounds())
{
setFlags(WILL_NOT_DRAW, DRAW_MASK);
}
mGroupFlags |= FLAG_CLIP_CHILDREN;
mGroupFlags |= FLAG_CLIP_TO_PADDING;
mGroupFlags |= FLAG_ANIMATION_DONE;
mGroupFlags |= FLAG_ANIMATION_CACHE;
mGroupFlags |= FLAG_ALWAYS_DRAWN_WITH_CACHE;
if (mContext.getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.HONEYCOMB)
{
mGroupFlags |= FLAG_SPLIT_MOTION_EVENTS;
}
setDescendantFocusability(FOCUS_BEFORE_DESCENDANTS);
mChildren = new View[ARRAY_INITIAL_CAPACITY]; //ARRAY_INITIAL_CAPACITY=12
mChildrenCount = 0;
mPersistentDrawingCache = PERSISTENT_SCROLLING_CACHE;
}
- 第二段
//运行布局动画
//FLAG_RUN_ANIMATION运行布局动画的flag
if ((flags & FLAG_RUN_ANIMATION) != 0 && canAnimate()) {
for (int i = 0; i < childrenCount; i++) {
final View child = children[i];
if ((child.mViewFlags & VISIBILITY_MASK) == VISIBLE) {
final LayoutParams params = child.getLayoutParams();
attachLayoutAnimationParameters(child, params, i, childrenCount);
bindLayoutAnimation(child);
}
}
final LayoutAnimationController controller = mLayoutAnimationController;
if (controller.willOverlap()) {
mGroupFlags |= FLAG_OPTIMIZE_INVALIDATE;
}
controller.start();
mGroupFlags &= ~FLAG_RUN_ANIMATION;
mGroupFlags &= ~FLAG_ANIMATION_DONE;
if (mAnimationListener != null) {
mAnimationListener.onAnimationStart(controller.getAnimation());
}
- 在哪里设置的FLAG_RUN_ANIMATION?
startLayoutAnimation()//如果存在LayoutAnimationController则设置FLAG_RUN_ANIMATION,并执行requestLayout()重新布局
scheduleLayoutAnimation()//只是简单的将flags设置为FLAG_RUN_ANIMATION
setLayoutAnimation(LayoutAnimationController)//设置LayoutAnimationController,如果设置成功即不为null,则设置FLAG_RUN_ANIMATION
- canAnimate()的作用是什么?
//指示视图组是否能够在第一个布局后为其子项设置动画,也就是判断该动画能否启动
protected boolean canAnimate() {
return mLayoutAnimationController != null;
}
-
判断了半天,什么动画?
就是viewGroup中子view出现的动画,可以为每一个view设置动画的延时事件。可重写 LayoutAnimationController中的getAnimationForView为不同view设置不同的动画效果,不重写的话就用统一的动画,只是动画的开始时间不同。
-
最后一个是动画监听器
可以通过这个函数设置setLayoutAnimationListener(Animation.AnimationListener animationListener)