I have two Buttons in main View, Button1 and Button2. How can I disable Button1 for specific time period after that time period it should Enable again.
Use a countdown Timer.
Say you have button button1 ;
button1.setEnabled(false);
new CountDownTimer(5000, 10) { //Set Timer for 5 seconds
public void onTick(long millisUntilFinished) {
}
#Override
public void onFinish() {
button1.setEnabled(true);
}
}.start()
Aba: Applied correct View.setEnabled method.
Here is an example:
Handler handler = new Handler();
handler.postDelayed(new Runnable(){
#Override
public void run(){
button.setEnabled(false);
}
}, 5000);
Rest, figure out yourself.
You can call this method. Try this once
private void blink(){
final Handler handler = new Handler();
new Thread(new Runnable() {
#Override
public void run() {
int timeToBlink = 5000;
try{
Thread.sleep(timeToBlink);
}catch (Exception e) {
}
handler.post(new Runnable() {
#Override
public void run() {
if(button.isEnabled()){
button.setEnabled(false);
}else{
button.setEnabled(true);
}
blink();
}
});
}
}).start();
}
By calling this method You will get the effect you wanted
private fun initButton() {
button.setOnClickListener {
it.isEnabled = false
it.postDelayed({ it.isEnabled = true }, 3000)
//do stuff
}
}
This works in Kt, does require a handler tho
In the simplest way
yourView.setEnabled(false);
yourView.postDelayed(() -> yourView.setEnabled(true), 5000); // Wait for 5 seconds
Related
I have a situation where I need to update the notification progress bar after some few more milliseconds. If I use notification manager to update the progress, then the notification will show up even after calling stopForground(true) which is not what I need.
Here is the sample code using the notification manager to update.
private void doStuff() {
// starting in foreground
startForeground(123, notification.build());
final Thread thread = new Thread(new Runnable() {
#Override
public void run() {
final Handler handler = new Handler(Looper.getMainLooper());
handler.postDelayed(new Runnable() {
#Override
public void run() {
timer++;
if(timer > 10){
stopForeground(true);
stopSelf();
return;
}
if(!bound){
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
notificationManager.notify(123, notification.setProgress(10, timer, false).build());
}
}, 2000);
}
handler.postDelayed(this, 1000);
}
}, 1000);
}
});
thread.start();
}
otherwise, if I use startForground() way, the notification won't show up after the 2000 milliseconds and I get the desired behavior as shown below:
private void doStuff() {
// starting in foreground
startForeground(123, notification.build());
final Thread thread = new Thread(new Runnable() {
#Override
public void run() {
final Handler handler = new Handler(Looper.getMainLooper());
handler.postDelayed(new Runnable() {
#Override
public void run() {
timer++;
if(timer > 10){
stopForeground(true);
stopSelf();
return;
}
if(!bound){
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
startForeground(123, notification.setProgress(10, timer, false).build());
}
}, 2000);
}
handler.postDelayed(this, 1000);
}
}, 1000);
}
});
thread.start();
}
My question is if there would be something wrong I'm not aware of using this way because I have never seen anyone doing it. Please help! Thanks!
After click button I would like to change its color, then wait one second and change its color back.
This is my code:
public void click(final View view) throws InterruptedException {
final Button btn = findViewById(view.getId());
btn.setBackgroundColor(Color.parseColor("#0000ff"));
btn.setClickable(false);
Thread t = new Thread(new Runnable() {
#Override
public void run() {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
t.start();
t.join();
btn.setBackgroundColor(Color.parseColor("#e2e2e2"));
btn.setClickable(true);
}
It doesn't work. I've checked it with more complex code and debugger and it looks like all UI changes are made collectively after finish this function.
I've found this thread: apply ui changes immediately and tried to put setBackgroundColor() and setClickable() into runOnUiThread function:
runOnUiThread(new Runnable() {
#Override
public void run() {
btn.setBackgroundColor(Color.parseColor("#0000ff"));
btn.setClickable(false);
}
});
But it also doesn't work. What should I do?
Something like this :
private final Handler handler = new Handler();
public void click(final View view) {
view.setBackgroundColor(Color.parseColor("#0000ff"));
view.setClickable(false);
handler.postDelayed(() -> {
view.setBackgroundColor(Color.parseColor("#e2e2e2"));
view.setClickable(true);
}, 1000);
}
#Override protected void onPause() {
super.onPause();
handler.removeCallbacks(null);
}
The question is not very clear. However, I am trying to summarize the question that I have understood from your question.
You are trying to set a button's background color on clicking on it and change it back after some time. If this is the situation, then I think your idea of how threads work is wanting.
In your code, the button will change the color immediately as the sleep that you are using is running in another thread (other than UI thread). The code is executed correctly, however, you cannot see the effect of the Thread.sleep as its running in a separate thread.
So all you need to do here is to change the background color again inside the thread. Modify your code like the following.
public void click(final View view) throws InterruptedException {
final Button btn = findViewById(view.getId());
btn.setBackgroundColor(Color.parseColor("#0000ff"));
btn.setClickable(false);
Thread t = new Thread(new Runnable() {
#Override
public void run() {
try {
Thread.sleep(1000);
btn.setBackgroundColor(Color.parseColor("#e2e2e2"));
btn.setClickable(true);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
t.start();
}
This should work.
I have created a demo trying to show what the code will do.
However, using Handler in case of updating UI elements in this specific case is recommended. Please see the comments below.
public void click(final View view) throws InterruptedException {
final Button btn = findViewById(view.getId());
btn.setBackgroundColor(Color.parseColor("#0000ff"));
btn.setClickable(false);
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
btn.setBackgroundColor(Color.parseColor("#e2e2e2"));
btn.setClickable(true);
}
}, 1000);
}
Not sure why that wouldn't work, but I've done something similar with
delayHandler = new Handler();
delayHandler.postDelayed(new Runnable() {
#Override
public void run() {
runOnUiThread(new Runnable() {
#Override
public void run() {
//change stuff on ui
}
});
}
}, 1000);
if that doesn't work the only other functional difference in my code is that instead of btn being a final Button it's a private global variable in my activity.
Hope the following code will help :
btn.setBackgroundColor(Color.RED); // color you want for a second
new CountDownTimer(1000, 1000) {
#Override
public void onTick(long arg0) {
// TODO Auto-generated method stub
}
#Override
public void onFinish() {
btn.setBackgroundColor(Color.BLUE); //to change back color to prior state
}
}.start();
Try this,i think it's work for you..
final Button bPdf = findViewById(R.id.pdf);
bPdf.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
bPdf.setBackgroundColor(Color.parseColor("#0000ff"));
new CountDownTimer(1000, 50) {
#Override
public void onTick(long arg0) {
// TODO Auto-generated method stub
}
#Override
public void onFinish() {
bPdf.setBackgroundColor(Color.parseColor("#e2e2e2"));
}
}.start();
}
});
How do i set a timer for TextView ? This code keeps crashing my app
final TextView textwel = (TextView) findViewById(R.id.welcometext);
Thread timer = new Thread() {
public void run() {
try {
// this should sleep for 4 seconds
sleep(4000);
} catch (InterruptedException e) {
e.printStackTrace();
}
textwel.setText("Welcome");
}
};
start the timer
timer.start();
That won't work.
Since the new thread that you create is not the UI thread, you can't update the UI (setting the text of a text view) on that thread.
A better way to do this would be to use the android.os.Handler class. It has a postDelayed method that will execute a Runnable with a delay. Here is the docs.
Alternatively, you can use this Timer class I wrote, which encapsulates a Handler instance and has a simple interface:
import android.os.Handler;
public class Timer {
private Handler handler;
private boolean paused;
private int interval;
private Runnable task = new Runnable () {
#Override
public void run() {
if (!paused) {
runnable.run ();
Timer.this.handler.postDelayed (this, interval);
}
}
};
private Runnable runnable;
public int getInterval() {
return interval;
}
public void setInterval(int interval) {
this.interval = interval;
}
public void startTimer () {
paused = false;
handler.postDelayed (task, interval);
}
public void stopTimer () {
paused = true;
}
public Timer (Runnable runnable, int interval, boolean started) {
handler = new Handler ();
this.runnable = runnable;
this.interval = interval;
if (started)
startTimer ();
}
}
Gist
You would probably use it like this:
Runnable run = new Runnable() {
public void run() {
textwel.setText("Welcome");
}
};
Timer timer = new Timer(run, 4000, true);
P.S. setting the textview's text to "Welcome" every 4 seconds is pointless.
You can you use CountDownTimer api to update TextView timer which is very easy to use and convenient.
Here is the simple example:
TextView tvTime = (TextView)findViewById(R.id.tv_time);
CountDownTimer countDownTimer = new CountDownTimer((durationInMilis * 60000), 1000) {
#Override
public void onTick(long millisUntilFinished)
{
String hms = String.format("%02d:%02d:%02d", TimeUnit.MILLISECONDS.toHours(millisUntilFinished),
TimeUnit.MILLISECONDS.toMinutes(millisUntilFinished) - TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS.toHours(millisUntilFinished)),
TimeUnit.MILLISECONDS.toSeconds(millisUntilFinished) - TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(millisUntilFinished)));
tvTime.setText(hms);
}
#Override
public void onFinish()
{
// Do your other task on finish
}
}.start();
This code this will update tvTime text every second and run for sepecified amount of time in durationInMilis. Output will look like hh:mm:ss e.g 01:23:57
If you don't want show anything on update then leave onTick() callback blank and update your TextView in onFinish(). Just pass value to parameter durationInMilis for which you want to run timer.
If you have any doubt please feel free to comment.
//use it, its easy and simple
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
textwel.setText("Welcome");
}
}, 4000);
why are you using textview??
Chronometer is a class provided by android that implements a simple timer so my suggestion is use it in place of textview.
here is the official link
try this , it will work 100% and also UI will not stuck
Thread timer = new Thread() {
public void run() {
try {
// this should sleep for 4 seconds
sleep(4000);
} catch (InterruptedException e) {
e.printStackTrace();
}
// after sleep call a UI thread
runOnUiThread(new Runnable() {
#Override
public void run() {
textwel.setText("Welcome");
}
});
}
};
I am working on an Android application in which I allow the users to enter text as many time they want in a single minute. But the thread is not terminating after a minute. My code:
public void startTimer(View view) throws Exception {
final Thread t = new Thread(new Runnable() {
final Button myButton = (Button) findViewById(R.id.myButton);
EditText mEdit = (EditText) findViewById(R.id.myTextInput);
#Override
public void run() {
while (!Thread.currentThread().isInterrupted()) {
myButton.setOnClickListener(
new Button.OnClickListener() {
public void onClick(View v) {
Log.d("Tag", mEdit.getText().toString());
}
}
);
}
}
});
t.start();
ScheduledExecutorService exec = Executors.newSingleThreadScheduledExecutor();
exec.schedule(new Runnable() {
#Override
public void run() {
t.interrupt();
}
},1, TimeUnit.MINUTES);
}
better use CountDownTimer http://developer.android.com/reference/android/os/CountDownTimer.html
In your solution you try do something with UI state in not main thread - this can be a issue.
Your thread isn't "taking input". It's continuously making and installing new onClick listeners.
You don't need a thread for what you're trying to do. You need a timer that goes off after one minute, and you need a listener that either accepts the input or rejects it depending on whether the timer has gone off yet or not.
You have two solutions you can do:
1st Solution:
You can simply use a handler.
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
t.interrupt();
}
}, 60000);
2nd Solution:
You can also use a CountDownTimer.
new CountDownTimer(60000, 1000) {
#Override
public void onTick(long millisUntilFinished) {
}
#Override
public void onFinish() {
t.interrupt();
}
}.start();
I am new in android development and now my launcher activity show only 5 seconds and after that I want to check the user is logged in or not function and perform the actions.
here is my code.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
exactPreferences = getSharedPreferences("ExactPreference",MODE_PRIVATE);
setContentView(R.layout.activity_landing_page);
session = exactPreferences.getString(Model.getSingleton().SHARED_SESSION_ID,null);
Log.i("Session Id",session);
displayData(); // I want to perform this function after 5 seconds.
}
private void displayData() {
if(session.equals("")){
Intent loginIntent = new Intent(LandingPage.this,
LoginActivity.class);
startActivity(loginIntent);
Log.i("User Logged In", "False");
}
else
{
Intent objIntent = new Intent(LandingPage.this,
IndexPageActivity.class);
startActivity(objIntent);
Log.i("User Logged In", "True");
}
}
You can use the Handler to add some delay.Call the method displayData() as below so that it will be executed after 5 seconds.
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
displayData();
}
}, 5000);
Note : Do not use the threads like Thread.sleep(5000); because it will block your UI and and makes it irresponsive.
Assign millisDelayTime variable with the milliseconds you desire to cause a delay. mActivity is an object of Activity for providing Application Context. In your case millisDelayTime should be initialized with 5000
mActivity.runOnUiThread(new Runnable() {
#Override
public void run() {
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
//your code here
}
}, millisDelayTime);
}
});
Use a CountDownTimer
// There's a TextView txtCount in Main Activity
final int secs = 5;
new CountDownTimer((secs +1) * 1000, 1000) // Wait 5 secs, tick every 1 sec
{
#Override
public final void onTick(final long millisUntilFinished)
{
txtCount.setText("" + (int) (millisUntilFinished * .001f));
}
#Override
public final void onFinish()
{
txtCount.setText("GO!");
finish();
// Time's up - Start the Login Activity
final Intent tnt =
new Intent(getApplicationContext(), LoginActivity.class);
startActivity(tnt);
}
}.start();
Since, Handler is now deprecated so use this code :
new Handler(Looper.myLooper()).postDelayed(new Runnable() {
#Override
public void run() {
//do what you want
}
}, 5000);
Try this, code create CountDownTimer with one tick
timer = new CountDownTimer(5000, 5000)
{
public void onTick(long millisUntilFinished)
{
}
public void onFinish()
{
displayData();
}
};
timer.start();
long delay = 1000;
long period = 50000;
Timer task = new Timer();
task.scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
getDriver(sessionManager.getKEY(), ride_id);
}
}, delay, period);
For kotlin way
Handler().postDelayed({
//do something
}, 5000)
When possible, try to avoid using postDelayed. It is a bad practice, since it can lose the reference to the objects that you want to draw on your screen and cause a NPE. Use a Handler instead. First of all, create a global variable Handler in which you will have to "handle" the logic for your code. Do so by using the function handleMessage.
Handler handler = new Handler(){
#Override
public void handleMessage(Message msg) {
if(msg.what == 1){
// your code here
}
}
};
Then, wherever you want to execute it, just call the function:
// 1 is the ID of your process
handler.sendEmptyMessageDelayed(1, 5000);
Please remember that in the onDestroyView method (in a Fragment) or the onDestroy (in an Activity) you will have to call
handler.removeMessages(1)
The best option to achieve this is using a Handler:
int TIME = 5000; //5000 ms (5 Seconds)
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
function(); //call function!
}
}, TIME);