在android开发中,
View
的滑动效果基本上处处可见。所以如果我们想自定义一些炫目的动画效果,熟练掌握View
的滑动方式必不可少。
首先我们要明白一点,scrollTo
、scrollBy
移动的是View
的内容,如果是ViewGroup
,移动的则是ViewGroup
里面的子View
,如果是View
,移动的则是View
里面的内容,比如TextView
调用scrollTo
、scrollBy
,移动的则是TextView
的文本内容。
然后从移动效果来看,我们可以发现scrollTo
移动是以View的初始坐标为基准,而scrollBy
则是以View的当前坐标为基准进行移动。
其实细心的同学会发现,我们调用scrollTo(100,0)
,scrollBy(200,0)
,结果文本沿X轴负方向移动,与我们预想的沿X轴正方向移动恰好相反。我们可以从源码中看出一些端倪:
public void scrollBy(int x, int y) {
scrollTo(mScrollX + x, mScrollY + y);
}
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();
}
}
}
public void invalidate(int l, int t, int r, int b) {
final int scrollX = mScrollX;
final int scrollY = mScrollY;
invalidateInternal(l - scrollX, t - scrollY, r - scrollX, b - scrollY, true, false);
}
从源码中可以看出,scrollBy
其实调用的还是scrollTo
,而invalidateInternal(l - scrollX, t - scrollY, r - scrollX, b - scrollY, true, false)
也解释了我们上面的疑问,为什么scrollTo
、scrollBy
方法中传入的参数是正值,结果实际却沿反方向移动。
mTvScroll.startAnimation(AnimationUtils.loadAnimation(ScrollToDemoActivity.this,R.anim.test_anim));
使用动画实现250ms内沿X轴平移100,
"http://schemas.android.com/apk/res/android"
android:fillAfter="true">
"0"
android:fromYDelta="0"
android:toXDelta="100"
android:toYDelta="0"
android:duration="250"
>
从效果图中可以看出,使用动画来实现,只是移动了View的位置,实际上的点击事件仍旧在初始位置才会响应。
在android3.0版本以后我们可以使用属性动画来实现滑动,在后面我们会专门来介绍使用属性动画实现View的弹性滑动。
修改布局参数,说白了就是修改layoutparams里面的参数,比如我们要往左偏移100,则设置leftMargin+100即可。
ViewGroup.MarginLayoutParams marginLayoutParams = (ViewGroup.MarginLayoutParams) mTvScroll.getLayoutParams();
marginLayoutParams.leftMargin+=100;
mTvScroll.setLayoutParams(marginLayoutParams);
最后我们来对比下三种滑动方式各自的优缺点。
滑动实现方法 | 操作难度 | 适用范围 |
---|---|---|
scrollTo、scrollBy | 容易 | 只能移动view的内容 |
使用动画 | 容易 | 可以实现复杂的动画效果,但不适合有交互需求 |
修改布局参数 | 复杂 | 适合有交互需求 |