TextView in einer Schleife "updaten"

  • 10 Antworten
  • Letztes Antwortdatum
D

DiaBloB555

Neues Mitglied
0
Hallo geehrte Experten, ich habe ein Problem mit der Umsetzung einer Idee bezüglich einiger TextViews:

Ich versuche (vereinfacht) einen Integer i schrittweise zu inkrementieren und in einem textView auszugeben. Mein Wunsch ist es nicht nur das Ergebinis der Inkrementierungsschleife auszugeben, sondern auch alle Teilschritte. Hier ist mein -nicht funktionierender- Versuch :

Code:
package com.example.testing;

import android.os.Bundle;
import android.view.View;
import android.widget.TextView;
import android.app.Activity;

public class MainActivity extends Activity {

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
	}
	
	//Wird aufgerufen, sobald ein Button geklickt wird
	public void onClick (View view) {
		
		TextView Tv = (TextView)findViewById(R.id.textView1);
		int i = 0;
		
			while (i <= 500) {      //Im TextView nur sichtbar: 5001 						  
				Tv.setText(i);      //-> Zwischenschritte werden "ausgelassen"
				i++;
				//Thread.sleep(100);
			} 
			
	}
}


Ich hoffe ihr könnt mir helfen. Ich habe schon in den letzten 3 Tagen viel gelesen über Handlers und runnable und Threads, hab es aber überhaupt nicht hinbekommen einen von diesen anzuwenden, ich bin über jede Hilfe dankbar,

Mit freundlichen Grüßen Daniel
 
Vielen dank für die Anwort, hat super geklappt ! :)

Sorry, habe den anderen Thread total vergessen :/
 
Ich habe noch eine Frage. Nun möchte ich einen String, den ich in einer schleife verändere in einem TextView wiedergeben, offenbar muss dieser aber "final" sein, dann kann ich ihn logischer weise nicht mehr verändern. Eine Idee ?

gibt es auch die Möglichkeit dem ASyncTasker einen String zu übergeben, den er "kompromisslos" in den TextView setzt ? - Also sowas wie:

Code:
AsyncTask UpdateTerminal = new AsyncTask(String Status) {
		
	
	//"Terminal"
	final TextView Terminal = (TextView)findViewById(R.id.textView6); 
							
		@Override
		protected Object doInBackground(Object... params) {
								
			//int i = 0;	    	  
			while (1+1==2) {  //Endlosschleife
				//final int x = i;
					    	              
				    runOnUiThread(new Runnable() {
				    @Override
				    public void run() {Terminal.setText(Status);}
				    });
					    
				;
//				try {Thread.sleep(100);} catch (InterruptedException e) {e.printStackTrace();}  	    	 	
			}
					    	     
		return null;
		}
};
//ASyncTasker
UpdateTerminal.execute(this);

Wäre natürlich schön, wenn man das ganze dann z.B. mit UpdateTerminal.execute(this, "TestString") aufrufen könnte. Geht das überhaupt ?

So funktiniert das ganze (natürlich) nicht, aber ich hoffe so kann ich besser verdeutlichen, was ich erreichen will.
Mit freundlichen Grüßen, Daniel
 
Hast du mal die Doku gelesen?
AsyncTask | Android Developers

Da wird eigentlich alles beschrieben was du damit machen kannst, und ich hab auch gerade gesehen, dass meine lösung nicht so optimal ist :D

Das runOnUiThread is eigentlich überflüssig, wenn man das updaten der TextView in onProgressUpdate macht, die Methode wird immer im UI Thread ausgeführt.

Und Parameter übergibst du an die execute Methode.
Die Parameter, die du da übergibst kommen dann hier wieder an
doInBackground(Object... params)

Wobei ich ehrlich gesagt nicht verstehe, warum du dann hier überhaupt eine Schleife einbaust wenn du die textView doch sowieso immer auf Status setzt und Status sich niemals ändert.

So wie du das gerade in deinem Code hast.. würde ein einfaches
Terminal.setText(Status);

ohne das ganze andere Zeug reichen.

Wenn sich dein Status ändern soll dann solltest du wieder mal nach onProgressUpdate gucken und immer wenn sich dein Status ändert rufst du publishProgress() auf und in onProgressUpdate änderst du dann deine textView.

Wobei eine Endlosschleife ohne möglichkeit zum beenden eigentlich IMMER falsch ist (mir fällt auf Anhieb keine sinnvolle Möglichekeit dafür ein.)

davon ab kannst du
while (1+1==2)
auch einfach durch
while(true) ändern.


Hab mal was gebastelt allerdings ohne das zu testen:
AsyncTask UpdateTerminal = new AsyncTask<String, String, Object>() {
//"Terminal"
final TextView Terminal = (TextView)findViewById(R.id.textView6);

@Override
protected Object doInBackground(Object... params) {
while (true) { //Endlosschleife
String newStatus = "new Status";//Hier Status meldung ändern oder auslesen, je nachdem wo sie her kommt
publishProgress(newStatus);
}
return null;
}

protected void onProgressUpdate (String... values) {
Terminal.setText(values[0]);
}
};
//ASyncTasker
UpdateTerminal.execute("Status");
 
