创建侦听器以移动 ImageView

Creating listener to move ImageView

如何为 xy 坐标创建侦听器并在屏幕上连续移动 ImageView 对象?

我有 ImageView jajko 对象和一个发布 xy 变量的线程。我希望我的应用程序将 jajko 从旧位置移动到 xy 描述的新位置。

我可以通过一些 UI 交互(即 onTouch 侦听器)来实现这一点,但我不知道如何连续进行。

不需要线程,使用ValueAnimators,图像从一个点随机移动到另一个点。

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity">

<ImageView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:id="@+id/image"
    android:src="@drawable/ic_launcher"/>

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

int height;
int width;

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

    DisplayMetrics displaymetrics = new DisplayMetrics();
    getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);

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

    findViewById(R.id.rootLayout).addOnLayoutChangeListener(new View.OnLayoutChangeListener() {
        @Override
        public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) {
            if(width == 0 || height == 0) {
                width = right - left;
                height = bottom - top;
                moveImage();
            }
        }
    });

    //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) {
                RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) image.getLayoutParams();
                params.leftMargin = leftMargin;
                params.topMargin = topMargin;
                image.setLayoutParams(params);
            }
            else if(!xRunning && !yRunning) {
                moveImage();
            }
            image.postDelayed(this, 30);
        }
    });
}

private void moveImage() {
    int newLeft = rnd.nextInt(width - image.getWidth());
    int newTop = rnd.nextInt(height - image.getHeight());
    Point pt = new Point(newLeft, newTop);
    doSomeAnimation(pt);
}

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

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

    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(3000);

    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;
}

}

为了解决这个问题,我将 ImageView jajko 传递给线程并用这两行处理动画:

jajko.animate().translationX(newX).setDuration(80);
jajko.animate().translationY(newY).setDuration(80);

其中 newXnewY 是以像素为单位描述的所需位置的坐标。