简体   繁体   English

在TextView上重复上浮动画

[英]Repeating a Float Up animation on TextView

I have a Button that can be pressed an infinite number of times. 我有一个可以无限次按下的Button When pressed, I show a +1 above the Button and then use an Animation to Float the TextView up and disappear. 按下时,我在Button上方显示+1 ,然后使用Animation向上浮动TextView并消失。 This all works good. 这一切都很好。 My problem happens when a user repeatedly taps the Button . 当用户反复点按Button时,会发生我的问题。 If the Animation is still in progress and floating up, the TextView 's position will reset and the Animation will restart. 如果Animation仍在进行中并向上浮动,则TextView的位置将重置, Animation将重新启动。

How can I continuously allow the Animation to finish while starting another Animation on the same TextView ? 在同一TextView上启动另一个Animation ,如何连续允许Animation完成? I guess my best example of what I want would be a game where you collect coins and each time one is collected you see a +1 float up above a character. 我想我想要的最好的例子是一个游戏,您收集硬币,每次收集硬币时,角色上方都会浮起+1。

float_up.xml float_up.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <translate
        android:duration="1500"
        android:fromYDelta="90%"
        android:toYDelta="0" />

    <alpha
        android:duration="1500"
        android:fromAlpha="1.0"
        android:toAlpha="0.0" />
</set>

MainActivity.Class MainActivity.Class

public class MainActivity extends AppCompatActivity  {

private long voteMultiplier = 1;
private TextView txtNoNumber;
private Animation fadeInAnimation;
private Button buttonNo;


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

    fadeInAnimation = AnimationUtils.loadAnimation(this, R.anim.float_up);

    buttonNo = (Button) findViewById(R.id.button_no);

    buttonNo.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            voteNo();

        }
    });
}

private void voteNo() {
    txtNoNumber.setText(String.format("%s%s", "+ ", voteMultiplier));
    txtNoNumber.setTextColor(getResources().getColor(R.color.text_color_add));
    txtNoNumber.startAnimation(fadeInAnimation);

 }
}

My Button and TextView are defined in my activity_main.xml . 我的ButtonTextView是在我的activity_main.xml中定义的。 There is nothing special about them. 他们没有什么特别的。

Thank you. 谢谢。

This following works but I can't say that it is really the best way. 以下方法有效,但我不能说这确实是最好的方法。 I think the Canvas and SurfaceView suggestion would be more robust. 我认为CanvasSurfaceView建议会更可靠。

The issue that you are having is that the animation occurs on the view and there is only one view that is moved during animation. 您遇到的问题是动画发生在视图上,并且在动画过程中仅移动了一个视图。 That is why it resets and you can only see one rising number at a time. 这就是为什么它会重置并且您一次只能看到一个上升数字的原因。 The following solution creates a stack of gone views that sit on top of the underlying view that shows. 以下解决方案创建了一组gone视图,这些视图位于所显示的基础视图之上。 The IDs for these views are kept in an array that is cycled through. 这些视图的ID保留在循环循环的数组中。 When the button is clicked, the next gone view is made visible and animated. 单击该按钮时,下一个gone视图将变为可见并具有动画效果。 At the end of the animation, the view is made gone again. 动画结束时,视图再次gone

Here is a little video of the effect: 以下是有关效果的一些视频:

Demo video 示范影片

I have exaggerated the movement to show better in the video. 我夸大了运动,以使其在视频中表现得更好。

MainActivity.java MainActivity.java

public class MainActivity extends AppCompatActivity {

    private long voteMultiplier = 1;
    private int[] txtNoNumber = new int[5];
    private Button buttonNo;
    private int animIndex = 0;

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

        buttonNo = (Button) findViewById(R.id.button_no);
        txtNoNumber[0] = R.id.txtNoNumber1;
        txtNoNumber[1] = R.id.txtNoNumber2;
        txtNoNumber[2] = R.id.txtNoNumber3;
        txtNoNumber[3] = R.id.txtNoNumber4;
        txtNoNumber[4] = R.id.txtNoNumber5;

