I want to have my runnable undate my UI every .75 second, I don't want to use AnsyTask. But the TextView is only set at the end of the for loop, any idea why?
...
robotWords = "........Hey hello user!!!";
wordSize = robotWords.length();
mHandler.postDelayed(r, 750);
}
private Runnable r = new Runnable()
{
public void run()
{
for(int i=0; i<wordSize; i++)
{
robotTextView.setText("why this words only display on the textView at last operation on this for loop?");
Log.i(TAG, robotWords.substring(0, i));
try
{
Thread.sleep(750);
} catch (InterruptedException e)
{
e.printStackTrace();
}
}
}
};
The TextView is only set at the end of the for loop because of this line Thread.sleep(750);
Your thread will sleep before the text is really set to your textview. I think you should call Handler.postDelayed every 750ms instead of using Thread.sleep(750); or use a CountDownTimer
new CountDownTimer(750 * wordSize, 750) {
public void onTick(long millisUntilFinished) {
robotTextView.setText("why this words only display on the textView at last operation on this for loop?");
Log.i(TAG, robotWords.substring(0, i));
}
public void onFinish() {
}
}.start();
You shouldn't be making calls to the UI thread from another thread.
use CountDownTimer
new CountDownTimer(wordSize*750, 750) {
public void onTick(long millisUntilFinished) {
robotTextView.setText("...");
}
public void onFinish() {
}
}.start();
Try this, call "doStuff()" when you want the operation to take place
public void doStuff() {
new Thread(new Runnable() {
public void run() {
for(int i=0; i<wordSize; i++) {
robotTextView.setText("why this words only display on the textView at last operation on this for loop?");
Log.i(TAG, robotWords.substring(0, i));
robotTextView.post(new Runnable() {
public void run() {
robotTextView.setText("why this words only display on the textView at last operation on this for loop?");
}
});
try {
Thread.sleep(750);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
}
Hope this helps!
Related
my_text.setText("Dave");
//Small pause...
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
my_text.setText("Bob");
I want to change my textView, pause 1 second, then change it again. When I run the program, it doesn't refresh after first change. It just shows the second change after returning. How can I force the refresh on the first change to the textview?
Try use Handler like below code
my_text.setText("Dave");
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
runOnUiThread(new Runnable() {
#Override
public void run() {
my_text.setText("Bob");
}
});
}
}, 1000);
Try below for the edited question
Keep your all 20 names in any collection array or list.
int position = 0;
String names [] = {"0","1","20"};
Handler handler = new Handler(getMainLooper());
Runnable runnable = new Runnable() {
public void run() {
my_text.setText(names[position++]);
if (position < names.length) {
handler.postDelayed(this, 1000);
}
}
};
handler.postDelayed(runnable, 1000);
How I can set dynamically set the progressbar status after reading a value from db SQLite?
I have this code.
int i = 0;
while (!c.isAfterLast()) {
i++;
pb.setProgress(i)
}
But my problem is that progress bar is update only at finish while so without "liveEffect"
You can use runOnUiThread method of Activity class:
runOnUiThread(new Runnable() {
#Override
public void run() {
pb.setProgress(i);
}
});
More here: https://developer.android.com/reference/android/app/Activity.html#runOnUiThread(java.lang.Runnable)
Actually, execution time is too low that by live effect not appear . take large cursor around 10000 value then apply loop now you can see progress
I resolved my problem with Handler and Thread.sleep (for simulate live)
new Thread(new Runnable() {
public void run() {
do {
mProgressStatus++;
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
mHandler.post(new Runnable() {
public void run() {
pb.setProgress(mProgressStatus);
}
);
} while (c.moveToNext());
}
}).start();
i am trying to display a Toast on the screen and when Toast fades off then move to the next question. I have tried with Thread but cannot seem to manage.
My code:
next.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (getUserSelection()){
position = position + 3;
if (position < questionsArray.size()) {
curName = questionsArray.get(position).getName();
curArray = questionsArray.get(position).getAnswers();
curIscorrect = questionsArray.get(position).getIscorrect();
setupQuestionView(curName, curArray, curIscorrect);
} else {
StringGenerator.showToast(QuestionsActivity.this, "Your score : " + score + "/" + (questionsArray.size() / 3));
}
}else {
StringGenerator.showToast(QuestionsActivity.this, getString(R.string.noanswerselected));
}
}
});
and the getUserSelectionMethod:
private boolean getUserSelection() {
correct = (RadioButton)findViewById(group.getCheckedRadioButtonId());
if (correct == null){
return false;
}else {
correctAnswerText = correct.getText().toString();
if (map.get(correctAnswerText).equals(Constants.CORRECTANSWER)) {
score++;
setCorrectMessage();
return true;
} else {
setWrongMessage();
return true;
}
}
}
private void setCorrectMessage() {
correctToast = new Toast(QuestionsActivity.this);
correctToastView = getLayoutInflater().inflate(R.layout.correct, (ViewGroup) findViewById(R.id.correctRootLayout));
correctText = (TextView)correctToastView.findViewById(R.id.correctTextView);
correctText.setText(getString(R.string.correctAnswer));
correctToast.setDuration(Toast.LENGTH_SHORT);
correctToast.setView(correctToastView);
correctToast.show();
correctThread = new Thread(new Runnable() {
#Override
public void run() {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
correctToast.cancel();
}
});
correctThread.start();
}
private void setWrongMessage() {
wrongToast = new Toast(QuestionsActivity.this);
wrongToastView = getLayoutInflater().inflate(R.layout.wrong, (ViewGroup) findViewById(R.id.wrongRootLayout));
wrongText = (TextView)wrongToastView.findViewById(R.id.wrongTextView);
wrongText.setText(getString(R.string.wrongAnswer));
wrongToast.setDuration(Toast.LENGTH_SHORT);
wrongToast.setView(wrongToastView);
wrongToast.show();
wrongThread = new Thread(new Runnable() {
#Override
public void run() {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
wrongToast.cancel();
}
});
wrongThread.start();
}
Any suggestion on how to do this?
You can determine the toast visibility:
toast.getView().getWindowToken()
If the result is null, than your toast isn't visible anymore, and than you can run any code you want.
as stated in this answer you can start a thread that waits the duration of the Toast:
Thread thread = new Thread(){
#Override
public void run() {
try {
Thread.sleep(3500); // 3.5seconds!
// Do the stuff you want to be done after the Toast disappeared
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
Toast.LENGTH_SHORT and Toast.LENGTH_LONG are only flags so you have to either hard code the duration or keep them in a constant. The durations are 3.5s (long) and 2s (short).
If you want to manipulate some of your views, you cannot do this in another thread than the "main" UI thread. So you have to implement a kind of callback/polling mechanism to get notified when the SleepThread has finished.
Check this answer to read about a couple of ways to do this. Probably the easiest of them to understand and implement is this:
After you started your Thread you can check if it is still alive and running by calling thread.isAlive(). In this way you can do a while loop that runs while the thread is running:
// start your thread
while(thread.isAlive()){}
// continue the work. The other thread has finished.
Please note that this is NOT the most elegant way to do this! Check the other possibilities in the answer I've mentioned above for more elegant solutions (especially the last one with the listeners is very interesting and worth reading!)
That's because the Thread class is purely executed in the background and you need to manipulate the view in the Main thread. To solve your issue just replace the Thread with AsynTask.
AsyncTask<Void,Void,Void> a = new AsyncTask<Void, Void, Void>() {
#Override
protected Void doInBackground(Void... params) {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
correctToast.cancel();
}
};
a.execute();
If you look at my code you can see my onPostExecute, this method is called in the Main Thread.
My Error was because i was trying to acess UI Elements through another Thread so modifying the code like this:
Thread thread = new Thread(new Runnable() {
#Override
public void run() {
try {
Thread.sleep(500);
QuestionsActivity.this.runOnUiThread(new Runnable() {
#Override
public void run() {
moveToNextQuestion();
}
});
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
thread.start();
did the trick. I hope my answer helps someone!!!
Can I use a thread for increment a counter and shows it in a frame of Android activity.
Public class MainActivity extendsActivity {
TextView counter;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
counter = (TextView) findViewById(R.id.TV_counter);
Thread t = new Thread() {
public void run() {
runOnUiThread(new Runnable() {
public void run() {
for (int i = 0; i < 5; i++) {
try {
counter.setText("" + i);
System.out.println("Value of i= " + i);
sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
}
};
t.start();
}
}
I wrote this code, but it run properly in console, but the text view displays i=4 in the terminal, I modified the time to sleep(3000) and the problem persists.
First you don't ever want to put sleep in UI Thread that can lead to unresponsive user interface and that is never good. You should use it just to update your graphics. Try replacing your code with this
Thread t = new Thread() {
public void run() {
for (int i = 0; i < 5; i++) {
try {
final int a = i;
runOnUiThread(new Runnable() {
public void run() {
counter.setText("" + a);
}
});
System.out.println("Value of i= " + i);
sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
};
t.start();
You are going to notice that sleep and for loop is outside UIThread and in your first thread, so basically all of your math is done outside and you just display the results.
This is just a correction of your code and suggestion for further thinking
EDIT: And for you to better understand why your code is not working, you set some value on your TextView, and immediately after you set UIThread to sleep, UIThread blocks instead of giving it time to finish updating graphics, after he finish sleep you set new value, and he never got to update previous one so in the end you see just the last one.
Hope this helps and enjoy your work.
you can use a CountDownTimer, and update your UI in the onTick() method ( this method is executed on the UI Thread):
int i=0;
CountDownTimer timer = new CountDownTimer(5000,1000) {
#Override
public void onTick(long millisUntilFinished) {
// this method will be executed every second ( 1000 ms : the second parameter in the CountDownTimer constructor)
i++;
txt.setText(i);
}
#Override
public void onFinish() {
// TODO Auto-generated method stub
}
};
timer.start();
I want to show 1 to 100 in a changeable text. I like to use sleep()function so that it looks like that it is increasing form 1 to 100. my code is
for(int i= 0;i<100;i++) {
scorelevel.setText(String.valueOf(i));
try{
Thread.sleep(1000);
}catch (InterruptedException e) {
e.printStackTrace();
}
}
but it did not show properly. Any help or suggestion is appreciated.
Don't block UI thread, use AsyncTask instead
Use Timer and TimerTask to perform any time based task.
You can start counter using runOnUiThread to update textView as:
private boolean mClockRunning=false;
private int millisUntilFinished=0;
public void myThread(){
Thread th=new Thread(){
#Override
public void run(){
try
{
while(mClockRunning)
{
Thread.sleep(1000L);// set time here for refresh time in textview
YourCurrentActivity.this.runOnUiThread(new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
if(mClockRunning)
{
if(millisUntilFinished==100)
{
mClockRunning=false;
millisUntilFinished=0;
}
else
{
millisUntilFinished++;
scorelevel.setText(String.valueOf(millisUntilFinished));//update textview here
}
}
};
}
}catch (InterruptedException e) {
// TODO: handle exception
}
}
};
th.start();
}
You could use a TimerTask (link), too.