In my android project, I have a countdown that randomizes a boolean for an array. The problem is, every time it ticks it always creates the array and the for loop. Can someone help me how to import my codes on a seperate class and method? I just want to call the returned value of an array in my countdown while it loops on a separate class. Please help me, TIA! :)
This is my countdown inside my onCreate():
new CountDownTimer(300000, 1000) {
public void onTick(long msUntilFinished) {
txtCounter.setText("" + msUntilFinished/1000);
ImageView[] pic= {img1, img2, img3, img4, img5};
Random aRandom = new Random();
for (int i=0;i<12;i++){
arrays[i] = aRandom.nextBoolean();
if(arrays[i]){
pic[i].setImageResource(R.drawable.show);
appear = true;
} else {
pic[i].setImageResource(R.drawable.hide);
appear = false;
}
}
} // end of onTick
public void onFinish() {
txtCounter.setText("done!");
}
}.start();
If you don't want the array to be created each time it ticks just place the array initialization outside of the thread like this:
for (int i=0;i<12;i++){ arrays[i] = aRandom.nextBoolean();}
new CountDownTimer(300000, 1000)
{
...
}.start();
Important: "arrays" has to be final. If you cannot do this then you have to do:
for (int i=0;i<12;i++){ arrays[i] = aRandom.nextBoolean();}
final SomeClass[] finalArray = arrays;
new CountDownTimer(300000, 1000)
{
...
if(finalArray[i]) ...
...
}.start();
Related
Android. I am trying to set background colour at time to make some sort of trainer. But this loop set background colour for all 4 LivearLayouts at ONE TIME - after the last iteration. And i need to do it one by one with pauses. How can i do it?
private LinearLayout[] lls;
lls = new LinearLayout[4];
lls[0] = findViewById(R.id.ll01);
lls[1] = findViewById(R.id.ll02);
lls[2] = findViewById(R.id.ll03);
lls[3] = findViewById(R.id.ll04);
public void onClick(View view) throws InterruptedException {
for (int i = 0; i < 4; i++) {
Thread.sleep(3000);
lls[i].setBackgroundColor(Color.parseColor("red"));
}
}
Such a code changes colour for all 4 objects at once - after the end of the 4th iteration. Prior to this, the colour of none has changed.
I think you should use a handler instead of for loop. Handlers are more convenient for delaying and doing some stuff. I am putting some edited code for you.
private LinearLayout[] lls;
private Long timeInMillis = 3000L;
private Handler handler;
private Runnable runnable;
private int index = 0;
private void setColors(){
lls = new LinearLayout[4];
lls[0] = findViewById(R.id.ll01);
lls[1] = findViewById(R.id.ll02);
lls[2] = findViewById(R.id.ll03);
lls[3] = findViewById(R.id.ll04);
handler = new Handler();
runnable = new Runnable() {
#Override
public void run() {
if(index!=lls.length){
lls[index++].setBackgroundColor(Color.parseColor("red"));
handler.postDelayed(runnable,timeInMillis);
}
}
};
handler.postDelayed(runnable,timeInMillis);
}
It was wrong code. You cant change smth in activity in one thread. It was solved by adding thread with loop that sends Broadcast messages for BroadcastReciever in MainActivity.
I am pretty new on programing, and I am having a hard time trying to figure out how to make a random countdowntimer. This random countdowntimer was supposed to execute an object after the time (between 3-10 sec) has reached zero.And I really don´t know how to do that. Could someone please give me some examples on how I maybe could solve this problem.
Thanks!
countDownTimer = new CountDownTimer(random value, tick value) {
public void onTick(long millisUntilFinished) {
}
public void onFinish() {
}
}
};
you can put random value as a value 3-10 its means onFinish called after this time
to create random value use code below
Random r = new Random();
int randomInt = r.nextInt(10 - 3) + 3;
int time = new Random().nextInt(8) + 3;
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
// execute yor code
}
},time * 1000);
Use this. Hope help you.
Ok, I have got following code from https://github.com/hongyangAndroid/Android-CircleMenu . Here, from print trace, I came to find that constructor is only invoked once, whereas run() method is recursively called till some condition.
My question is, why only run() method is recursively called from postDelayed(), why not constructor? and how variable anglePerSecond retains the value ? I want to understand it's flow. Thanks you.
//Automatic scrolling tasks
private class AutoFlingRunnable implements Runnable{
private float anglePerSecond;
public AutoFlingRunnable(float velocity){
this.anglePerSecond = velocity;
}
public void run(){
if((int)Math.abs(anglePerSecond) < 20){
isFling = false;
return;
}
isFling = true;
//anglePerSecond/30 in order to avoid rolling too fast
mStartAngle += (anglePerSecond/30);
//Gradually reduce this value
anglePerSecond /= 1.0666F;
postDelayed(this, 30);
//gradually reduce this value
requestLayout(); //re-layout views
}
}
When you want to update the textView in the Activity, for example , a textView with the countdowntimer, you normally update it with the following code
final int time = 50;
final TextView textView = new TextView(this);
textView.postDelayed(new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
textView.setText(String.format("Remaing Time : %d s", time));
}
/*
* Update it after 1 second
* 1秒後更新
*/
},1000);
If you understand the above code, then try to understand the following
textView.postDelayed(new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
textView.setText(String.format("Remaing Time : %d s", time));
/*
* Update it after 1 second
* 1秒後更新
*/
textView.postDelayed(this, 1000);
}
/*
* Update it after 1 second
* 1秒後更新
*/
},1000);
Actually, it is the same progress inside the library you provided.
It is dosing sth like that.
1.call AutoFlingRunnable consturctor to create
2.Method call in line 366
3.run the AutoFlingRunnable run() method
4.run the same runnable run() method after 0.03 second in line 574
5.back to step 3
I am making a piano app in which I need to emulate pressing keys in order to show the user the notes of a song. By using a handler, I am able to make a delay pressing up and down a key.
However, I am not able to make a delay between all the keys which have to be touched. I thought something like this, but I only see the last 2 notes get pressed and sound.
final String[] keys = {"1b","2w","9b","10w","11b","12w"};
handler = new Handler(Looper.getMainLooper());
for(int i = 0; i < keys.length - 1; i++) {
final int nextKey = i+1;
//Method in which I used other handler to delay pressing up and down
pressKey(keys[i]);
//Next key i would like to get pressed with a delay
handler.postDelayed(new Runnable() {
#Override
public void run() {
pressKey(keys[nextKey]);
}
},1500);
}
Instead of using for, use a runnable that will keep posting itself with the specified delay:
new Runnable()
{
int nextKey = 0;
#Override
public void run()
{
pressKey(keys[nextKey]);
if (++nextKey < keys.length)
handler.postDelayed(this, 1500);
// else no more keys
}
}.run();
I feel kinda stupid after all the night trying to figure it out. I just had to make a variable with the delay, and increment it in each iteration.
You can do this with a thread if in pressKey method there is no work that needs to be done in the UI thread.
new Thread(
new Runnable(){
#Override
public void run(){
for(int i = 0; i < keys.length - 1; i++) {
pressKey(keys[i]);
Thread.sleep(1500);
}
}
}
).run();
In Java for Android, I want to create a variable that increases by 1 every second, in other words, it counts, that way I can check to see if a function has been called in the past 3 seconds, and if not, I want it to do something different than if it had been.
Is there any built-in way to do this? I'm familiar with the Timer class, but it doesn't seem to work the way I would want it to.. is there anything else?
tl;dr: I want to create a variable that increases by 1 every second, so I can use it to treat a function differently based on how long it has been since its last call. Is there an easy way to do this? If not, what is the hard way to do this?
Why not store the last time the method was called instead, then check it against the current time?
private long timeLastCalled;
public void someMethod() {
timeLastCalled = SystemClock.elapsedRealTime();
}
public boolean someMethodCalledRecently() {
return (SystemClock.elapsedRealTime() - timeLastCalled) > 3000;
}
final int[] yourVariable = new int[1];
yourVariable[0] = 0;
updateVariableTimer = new CountDownTimer(howLongYouWantTimerToLast, 1000) {
#Override
public void onTick(long l) {
yourVariable[0] += 1;
}
}.start();
Or Alternatively to do it with a flag instead of keeping track of variable counting:
final boolean functionCalledRecently = false;
hasFunctionBeenCalledRecentlyTimer = new CountDownTimer(3000, 1000) {
#Override
public void onTick(long l) {
functionCalledRecently = true;
}
#Override
public void onFinish() {
functionCalledRecently = false;
}
}.start();
If you just need to see if the method has been called within the last 3 seconds you can use a Handler and a Boolean flag to acomplish this.
private Handler mHandler = new Handler();
private boolean wasRun = false;
mHandler.postDelayed(new Runnable() {
#Override
public void run() {
if(wasRun){
//whatever you want to do if run
}
mHandler.postDelayed(this, 3000);
}
},3000); //3 sec
In this example the Handler will run on a 3 second delay. Each time it runs it will check to see if the other method was perviously called by evaluating if(wasRun). This way you can change what happens if the method was/was not called. The handler will then start iself again on another 3 second delay. All you have to do then is update the wasRun flag to be true if your method was called, or false if it was not. .