So I'm making a game in Android Studio where you are supposed to tap the circle as many times as you can in 60 seconds.I have specific TextView's for time and the score that you achieved BUT! before the first tap the time says "Tap to start" so that the timer starts when the user want's and not on it's own.
My problem is that i have a Reset button under the circle where the user can restart back to the start the score is saved and the time should say "Tap to start" but the counter just freezes and does nothing until the user tap's again and it start's as normal.I can't figure out why it won't change it's value to "Tap to start" when i told it to do so in the On click listener from the Reset button
the code:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
final Button button = (Button) findViewById(R.id.button);
final TextView txtview2 = (TextView) findViewById(R.id.textView2);
final TextView txtview = (TextView) findViewById(R.id.textView);
updatetime(txtview2);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(started == false)
{
reverseTimer(60,txtview2,button,txtview);
started = true;
}
score++;
randnum = r.nextInt(10 - 0) + 0;
if(randnum == 0)
button.setBackground(getResources().getDrawable(R.drawable.circle));
else if(randnum == 1)
button.setBackground(getResources().getDrawable(R.drawable.circle1));
else if(randnum == 2)
button.setBackground(getResources().getDrawable(R.drawable.circle2));
else if(randnum == 3)
button.setBackground(getResources().getDrawable(R.drawable.circle3));
else if(randnum == 4)
button.setBackground(getResources().getDrawable(R.drawable.circle4));
else if(randnum == 5)
button.setBackground(getResources().getDrawable(R.drawable.circle5));
else if(randnum == 6)
button.setBackground(getResources().getDrawable(R.drawable.circle6));
else if(randnum == 7)
button.setBackground(getResources().getDrawable(R.drawable.circle7));
else if(randnum == 8)
button.setBackground(getResources().getDrawable(R.drawable.circle8));
else if(randnum == 9)
button.setBackground(getResources().getDrawable(R.drawable.circle9));
button.setText(String.valueOf(score));
}
});
Button reset_button = (Button) findViewById(R.id.button3);
reset_button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Reset(txtview2,button);
started = true;
}
});
}
My reset function:
public void Reset(TextView txt,Button button)
{
updatetime(txt);
score = 0;
button.setText(String.valueOf(score));
button.setBackground(getResources().getDrawable(R.drawable.circle));
}
set high score is actuall just set score...
public void updatetime(TextView txt)
{
txt.setText("Time : Tap to start");
}
public void sethighscore(TextView txt)
{
txt.setText("Score: " + String.valueOf(score));
}
My timer that counts from 60 to 0:
public void reverseTimer(int Seconds,final TextView tv,final Button button,final TextView txt2){
CountDownTimer CountDownTimer1 = new CountDownTimer(Seconds* 1000+1000, 1000) {
public void onTick(long millisUntilFinished) {
if(clicked)
{
this.cancel();
clicked = false;
if(score > highscore)
sethighscore(txt2);
Reset(tv,button);
started = false;
}
int seconds = (int) (millisUntilFinished / 1000);
int minutes = seconds / 60;
Button button3 = (Button) findViewById(R.id.button3);
button3.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
clicked = true;
}
});
seconds = seconds % 60;
tv.setText("Time : " + String.valueOf(minutes)
+ ":" + String.valueOf(seconds));
}
public void onFinish() {
if(score > highscore)
sethighscore(txt2);
tv.setText("Completed");
Reset(tv,button);
}
}.start();
}
What happening is that textView is defined in main thread i.e UI thread. Setting text in it wont work on another thread.what u have to do is make a handler object.
Handler handler=new Handler(getApplicationContext().getMainLooper());
now the place where u want to do the textView.setText("string"); add this code there.
handler.post(new Runnable() {
#Override
public void run() {
textView.setText("string");
}
});
Related
I have made an alarm clock app however, I am trying to make a homepage where the user can see all the alarms they have set. I want to infinitely run a block of code that updates the homepage of my app, but the methods I have found have not worked (i.e using a timer loop, while, and for loop). Any suggestion would help me a lot, also any critique to the code would help to, Thanks everyone!
I have tried
Timers, Do-While, While, and For Loops
The While loop that is in there currently cause an error and the app does not even run.
All the code I need help with is in the While Loop.
I think this is the error
(I/zygote64: Rejecting re-init on previously-failed classjava.lang.Class: java.lang.NoClassDefFoundError: Failed resolution of: Landroid/view/View$OnUnhandledKeyEventListener;)
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_alarms);
final Button selectAlarm1 = (Button) findViewById(R.id.selectAlarm1);
final Button selectAlarm2 = (Button) findViewById(R.id.selectAlarm2);
final Button selectAlarm3 = (Button) findViewById(R.id.selectAlarm2);
selectAlarm1.setVisibility(View.INVISIBLE);
selectAlarm2.setVisibility(View.INVISIBLE);
selectAlarm3.setVisibility(View.INVISIBLE);
final TextView textView = (TextView) findViewById(R.id.textView);
final Button createAlarm = (Button) findViewById(R.id.createAlarm);
final Button createAlarm2 = (Button) findViewById(R.id.createAlarm2);
final Button createAlarm3 = (Button) findViewById(R.id.createAlarm3);
createAlarm.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
openMainActivity();
createAlarm2.bringToFront();
}
});
createAlarm2.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
openMainActivity2();
createAlarm3.bringToFront();
}
});
createAlarm3.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
openMain3Activity();
}
});
selectAlarm1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
openMainActivity();
}
});
selectAlarm2.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
openMainActivity2();
}
});
selectAlarm3.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
openMain3Activity();
}
});
while(true){
if (Global.intHour1 != 0 && Global.intMinute1 != 0) {
textView.setVisibility(View.GONE);
selectAlarm1.setVisibility(View.VISIBLE);
//fixing minute format
if (Global.intMinute1 <= 9) {
selectAlarm1.setText("Alarm 1 is set for " +
Global.intHour1 + ":0" + Global.intMinute1);
} else {
selectAlarm1.setText("Alarm 1 is set for " +
Global.intHour1 + ":" + Global.intMinute1);
}
} else if (Global.intHour1 == 0 && Global.intMinute1 == 0) {
textView.setVisibility(View.VISIBLE);
}
if (Global.intHour2 != 0 && Global.intMinute2 != 0) {
selectAlarm2.setVisibility(View.VISIBLE);
//fixing minute format
if (Global.intMinute2 <= 9) {
selectAlarm2.setText("Alarm 1 is set for " +
Global.intHour2 + ":0" + Global.intMinute2);
} else {
selectAlarm2.setText("Alarm 1 is set for " +
Global.intHour2 + ":" + Global.intMinute2);
}
} else {
}
if (Global.intHour3 != 0 && Global.intMinute3 != 0) {
selectAlarm3.setVisibility(View.VISIBLE);
//fixing minute format
if (Global.intMinute3 <= 9) {
selectAlarm3.setText("Alarm 1 is set for " +
Global.intHour3 + ":0" + Global.intMinute3);
} else {
selectAlarm3.setText("Alarm 1 is set for " +
Global.intHour3 + ":" + Global.intMinute3);
}
}
else {
}
if (selectAlarm1.getVisibility() == View.INVISIBLE &&
selectAlarm2.getVisibility() == View.INVISIBLE &&
selectAlarm3.getVisibility() == View.INVISIBLE) {
textView.setVisibility(View.VISIBLE);
}
else
{
}
}
}
public void openMainActivity () {
Intent openAlarm = new Intent(this, MainActivity.class);
startActivity(openAlarm);
}
public void openMainActivity2 () {
Intent openAlarm2 = new Intent(this, MainActivity2.class);
startActivity(openAlarm2);
}
public void openMain3Activity () {
Intent openAlarm3 = new Intent(this, Main3Activity.class);
startActivity(openAlarm3);
}
public void makeTextVisible () {
}
}
I want the code to recognize when the intHour1-3 and intMinute1-3 are changed and change the visibility state of a button so that when the user returns to the homepage they can see which alarms are set.
My problem is towards the bottom, I have a boolean, ongoing, which is false. It is supposed to become true with a button press, then initiate a countdown timer, but the timer is not initiated. The timer works placed elsewhere in the code. Sorry if it's a complete mess I'm new to this.
public int counter;
public boolean ongoing = false;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//0-59 number picker to represent seconds
final NumberPicker secPicker = (NumberPicker) findViewById(R.id.secPicker);
secPicker.setMaxValue(59);
Button btnStart = (Button) findViewById(R.id.btnStart);
Button btnSet = (Button) findViewById(R.id.btnSet);
Button btnPause = (Button) findViewById(R.id.btnPause);
final TextView label = (TextView) findViewById(R.id.txtCount);
//sets the time chosen to timer with button press btnSet
btnSet.setOnClickListener(
new View.OnClickListener() {
public void onClick(View v) {
counter = secPicker.getValue();
label.setText(String.valueOf(counter));
}
}
);
//starts timer from selected time, from number picker, with btnStart
btnStart.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
ongoing = true;
}
});
//disables, not worried about this yet
btnPause.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
ongoing = false;
}
});
//supposed to turn on a timer with button press btnStart, but it does nothing this is my problem.
if (ongoing == true) {
//any replacement for 9999999, as an infinite value?
new CountDownTimer(999999999, 1000) {
public void onTick(long millisUntilFinished) {
label.setText(String.valueOf(counter));
counter--;
if (counter == -1) {
counter = 0;
cancel();
}
}
public void onFinish() {
}
}.start();
}
}
}
if (ongoing == true) // this will never work for you
You have putted above code inside oncreate before you click anything it will get call.
Either you should write below code inside btnStart click event or create one method and call from it.
//supposed to turn on a timer with button press btnStart, but it does nothing this is my problem.
if (ongoing == true) {
//any replacement for 9999999, as an infinite value?
new CountDownTimer(999999999, 1000) {
public void onTick(long millisUntilFinished) {
label.setText(String.valueOf(counter));
counter--;
if (counter == -1) {
counter = 0;
cancel();
}
}
public void onFinish() {
}
}.start();
}
Hope these help you.
In my game the user gets a point when he clicks a button within five seconds. Now I want the timer to decrease the time with every point the user gets - so e.g. with zero points the user has five seconds, and when he has one point he gets only 4.5 seconds to click it again and get the second point. Do I solve it with a for loop?
public class GameScreen extends Activity {
public int score = 0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_game);
Button count = (Button) findViewById(R.id.button1);
text = (TextView) this.findViewById(R.id.textView3);
tvscore = (TextView) findViewById(R.id.score);
timer();
}
public void gameover() {
Intent intent = new Intent(this, GameOverScreen.class);
startActivity(intent);
}
public void onClick (View view) {
score++;
tvscore.setText(String.valueOf(score));
timer();
}
public void timer(){
new CountDownTimer(5000, 10) {
public void onTick(long millisUntilFinished) {
text.setText(""+String.format("%02d:%03d",
TimeUnit.MILLISECONDS.toSeconds(millisUntilFinished) - TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(millisUntilFinished)),
TimeUnit.MILLISECONDS.toMillis(millisUntilFinished) - TimeUnit.SECONDS.toMillis(TimeUnit.MILLISECONDS.toSeconds(millisUntilFinished))
));
if(animationRunning) {
cancel();
}
}
public void onFinish() {
text.setText("Too slow.");
gameover();
}
}.start();
}
}
What about doing this:
public void timer(float time) {
new CountDownTimer(time, 10) {
// YOUR CODE
}
}
public void onClick (View view) {
score++;
tvscore.setText(String.valueOf(score));
timer(Math.max(5000-score*500, 2000));
}
I suppose each click (score) will decrease the time with 500 millis...
Limit - Math.max(a, b) will choose the biggest value. Means when 5000-score*500 will be lower than 2000, it will choose 2000 millis instead
Only timer method:
public void timer() {
float time = Math.max(5000-score*500, 2000)
new CountDownTimer(time, 10) {
// YOUR CODE
}
}
I create a simple math game and I would like to update my progress bar base on the right question answer.
Examples: every time I answer correctly to a question the progress bar should go bu 10% and so on.
public class QuestionActivity extends Activity
{
List<Question> quesList;
int score = 0;
int qid = 0;
Question currentQ;
TextView txtQuestion, times, scored;
Button button1, button2, button3;
ProgressBar pb;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
QuizHelper db = new QuizHelper(this); // my question bank class
quesList = db.getAllQuestions(); // this will fetch all quetonall
questions
currentQ = quesList.get(qid); // the current question
// the textview in which the question will be displayed
txtQuestion = (TextView) findViewById(R.id.txtQuestion);
//the progress bar in which progress will be displayed
pb = (ProgressBar)findViewById(R.id.progressBar);
// the three buttons,
// the idea is to set the text of three buttons with the options from
question bank
button1 = (Button) findViewById(R.id.button1);
button2 = (Button) findViewById(R.id.button2);
button3 = (Button) findViewById(R.id.button3);
// the textview in which score will be displayed
scored = (TextView) findViewById(R.id.score);
// the timer
times = (TextView) findViewById(R.id.timers);
// method which will set the things up for our game
setQuestionView();
times.setText("00:02:00");
// A timer of 60 seconds to play for, with an interval of 1 second (1000
milliseconds)
CounterClass timer = new CounterClass(60000, 1000);
timer.start();
// button click listeners
button1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// passing the button text to other method
// to check whether the answer is correct or not
// same for all three buttons
getAnswer(button1.getText().toString());
setProgressBar();
}
});
button2.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
getAnswer(button2.getText().toString());
setProgressBar();
}
});
button3.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
getAnswer(button3.getText().toString());
setProgressBar();
}
});
}
public void getAnswer(String AnswerString) {
if (currentQ.getAnswer().equals(AnswerString)) {
// if conditions matches increase the int (score) by 1
// and set the text of the score view
score++;
scored.setText("Score : " + score);
} else {
// if unlucky start activity and finish the game
Intent intent = new Intent(QuestionActivity.this,
ResultActivity.class);
// passing the int value
Bundle b = new Bundle();
b.putInt("score", score); // Your score
intent.putExtras(b); // Put your score to your next
startActivity(intent);
finish();
}
if (qid < 20) {
// if questions are not over then do this
currentQ = quesList.get(qid);
setQuestionView();
} else {
// if over do this
Intent intent = new Intent(QuestionActivity.this,
ResultActivity.class);
Bundle b = new Bundle();
b.putInt("score", score); // Your score
intent.putExtras(b); // Put your score to your next
startActivity(intent);
finish();
}
}
#TargetApi(Build.VERSION_CODES.GINGERBREAD)
#SuppressLint("NewApi")
public class CounterClass extends CountDownTimer {
public CounterClass(long millisInFuture, long countDownInterval) {
super(millisInFuture, countDownInterval);
// TODO Auto-generated constructor stub
}
#Override
public void onFinish() {
times.setText("Time is up");
}
//#Override
public void onTick(long millisUntilFinished) {
// TODO Auto-generated method stub
long millis = millisUntilFinished;
String hms = String.format(
"%02d:%02d:%02d",
TimeUnit.MILLISECONDS.toHours(millis),
TimeUnit.MILLISECONDS.toMinutes(millis)
- TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS
.toHours(millis)),
TimeUnit.MILLISECONDS.toSeconds(millis)
- TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS
.toMinutes(millis)));
System.out.println(hms);
times.setText(hms);
}
}
private void setQuestionView() {
// the method which will put all things together
txtQuestion.setText(currentQ.getQuestion());
button1.setText(currentQ.getOptionA());
button2.setText(currentQ.getOptionB());
button3.setText(currentQ.getOptionC());
qid++;
}
private void setProgressBar()
{
}
}
private void setProgressBar()
{
int progress=pb.getProgress();
if(progress<100)
pb.setProgress(progress+10)
}
this should do the trick, it will increase progress by 10 every time you call setProgressBar() method
First :
Set ur Progress bar limit
pb.setMax(Total Quest *10)
later in
For every Correct Answer Inc score++;
private void setProgressBar()
{
pb.setProgress(score*10);
}
I have a 20 second countdown timer successfully working on my trivia game. I want to add a ProgressBar (not a ProgressDialog) to the screen. I found the developer guide for Android confusing. I googled lots of examples and tried to combine them into my code. Right now all that displays when I run a game is an empty bar with no "progress" made during each question of the game.
QuestionView.java
public class QuestionView extends Activity {
int correctAnswers = 0;
int wrongAnswers = 0;
int answer = 0;
int i = 0;
long score = 0;
long startTime = 20000;
long interval = 1000;
long points;
boolean timerHasStarted = false;
String category;
Button answer1, answer2, answer3, answer4;
TextView question, pointCounter, questionNumber, timeCounter;
ArrayList<Question> queries;
Timer cdTimer;
ProgressBar bar;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.questionviewmain);
answer1 = (Button)findViewById(R.id.answer1);
answer2 = (Button)findViewById(R.id.answer2);
answer3 = (Button)findViewById(R.id.answer3);
answer4 = (Button)findViewById(R.id.answer4);
question = (TextView)findViewById(R.id.question);
category = getIntent().getStringExtra("category");
queries = getIntent().getParcelableArrayListExtra("queries");
pointCounter = (TextView)findViewById(R.id.timer);
questionNumber = (TextView)findViewById(R.id.timeElapsedView);
timeCounter = (TextView)findViewById(R.id.timeCounter);
cdTimer = new Timer(startTime, interval);
bar = (ProgressBar)findViewById(R.id.progressbar);
bar.setIndeterminate(false);
bar.setMax(9);
loadQuestion();
}
public void loadQuestion() {
bar.setProgress(i);
if(i == 10) {
endQuiz();
} else {
if(!timerHasStarted) {
cdTimer.start();
timerHasStarted = true;
} else {
cdTimer.start();
timerHasStarted = false;
}
answer = queries.get(i).getCorrectAnswer();
question.setText(queries.get(i).getQuery());
answer1.setText(queries.get(i).getA1());
answer2.setText(queries.get(i).getA2());
answer3.setText(queries.get(i).getA3());
answer4.setText(queries.get(i).getA4());
answer1.setOnClickListener(new OnClickListener() {
public void onClick(View arg0) {
queries.get(i).setSelectedAnswer(0);
if(answer == 0) {
correctAnswers++;
nextQuestion();
} else {
wrongAnswers++;
nextQuestion();
}
}
});
answer2.setOnClickListener(new OnClickListener() {
public void onClick(View arg0) {
queries.get(i).setSelectedAnswer(1);
if(answer == 1) {
correctAnswers++;
nextQuestion();
} else {
wrongAnswers++;
nextQuestion();
}
}
});
answer3.setOnClickListener(new OnClickListener() {
public void onClick(View arg0) {
queries.get(i).setSelectedAnswer(2);
if(answer == 2) {
correctAnswers++;
nextQuestion();
} else {
wrongAnswers++;
nextQuestion();
}
}
});
answer4.setOnClickListener(new OnClickListener() {
public void onClick(View arg0) {
queries.get(i).setSelectedAnswer(3);
if(answer == 3) {
correctAnswers++;
nextQuestion();
} else {
wrongAnswers++;
nextQuestion();
}
}
});
}
}
public ArrayList<Question> getQueries() {
return queries;
}
public void nextQuestion() {
score = score + points;
i++;
loadQuestion();
}
public class Timer extends CountDownTimer {
public void startCountdownTimer() {
}
public Timer(long startTime, long interval) {
super(startTime, interval);
}
#Override
public void onFinish() {
if(i >= 9) {
cdTimer.cancel();
endQuiz();
} else {
wrongAnswers++;
nextQuestion();
}
}
#Override
public void onTick(long millisUntilFinished) {
timeCounter.setText("Time remaining: " + (millisUntilFinished / 100));
points = (millisUntilFinished / 100) / 2;
pointCounter.setText("Points remaining: " + points);
if(i < 10) {
questionNumber.setText("Question " + (i + 1) + " of 10");
}
}
}
public void endQuiz() {
Intent intent = new Intent(QuestionView.this, Results.class);
intent.putExtra("correctAnswers", correctAnswers);
intent.putExtra("wrongAnswers", wrongAnswers);
intent.putExtra("score", score);
intent.putParcelableArrayListExtra("queries", queries);
intent.putExtra("category", category);
startActivity(intent);
}
}
XML code
<ProgressBar
android:id="#+id/progressbar"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:visibility="visible"
style="#android:style/Widget.ProgressBar.Horizontal" />
What I am looking for is for the ProgressBar to slowly tick down until the 20 seconds the user is allotted for each question is gone.
New Answer
To do this let's add a new line to onTick():
bar.setProgress((int) Math.round(millisUntilFinished / 1000.0));
(You may need to tweak the data types, I am away from my compiler... Also I don't like the CountDownTimer class, it is inaccurate and often skips the second to last number. I wrote an alternate class here: android CountDownTimer - additional milliseconds delay between ticks)
Original Answer
I have a couple pointers:
Have you defined a maximum value for your ProgressBar?
bar.setMax(9);
I suggest loading i as the progress instead of the constant value of 10:
bar.setProgress(i);
If you still do not see any progress ensure that you are not in indeterminate mode:
bar.setIndeterminate(false);
(This assume that you are using a ProgressBar that can depict progress.)
Addition
Move this code into onCreate():
bar = (ProgressBar)findViewById(R.id.progressbar);
bar.setIndeterminate(false); // May not be necessary
bar.setMax(9);
Then move this line to loadQuestion():
bar.setProgress(i);
Otherwise the progress will never be updated since you only create one CountDownTimer and you never actually call startCountdownTimer().