如何将图像视图动画化到另一个视图并再次回到原始位置
How to animate an imageview up to the another view and again back to original position
我想以这样一种方式为 ImageView 设置动画,即它开始从初始位置移动到按钮(将 ImageView 向上移动)并再次回到其初始位置并无限重复。我对制作动画完全陌生,所以请指导我如何做?
我的layout.xml如下:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout 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"
xmlns:app="http://schemas.android.com/apk/res-auto"
tools:context=".fragment.Scratch1Fragment">
<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="@+id/btn_scratch_now"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="@style/buttonStyle"
android:text="@string/str_scratch_now"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintVertical_bias="0.2"/>
<View
android:id="@+id/upper_bound"
android:layout_width="match_parent"
android:layout_height="2dp"
android:background="@color/primary"
android:layout_marginEnd="10dp"
android:layout_marginStart="10dp"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintVertical_bias="0.5"/>
<TextView
android:id="@+id/text_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/str_scratch"
style="@style/tvDarkLargeStyle"
android:gravity="center"
android:textAlignment="center"
app:layout_constraintTop_toBottomOf="@+id/upper_bound"
/>
<View
android:id="@+id/lower_bound"
android:layout_width="match_parent"
android:layout_height="2dp"
android:background="@color/primary"
android:layout_marginEnd="10dp"
android:layout_marginStart="10dp"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toBottomOf="@+id/text_view"
/>
<TextView
android:id="@+id/tv_tap_here"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toBottomOf="@id/lower_bound"
android:layout_margin="20dp"
android:padding="10dp"
android:gravity="center"
style="@style/tvLightLargeStyle"
android:textAlignment="center"
android:text="Tap here"/>
<ImageView
android:id="@+id/img_hand"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/clicker_hand_64"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintBottom_toBottomOf="@+id/upper_bound"/>
</android.support.constraint.ConstraintLayout>
</FrameLayout>
如果我的问题听起来不清楚,请随时询问更多代码或更多细节。
更新
在开始获取一些资源后,我尝试了一下,发现了以下代码。但不知何故我无法获得按钮浮动的位置(它总是返回 0。)
我的代码如下:
private void animate() {
Log.e("button top", String.valueOf(btnScratch.getTop()));
int location[] = new int[2];
btnScratch.getLocationOnScreen(location);
Log.e("button location x and y",location[0]+" "+location[1]);
int location2[] = new int[2];
imgHand.getLocationOnScreen(location2);
Log.e("image location x and y",location2[0]+" "+location2[1]);
ValueAnimator valueAnimator = ValueAnimator.ofFloat(0f, btnScratch.getTop());
valueAnimator.setInterpolator(new AccelerateDecelerateInterpolator()); // increase the speed first and then decrease
valueAnimator.setDuration(1000);
valueAnimator.setRepeatCount(ValueAnimator.INFINITE);
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
float progress = (float) animation.getAnimatedValue();
imgHand.setTranslationY(progress);
// no need to use invalidate() as it is already present in //the text view.
}
});
valueAnimator.start();
}
我也尝试过使用 ObjectAnimatior
而不是 ValueAnimator
。但是没用。
试试这个:
ObjectAnimator slideUp = ObjectAnimator.ofFloat(mImageView,"translationY",-btn_scratch_now.getTop());
slideUp.setRepeatMode(ObjectAnimator.RESTART);
slideUp.setRepeatCount(ObjectAnimator.INFINITE);
slideUp.start();
最后,借助其中提供的所有评论和链接,我找到了答案。我不知道这是否是理想的解决方案,但它确实有效。如果有人有更好的解决方案,请提供。
我为获取按钮的位置所做的(在解决方案之前为 0)。
btnScratch.post(new Runnable() {
@Override
public void run() {
float center = (btnScratch.getTop() + btnScratch.getBottom()) / 2;
Log.e("center point", String.valueOf(center));
animateUpToButton(center - imgHand.getTop());
}
});
为了获得按钮的中心,我使用了以下行:
float center = (btnScratch.getTop() + btnScratch.getBottom()) / 2;
和动画:
private void animateUpToButton(final float distance) {
ObjectAnimator imageAnimator = ObjectAnimator.ofFloat(imgHand, "translationY", 0f, distance);
imageAnimator.setDuration(ANIM_DURATION);
imageAnimator.setInterpolator(new AccelerateDecelerateInterpolator());
imageAnimator.addListener(new Animator.AnimatorListener() {
@Override
public void onAnimationStart(Animator animator) {
}
@Override
public void onAnimationEnd(Animator animator) {
animateBackToOrigin(distance);
}
@Override
public void onAnimationCancel(Animator animator) {
}
@Override
public void onAnimationRepeat(Animator animator) {
}
});
imageAnimator.start();
}
并且,onAnimationEnd()
,我添加了另一个动画来让图像回到初始位置。
private void animateBackToOrigin(final float distance) {
ObjectAnimator imageAnimator = ObjectAnimator.ofFloat(imgHand, "translationY", distance, 0f);
imageAnimator.setDuration(ANIM_DURATION);
imageAnimator.setInterpolator(new LinearInterpolator());
imageAnimator.addListener(new Animator.AnimatorListener() {
@Override
public void onAnimationStart(Animator animator) {
}
@Override
public void onAnimationEnd(Animator animator) {
animateUpToButton(distance);
}
@Override
public void onAnimationCancel(Animator animator) {
}
@Override
public void onAnimationRepeat(Animator animator) {
}
});
imageAnimator.start();
}
又一次 onAnimationEnd()
,我添加了动画以将图像移向按钮。这样一来,动画就会一个接一个地继续。
我想以这样一种方式为 ImageView 设置动画,即它开始从初始位置移动到按钮(将 ImageView 向上移动)并再次回到其初始位置并无限重复。我对制作动画完全陌生,所以请指导我如何做?
我的layout.xml如下:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout 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"
xmlns:app="http://schemas.android.com/apk/res-auto"
tools:context=".fragment.Scratch1Fragment">
<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="@+id/btn_scratch_now"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="@style/buttonStyle"
android:text="@string/str_scratch_now"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintVertical_bias="0.2"/>
<View
android:id="@+id/upper_bound"
android:layout_width="match_parent"
android:layout_height="2dp"
android:background="@color/primary"
android:layout_marginEnd="10dp"
android:layout_marginStart="10dp"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintVertical_bias="0.5"/>
<TextView
android:id="@+id/text_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/str_scratch"
style="@style/tvDarkLargeStyle"
android:gravity="center"
android:textAlignment="center"
app:layout_constraintTop_toBottomOf="@+id/upper_bound"
/>
<View
android:id="@+id/lower_bound"
android:layout_width="match_parent"
android:layout_height="2dp"
android:background="@color/primary"
android:layout_marginEnd="10dp"
android:layout_marginStart="10dp"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toBottomOf="@+id/text_view"
/>
<TextView
android:id="@+id/tv_tap_here"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toBottomOf="@id/lower_bound"
android:layout_margin="20dp"
android:padding="10dp"
android:gravity="center"
style="@style/tvLightLargeStyle"
android:textAlignment="center"
android:text="Tap here"/>
<ImageView
android:id="@+id/img_hand"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/clicker_hand_64"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintBottom_toBottomOf="@+id/upper_bound"/>
</android.support.constraint.ConstraintLayout>
</FrameLayout>
如果我的问题听起来不清楚,请随时询问更多代码或更多细节。
更新
在开始获取一些资源后,我尝试了一下,发现了以下代码。但不知何故我无法获得按钮浮动的位置(它总是返回 0。)
我的代码如下:
private void animate() {
Log.e("button top", String.valueOf(btnScratch.getTop()));
int location[] = new int[2];
btnScratch.getLocationOnScreen(location);
Log.e("button location x and y",location[0]+" "+location[1]);
int location2[] = new int[2];
imgHand.getLocationOnScreen(location2);
Log.e("image location x and y",location2[0]+" "+location2[1]);
ValueAnimator valueAnimator = ValueAnimator.ofFloat(0f, btnScratch.getTop());
valueAnimator.setInterpolator(new AccelerateDecelerateInterpolator()); // increase the speed first and then decrease
valueAnimator.setDuration(1000);
valueAnimator.setRepeatCount(ValueAnimator.INFINITE);
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
float progress = (float) animation.getAnimatedValue();
imgHand.setTranslationY(progress);
// no need to use invalidate() as it is already present in //the text view.
}
});
valueAnimator.start();
}
我也尝试过使用 ObjectAnimatior
而不是 ValueAnimator
。但是没用。
试试这个:
ObjectAnimator slideUp = ObjectAnimator.ofFloat(mImageView,"translationY",-btn_scratch_now.getTop());
slideUp.setRepeatMode(ObjectAnimator.RESTART);
slideUp.setRepeatCount(ObjectAnimator.INFINITE);
slideUp.start();
最后,借助其中提供的所有评论和链接,我找到了答案。我不知道这是否是理想的解决方案,但它确实有效。如果有人有更好的解决方案,请提供。
我为获取按钮的位置所做的(在解决方案之前为 0)。
btnScratch.post(new Runnable() {
@Override
public void run() {
float center = (btnScratch.getTop() + btnScratch.getBottom()) / 2;
Log.e("center point", String.valueOf(center));
animateUpToButton(center - imgHand.getTop());
}
});
为了获得按钮的中心,我使用了以下行:
float center = (btnScratch.getTop() + btnScratch.getBottom()) / 2;
和动画:
private void animateUpToButton(final float distance) {
ObjectAnimator imageAnimator = ObjectAnimator.ofFloat(imgHand, "translationY", 0f, distance);
imageAnimator.setDuration(ANIM_DURATION);
imageAnimator.setInterpolator(new AccelerateDecelerateInterpolator());
imageAnimator.addListener(new Animator.AnimatorListener() {
@Override
public void onAnimationStart(Animator animator) {
}
@Override
public void onAnimationEnd(Animator animator) {
animateBackToOrigin(distance);
}
@Override
public void onAnimationCancel(Animator animator) {
}
@Override
public void onAnimationRepeat(Animator animator) {
}
});
imageAnimator.start();
}
并且,onAnimationEnd()
,我添加了另一个动画来让图像回到初始位置。
private void animateBackToOrigin(final float distance) {
ObjectAnimator imageAnimator = ObjectAnimator.ofFloat(imgHand, "translationY", distance, 0f);
imageAnimator.setDuration(ANIM_DURATION);
imageAnimator.setInterpolator(new LinearInterpolator());
imageAnimator.addListener(new Animator.AnimatorListener() {
@Override
public void onAnimationStart(Animator animator) {
}
@Override
public void onAnimationEnd(Animator animator) {
animateUpToButton(distance);
}
@Override
public void onAnimationCancel(Animator animator) {
}
@Override
public void onAnimationRepeat(Animator animator) {
}
});
imageAnimator.start();
}
又一次 onAnimationEnd()
,我添加了动画以将图像移向按钮。这样一来,动画就会一个接一个地继续。