        buttonNo.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                voteNo();

            }
        });
    }

    private void voteNo() {
        TextView tv;
        Animation fadeInAnimation;

        if (animIndex >= txtNoNumber.length) {
            animIndex = 0;
        }
        tv = (TextView) findViewById(txtNoNumber[animIndex]);
        tv.setVisibility(View.VISIBLE);
        tv.setText(String.format("%s%s", "+ ", voteMultiplier++));
//        txtNoNumber.setTextColor(getResources().getColor(R.color.text_color_add));
        fadeInAnimation = AnimationUtils.loadAnimation(this, R.anim.float_up);
        fadeInAnimation.setAnimationListener(new MyAnimationListener(tv));
        tv.startAnimation(fadeInAnimation);
        animIndex++;
    }

    private class MyAnimationListener implements Animation.AnimationListener {
        View mView;

        MyAnimationListener(View view) {
            mView = view;
        }

        @Override
        public void onAnimationStart(Animation animation) {

        }

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

        @Override
        public void onAnimationRepeat(Animation animation) {

        }
    }
}

activity_main.xml activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.example.floatanimation.MainActivity">

    <TextView
        android:id="@+id/txtNoNumber1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.319" />

    <TextView
        android:id="@+id/txtNoNumber2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!"
        android:visibility="gone"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.319" />

    <TextView
        android:id="@+id/txtNoNumber3"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!"
        android:visibility="gone"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.319" />

    <TextView
        android:id="@+id/txtNoNumber4"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!"
        android:visibility="gone"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.319" />

    <TextView
        android:id="@+id/txtNoNumber5"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!"
        android:visibility="gone"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.319" />

    <Button
        android:id="@+id/button_no"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginBottom="8dp"
        android:layout_marginTop="8dp"
        android:text="Button"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        tools:ignore="HardcodedText" />

</android.support.constraint.ConstraintLayout>

1. Add AnimationListener to your animation fadeInAnimation . 1.AnimationListener添加到动画fadeInAnimation

2. Add an extra variable voteCount to count the button click. 2.添加一个额外的voteCount变量来计算button点击。

3. In onClick() method, call voteNo() method only for first time to start animation and for others handle it from onAnimationEnd() method. 3.onClick()方法中,仅first一次调用voteNo()方法以启动动画,而其他人则通过onAnimationEnd()方法进行处理。

3. Inside onAnimationEnd() method, check the value of voteCount . 3.onAnimationEnd()方法中,检查voteCount的值。 If value is greater than 0 then call voteNo() method to start animation again. 如果value大于0则调用voteNo()方法再次开始动画。

Here is the working code: 这是工作代码:

import android.graphics.Color;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.Button;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity implements Animation.AnimationListener{

    private long voteMultiplier = 1;
    private TextView txtNoNumber;
    private Animation fadeInAnimation;
    private Button buttonNo;

    int voteCount  = 0;

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

        fadeInAnimation = AnimationUtils.loadAnimation(this, R.anim.float_up);
        fadeInAnimation.setAnimationListener(this);

        txtNoNumber = (TextView) findViewById(R.id.text_no_number);
        buttonNo = (Button) findViewById(R.id.button_no);

        buttonNo.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                voteCount++;

                if (voteCount == 1)
                    voteNo();
            }
        });
    }

    private void voteNo() {
        txtNoNumber.setText(String.format("%s%s", "+ ", voteMultiplier));
        txtNoNumber.setTextColor(Color.GREEN);
        txtNoNumber.startAnimation(fadeInAnimation);
    }

    @Override
    public void onAnimationStart(Animation animation) {

    }

    @Override
    public void onAnimationEnd(Animation animation) {

        if (animation == fadeInAnimation) {
            voteCount--;

            if (voteCount > 0)
                voteNo();
        }
    }

    @Override
    public void onAnimationRepeat(Animation animation) {

    }
}

Hope this will help~ 希望这会有所帮助〜

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM