简体   繁体   中英

Move a view by translate animation Android

I am trying to move a view on the screen to a random point by clicking it, then have it stay there and move again by click, however, the view only does the correct movement when starting at 0,0 coordinates, once changed, it is animating from random position to random position and finishing on a third random position.

here is my snippet, can some one please run this and see if it works properly? and if not, what am i missing?

public class MainActivity extends ActionBarActivity {

ImageView image;
Rect rect;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    DisplayMetrics displaymetrics = new DisplayMetrics();
    getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
    final int height = displaymetrics.heightPixels;
    final int width = displaymetrics.widthPixels;

    image = (ImageView) findViewById(R.id.image);

    findViewById(R.id.image).setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            final int newLeft = ((int)Math.round(Math.random()*width))/2;
            final int newTop = ((int)Math.round(Math.random()*height))/2;;
            final int newRight = ((int)Math.round(Math.random()*width))/2;;
            final int newBottom = ((int)Math.round(Math.random()*height))/2;;
            rect = new Rect(newLeft, newTop, newRight, newBottom);

           doSomeAnimation(rect);

        }
    });
}

 public void doSomeAnimation(final Rect rect) {
    final FrameLayout.LayoutParams imageParasms = (FrameLayout.LayoutParams) image.getLayoutParams();


    TranslateAnimation animation = new TranslateAnimation(
            imageParasms.leftMargin, rect.left, imageParasms.topMargin, rect.top);



    animation.setDuration(1000);

    animation.setAnimationListener(new Animation.AnimationListener() {
        @Override
        public void onAnimationStart(Animation animation) {

       }

        @Override
        public void onAnimationEnd(Animation animation) {


            FrameLayout.LayoutParams imageParasms = (FrameLayout.LayoutParams) image.getLayoutParams();
            imageParasms.width = rect.width();
            imageParasms.height = rect.height();

            imageParasms.leftMargin = rect.left;
            imageParasms.topMargin = rect.top;

            image.setLayoutParams(imageParasms);

            image.requestLayout();

             }

        @Override
        public void onAnimationRepeat(Animation animation) {

        }
    });

    image.startAnimation(animation);
}

It's better to use ValueAnimator, because TranslateAnimation uses matrix, and its very hard do deal with previous matrix values, I look source codes and understand that its better to use ValueAnimator, becauses have more control on how values are changing, I implemented it in different way, check this

public class MainActivity extends FragmentActivity {
ImageView image;
Random rnd = new Random();
int leftMargin;
int topMargin;
boolean xRunning;
boolean yRunning;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    DisplayMetrics displaymetrics = new DisplayMetrics();
    getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
    final int height = displaymetrics.heightPixels;
    final int width = displaymetrics.widthPixels;

    image = (ImageView) findViewById(R.id.image);

    findViewById(R.id.image).setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            int newLeft = rnd.nextInt(height);
            int newTop = rnd.nextInt(width);
            Point pt = new Point(newLeft, newTop);
            doSomeAnimation(pt);
        }
    });

    //This Handler is used for optimization, for setting a layout in one place, instead of calling
    //it in every onAnimationUpdate method
    image.post(new Runnable() {
        @Override
        public void run() {
            if(xRunning && yRunning) {
                FrameLayout.LayoutParams params = (FrameLayout.LayoutParams) image.getLayoutParams();
                params.leftMargin = leftMargin;
                params.topMargin = topMargin;
                image.setLayoutParams(params);
            }
            image.postDelayed(this, 30);
        }
    });
}

public void doSomeAnimation(final Point pt) {
    FrameLayout.LayoutParams params = (FrameLayout.LayoutParams) image.getLayoutParams();

    ValueAnimator xAnim = ValueAnimator.ofFloat(pxFromDp(this, params.leftMargin), pt.x);
    xAnim.setDuration(1000);

    xAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
        @Override
        public void onAnimationUpdate(ValueAnimator animation) {
            leftMargin = (int) dpFromPx(MainActivity.this, (float) animation.getAnimatedValue());
        }
    });

    xAnim.addListener(new Animator.AnimatorListener() {
        @Override
        public void onAnimationStart(Animator animation) {

        }

        @Override
        public void onAnimationEnd(Animator animation) {
            xRunning = false;
        }

        @Override
        public void onAnimationCancel(Animator animation) {

        }

        @Override
        public void onAnimationRepeat(Animator animation) {

        }
    });

    xAnim.start();
    xRunning = true;

    ValueAnimator yAnim = ValueAnimator.ofFloat(pxFromDp(this, params.topMargin), pt.y);
    yAnim.setDuration(1000);

    yAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
        @Override
        public void onAnimationUpdate(ValueAnimator animation) {
            topMargin = (int) dpFromPx(MainActivity.this, (float) animation.getAnimatedValue());
        }
    });

    yAnim.addListener(new Animator.AnimatorListener() {
        @Override
        public void onAnimationStart(Animator animation) {

        }

        @Override
        public void onAnimationEnd(Animator animation) {
            yRunning = false;
        }

        @Override
        public void onAnimationCancel(Animator animation) {

        }

        @Override
        public void onAnimationRepeat(Animator animation) {

        }
    });

    yAnim.start();
    yRunning = true;
}

public static float dpFromPx(final Context context, final float px) {
    return px / context.getResources().getDisplayMetrics().density;
}

public static float pxFromDp(final Context context, final float dp) {
    return dp * context.getResources().getDisplayMetrics().density;
}

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM