Hi im trying to get a button to flash, I have tried to change the background with a loop, but not having much luck any suggestions thanks
int count = 0;
while (count < 10000) { // test: boolean test within (..)
if (count % 2 != 0) {
helpt.setBackgroundColor(getResources().getColor(R.color.Blue));
}
else {
helpt.setBackgroundColor(getResources().getColor(R.color.Red));
}
count = count + 1;
}
This will change the colour every one second:
int count = 0; //Declare as instance variable
Activity activity; //Declare as instance variable
//Inside onCreate()
activity = this;
new Timer().schedule(new TimerTask() {
#Override
public void run() {
activity.runOnUiThread(new Runnable() {
public void run() {
if (count < 10000) {
if (count % 2 != 0) {
helpt.setBackgroundColor(getResources()
.getColor(android.R.color.black));
} else {
helpt.setBackgroundColor(getResources()
.getColor(android.R.color.white));
}
count = count + 1;
}
}
});
}
}, 0, 1000);
You dont have any form of delay, of course you wouldn't see it flash. It will run through that loop very quickly. Also for standards you should be using a for loop, not a while. For is explicityly for when you know how many times you are going to run.
Related
I am struggling with wierd issue, I've made countdown timer with round progressbar. Sometimes as the time runs out, there is few pixels of progressbar left (orange between x and t), even though it reaches onFinish function. It's not a problem no more as I set countDownInterval to 10, but then showProgress function doesn't quite work, it enters else statement, but doesn't actually set progressbar to 0.
private void startCountingTime() {
if (!counting) {
timeLeftInMillis = maxTime * 1000;
endTime = System.currentTimeMillis() + timeLeftInMillis;
}
if (maxTime != 0) {
countDownTimer = new CountDownTimer(timeLeftInMillis, 100) {
#Override
public void onTick(long l) {
String text = String.format(Locale.getDefault(), "%02d:%02d",
TimeUnit.MILLISECONDS.toMinutes(l) % 60,
TimeUnit.MILLISECONDS.toSeconds(l) % 60);
timeLeftInMillis = l;
showProgress(l, maxTime);
counting = true;
question.setText(exposePasswd ? text : currentQuestion);//displays the timer or question
}
#Override
public void onFinish() {
step = 4;
counting = false;
progressBar.setProgress(0);
question.setText("Out of time! doubletap for next question");
}
}.start();
} else {
question.setText("tap to reveal, doubletap for next");
exposePasswd = false;
}
}
private void showProgress(long l, int maxTime) {
maxTime = maxTime * 1000;
int prog = (int) ((l * 100) / maxTime);
if (exposePasswd) {
// progressBar.setVisibility(View.VISIBLE);
if (progressBar.getProgress() == 0) {
progressBar.setProgress(prog);
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
progressBar.setProgress(prog, true);
} else {
progressBar.setProgress(prog);
}
} else {
progressBar.setProgress(0);
Log.wtf("idk","setted");
}
}
Any ideas how to fix it?
Im not sure, why this is happening, but you could probably easily bypass this issue by adding:
progressbar.setVisibility(Visibility.GONE);
in the else statement and
progressbar.setVisibility(Visibility.VISIBLE);
when the timer starts.
I'm coding the game "Simon", and I'm having some trouble figuring out how to use runnables and handlers. This is for the part of the game where the colors light up in a sequence pattern, right before the player has to press the buttons.
This is the code I have so far:
Handler handler = new Handler();
Runnable g = new Runnable() {
#Override
public void run() {
setBtnBackGround(oldColors[0], 10, mButtons[0]);
}
};
Runnable r = new Runnable() {
#Override
public void run() {
setBtnBackGround(oldColors[1], 10, mButtons[1]);
}
};
Runnable y = new Runnable() {
#Override
public void run() {
setBtnBackGround(oldColors[2], 10, mButtons[2]);
}
};
Runnable b = new Runnable() {
#Override
public void run() {
setBtnBackGround(oldColors[3], 10, mButtons[3]);
}
};
Also:
for (int i = 0; i < mGame.getLevel(); i++) {
int color = colors.get(i);
setBtnBackGround(newColors[color], 10, mButtons[color]);
if (color == 0) {
handler.postDelayed(g, 1000);
} else if (color == 1) {
handler.postDelayed(r, 1000);
} else if (color == 2) {
handler.postDelayed(b, 1000);
} else {
handler.postDelayed(y, 1000);
}
}
The buttons all light up at the same time, since, I guess, they're all placed one after another on the "message sequence"? How would I use runnables/handles to space apart the light-ups?
Thanks so much guys!
The reason all the buttons light up at the same time is because you for loop runs through all values of i without waiting at all in between.
So it effectively calls
//start loop
//i = 0
handler.postDelayed(g, 1000);
...
//i = 1
handler.postDelayed(r, 1000);
...
//i = mGame.getLevel()-1
handler.postDelayed(b, 1000);
//end loop
all at the same time.
There's no queue per-se, so you need to make it yourself by incrementing the delay depending on which i you're at. Try this:
int LIGHT_DURATION = 1000;
for (int i = 0; i < mGame.getLevel(); i++) {
int color = colors.get(i);
int delay = LIGHT_DURATION*i;
setBtnBackGround(newColors[color], 10, mButtons[color]);
if (color == 0) {
handler.postDelayed(g, delay);
} else if (color == 1) {
handler.postDelayed(r, delay);
} else if (color == 2) {
handler.postDelayed(b, delay);
} else {
handler.postDelayed(y, delay);
}
}
I'm not sure what the parameters of setBtnBackGround(newColors[color], 10, mButtons[color]); mean/are but the way I'd do it, with the code I added above is as follows:
Add all the delayed handlers with the above for loop, passing the colour
In each handler set all buttons back to default and the selected colour button to the correct colour
I got it to work by creating a runnable for each unlit color and each lit color, so I had 8 runnables total with 1 handler. Then, as roarster suggested, I created a delay based on the iteration, like this:
for (int i = 0; i < mGame.getLevel(); i++) {
int color = colors.get(i);
if (color == 0) {
handler.postDelayed(newG, (long) ((0.1+i)*1000));
handler.postDelayed(oldG, (long) ((0.9+i)*1000));
} else if (color == 1) {
handler.postDelayed(newR, (long) ((0.1+i)*1000));
handler.postDelayed(oldR, (long) ((0.9+i)*1000));
} else if (color == 2) {
handler.postDelayed(newY, (long) ((0.1+i)*1000));
handler.postDelayed(oldY, (long) ((0.9+i)*1000));
} else {
handler.postDelayed(newB, (long) ((0.1+i)*1000));
handler.postDelayed(oldB, (long) ((0.9+i)*1000));
}
}
in my app I have a timer and stop/start buttons. Timer works with thread
when I click the button my timer starts working. when I click stop and start it seems like my thread works as 2 parallel threads.
How to stop the first thread and create the second ?
Here is the code
timer = new Thread(new Runnable() {
#Override
public void run() {
final boolean cont = mSharedPreferences.getBoolean("continuesMode", false);
final boolean statemant = !stopedAlgo && !mUserStop;
if(!statemant){
timerMinutes = 0;
timerHours = 0;
}
while(statemant){
time="";
if(timerMinutes>=60){
timerMinutes = 0;
timerHours++;
}
if(timerHours<10)
time = "0" + String.valueOf(timerHours)+":";
else
time = String.valueOf(timerHours)+":";
if(timerMinutes<10)
time += "0" + String.valueOf(timerMinutes);
else
time += String.valueOf(timerMinutes);
HeadSense.this.runOnUiThread(new Runnable(){
public void run(){
boolean state = mContinuousMode && !stopedAlgo && !mUserStop ;
if(!stopedAlgo && cont){
mTfsValue.setText(time);
timerMinutes++;
}
else{
timerMinutes = 0;
timerHours = 0;
}
}
});
try {
Thread.sleep(1*1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
timer.start();
Of my understanding your first Thread (or second) will never stop because of the following line:
final boolean statemant = !stopedAlgo && !mUserStop;
This is final, and will only be evaluated once and never change. If it evalutes to true when you create the Thread it will stay true and keep running.
You need to declare your boolean statemant as volatile here. What this does is give a hint to the compiler that certain optimizations cannot be taken because this variable is modified by external threads.
Also, you would be interested in this - How to stop a java thread gracefully?
Ok so I have created a game and it works perfectly, except I don't want the player to win after just one defeat I want him to have to kill 10 enemies well I created my spawnmore method and I know the problem I just don't know how to fix it, in my if statement I have it saying if(dead < 10) then do my stuff, when I only want it to do it once every time dead increments one if you get what I mean here's my method thanks
public void spawnMore(){
int delay = 1000;
Timer time = new Timer(delay, new ActionListener(){
public void actionPerformed(ActionEvent e){
if(WizardCells[BadGuy.getx()][BadGuy.gety()].getIcon() != null){
return;
}
if(WizardCells[BadGuy.getx()][BadGuy.gety()].getIcon() == null){
dead += 1;
}
if(dead < 10){
int where = (int)(10 + Math.random() *9);
BadGuy.spawnEnemy(where, where);
move();
}
}
});
time.start();
}
If I understand you correctly, you could just move the if statement inside the previous if statement:
public void spawnMore(){
int delay = 1000;
Timer time = new Timer(delay, new ActionListener(){
public void actionPerformed(ActionEvent e){
if(WizardCells[BadGuy.getx()][BadGuy.gety()].getIcon() != null){
return;
}
if(WizardCells[BadGuy.getx()][BadGuy.gety()].getIcon() == null){
dead += 1;
if(dead < 10){
int where = (int)(10 + Math.random() *9);
BadGuy.spawnEnemy(where, where);
move();
}
}
}
});
time.start();
}
I am working on an app that counts the number of questions marks in a few paragraphs of text.
After the scanning is done (which takes no time at all) I would love to have the total presented after the number goes from 0 to TOTAL. So, for 10: 0,1,2,3,4,5,6,7,8,9 10 and then STOP.
I have tried a couple of different techniques:
TextView sentScore = (TextView) findViewById(R.id.sentScore);
long freezeTime = SystemClock.uptimeMillis();
for (int i = 0; i < sent; i++) {
if ((SystemClock.uptimeMillis() - freezeTime) > 500) {
sentScore.setText(sent.toString());
}
}
Also I tried this:
for (int i = 0; i < sent; i++) {
// try {
Thread.sleep(500);
} catch (InterruptedException ie) {
sentScore.setText(i.toString());
}
}
I am sure these are both completely amateur attempts. Any help would be much-appreciated.
Thanks,
Richard
I've used a more conventional Android-style animation for this:
ValueAnimator animator = new ValueAnimator();
animator.setObjectValues(0, count);
animator.addUpdateListener(new AnimatorUpdateListener() {
public void onAnimationUpdate(ValueAnimator animation) {
view.setText(String.valueOf(animation.getAnimatedValue()));
}
});
animator.setEvaluator(new TypeEvaluator<Integer>() {
public Integer evaluate(float fraction, Integer startValue, Integer endValue) {
return Math.round(startValue + (endValue - startValue) * fraction);
}
});
animator.setDuration(1000);
animator.start();
You can play with the 0 and count values to make the counter go from any number to any number, and play with the 1000 to set the duration of the entire animation.
Note that this supports Android API level 11 and above, but you can use the awesome nineoldandroids project to make it backward compatible easily.
Try this:
private int counter = 0;
private int total = 30; // the total number
//...
//when you want to start the counting start the thread bellow.
new Thread(new Runnable() {
public void run() {
while (counter < total) {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
t.post(new Runnable() {
public void run() {
t.setText("" + counter);
}
});
counter++;
}
}
}).start();
The question is very old, but I am posting this so that it would help someone else.
I have used these 2 amazing libraries.
Try them
https://github.com/MasayukiSuda/CountAnimationTextView
Or
2. https://github.com/robinhood/ticker
Hope this helps :) Happy Coding!!!
Use TextSitcher
for the best effects. It will transform the text softly.
When coming to the change of the text use the below Code.
> int number = 0;
> Timer obj = new Timer();
> TimerTask tt = new TimerTask() {
> #Override public void run() {
> // TODO Auto-generated method stub
> textView.setText(number++);
> if(number < score)
> obj.schedule(tt, 200); } };
> obj.schedule(tt, 200);
Use a worker thread to do the waiting and update your UI thread.
You could use an AsyncTask, though it might be an overkill for this job. If you use this, In the doInBackground() loop over the number of sleep periods and after every sleep period, update the count in the UIthread.
There you go! Slukain just gave you the working code :P
Maybe try changing the for loop to something like:
int count = 0;
while (count != sent) {
if ((SystemClock.uptimeMillis() - freezeTime) > 500) {
count++;
sentScore.setText("" + count);
freezeTime = SystemClock.uptimeMillis();
}
}