在 TextView 上重复 Float Up 动画
Repeating a Float Up animation on TextView
我有一个可以无限次按下的Button
。按下时,我在 Button
上方显示 +1
,然后使用 Animation
使 TextView
向上浮动并消失。这一切都很好。我的问题发生在用户重复点击 Button
时。如果Animation
仍在进行中并向上浮动,则TextView
的位置将重置并且Animation
将重新启动。
如何在同一个 TextView
上开始另一个 Animation
的同时继续让 Animation
完成?我想我想要的最好的例子是一个你收集硬币的游戏,每次收集一个你都会看到 +1 漂浮在角色上方。
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
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);
}
}
我的Button
和TextView
定义在我的activity_main.xml
中。他们没有什么特别的。
谢谢。
1. 添加 AnimationListener
到您的动画 fadeInAnimation
.
2. 添加一个额外的变量 voteCount
来计算 button
点击。
3.在onClick()
方法中,调用voteNo()
方法仅first
时间开始动画,其他人从onAnimationEnd()
方法。
3. 在 onAnimationEnd()
方法中,检查 voteCount
的值。如果 value
大于 0
则调用 voteNo()
方法重新开始动画。
这是工作代码:
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) {
}
}
希望对你有所帮助~
以下方法有效,但我不能说这真的是最好的方法。我认为 Canvas
和 SurfaceView
的建议会更可靠。
您遇到的问题是动画发生在视图上,并且只有一个视图在动画期间移动。这就是它重置的原因,您一次只能看到一个上升的数字。以下解决方案创建了一堆 gone
视图,这些视图位于显示的基础视图之上。这些视图的 ID 保存在循环遍历的数组中。单击该按钮后,下一个 gone
视图将变为可见和动画。在动画结束时,视图再次gone
。
这里有一段效果视频:
Demo video
为了在视频中表现得更好,我夸大了动作。
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
<?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>
我有一个可以无限次按下的Button
。按下时,我在 Button
上方显示 +1
,然后使用 Animation
使 TextView
向上浮动并消失。这一切都很好。我的问题发生在用户重复点击 Button
时。如果Animation
仍在进行中并向上浮动,则TextView
的位置将重置并且Animation
将重新启动。
如何在同一个 TextView
上开始另一个 Animation
的同时继续让 Animation
完成?我想我想要的最好的例子是一个你收集硬币的游戏,每次收集一个你都会看到 +1 漂浮在角色上方。
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
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);
}
}
我的Button
和TextView
定义在我的activity_main.xml
中。他们没有什么特别的。
谢谢。
1. 添加 AnimationListener
到您的动画 fadeInAnimation
.
2. 添加一个额外的变量 voteCount
来计算 button
点击。
3.在onClick()
方法中,调用voteNo()
方法仅first
时间开始动画,其他人从onAnimationEnd()
方法。
3. 在 onAnimationEnd()
方法中,检查 voteCount
的值。如果 value
大于 0
则调用 voteNo()
方法重新开始动画。
这是工作代码:
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) {
}
}
希望对你有所帮助~
以下方法有效,但我不能说这真的是最好的方法。我认为 Canvas
和 SurfaceView
的建议会更可靠。
您遇到的问题是动画发生在视图上,并且只有一个视图在动画期间移动。这就是它重置的原因,您一次只能看到一个上升的数字。以下解决方案创建了一堆 gone
视图,这些视图位于显示的基础视图之上。这些视图的 ID 保存在循环遍历的数组中。单击该按钮后,下一个 gone
视图将变为可见和动画。在动画结束时,视图再次gone
。
这里有一段效果视频:
Demo video
为了在视频中表现得更好,我夸大了动作。
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
<?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>