我有一个计时器,当用户回答问题时就会启动,我想要一个小圆形饼,它会慢慢地倒计时。经过一番研究后我发现:Circular Progress Bar ( for a countdown timer )这似乎是我想要的,但我在实现它时遇到了困难。
我复制粘贴了 xml 进度条的代码,看起来不错,但在 java 中,我想在用户得到正确答案时调用 startTimer 方法,以便计时器可以再次启动。但它根本不起作用,而且我在过去的两个小时里一直在胡闹,这让我发疯了。
这是我的 xml 可绘制文件:
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:id="@android:id/progress">
<shape
android:innerRadiusRatio="5"
android:shape="ring"
android:thicknessRatio="10.0"
android:useLevel="true">
<gradient
android:startColor="#fb0000"
android:endColor="#00FF00"
android:centerColor="#fbf400"
android:type="sweep" />
</shape>
</item>
</layer-list>
我的activity_color_match文件:(尽管你可能只需要最底部的“进度条”
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_color_match"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.example.ali.colormatch2.ColorMatch2">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/blueButton"
android:background="@drawable/rounded_blue_button"
android:onClick="sendBlue"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_toLeftOf="@+id/textView3"
android:layout_toStartOf="@+id/textView3" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/greenButton"
android:background="@drawable/rounded_green_button"
android:onClick="sendGreen"
android:layout_alignBottom="@+id/redButton"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
android:layout_alignTop="@+id/redButton"
android:layout_alignLeft="@+id/yellowButton"
android:layout_alignStart="@+id/yellowButton" />
<TextView
android:text="Score:"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:id="@+id/textView4" />
<TextView
android:text="@string/matchText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/textView3"
android:textAppearance="@style/TextAppearance.AppCompat.Body2"
android:textSize="20dp"
android:layout_below="@+id/textView4"
android:layout_centerHorizontal="true"
android:layout_marginTop="26dp" />
<TextView
android:text="@string/mainColor"
android:id="@+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:textColor="@android:color/holo_blue_dark"
android:textSize="80dp"
android:textAppearance="@style/TextAppearance.AppCompat.Display3"
android:layout_below="@+id/textView3"
android:layout_centerHorizontal="true"
android:layout_marginTop="114dp"
android:shadowColor="#000000"
android:shadowDx="10"
android:shadowDy="10"
android:shadowRadius="10"/>
<Button
android:layout_height="wrap_content"
android:id="@+id/yellowButton"
android:background="@drawable/rounded_yellow_button"
android:elevation="0dp"
android:layout_width="wrap_content"
android:onClick="sendYellow"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
android:layout_toRightOf="@+id/textView3"
android:layout_toEndOf="@+id/textView3" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/redButton"
android:background="@drawable/rounded_red_button"
android:onClick="sendRed"
android:elevation="0dp"
android:layout_above="@+id/blueButton"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_marginBottom="22dp"
android:layout_alignRight="@+id/blueButton"
android:layout_alignEnd="@+id/blueButton" />
<ProgressBar
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="60dp"
android:layout_height="60dp"
android:indeterminate="false"
android:max="100"
android:progress="100"
android:id="@+id/progressBar"
android:progressDrawable="@drawable/timer"
android:layout_below="@+id/textView4"
android:layout_toRightOf="@+id/textView2"
android:layout_toEndOf="@+id/textView2" />
</RelativeLayout>
还有怪物本身,我的 ColorMatch2.java 文件。我已经把所有东西都放在这里了,除了 startTimer();在 checkAnswer() 中调用方法;和 startTimer();方法本身位于最底部
package com.example.ali.colormatch2;
import android.content.Intent;
import android.graphics.Color;
import android.os.CountDownTimer;
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.RotateAnimation;
import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.app.Activity;
import android.view.MotionEvent;
import android.view.View.OnTouchListener;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import java.util.Random;
import static com.example.ali.colormatch2.R.id.progressBar;
public class ColorMatch2 extends AppCompatActivity {
//int answer; //1 = red, 2 = green, 3 = blue, 4 = yellow
CounterClass timer;
TextView textView3, textView2, textView4;
int count = 0;
int score = 0;
int correctAnswer;
boolean matchColor = true, matchText = false;
boolean firstTime = true;
boolean correctAnswerGiven = false;
RelativeLayout relativeLayout;
//ProgressBar progressBar = (ProgressBar) findViewById(R.id.progressBar);
//Animation an = new RotateAnimation(0.0f, 90.0f, 250f, 273f);
CountDownTimer countDownTimer;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_color_match);
textView3 = (TextView) findViewById(R.id.textView3);
textView2 = (TextView) findViewById(R.id.textView2);
textView4 = (TextView) findViewById(R.id.textView4);
relativeLayout = (RelativeLayout) findViewById(R.id.activity_color_match);
Button redButton, blueButton, greenButton, yellowButton;
redButton = (Button) findViewById(R.id.redButton);
blueButton = (Button) findViewById(R.id.blueButton);
greenButton = (Button) findViewById(R.id.greenButton);
yellowButton = (Button) findViewById(R.id.yellowButton);
if (firstTime) {
generateNewWord();
firstTime = false;
}
//ProgressBar progressBar = (ProgressBar) findViewById(R.id.progressBar);
//Animation an = new RotateAnimation(0.0f, 90.0f, 250f, 273f);
redButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
checkAnswer(1);
}
});
greenButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
checkAnswer(2);
}
});
blueButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
checkAnswer(3);
}
});
yellowButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
checkAnswer(4);
}
});
}
public void checkAnswer(int answer) {
Random rand = new Random();
int x;
//Let's think about this. If the score is less than <10, I want a 1 in 5
//chance of it changing. If it's between 10 and 20, 1 in 4, and if it's higher
//than 20, 1 in 3
if (score < 5) {
x = 5;
} else if (score >= 5 && score < 15) {
x = 4;
} else {
x = 3;
}
int randCount = rand.nextInt(x) + 1;
if (randCount == x) {
if (matchColor) {
textView3.setText(getString(R.string.gameSetting2)); // might need to add context with this - check https://stackoverflow.com/questions/10698945/reference-string-resource-from-code
matchText = true;
matchColor = false;
relativeLayout.setBackgroundColor(Color.argb(255, 84, 84, 84));
} else if (matchText) {
textView3.setText(getString(R.string.gameSetting1));
matchColor = true;
matchText = false;
relativeLayout.setBackgroundColor(Color.argb(255, 255, 255, 255));
}
}
if (answer == correctAnswer) {
score++;
count++;
textView4.setText("Score: " + score);
generateNewWord();
//Timer and animation explanation: timer starts first time user gives correct answer.
//After that, if they give correct answer again it cancels the timer and starts it over,
//resetting it. I am trying to achieve the same effect with the animation.
ProgressBar progressBar = (ProgressBar) findViewById(R.id.progressBar);
Animation an = new RotateAnimation(0.0f, 90.0f, 250f, 273f);
an.setFillAfter(true);
progressBar.startAnimation(an);
if (correctAnswerGiven) {
timer.cancel();
}
//progressBar.setProgress(100);
timer = new CounterClass(4000, 1000);
timer.start(); //This is the actual timer that if expires will cause user to fail game
startTimer(4000); // This is the timer for the progress bar
if (!correctAnswerGiven) {
correctAnswerGiven = true;
}
} else {
textView3.setText("Wrong");
//quit();
}
}
public void generateNewWord() {
//randomly select between red, green, blue, yellow
Random rand = new Random();
int randomInt1 = rand.nextInt(4) + 1; // assigns randomInt a value between 1 - 4
int randomInt2 = rand.nextInt(4) + 1;
if (randomInt1 == 1) {
textView2.setText(R.string.Red);
} else if (randomInt1 == 2) {
textView2.setText(R.string.Green);
} else if (randomInt1 == 3) {
textView2.setText(R.string.Blue);
} else if (randomInt1 == 4) {
textView2.setText(R.string.Yellow);
}
//randomly select hex codes between rgby
if (randomInt2 == 1) {
textView2.setTextColor(0xffcc0000);
} else if (randomInt2 == 2) {
textView2.setTextColor(0xff669900);
} else if (randomInt2 == 3) {
textView2.setTextColor(0xff000080);
} else if (randomInt2 == 4) {
textView2.setTextColor(0xffffff00);
}
if (firstTime) {
textView3.setText(getString(R.string.gameSetting2));
correctAnswer = randomInt1;
relativeLayout.setBackgroundColor(Color.argb(255, 84, 84, 84));
firstTime = false;
} else {
if (matchColor) {
correctAnswer = randomInt2;
textView3.setText(getString(R.string.gameSetting1));
relativeLayout.setBackgroundColor(Color.argb(255, 255, 255, 255));
} else if (matchText) {
correctAnswer = randomInt1;
textView3.setText(getString(R.string.gameSetting2));
relativeLayout.setBackgroundColor(Color.argb(255, 84, 84, 84));
}
}
}
public class CounterClass extends CountDownTimer {
public CounterClass(long millsInFuture, long countDownInterval) {
super(millsInFuture, countDownInterval);
}
@Override
public void onFinish() {
//quit();
// I need something to test if this is happening
//textView3.setText("Timer Finished");
}
@Override
public void onTick(long millisUntilFinished) {
//Nothing
}
}
public void quit() {
Intent intent = new Intent(ColorMatch2.this,
LoseScreen.class);
Bundle b = new Bundle();
b.putInt("score", score); // Your score
intent.putExtras(b); // Put your score to your next
startActivity(intent);
overridePendingTransition(R.anim.slide_in, R.anim.slide_out);
}
private void startTimer(final int x) {
countDownTimer = new CountDownTimer(x, 500) {
// 500 means, onTick function will be called at every 500 milliseconds
ProgressBar progressBar = (ProgressBar) findViewById(R.id.progressBar);
@Override
public void onTick(long leftTimeInMilliseconds) {
long seconds = leftTimeInMilliseconds / 1000;
double percentage;
if(leftTimeInMilliseconds > 0){
percentage = 4000 / leftTimeInMilliseconds;}
else {percentage = 0.0;}
progressBar.setProgress((int) percentage * 100 );
}
@Override
public void onFinish() {
// Nothing
}
}.start();
}
}
回顾一下,进度条一直在那里(虽然奇怪的是没有旋转,但我现在几乎不关心它),直到调用 checkAnswer 方法,在这种情况下它就会消失。谢谢。另外,我不想在里面包含任何实际数字,只想要小条本身,所以这就是为什么我删除了原始帖子中的一些代码。
最佳答案
我最终通过完全抛弃该答案中的方法来使其工作。我查看了这篇博文的评论http://mrigaen.blogspot.it/2013/12/create-circular-progress-bar-in-android.html并使用了以下方法:
//class to create progressbar circular animation
private class ProgressBarAnimation extends Animation{
private float from;
private float to;
public ProgressBarAnimation(float from, float to) {
super();
this.from = from;
this.to = to;
}
@Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
super.applyTransformation(interpolatedTime, t);
float value = from + (to - from) * interpolatedTime;
String prg = String.valueOf((int)value);
}
pb.setProgress((int) value);
tv_today.setText(prg);
}
}
这样调用它:
//动画到100
ProgressBarAnimation anim = new ProgressBarAnimation(0, 100);
动画.setDuration(2000);
pb.startAnimation(anim);
如果您将来遇到这个问题,pb 就是他们在那篇博客文章中所说的进度条。
关于java - 尝试遵循之前关于如何创建动画的答案,但它完全消失了,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40121189/