使用Android Studio创建扫描动画

25

我在我的Android应用程序中遇到了创建扫描动画的问题。例如,我遇到了这个名为“指纹爱情扫描仪恶作剧”的应用程序'(Fingerprint love scanner prank)', 它有一个扫描动画,我想在我的Android应用程序上实现同样的效果。我已经尝试在我的Android应用程序上实现,但是失败了。以下是我的Android代码片段。

Animation.Java Activity

          scan.setOnTouchListener(new View.OnTouchListener() {
                @Override
                public boolean onTouch(View view, MotionEvent motionEvent) {


                    final CountDownTimer start = new CountDownTimer(4000, 1000) {

                        public void onTick(long millisUntilFinished) {
                            scanner.setVisibility(View.VISIBLE);
                            anim1 = AnimationUtils.loadAnimation(getApplicationContext(), R.anim.progress);
                            scanner.startAnimation(anim1);


                        }

                        public void onFinish() {

                            scanner.setVisibility(View.INVISIBLE);

                        }
                    }.start();
                    return false;
                }


            });

动画文件.xml

包含由下面的imageView定义的扫描仪图像。

<LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="40dp"
            android:id="@+id/scan"
            android:background="@drawable/bgscanner">

            <ImageView
                android:layout_width="100dp"
                android:layout_height="wrap_content"
                android:src="@drawable/scanner"
                android:id="@+id/scanner1"
                android:layout_marginTop="20dp"
                android:visibility="invisible"
                />
        </LinearLayout>

我的动画可绘制对象

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:interpolator="@android:anim/linear_interpolator"
    android:fillAfter="true">

    <translate
        android:fromYDelta="0%p"
        android:toYDelta="75%p"
        android:duration="800"
        />
</set>

我的主要问题是,触摸事件时,动画不会执行。也就是说,图像栏不会沿垂直轴振荡。我恳请stackoverflow的任何帮助。

5个回答

16

已编辑

这个问题可以用很短的代码来解决。

首先,将你的XML动画代码更改为以下代码:

<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:interpolator="@android:anim/accelerate_decelerate_interpolator"
    android:fillAfter="false">

    <translate
        android:fromYDelta="0%p"
        android:toYDelta="100%p"
        android:duration="1000"
        android:repeatCount="infinite"
        android:repeatMode="restart"
        />
</set>

你的布局应该像这样:

<LinearLayout
        android:id="@+id/image"
        android:layout_width="200dp"
        android:layout_height="200dp"
        android:background="@mipmap/ic_launcher">

        <View
            android:id="@+id/bar"
            android:layout_width="200dp"
            android:layout_height="6dp"
            android:visibility="gone"
            android:background="@android:color/black"
            android:src="@mipmap/ic_launcher"/>
    </LinearLayout>

在你的活动中,代码可以是这样的:

LinearLayout imageView = (LinearLayout) findViewById(R.id.image);
        final View bar = findViewById(R.id.bar);
        final Animation animation = AnimationUtils.loadAnimation(MainActivity.this, R.anim.anim);
        animation.setAnimationListener(new Animation.AnimationListener() {
            @Override
            public void onAnimationStart(Animation animation) {}

            @Override
            public void onAnimationEnd(Animation animation) {
                bar.setVisibility(View.GONE);
            }

            @Override
            public void onAnimationRepeat(Animation animation) {}
        });

        imageView.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View view, MotionEvent motionEvent) {
                bar.setVisibility(View.VISIBLE);
                bar.startAnimation(animation);
                return false;
            }
        });

按照这种方式,您将得到以下结果:

enter image description here

我使用了View而不是ImageView来制作扫描条,但您可以根据需要更改代码。

希望对您有所帮助!

编辑2:

如果您希望只有在按下图像时才发生动画,请将代码更改为:

imageView.setOnTouchListener(new View.OnTouchListener() {
        @Override
        public boolean onTouch(View view, MotionEvent motionEvent) {
            if(motionEvent.getAction() == MotionEvent.ACTION_DOWN){
                bar.setVisibility(View.VISIBLE);
                bar.startAnimation(animation);
            } else if(motionEvent.getAction() == MotionEvent.ACTION_UP){
                bar.setVisibility(View.GONE);
                animation.cancel();
            }

            return false;
        }
    });

当图像被按下时(MotionEvent.ACTION_DOWN),触发动画,当图像被释放时(MotionEvent.ACTION_UP),停止动画。


谢谢Leandro...它起作用了...你如何使它连续? - Daniel Nyamasyo
你的意思是让它无限重复吗?将android:repeatCount=4更改为android:repeatCount="infinite"。如果你想要在图像被按下时才显示动画,请遵循EDIT 2。 - Leandro Borges Ferreira
太棒了!谢谢你,伙计 :) - Vivek Solanki

7

在触摸监听器中使用值动画器(value animator)替代倒计时器(countDownTimer)进行动画。

