Goal:
When you start the android app, the button should not be displayed after 5 seconds.
Problem:
The code doesn't work and what part am I missing?
Info:
*Im new in android
*The code is inspired from this page Android - Hide button during an onClick action
Thank you!
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Button button2 = (Button) findViewById(R.id.btn_test);
button2.setVisibility(GONE);
new Thread(new Runnable() {
#Override
public void run() {
try
{
//dummy delay for 5 second
Thread.sleep(5000);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
runOnUiThread(new Runnable() { //resetting the visibility of the button
#Override
public void run() {
//manipulating UI components from outside of the UI Thread require a call to runOnUiThread
button2.setVisibility(VISIBLE);
}
});
}
}).start();
}
}
This can be achieved in a simpler way. If your needed sequence is:
Start the app -> Display a button -> Wait 5 seconds -> Hide the button
final Button button2 = (Button) findViewById(R.id.btn_test);
button2.postDelayed(new Runnable() {
#Override
public void run() {
if (!isDestroyed() && !isFinishing()) {
button2.setVisibility(View.GONE);
}
}
},5000);
Otherwise, if you should display the button after 5 seconds after app launch, then just set button's visibility to GONE in your layout and change button2.setVisibility(View.GONE) to button2.setVisibility(View.VISIBLE) inside post delayed action
You need to set a listener to start your command, onCreate is the creation.
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
final Button button2 = (Button) findViewById(R.id.btn_test);
button2.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
button2.setVisibility(GONE);
new Thread(new Runnable() {
#Override
public void run() {
try
{
//dummy delay for 5 second
Thread.sleep(5000);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
runOnUiThread(new Runnable() { //resetting the visibility of the button
#Override
public void run() {
//manipulating UI components from outside of the UI Thread require a call to runOnUiThread
button2.setVisibility(VISIBLE);
}
});
}
}).start();
}
this code will hide the button AFTER onClick, start the thread, and after 5 seconds it will appear again.
Related
I'm very new to Android development. Can anyone help me with this snippet, I don't know why it works perfectly although I'm updating my TextView from the worker thread.
When I say works perfectly, I mean the TextView shows the value count without any problem.
So, My question is - "Is it really possible to update the UI from background thread and if not, where I'm wrong"
public class MainActivity extends AppCompatActivity {
TextView textView ;
private int count;
Button btn;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView = findViewById(R.id.textview);
btn = findViewById(R.id.startbtn);
btn.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View v) {
listen();
}
});
}
public void listen(){
new Thread(new Runnable() {
#Override
public void run() {
long time = System.currentTimeMillis();
while(System.currentTimeMillis()<=time +10000) {
count++;
}
textView.setText(count+"");
}
}).start();
}
}
Use
runOnUiThread(new Runnable() {
#Override
public void run() {
// Add UI code here
}
});
All UI updates should be done on the main thread.
I am trying to perform sort of a stop light function on a button press but instead there are two of every color. The desired functionality would be red, red, yellow, yellow, green, and green. I have tried to set a delay in between each color but it doesn't happen sequentially it just adds up the delays and they all show up at once.
Here is the snippet of the activity that I have tried to do this:
Button previewButton = (Button) findViewById(R.id.preview_visual_button);
final Button redButton1 = (Button) findViewById(R.id.red_button_1);
final Button redButton2 = (Button) findViewById(R.id.red_button_2);
final Button yellowButton1 = (Button) findViewById(R.id.yellow_button_1);
final Button yellowButton2 = (Button) findViewById(R.id.yellow_button_2);
final Button greenButton1 = (Button) findViewById(R.id.green_button_1);
final Button greenButton2 = (Button) findViewById(R.id.green_button_2);
redButton1.setVisibility(View.GONE);
redButton2.setVisibility(View.GONE);
yellowButton1.setVisibility(View.GONE);
yellowButton2.setVisibility(View.GONE);
greenButton1.setVisibility(View.GONE);
greenButton2.setVisibility(View.GONE);
if(previewButton != null) {
previewButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
int time = 100;
delay(time);
}
});
}
}
public void delay(final int c){
runOnUiThread(new Runnable() {
#Override
public void run() {
try {
Thread.sleep(c);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
Button redButton1 = (Button) findViewById(R.id.red_button_1);
Button redButton2 = (Button) findViewById(R.id.red_button_2);
Button yellowButton1 = (Button) findViewById(R.id.yellow_button_1);
Button yellowButton2 = (Button) findViewById(R.id.yellow_button_2);
Button greenButton1 = (Button) findViewById(R.id.green_button_1);
Button greenButton2 = (Button) findViewById(R.id.green_button_2);
redButton1.setVisibility(View.VISIBLE);
redButton2.setVisibility(View.VISIBLE);
yellowButton1.setVisibility(View.VISIBLE);
yellowButton2.setVisibility(View.VISIBLE);
greenButton1.setVisibility(View.VISIBLE);
greenButton2.setVisibility(View.VISIBLE);
}
}, c);
}
EDIT:
previewButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
int time = 1000;
redButton1.setVisibility(View.VISIBLE);
delay(time);
redButton2.setVisibility(View.VISIBLE);
delay(time);
yellowButton1.setVisibility(View.VISIBLE);
delay(time);
yellowButton2.setVisibility(View.VISIBLE);
delay(time);
greenButton1.setVisibility(View.VISIBLE);
delay(time);
greenButton2.setVisibility(View.VISIBLE);
}
});
}
public void delay(final int time) {
new Thread(new Runnable() {
#Override
public void run() {
try {
Thread.sleep(time);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
}
Because that's basically what the postDelayed method does. It runs the code in the runnable after the specified time. So it delays for 100ms then runs just turns all the buttons on at once. Also I'm not sure what you are trying to do by calling Thread.sleep() on your UI thread. I would suggest writing a new method that just runs a Thread.sleep() inside a separate thread and call it between each pair of button toggle commands. Kind of like this
public void pause(int time) {
new Thread(new Runnable() {
#Override
public void run() {
try {
Thread.sleep(time);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
}
Then basically call this in between each pair of button toggle statements. This should do the trick.
Update UI with Thread sleep
This will help answer the question if anyone visits in the future.
I'm pretty new to Android's Java (so please don't beat me up) and I have a question to my button action. The called method is running only one time. When I click the button the second time nothing happens anymore. I do not understand why. No errors, no flaws, the method is doing what is expected. Any hints?
Thanks!
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
TextView mainFortuneTextView;
Button mainFortuneButton;
private int counter, i, x;
//private int randomNumber;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
// 1. Access the TextView defined in layout XML
// and then set its text
mainFortuneTextView = (TextView) findViewById(R.id.fortuneTextView);
// 2. Access the Button defined in layout XML
// and listen for it here by using "this"
mainFortuneButton = (Button) findViewById(R.id.fortuneButton);
mainFortuneButton.setOnClickListener(this);
}
#Override
public void onClick(View v) {
// happens on button action in main view
runThread();
Random rnd = new Random();
x = rnd.nextInt(11) + 1;
}
private void runThread() {
mainFortuneButton.setEnabled(false);
new Thread() {
public void run() {
while (i++ < 10) {
try {
runOnUiThread(new Runnable() {
#Override
public void run() {
mainFortuneTextView.setText("#" + i);
}
});
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
// activate button again
runOnUiThread(new Runnable() {
#Override
public void run() {
mainFortuneButton.setEnabled(true);
}
});
}
}.start();
}
}
Your variable i used in your while is a field. That means that it will not reset. That's why the second time you call your thread the i value will be 10 and it will be called not again. You have to reset your i again before starting a new thread.
public class MainActivity extends Activity {
ImageView img;
MediaPlayer failure;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button bButton= (Button)findViewById(R.id.blueBtn);
img = (ImageView)findViewById(R.id.image);
img.setVisibility(View.VISIBLE);
failure= MediaPlayer.create(this,R.raw.failure_sound);
bButton.setOnClickListener(new View.OnClickListener(){
public void onClick(View v){
img.setVisibility(View.VISIBLE);
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
failure.start();
}
});
}
well thats my code.
I just want to make that when I press the button it'll show the image
then wait 1000 miliseconds, and then make a sound.
BUT(!) unfortunaltly when I press that button: the process waits 1000 ms, and then make the sound and shows the img.
help plz!!!
Replace your onClick handler:
public void onClick(View v){
img.setVisibility(View.VISIBLE);
v.postDelayed(new Runnable() {
public void run() { failure.start(); }
},1000);
}
With Thread.sleep(10000); you are causing the main thread to freeze and thus the UI cannot be updated for that amount of time.
If you want to wait for a certain amount of time to do something, you may use a Handler instead, so the UI can be updated in the meantime:
public void onClick(View v){
img.setVisibility(View.VISIBLE);
new Handler().postDelayed(new Runnable() {
public void run() {
failure.start();
}
}, 1000);
}
You're putting your UI thread to sleep, which causes your app to freeze and the image not showing up.
A better approach for this is to use a handler, which will execute code after a delay and will not freeze your UI.
A quick adaption of your clickListener would be:
bButton.setOnClickListener(new View.OnClickListener(){
public void onClick(View v){
img.setVisibility(View.VISIBLE);
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
failure.start();
}
}, 1000);
});
}
I have three layouts:
Layout1
-->onClick()-->show
Layout2
-->wait three seconds-->show
Layout3
The problem is that Layout2 is not shown. To set the layouts I use
setContentView(int);
The relevant code might be:
public class TrainingActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.layout1);
final Button inputButton = (Button)findViewById(R.id.inputButton);
inputButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
changeLayouts();
}
});
}
public void changeLayouts() {
setContentView(R.layout.layout2);
try {
TimeUnit.MILLISECONDS.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
setContentView(R.layout.layout3);
}
}
My idea was that Android might use something like an "Event-Loop" (like Qt) and my method would block the control to get back to the "Event-Loop" which would make the layout displayed.
But I couldn't find my error.
The problem why your layout2 is not shown is because of TimeUnit.MILLISECONDS.sleep(3000); - what you are doing here is you put your UI thread into sleep, so UI thread cannot process your request to change layout. And when it wakes up - it immediately sets layout3 that's why layout2 is not shown.
You might consider using Handler.postDelayed(Runnable, long) to postpone execution
So this should work as you expected:
public class TrainingActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.layout1);
final Button inputButton = (Button)findViewById(R.id.inputButton);
inputButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
changeLayouts();
}
});
}
public void changeLayouts() {
setContentView(R.layout.layout2);
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
setContentView(R.layout.layout3);
}
}, 3000);
}
}
Try this, it will surely work
public void changeLayouts() {
setContentView(R.layout.layout2);
Thread Timer = new Thread(){
public void run(){
try{
sleep(3000);
} catch(InterruptedException e){
e.printStackTrace();
} finally {
setContentView(R.layout.layout3);
}
}
}; Timer.start();
}