补间动画迁徙后排列五三公,点击事件的反应为什么还在原本的位置?
皇冠客服飞机:@seo3687那今天咱们就来从源码分解旨趣
一、补间动画补间动画不错在一个视图容器内现实一系列浮浅变换(具体的变换要领有:位置、大小、旋转、透明度);
咱们不错通过平移、旋转、缩放、透明度等API进行具体的操作;

补间动画的完了相貌不错通过 XML或通过Android代码两种相貌 去界说;
1、xml相貌完了文献名:animator_translate.xml
官网无法打开最近一场体育比赛,皇冠赔率引起不少关注,赌徒们争相下注。皇冠信用盘口<?xml version="1.0" encoding="utf-8"?> <translate xmlns:android="http://schemas.android.com/apk/res/android" android:fromXDelta="0" android:fromYDelta="0" android:toYDelta="0" android:toXDelta="200" android:duration="500" android:fillAfter="true"> </translate>
皇冠a盘b盘c盘d盘有什么区别
代码加载xml文献获得动画
//加载动画 Animation animation = AnimationUtils.loadAnimation(this, R.anim.animator_translate); //现实动画 testBtn.startAnimation(animation);2、代码相貌完了
TranslateAnimation translateAnimation = new TranslateAnimation(0,200,0,0); translateAnimation.setDuration(500);//动画现及时分 translateAnimation.setFillAfter(true);//动画现实完成后保握现象 //现实动画 testBtn.startAnimation(translateAnimation);二、补间动画原交融
startAnimation(rotateAnimation)设施插足源码;
皇冠比分//View.java public void startAnimation(Animation animation) { animation.setStartTime(Animation.START_ON_FIRST_FRAME); setAnimation(animation); invalidateParentCaches(); invalidate(true); }
最初是通过setStartTime()设立了动画的开动时分;
爱心体育彩票大乐基本透走势图//View.java public void setStartTime(long startTimeMillis) { mStartTime = startTimeMillis; mStarted = mEnded = false; mCycleFlip = false; mRepeated = 0; mMore = true; }
这里只是对一些变量进行赋值,再来望望下一个设施;
设立动画setAnimation(animation):
22-23赛季他在波多黎各联赛的Piratas de Quebradillas队场均拿到22.1分13.4篮板2.6盖帽。
//View.java public void setAnimation(Animation animation) { mCurrentAnimation = animation; if (animation != null) { if (mAttachInfo != null && mAttachInfo.mDisplayState == Display.STATE_OFF && animation.getStartTime() == Animation.START_ON_FIRST_FRAME) { animation.setStartTime(AnimationUtils.currentAnimationTimeMillis()); } animation.reset(); } }
这内部亦然将动画实例赋值给现时的成员变量;
分析startAnimation()设施里的invalidateParentCaches();
//View.java protected void invalidateParentCaches() if (mParent instanceof View) { ((View) mParent).mPrivateFlags |= PFLAG_INVALIDATED; } }
不错看到这里只是是设立动画标志,在视图构建大约属性转换时是必要的;
再回到startAnimation()设施内部invalidate(true);
2、invalidate//View.java public void invalidate(boolean invalidateCache) { invalidateInternal(0, 0, mRight - mLeft, mBottom - mTop, invalidateCache, true); } void invalidateInternal(int l, int t, int r, int b, boolean invalidateCache, boolean fullInvalidate) { if (mGhostView != null) { mGhostView.invalidate(true); return; } ................. // Propagate the damage rectangle to the parent view. final AttachInfo ai = mAttachInfo; final ViewParent p = mParent; if (p != null && ai != null && l < r && t < b) { final Rect damage = ai.mTmpInvalRect; damage.set(l, t, r, b); p.invalidateChild(this, damage); } } }
这里谨防看p.invalidateChild(this, damage);
//ViewGroup.java @Deprecated @Override public final void invalidateChild(View child, final Rect dirty) { final AttachInfo attachInfo = mAttachInfo; if (attachInfo != null && attachInfo.mHardwareAccelerated) { // HW accelerated fast path onDescendantInvalidated(child, child); return; } ViewParent parent = this; ......... do { View view = null; if (parent instanceof View) { view = (View) parent; } ......... parent = parent.invalidateChildInParent(location, dirty); } while (parent != null); } }因为ViewParent p = mParent,this是View的子类ViewGroup; 是以p.invalidateChild(this, damage)内部其实是调用了ViewGroup的invalidateChild(); 这里有一个do{}while()轮回,第一次的时刻parent = this即ViewGroup,然后调用parent.invalidateChildInParent(location, dirty)设施,当parent == null的时刻放胆轮回; invalidateChildInParent设施中,唯有条款诞生就会复返mParent;
//ViewGroup.java @Deprecated @Override public ViewParent invalidateChildInParent(final int[] location, final Rect dirty) { if ((mPrivateFlags & (PFLAG_DRAWN | PFLAG_DRAWING_CACHE_VALID)) != 0) { ....... return mParent; } return null; }((mPrivateFlags & (PFLAG_DRAWN | PFLAG_DRAWING_CACHE_VALID)) != 0)是保握诞生的,是以会一直复返mParent,那么诠释View的mParent是ViewGroup; ViewGroup的mParent亦然ViewGroup,欧博体育代理而do{}while()轮回一直找mParent,而一个View最尖端的mParent是ViewRootImpl,是以终末走到ViewRootImpl的invalidateChildInParent()内部; 在onCreate()设施内部通过setContentView()将布局添加到以DecorView为根布局的一个ViewGroup内部,因为在onResume()现实完成后,WindowManager会现实addView()设施,然后会创建一个ViewRootImpl对象,与DecorView绑定起来,DecorView的mParent设立成ViewRootImpl,ViewRootImpl完了了ViewParent接口,是以ViewRootImpl天然莫得招揽View大约ViewGroup; ViewRootImpl的invalidateChildInParent()设施中;
//ViewRootImpl.java @Override public ViewParent invalidateChildInParent(int[] location, Rect dirty) { checkThread(); if (DEBUG_DRAW) Log.v(mTag, "Invalidate child: " + dirty); if (dirty == null) { invalidate(); return null; } else if (dirty.isEmpty() && !mIsAnimating) { return null; } ....... invalidateRectOnScreen(dirty); return null; }
这里通盘的复返值王人变为null了排列五三公,之前现实的do{}while()循坏也会住手。
皇冠体育hg86a
3、scheduleTraversals() 接着分析invalidateRectOnScreen(dirty)设施; 插足 scheduleTraversals()设施;//ViewRootImpl.java private void invalidateRectOnScreen(Rect dirty) { ...... if (!mWillDrawSoon && (intersected