scan.setOnTouchListener(new View.OnTouchListener() {
  @Override
  public boolean onTouch(View view, MotionEvent motionEvent) {
   if(motionEvent.getAction==MotionEvent.ACTION_DOWN){ 
     ValueAnimator valueAnimator=ValueAnimator.ofFloat(0,75);
     valueAnimator.setDuration(4000);
     valueAnimator.setInterpolator(new DecelerateInterpolator());
     valueAnimator.addListener(new Animator.AnimatorListener() {
        @Override
        public void onAnimationStart(Animator animation) {
           scanner.setVisibilty(View.VISIBLE);
        }
        @Override
        public void onAnimationEnd(Animator animation) {
            scanner.setVisibilty(View.INVISIBLE);
        }
        @Override
        public void onAnimationCancel(Animator animation) {
             scanner.setVisibilty(View.INVISIBLE);
        }
        @Override
        public void onAnimationRepeat(Animator animation) {
         }
        });
     valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener()      {
           @Override
           public void onAnimationUpdate(ValueAnimator animation) {
              float translate= (float) animation.getAnimatedValue();
              scanner.setTranslationY(translate);//translate scanner in Y direction
           }
       });
    valueAnimator.start();
   }
 return true;
}

1
现在,动画栏失去了焦点。它在触摸事件中从视图中隐藏。 - Daniel Nyamasyo

4
对于Android上的动画,我建议您使用Animation Drawable,它很容易实现:https://developer.android.com/reference/android/graphics/drawable/AnimationDrawable.html。首先,我们需要将动画(例如GIF)拆分为PNG格式(例如使用在线工具http://ezgif.com/),然后在XML drawable文件中应用初始化。
<!-- Animation frames are wheel0.png through wheel5.png
     files inside the res/drawable/ folder -->
 <animation-list android:id="@+id/selected" android:oneshot="false">
    <item android:drawable="@drawable/wheel0" android:duration="50" />
    <item android:drawable="@drawable/wheel1" android:duration="50" />
    <item android:drawable="@drawable/wheel2" android:duration="50" />
    <item android:drawable="@drawable/wheel3" android:duration="50" />
    <item android:drawable="@drawable/wheel4" android:duration="50" />
    <item android:drawable="@drawable/wheel5" android:duration="50" />
 </animation-list>

最后我将它加载到我定义的类中:
// Load the ImageView that will host the animation and
 // set its background to our AnimationDrawable XML resource.
 ImageView img = (ImageView)findViewById(R.id.spinning_wheel_image);
 img.setBackgroundResource(R.drawable.spin_animation);

 // Get the background, which has been compiled to an AnimationDrawable object.
 AnimationDrawable frameAnimation = (AnimationDrawable) img.getBackground();

 // Start the animation (looped playback by default).
 frameAnimation.start();

3

将您的动画更改为以下内容

<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:interpolator="@android:anim/linear_interpolator"
    duration="4000"
    android:repeatMode="reverse"
    android:fillAfter="false">

    <translate
        android:fromYDelta="0%p"
        android:toYDelta="75%p"
        android:duration="800"/>
</set>

以及您的代码

scan.setOnTouchListener(new View.OnTouchListener() {
                @Override
                public boolean onTouch(View view, MotionEvent motionEvent) {

                            scanner.setVisibility(View.VISIBLE);
                            anim1 = AnimationUtils.loadAnimation(getApplicationContext(), R.anim.progress);
                            anim1.setAnimationListener(new Animation.AnimationListener() {
                                @Override
                                public void onAnimationStart(Animation animation) {

                                }

                                @Override
                                public void onAnimationEnd(Animation animation) {
                                scanner.setVisibility((View.INVISIBLE)
                                }

                                @Override
                                public void onAnimationRepeat(Animation animation) {

                                }
                            });
                            scanner.startAnimation(anim1);

                 }
            });

仍然无法工作。我做错了什么吗?请帮忙。我真的卡住了。 - Daniel Nyamasyo
更好地描述您的问题。“仍然不起作用”并不是很有帮助。 - Jozef Dochan
动画栏仍然不会摆动,它停留在同一位置。 - Daniel Nyamasyo

3

试试这个:

@Override
public boolean onTouch(View view, MotionEvent motionEvent) {

      final CountDownTimer start = new CountDownTimer(4000, 1000) {

     anim1 = AnimationUtils.loadAnimation(getApplicationContext(),
            R.anim.progress);

    // set animation listener
    anim1.setAnimationListener(this);

    // button click event
    scan.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onTick(View v) {
            scanner.setVisibility(View.VISIBLE);

            // start the animation
            scanner.startAnimation(anim1);
        }            
    });

}
@Override
public void onAnimationEnd(Animation animation) {
    // Take any action after completing the animation

    // check for fade in animation
    if (animation == anim1) {
        Toast.makeText(getApplicationContext(), "Animation Stopped",
                Toast.LENGTH_SHORT).show();
    }

}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接