创建侦听器以移动 ImageView
Creating listener to move ImageView
如何为 x
和 y
坐标创建侦听器并在屏幕上连续移动 ImageView
对象?
我有 ImageView jajko
对象和一个发布 x
和 y
变量的线程。我希望我的应用程序将 jajko
从旧位置移动到 x
和 y
描述的新位置。
我可以通过一些 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);
其中 newX
和 newY
是以像素为单位描述的所需位置的坐标。
如何为 x
和 y
坐标创建侦听器并在屏幕上连续移动 ImageView
对象?
我有 ImageView jajko
对象和一个发布 x
和 y
变量的线程。我希望我的应用程序将 jajko
从旧位置移动到 x
和 y
描述的新位置。
我可以通过一些 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);
其中 newX
和 newY
是以像素为单位描述的所需位置的坐标。