代码之家  ›  专栏  ›  技术社区  ›  Riddhi

如何设置imageview的动画,使其向上移动到另一个视图,然后再次返回到原始位置

  •  -1
  • Riddhi  · 技术社区  · 6 年前

    我想动画一个图像视图的方式,它开始从它的初始位置移动到一个按钮(向上移动图像视图),然后再次回到它的初始位置,这将无限重复。我对动画很陌生,所以请指导我怎么做?

    我的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 .但没用。

    2 回复  |  直到 6 年前
        1
  •  0
  •   Riddhi    6 年前

    最后,我找到了我的答案,所有的评论和链接提供了帮助。我不知道这是否是理想的解决方案,但它正在发挥作用。如果有人有更好的解决方案,请提供。

    我做了什么来得到按钮的位置(在解之前是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();
    }
    

    一次又一次 动画结束() ,我添加了动画以将图像移向按钮。这样,动画将一个接一个地继续。

        2
  •  -1
  •   Shubham Vala    6 年前

    试试这个:

    ObjectAnimator slideUp = ObjectAnimator.ofFloat(mImageView,"translationY",-btn_scratch_now.getTop());
        slideUp.setRepeatMode(ObjectAnimator.RESTART);
        slideUp.setRepeatCount(ObjectAnimator.INFINITE);
        slideUp.start();