I have this code in an attempt to have my app change it's background every 5 seconds, however, it only displays the first image in my array. Is there a simple tweak to this I can make so it will run through the 5 different images continuously??
Here is what I have in my MainActivity.class
int count=0; //outside oncreate
//all that is below is within oncreate
final int[] drawablearray=new int[]{R.drawable.one,R.drawable.two,R.drawable.three,R.drawable.four,R.drawable.five};
new Handler().postDelayed(new Runnable() {
public void run() {
if(count<drawablearray.length){
MainActivity.this.getWindow().
setBackgroundDrawableResource(drawablearray[count]);
count++;
}
else{
count=0;
}
}
}, 5000);
Thanks for all and any help!!
You need to call the method recursivly. The way you have currently set it up you only call it once.
int count =0;
boolean abort;
onResume(){
super.onResume();
abort = false;
this.changeBackground(count);
}
onPause(){
abort = true;
super.onPause();
}
private void changeBackground(int count){
if (abort)
return;
new Handler().postDelayed(new Runnable() {
public void run() {
if(count<drawablearray.length){
count++;
}
else{
count=0;
}
changeBackgroundColor(count);
changeBackground(count);
}
}, 5000);
}
private void changeBackgroundColor(int count){
if (abort)
return;
MainActivity.this.getWindow().
setBackgroundDrawableResource(drawablearray[count]);
}
Spin in an infinite loop. Also, you can remove the if-else condition with %:
while (changeBackground == true)
{
new Handler().postDelayed(new Runnable() {
public void run() {
MainActivity.this.getWindow().
setBackgroundDrawableResource(drawablearray[count]);
count = (count + 1) % drawablearray.length;
}, 5000);
}
PS: You may want to configure background change from some event, like on Event e, background changing should stop. One example of such event may be switching from one activity to other. You can achieve this by setting/resetting variable changeBackground.
int count=0;
#Override
protected void onCreate(Bundle savedInstanceState) {
requestWindowFeature(Window.FEATURE_NO_TITLE);
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
//all that is below is within oncreate
final int[] drawablearray=new int[]{R.drawable.one,R.drawable.two,R.drawable.three,R.drawable.four,R.drawable.five};
gettingBackground(drawablearray);
}
private void gettingBackground(final int[] drawablearray) {
// TODO Auto-generated method stub
new Handler().postDelayed(new Runnable() {
public void run() {
if(count<drawablearray.length){
LoginAct.this.getWindow().
setBackgroundDrawableResource(drawablearray[count]);
count++;
gettingBackground(drawablearray);
}
else{
count=0;
}
}
}, 5000);
}
Related
I have implemented one counter and onFinish() of first counter,I started second counter but the first counter not able to finish.Text "Bye Guyz" remain for some time so how to finish the text.
Please help me.
Thanks in advance.!!!
Code :-
counter= new CountDownTimer(10000, 1000) {
public void onTick(long millisUntilFinished) {
if (count == 0) {
tv.setText("First counter");
tv2.setVisibility(View.VISIBLE);
tv2.setText("Hello Guyz");
}
}
public void onFinish() {
if(!flag) {
tv2.setText("Bye Guyz");
count = 0;
try {
counter.cancel();
}catch (Exception e){}
}
else if(flag) {
counter1 = new CountDownTimer(9000, 1000) {
public void onTick(long millisUntilFinished) {
flag = false;
tv.setText("Second counter");
tv2.setVisibility(View.VISIBLE);
tv2.setText("Hello Girls");
count = 0;
}
public void onFinish() {
tv2.setVisibility(View.VISIBLE);
tv2.setText("Bye Girls");
count = 0;
}
}.start();
Did you "debug" the code to be sure the code is arriving to counter1 = new CountDownTimer(9000, 1000)?
Are you sure when the first counter arrives to onFinish() the flag variable is true?
Why do you call counter.cancel() in onFinish() when obviously the counter is already over?
public void onFinish() {
if(!flag) {
tv2.setText("Bye Guyz");
count = 0;
try {
counter.cancel();
}catch (Exception e){}
}
If you say your tv2 displays "Bye Guyz" it means that your flag is set to false, so the "else if" part is not being executed. onFinish() is only executed once, so you need to make sure the flag is set for true to start the second counter.
Also you shouldn't cancel your counter in onFinish() because it's already finished.
Here is my alternative is as follows
Create the custom Counterextending Thread
class Counter extends Thread {
private long timeOne, timeTwo;
private OnCounterFinishedListener mCounterFinishedListener;
private Thread t;
Activity activity = null;
Counter(Context context){
t = new Thread(this);
activity = (Activity)context;
}
#Override
public void run() {
try {
sleep(timeOne);
activity.runOnUiThread(new Runnable() {
#Override
public void run() {
mCounterFinishedListener.firstCounterFinished();
}
});
sleep(timeTwo);
activity.runOnUiThread(new Runnable() {
#Override
public void run() {
mCounterFinishedListener.secondCounterFinished();
}
});
} catch (InterruptedException e) {
e.printStackTrace();
}
}
void setTimes(long timeOne, long timeTwo){
this.timeOne = timeOne;
this.timeTwo = timeTwo;
}
public void start(OnCounterFinishedListener listener){
mCounterFinishedListener = listener;
t.start();
}
interface OnCounterFinishedListener{
void firstCounterFinished();
void secondCounterFinished();
}
}
Then inside your main thread you can start this counter as
final Counter counter = new Counter(this);
counter.setTimes(5000, 5000);
counter.start(new Counter.OnCounterFinishedListener() {
#Override
public void firstCounterFinished() {
// Update your first TextView
}
#Override
public void secondCounterFinished() {
// Update your second TextView
}
});
i'm working on an Android application in which i want the background image to be changed after every 5 seconds. i have all the images in my drawable folder.
i am giving the code which i am using but i am not getting the output. As an output i am getting a still image which is not changing.
Please help
Thanks
[CODE]
public class Home extends Activity {
public static int count=0;
int[] drawablearray=new int[]{R.drawable.slider_1,R.drawable.slider_2,R.drawable.slider_3,R.drawable.slider_4,R.drawable.slider_5};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home);
new Handler().postDelayed(new Runnable() {
public void run() {
if(count<drawablearray.length){
Home.this.getWindow().
setBackgroundDrawableResource(drawablearray[count]);
count++; //<<< increment counter here
}
else{
// reset counter here
count=0;
}
}
}, 5000);
}
}
You can achieve this using Timer
public class Home extends Activity {
public static int count=0;
int[] drawablearray=new int[]{R.drawable.slider_1,R.drawable.slider_2,R.drawable.slider_3,R.drawable.slider_4,R.drawable.slider_5};
Timer _t;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home);
lnMain = (LinearLayout) findViewById(R.id.lnMain);
_t = new Timer();
_t.scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
runOnUiThread(new Runnable() // run on ui thread
{
public void run() {
if (count < drawablearray.length) {
lnMain.setBackgroundDrawable(drawablearray[count]);
count = (count + 1) % drawablearray.length;
}
}
});
}
}, 5000, 5000);
}
}
Why don't you have a look at the ViewFlipper class
http://developer.android.com/reference/android/widget/ViewFlipper.html
final Handler h = new Handler();
Runnable r = new Runnable() {
public void run() {
Home.this.getWindow().setBackgroundDrawableResource(drawablearray[count]);
count += (count+1)%drawablearray.length; //<<< increment counter here
h.postDelayed(this, 5000);
}
};
now call like
h.postDelayed(r, 5000);
I think that would be easier to work with the xmls. You can change the background of the main layout of the activity.
Try something like this:
public class Home extends Activity {
public static int count=0;
int[] drawablearray=new int[]{R.drawable.slider_1,R.drawable.slider_2,R.drawable.slider_3,R.drawable.slider_4,R.drawable.slider_5};
LinearLayout ll;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home);
ll = (LinearLayout) findViewByID(R.id.mainlayout) //It depends of the name that you gave to it
new Handler().postDelayed(new Runnable() {
public void run() {
ll.setBackgroundDrawable(drawablearray[count]);
// or ll.setBackgroundResource(resid) if you want.
count += (count+1)%drawablearray.length;
}
}, 5000);
}
}
I am trying to change image after 1 second for image view.but its doesn't show any image on screen. following is code.please help.thank you.
code-
public class Shapes extends Activity {
Timer timer = new Timer();
int flag;
String images[]={};
ImageView iv;
static int v[]={R.drawable.round,R.drawable.rectangle};
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.shapes);
iv=(ImageView) findViewById(R.id.imageView1);
timer.schedule(new TimerTask() {
public void run() {
runOnUiThread(new Runnable() {
public void run() {
if (flag > 1) {
timer.cancel();
timer = null;
} else
iv.setImageResource(v[flag++]);
}
});
}
}, System.currentTimeMillis(), 1000);
}
}
how can i check resource image and change it
Use Handler instead of Timer
Handler handler = new Handler();
Runnable changeImage = new Runnable(){
#Override
public void run(){
if(flag>1)
handler.removeCallbacks(changeImage);
else{
iv.setImageResource(v[flag++]);
handler.postDelayed(changeImage, 1000);
}
}
};
start the first time from oncreate()
public void onCreate(Bundle b){
handler.postDelayed(changeImage, 1000);
}
timer.scheduleAtFixedRate(new TimerTask() {
public void run() {
runOnUiThread(new Runnable() {
public void run() {
flag++;
if (flag > 1) {
timer.cancel();
timer = null;
}
else
iv.setImageResource(v[flag]);
}
});
}
}, 1000, 1000); // wait 1 second before start.. then repeat every second..
It's because you put System.currentTimeMillis() as delay.
Try replacing that with 0, because the time should start after 0 ms.
I have two buttons in my sample application and I want to change the background image of the buttons one after another with 4-seconds delay, So far i have developed the code, you can see it below, but it gets sleep my application and display nothing.
Please somebody help me that I could do so.
int m =0;
int delay = 4; //Seconds
while(m < 4)
{
// int i = (int) (Math.random() * num + 1);
if(m==0)
{
button1.postDelayed(new Runnable()
{
public void run()
{
// TODO Auto-generated method stub
button1.setBackgroundResource(R.drawable.buttonyellow);
m++;
}
}, 1000*delay);
}
else if(m==1)
{
button2.postDelayed(new Runnable()
{
public void run()
{
// TODO Auto-generated method stub
button2.setBackgroundResource(R.drawable.buttonyellow);
m++;
}
}, 1000*delay);
}
if(m==2)
{
button1.postDelayed(new Runnable()
{
public void run()
{
// TODO Auto-generated method stub
button1.setBackgroundResource(R.drawable.buttonblue);
m++;
}
}, 1000*delay);
}
else if(m==3)
{
button2.postDelayed(new Runnable()
{
public void run()
{
// TODO Auto-generated method stub
button2.setBackgroundResource(R.drawable.buttonblue);
m++;
}
}, 1000*delay);
}
}
int mark = 0;
button2.postDelayed(new Runnable()
{
public void run()
{
switch(mark++){
case 0:button2.setBackgroundResource(R.drawable.buttonyellow); break;
case 1:button2.setBackgroundResource(R.drawable.buttongreen); break;
..ect
}
if(mark==Max)mark=0;
button2.postDelayed(this,4000);
}
}, 4000);
Note, this will go on till the end of time, or when your app stops.
postDelayed doesn't delay execution of the current thread, so your thread is stuck posting the m == 0 case repeatedly.
You probably want your posted Runnable to invoke some method that not only sets the background and increments the number, but also calls this logic (to choose a new Runnable to post) again.
e.g. (warning: untested code)
// assuming button1 and button2 are available
new Runnable() {
private int m = 0;
private final int delay = 4000;
#Override
public void run() {
if (m == 0) {
button1.setBackgroundResource(R.drawable.buttonyellow);
button1.postDelayed(this, delay);
} else if (m == 1) {
button2.setBackgroundResource(R.drawable.buttonyellow);
button2.postDelayed(this, delay);
}
// more cases here -- also consider making m wrap around
m++;
}
}.run();
Naturally this should be invoked on the UI thread (if it's not called on the UI thread, it should be dispatched to the UI thread with post or similar).
Your while loop is causing your UI thread to wait for these operations to complete. Your best two options would be to call this inside a new thread:
new Runnable() {
#Override
public void run() {
//Your code
}
}.run();
Or to embed them in a chain:
button1.postDelayed(new Runnable()
{
public void run()
{
button1.setBackgroundResource(R.drawable.buttonyellow);
button2.postDelayed(new Runnable()
{
public void run()
{
button2.setBackgroundResource(R.drawable.buttonyellow);
button1.postDelayed(new Runnable()
{
public void run()
{
button1.setBackgroundResource(R.drawable.buttonblue);
button2.postDelayed(new Runnable()
{
public void run()
{
button2.setBackgroundResource(R.drawable.buttonblue);
}
}, 1000*delay);
}
}, 1000*delay);
}
}, 1000*delay);
}
}, 1000*delay);
i got thread exception in android , what i intend to do is, while clicking a button i started a thread going to dynamically invoke the handler ,handler update the text view with integer value , while reaching integer 10, i going to stop the thread and have to show an alert ,but it will cause an error, what i possibly doing is shown below
public class sample extends Activity implements Runnable{
public Camcorder()
{
try{
counterThread = new Thread(this);
}catch(Exception ee)
{
}
}
public void run()
{
try{
while(counterFlag)
{
System.out.println("The time starts at : "+counter);
Thread.sleep(1000);
calculate(counter);
counter++;
}
}catch(Exception ee){
System.out.println("Err in ee : "+ee);
}
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
c=this.getApplicationContext();
requestWindowFeature(Window.FEATURE_NO_TITLE);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
setContentView(R.layout.main);
authalert3 = new AlertDialog.Builder(this);
authalert3.setTitle("Save Video");
authalert3.setMessage("Do you want to save this Video?");
authalert3.setPositiveButton("Yes", null);
Button test = (Button) findViewById(R.id.widget33);
test.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
counter = 0;
counterFlag = true;
counterThread.start();
}
});
public void calculate(int counter2) {
// TODO Auto-generated method stub
if(counter2<60){
if(counter2<10)
{
smin="0"+counter2;
}
else{
smin=""+counter2;
}
}
else{
hours++;
counter=0;
smin="00";
if(hours<10){
shours="0"+hours;
}
else{
shours=""+hours;
}
}
handler.sendEmptyMessage(0);
}
Handler handler = new Handler(){
public void handleMessage(android.os.Message msg) {
String tes=shours+":"+smin;
time.setText(tes);
test();
};
};
public void test(){
duration=1;
if(duration==hours){
counterFlag = false;
videoPath=camcorderView.stopRecording();
authalert3.create().show();
counterThread.stop();
}
}
the error is thrown at counterThread.stop();
Anyone suggest me , how to solve this error.
You don't stop threads by calling counterThread.stop. This method is deprecated. In your case, by setting counterFlag = false; your thread should be stopping itself.
You will also be getting an exception if you click twice on your button: you cannot call start on a Thread that has already been started. You must create a new instance of that Thread and start that new instance (stop the old instance before if necessary).
You can see that SO answer for some sample code on how to create/stop threads: Android thread in service issue. I suggest that you also read some tutorial on Java Threads (this is not specific to Android).
Additionally I think that you don't need a thread at all, you are doing nothing complicated and thus you could simply use the handler to do all the work:
private static final int MSG_REFRESH_UI = 0;
private static final int MSG_UPDATE_COUNTER = 1;
private int counter = 0;
Handler handler = new Handler(){
public void handleMessage(android.os.Message msg) {
if (msg.what==MSG_REFRESH_UI) {
String tes=shours+":"+smin;
time.setText(tes);
test();
} else if (msg.what==MSG_UPDATE_COUNTER) {
counter++;
if (counter<10) {
calculate(counter);
handler.sendEmptyMessageDelayed(MSG_UPDATE_COUNTER, 1000);
handler.sendEmptyMessage(MSG_REFRESH_UI);
}
}
};
};
public void onResume() {
handler.sendEmptyMessage(MSG_UPDATE_COUNTER);
}
public void calculate(int counter2) {
if (counter2<10) {
smin = "0"+counter2;
} else if (counter2<60) {
smin = ""+counter2;
} else{
hours++;
counter=0;
smin="00";
if(hours<10){
shours="0"+hours;
} else {
shours=""+hours;
}
}
}
This will stop the thread at 10
while(counterFlag)
{
System.out.println("The time starts at : "+counter);
Thread.sleep(1000);
calculate(counter);
counter++;
if(counter == 10) counterFlag = false;
}