关于使用属性动画来动态改变控件的布局位置

  • 属性动画大家用的都很多了,这里就直接重点说一下自己所用到的知识,希望对你们有点用
  • 本文主要说的是关于如何在代码中用属性动画去动态更改控件在布局中的位置
    • 因为我们的项目不能用xml,而且有的控件是不间断的要换位置….(奇葩啊..),所有才用了属性动画
    • 本文仅作为参考

  • 首先是属性动画的简单使用
    • 将button 变大为原来的5倍,但是只能变大,缩小,或者平移等才能到我们想要的位置
 AnimatorSet set = new AnimatorSet();
        set.playTogether(
                ObjectAnimator.ofFloat(mButton , "scaleX" , 1f , 5f ),
                ObjectAnimator.ofFloat(mButton , "scaleY" , 1f , 5f )

        );
        set.setDuration(2000).start();

  • 这里有任大神的博客

    • 点这里
  • 针对上述问题,Google告诉我们有3中解决方法:

    • 给你的对象加上get和set方法,如果你有权限的话
    • 用一个类来包装原始对象,间接为其提供get和set方法
    • 采用ValueAnimator,监听动画过程,自己实现属性的改变
  • 这里直接使用第二种方法(根据任玉刚大神来扩展的0.0)

    • 既然可以使用ViewWrapper间接提供get 和 set 方法,那么就可以提供更多别的方法!比如getLeftMargin 、setLeftMargin,有了边距就可以直接设置控件在布局中的位置了
  • 这里是ViewWrapper的代码, 里面也有点小瑕疵

public class ViewWrapper {
    private View mTarget ;

    //这里的params必须是传入控件的父布局的params!!
    // 当然也可以直接在构造函数中传入params, 这样会保险点 , 不过params需要有下面的mParams.leftMargin 。。等对应方法!!
    private RelativeLayout.LayoutParams mParams ; 

    private int mLeftMargin ;

    public ViewWrapper(View target) {
        mTarget = target;
        mParams = (RelativeLayout.LayoutParams) mTarget.getLayoutParams();
    }
    //对应的宽高
    public int getWidth(){
        return mTarget.getLayoutParams().width;
    }
    public int getHeight(){
        return mTarget.getLayoutParams().height;
    }
    public void setWidth(int width){
        mTarget.getLayoutParams().width = width ;
        mTarget.requestLayout();
    }
    public void setHeight(int height){
        mTarget.getLayoutParams().height = height ;
        mTarget.requestLayout();
    }

    //对应的左上边距
    public int getLeftMargin(){
        return mParams.leftMargin ;
    }
    //这个先获取左边距 ,不需要设置 
    public void setLeftMargin(int leftMargin ){
       mLeftMargin = leftMargin;
    }

    public int getTopMargin(){
        return mParams.topMargin ;
    }
    //这里讲  左   和  上   一起进行设置 。对应的在设置动画的时候,要吧这个放到最后才会生效!!
    public void setTopMargin(int topMargin){
        mParams.setMargins( mLeftMargin  , topMargin  , 0 , 0 );
        mTarget.setLayoutParams(mParams);
        mTarget.requestLayout();
    }
}
  • 然后就是在用的地方使用了
 mButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mButton.post(new Runnable() {
                    @Override
                    public void run() {
                        mWidth = mButton.getWidth();
                        mHeight = mButton.getHeight();
                        changeBigSmall(mButton);
                    }
                });

            }
        });

//这里说明几点注意事项
// ObjectAnimator.ofInt(wrapper, "width", mWidth , mWidth + 60 ),这里第二个参数说明!是你在viewWrap中去掉get 、 set 后面的字符串!(大小写随便写,不用在意)
   private void changeBigSmall(View view) {
        if (view == null) return;

        RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) view.getLayoutParams();
        int leftMargin = params.leftMargin;
        int topMargin = params.topMargin;

        AnimatorSet set = new AnimatorSet();
        ViewWrapper wrapper = new ViewWrapper(view);
        set.playTogether(
                ObjectAnimator.ofInt(wrapper, "width", mWidth , mWidth + 60 ),
                ObjectAnimator.ofInt(wrapper, "height", mHeight , mHeight + 60),
                ObjectAnimator.ofInt(wrapper, "leftMargin", leftMargin , leftMargin + 50 ),
                ObjectAnimator.ofInt(wrapper, "topMargin", topMargin , topMargin + 50)//记得这个最后写,因为上面的viewWrap到这个才被设置
        );
        set.setDuration(2000).start();

    }
  • 这里只提供了一个小的思路,并不一定完善,大家也可以直接来个mParams.setMargins( aaa, bbb, ccc, ddd) 直接设置位置
  • 当然一般情况下,大家不需要直接用属性动画的!!!直接用父布局的mParams.setMargins( aaa, bbb, ccc, ddd)就行了,哪来的那么麻烦….(需求奇葩而已,才用属性动画…)

你可能感兴趣的:(动画)