amfa schrieb:
Hast du mal die Doku gelesen?
AsyncTask | Android Developers

Da wird eigentlich alles beschrieben was du damit machen kannst, und ich hab auch gerade gesehen, dass meine lösung nicht so optimal ist :D

Das runOnUiThread is eigentlich überflüssig, wenn man das updaten der TextView in onProgressUpdate macht, die Methode wird immer im UI Thread ausgeführt.

Und Parameter übergibst du an die execute Methode.
Die Parameter, die du da übergibst kommen dann hier wieder an
doInBackground(Object... params)

Wobei ich ehrlich gesagt nicht verstehe, warum du dann hier überhaupt eine Schleife einbaust wenn du die textView doch sowieso immer auf Status setzt und Status sich niemals ändert.

So wie du das gerade in deinem Code hast.. würde ein einfaches
Terminal.setText(Status);

ohne das ganze andere Zeug reichen.

Wenn sich dein Status ändern soll dann solltest du wieder mal nach onProgressUpdate gucken und immer wenn sich dein Status ändert rufst du publishProgress() auf und in onProgressUpdate änderst du dann deine textView.

Wobei eine Endlosschleife ohne möglichkeit zum beenden eigentlich IMMER falsch ist (mir fällt auf Anhieb keine sinnvolle Möglichekeit dafür ein.)

davon ab kannst du
while (1+1==2)
auch einfach durch
while(true) ändern.


Hab mal was gebastelt allerdings ohne das zu testen:

Vielen Dank für die Mühe, werde es gleich morgen ausprobieren und mir mal die Goolge-Developer seite durchlesen (dachte immer die sei so kompliziert und ich sollte es nichteinmal versuchen, scheint aber doch ganz gut verständlich zu sein)

Vielen Dank :)
 
DiaBloB555 schrieb:
...dachte immer die sei so kompliziert und ich sollte es nichteinmal versuchen...

Vielen Dank :)

super einstellung
 
Also die Google Developer Seite ist mit das beste was du Dokumentation finden kannst.
Da hat sich Google echt viel Mühe gegeben.
Vorallem im Vergleich zu vielen anderen Dokumentationen auch und vorallem im Open Source Bereich.
Da können sich einige eine Scheibe von abschneiden finde ich ;)
 
Hey, ich bins wieder. ICh habe die Google-Seite durchgelesen und weiterexperimentiert. Habe es nun ein Stückchen weiter geschafft, als gedacht:



Code:
package com.example.debugging_testing;

import android.os.AsyncTask;
import android.os.Bundle;
import android.view.View;
import android.widget.TextView;
import android.app.Activity;

public class MainActivity extends Activity {

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
	
	}
	
	public void onClick (View view) {
		
		int i = 0 ;
		while (i <= 50000) {
			UpdateTV(Integer.toString(i));
//			System.out.println(i);
			i++;
		}
		
	}
	
public void UpdateTV (final String StringToSet) {
					
	//Using ASyncTasker to Update current Process to "Terminal":			    	
	AsyncTask UpdateTerminal = new AsyncTask() {
	
		//Set up "Terminal"
		TextView Terminal = (TextView)findViewById(R.id.textView1);
						
			@Override
			protected Object doInBackground(Object... params) {		
						    	              
					    runOnUiThread(new Runnable() {
					    @Override
					    public void run() {Terminal.setText(StringToSet);}
					    });
						    	    	     
			return null;
			}
		};
		//ASyncTasker
				    
	UpdateTerminal.execute(this);
}

	
		 

//End of Class Main;
}



Ich habe nun folgendes Problem:
Wenn ich auf den Button clicke, dann wird dieser in der App eine gewisse zeit (ca. 3 sec) animiert gefärbt und ist "gedrückt" - ich vermute ist ist die Dauer der Ausführung der Funktionen in der Zwischenzeit passiert nichts, erst nachdem der Button wieder normal gefärbt und nicht mehr gedrückt animiert wird, läuft im Textview die zahlenschleife ab, wie ich sie mir vorstelle, von 0 -5000 - nur eben nicht beim drücken, sondern erst nachdem die Funktionen durchlaufen wurden, dies bestätigte auch ein blick in die Logcat mit System.out - erst nachdem System.out.prinltn 5000 liefert, begitt der Textview die Zahlen zu durchlaufen. Habt ihr noch tipps ? - Ich weiß nicht mehr s richtig weiter - meiner logik nach sollte nun alles funktionieren, tut es aber leider nicht richtig....

Der ursprüngliche Beitrag von 17:21 Uhr wurde um 17:50 Uhr ergänzt:

PS: Sehe gerade, dass der Logcat auch noch das ausspuckt:

Choreographer: Skipped 237 frames! The application may be doing too much work on its main thread.
 
Wieso hat du die Schleife denn jetzt wieder in den UI Thread gelegt?
Wenn du die Schleife mit in den AsyncTask packst sollte es funktionieren.
So wie du das jetzt gemacht hast ist das komplett unsinnig, da du in dem AsyncTask NUR dein TextView änderst, was wiederum auf dem UI Thread passiert.
Dann kannst du das auch direkt lassen ;)
 
Hat geklappt, habs endlich :) - schleife war an der falschen stelle :D
 
Zurück
Oben Unten