本文,一是为记录,二是帮助他人。若有错误之处,麻烦指出。  (文末附上简单demo下载)                                            --箫洛

移动控件的三种方式:

1.改变布局参数

 RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) mGirl.getLayoutParams();
                layoutParams.leftMargin = mGirl.getLeft()+100;
                layoutParams.topMargin = mGirl.getTop()+100;
                mGirl.setLayoutParams(layoutParams);

得到控件的布局参数,然后改变左上的位置,达到改变控件位置效果,这里也可以设置宽高达到改变大小的效果。

2.动画效果实现

动画实现又分为两种,一种是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的布局参数。

属性动画实质上也是利用改变控件的布局参数来达到动画效果,也由于改变的是布局参数,所以改变了实际位置。

3.Scroll实现

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下载

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