<com.example.jinxiong.scrollandtransition.TestViewGroup
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="500dp"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:background="@android:color/darker_gray"
android:orientation="vertical"
tools:context="com.example.jinxiong.scrollandtransition.MainActivity">
<com.example.jinxiong.scrollandtransition.TestView
android:layout_width="50dp"
android:layout_height="50dp"
android:id="@+id/testView"
android:background="@android:color/holo_red_dark"
/>
</com.example.jinxiong.scrollandtransition.TestViewGroup>
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final View viewGroup = this.findViewById(R.id.activity_main);
final View view = this.findViewById(R.id.testView);
viewGroup.setWillNotDraw(false);
view.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
view.setTranslationY(view.getTranslationY() + 20);
}
});
viewGroup.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
viewGroup.scrollBy(0, -500);
if (viewGroup.getScrollY() < -1500) {
viewGroup.scrollTo(0, 0);
}
}
});
}
TestView只是单纯的继承View 并没有做什么,只是在onMeasure onLayout onDraw中Log ,TestViewGroup 继承linearLayout 也只是在上面三个方法中Log,但是Log
的 结果不是很理解,当我testViewGroup.scrollBy的时候,只是调用了TestViewGroup的onDraw 而当我的testView.setTransation 的时候有时候基本什么都打印不出来
,有没有人了解这个啊,求解
看源代码就会清晰了,我知道你懒得看,我直接贴上来
public void scrollBy(int x, int y) {
scrollTo(mScrollX + x, mScrollY + y);
}
所以ScrollBy其实就是调用ScrollTo,再往下看
public void scrollTo(int x, int y) {
if (mScrollX != x || mScrollY != y) {
int oldX = mScrollX;
int oldY = mScrollY;
mScrollX = x;
mScrollY = y;
invalidateParentCaches();
onScrollChanged(mScrollX, mScrollY, oldX, oldY);
if (!awakenScrollBars()) {
postInvalidateOnAnimation();
}
}
}
这一段代码的意思就是,判断入参是否和当前所在位置不同,如果不同则滚动,那哪一行代码是让View滚动的呢,就是postInvalidateOnAnimation(),当然继续看里面的代码
public void postInvalidateOnAnimation() {
// We try only with the AttachInfo because there's no point in invalidating
// if we are not attached to our window
final AttachInfo attachInfo = mAttachInfo;
if (attachInfo != null) {
attachInfo.mViewRootImpl.dispatchInvalidateOnAnimation(this);
}
}
这一段代码其实很好读懂,就是如果你的界面还没有和Activity相关联,则不会分发移动效果,这就是为什么不走onLayout呢,因为他根本不是将view放置到另一个位置,而是采取动画的形式将View移动到所指定的位置,如果你再往代码内部看,就会知道其实里面有一个runnable接口会被调用,里面才是真正操作动画的代码,逻辑比较复杂你就自己看吧