本文,一是为记录,二是帮助他人。若有错误之处,麻烦指出。 (文末附上简单demo下载) --箫洛
移动控件的三种方式:
RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) mGirl.getLayoutParams();
layoutParams.leftMargin = mGirl.getLeft()+100;
layoutParams.topMargin = mGirl.getTop()+100;
mGirl.setLayoutParams(layoutParams);
得到控件的布局参数,然后改变左上的位置,达到改变控件位置效果,这里也可以设置宽高达到改变大小的效果。
动画实现又分为两种,一种是View动画,第二种是属性动画。
两者区别在于View动画只是改变控件里面的内容的位置,实际位置还在原处,属性动画可以通过改变控件的布局参数,实现控件位置真正移动。简单来说就是,View动画移动后的控件显示的位置是不能够响应点击,而属性动画是可以响应点击事件的。
View动画代码块:
TranslateAnimation animation = new TranslateAnimation(0,100,0,100);
animation.setDuration(300);
animation.setFillAfter(true);
mGirl.startAnimation(animation);
这个API有一点值得注意的是,是从距离View原本的位置的多少地方,移动多少距离。如上的(0,100,0,100),因为是第一个参数和第三个参数都是0,所以是从view的原位置,移动到距离View的X,Y都为100的地方。
属性动画代码块:
final int left = mGirl.getLeft();
final int top = mGirl.getTop();
final ValueAnimator animator = ValueAnimator.ofInt(1,100);
animator.setDuration(400);
animator.setInterpolator(new LinearInterpolator());
animator.addUpdateListener(animation1 -> {
int current = (int) animator.getAnimatedValue();
RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) mGirl.getLayoutParams();
layoutParams.leftMargin = left+current;
layoutParams.topMargin = top+current;
mGirl.setLayoutParams(layoutParams);
});
animator.start();
上述代码块值得注意的一点是,父布局什么布局,则取什么样的布局参数。上述取得为RelativeLayout的布局参数。
属性动画实质上也是利用改变控件的布局参数来达到动画效果,也由于改变的是布局参数,所以改变了实际位置。
mGirl.scrollBy(-100,-100);
scroll实现的是控件内容的移动,demo下载如滚动字幕。
scroll常用的两个API为ScrollTo和ScrollBy,ScrollBy的底层实际是用ScrollTo来实现的。在scrollTo的底层实现的是减去输入的X,Y参数,所以要想正向移动需要输入负的参数。
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();
}
}
}
从上述代码块可以看出如果mScrollX和mScrollY均与输入的X,Y相等则无法实现滑动,mScrollX和mScrollY为之前输入的X,Y,所以输入同样的X,Y无法实现第二次滑动。
demo下载