View 的滑动
主要有三种方式:View本身的srollTo/srollBy,通过动画,通过改变View的LayoutParams重新布局。
1.使用srollTo/srollBy
/**
* Set the scrolled position of your view. This will cause a call to
* {@link #onScrollChanged(int, int, int, int)} and the view will be
* invalidated.
* @param x the x position to scroll to
* @param y the y position to scroll to
*/
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();
}
}
}
/**
* Move the scrolled position of your view. This will cause a call to
* {@link #onScrollChanged(int, int, int, int)} and the view will be
* invalidated.
* @param x the amount of pixels to scroll by horizontally
* @param y the amount of pixels to scroll by vertically
*/
public void scrollBy(int x, int y) {
scrollTo(mScrollX + x, mScrollY + y);
}
源码上srollBy也是调用scrollTo方法,scrollTo实现基于参数的绝对滑动,需要注意scrollX的值总是等于View的边缘和View的内容的水平距离,scrollY也是同理,区分正负值,需要理解View的坐标体系,屏幕左上角是(0,0)。
2 使用动画
View动画主要是改变view的translationX和translatioY属性,
<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="1000"
android:fromYDelta="0%p"
android:interpolator="@android:anim/accelerate_interpolator"
android:toYDelta="-100%p" />
android:interpolator: 加速器,非常有用的属性,可以简单理解为动画的速度,可以是越来越快,也可以是越来越慢,或者是先快后忙,或者是均匀的速度等等,对于值如下:
@android:anim/accelerate_interpolator: 越来越快
@android:anim/decelerate_interpolator:越来越慢
@android:anim/accelerate_decelerate_interpolator:先快后慢
@android:anim/anticipate_interpolator: 先后退一小步然后向前加速
@android:anim/overshoot_interpolator:快速到达终点超出一小步然后回到终点
@android:anim/anticipate_overshoot_interpolator:到达终点超出一小步然后回到终点
@android:anim/bounce_interpolator:到达终点产生弹球效果,弹几下回到终点
@android:anim/linear_interpolator:均匀速度。
属性动画更简单(布局,属性,开始值,结束值),持续时间,开始
ObjectAnimator.ofFloat(getRootView(),"translationX",0,100).setDuration(100).start();
例二:
ValueAnimator animator = ValueAnimator.ofFloat(m.progress, progress);
animator.addUpdateListener(animation -> {
float animatedValue = (float) animation.getAnimatedValue();
setProgress(animatedValue);
});
animator.setInterpolator(new OvershootInterpolator());
animator.setDuration(animTime);
animator.start();
View动画的主要问题是不会改变控件真正的位置,点击事件响应还在原来位置。
3 改变布局参数
改变LayoutParams参数,思路上就是增大间距,或者增加空的VIEW在中间,改变这个view的大小打到平移的效果
public void setWidth(int width) {
view.getLayoutParams().width = width;
view.requestLayout();
}
这个是比较灵活的方法,在系统WindowsManager里面,提供就是改变布局参数实现布局动画
三种方式对比
srollTo/srollBy:操作简单,适合对View内容的滑动
动画:操作简单,主要适合没有交互的View和实现复杂的动画效果
改变布局参数:操作稍微复杂,适用于有交互的View