how to change the contents of TextView in realtime - android

the UI is very simple, only having a button login and a scrollable TextView on it, when i press the button login, 100 lines of messages will add to the TextView, but they are added at the same time, and because i need do with the messages that will add to the TextView, which will cost a few time, sometimes the app looks like no response. i hope that the message could add to the TextView line by line. IOW i want the TextView displays the added line of message in each loop. how can i realize that? Here is the main code which has been simplified:
login.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
for(int i = 0; i < 100; i++) {
mTextView.append("test\n");
}
}
}

login.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
mTextView.setText("");
for(int i = 0; i < 100; i++) {
mTextView.setText(mTextView.getText()+"test\n");
}
}
}
Try this code it should work

Use this:
login.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
mTextView.setText("");
if (!isStopped) {
Acitivut.this.runOnUiThread(new Runnable() {
#Override
public void run() {
for(int i = 0; i < 100; i++) {
mTextView.append("test\n");
}
isStopped=true;
}
});
}
}
}

Anything that changes UI element, must run on UI thread. Since you are running long running loop, your app freezes. You should either change the design and avoid updating UI in loop or you can use run a background thread and append the text to StringBuilder and when loop is over, append the StringBuilder text to the mtextView.
Again, if your StringBuilder contains very large text, updating that to UI may freeze it again.

login.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
i=0;
Thread thread=new Thread(new SleepThread());
thread.start();
}
}
private class SleepThread implements Runnable
{
public void run()
{
sleep(10);
handler.sendEmptyMessage();
}
}
Handler handler=new Handler()
{
public void handleMessage(Message msg)
{
mTextView.append("test\n");
i++;
if(i<100)
{
Thread thread=new Thread(new SleepThread());
thread.start();
}
}
}

Related

Threading and parallelism in Android

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.

How I make an ImageView show-up immediatlly

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);
});
}

Android Why does this line of code execute after the for loop?

btnSwitch2.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
btnSwitch2.setImageResource(R.drawable.on);
myVib.vibrate(50);
strobeFlash();
}
});
}
private void strobeFlash(){
for(int i=0; i<10;++i){
turnOnFlash2();
turnOffFlash2();
}
}
The code above executes when a button is pressed, I would like to change the picture of the image button. However, when the button is pressed, the for loop executes first then the line above it
btnSwitch2.setImageResource(R.drawable.on);
executes. Is there something I'm doing that's causing the loop to execute completely first?
Actually for loop execution is faster the then changing the image resource. You can add a postDelay() between the UI update and the for loop execution.
It will solve the issue.
btnSwitch2.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
btnSwitch2.setImageResource(R.drawable.on);
myVib.vibrate(50);
handler=new Handler();
Runnable r=new Runnable() {
public void run() {
strobeFlash();
}
};
handler.postDelayed(r, 3000);
}
});
}
private void strobeFlash(){
for(int i=0; i<10;++i){
turnOnFlash2();
turnOffFlash2();
}
}

Android dev't using thread with textview: why this is crashing?

My goal is when the user tap start button, letters "o" "n" "o" "m" and so forth will appear at the center of the screen. "o" will appear first then after a few seconds will be replaced by "n" then "o" and so forth.
note: for brevity, i just make the guessword = onomatopoeia, first. In reality, guessword will changes every time i tap the start bottom.
this is the code:
private String guessword = "onomatopoeia";
private TextView showchar;
private int n = guessword.length();
private char letArray[]= guessword.toCharArray();;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_play);
addStartListener();
}
public void addStartListener(){
Button start = (Button) findViewById(R.id.start);
showchar = (TextView) findViewById (R.id.charView);
start.setOnClickListener(new OnClickListener(){
#Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
Thread thread = new Thread()
{
#Override
public void run() {
try {
for(int i = 0 ; i < n ; i++) {
sleep(1000);
showchar.setText(letArray[i]);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
thread.start();
}
});
}
thanks for the help
I decided to implement runonuithread but still it crashes:
this is the updated version:
private String guessword = "onomatopoeia";
private TextView showchar;
private int n = guessword.length();
private char letArray[]= guessword.toCharArray();
private Handler handler;
private int i = 0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_play);
handler = new Handler();
showchar = (TextView) findViewById (R.id.charView);
}
public void startGame(View view){
new Thread() {
public void run() {
while(i++ < n) {
try {
runOnUiThread(new Runnable() {
#Override
public void run() {
showchar.setText(letArray[i]);
}
});
Thread.sleep(300);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}.start();
}
use this code for setting the text in your textview
runOnUiThread(new Runnable() {
#Override
public void run() {
showchar.setText(letArray[i]);
}
});
You are updating ui from a thread which is not possible.
showchar.setText(letArray[i]);
UI must be updated ui thread.
All you are doing is repeatedly setting value to TextView you can use Handler with a delay for this purpose.
You could use runOnUiThread also but i don't see the need for a thread for what you are doing.
Use a Handler. You can find an example #
Android Thread for a timer

Display Values Dynamically in TextView - Android

I have a simple program with one button. Once I clicked on the button loop started and should display the current value in TextView dynamically. But this display the value when loop is completed.
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv=(TextView) findViewById(R.id.textView2);
}
public void btnClick(View v) throws Exception {
for (int i=0;i<10;i++){
tv.setText("Value of I "+i);
Thread.sleep(500);
}
}
My expected output is displaying values from 0, 1,.... dynamically but displayed 9 at last. if I use append I have to wait until loop terminated. Please help me.
Try this:
int i = 0; //declare this globally
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
if(i != 10) {
text.append(" " + i);
i++;
handler.postDelayed(this, 1000);
}
}
}, 1000);
}
Make sure you declare int i = 0 globally
tv.append("text here") is your answer.
don't use Thread.sleep() in your main UI thread this should give an exception instead use a new Thread like this
Thread myThread = new Thread(new Runnable() {
#Override
public void run() {
for (int i=0;i<10;i++){
tv.setText("Value of I "+i);
Thread.sleep(500);
}
}
});
myThread.start();
or if there is more complex operations you make you will have to use AsyncTask calss

Categories

Resources