Próbowałem to zrobić
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
t=new TextView(this);
t=(TextView)findViewById(R.id.TextView01);
t.setText("Step One: blast egg");
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
t.setText("Step Two: fry egg");
ale z jakiegoś powodu po uruchomieniu pojawia się tylko drugi tekst. Myślę, że może to mieć coś wspólnego z Thread.sleep()
blokowaniem metody. Czy ktoś może mi więc pokazać, jak zaimplementować licznik czasu „asynchronicznie”?
Dzięki.
.setText()
zastępuje cały „widżet” tekstem, który każesz mu ustawić; WŁĄCZAJĄC tekst, który już tam umieściłeś.Odpowiedzi:
Właśnie opublikowałem tę odpowiedź w grupie dyskusyjnej Google na temat Androida
Jeśli próbujesz tylko dodać tekst do widoku, tak aby wyświetlał się „Krok pierwszy: wysmaż jajko Krok drugi: smaż jajko” Rozważ użycie
t.appendText("Step Two: fry egg");
zamiastt.setText("Step Two: fry egg");
Jeśli chcesz całkowicie zmienić to, co jest w
TextView
środku, tak aby podczas uruchamiania wyświetlał się komunikat „Krok pierwszy: wydmuchaj jajko”, a następnie powiedział „Krok drugi: smaż jajko” po jakimś czasie, zawsze możesz użyćWykonalny przykład podany przez sadboya
Powodzenia
źródło
Twoja
onCreate()
metoda ma kilka ogromnych wad:1)
onCreate
przygotowuje Twoje działanie - więc nic, co tu robisz, nie będzie widoczne dla użytkownika, dopóki ta metoda się nie zakończy! Na przykład - nigdy nie będziesz mógł zmienićTextView
tutaj tekstu więcej niż JEDEN raz, ponieważ tylko ostatnia zmiana zostanie narysowana, a tym samym widoczna dla użytkownika!2) Pamiętaj, że program na Androida - domyślnie - działa tylko w JEDNYM wątku! Dlatego: nigdy nie używaj
Thread.sleep()
aniThread.wait()
w głównym wątku, który jest odpowiedzialny za Twój interfejs użytkownika! ( aby uzyskać więcej informacji, przeczytaj „Utrzymuj responsywność aplikacji” )To, co robi inicjalizacja działania, to:
TextView
obiektt
!TextView
w zmiennejt
.t
(ale pamiętaj: będzie on wyświetlany dopiero poonCreate()
zakończeniu pracy i uruchomieniu głównej pętli zdarzeń Twojej aplikacji!)onCreate
metodzie - nigdy nie wolno tego robić, ponieważ zatrzymuje to całą aktywność interfejsu użytkownika i na pewno wymusi ANR (aplikacja nie odpowiada, patrz link powyżej!)onCreate()
zakończy się Twoja metoda i kilka innych metod cyklu życia działania zostanie przetworzonych!Rozwiązanie:
Ustaw tekst tylko raz
onCreate()
- musi to być pierwszy tekst, który powinien być widoczny.Utwórz a
Runnable
iHandler
private final Runnable mUpdateUITimerTask = new Runnable() { public void run() { // do whatever you want to change here, like: t.setText("Second text to display!"); } }; private final Handler mHandler = new Handler();
zainstaluj to runnable jako handler, możliwe w
onCreate()
(ale przeczytaj moją radę poniżej):// run the mUpdateUITimerTask's run() method in 10 seconds from now mHandler.postDelayed(mUpdateUITimerTask, 10 * 1000);
Rada: upewnij się, że znasz
Activity
cykl życia! Jeśli będziesz robić takie rzeczy, stanie sięonCreate()
to tylko wtedy, gdy TwójActivity
zostanie utworzony po raz pierwszy! Android prawdopodobnie utrzyma CięActivity
przy życiu przez dłuższy czas, nawet jeśli nie jest widoczny! Kiedy użytkownik „uruchomi” go ponownie - a on nadal istnieje - nie zobaczysz już swojego pierwszego tekstu!=> Zawsze instaluj programy obsługi
onResume()
i wyłączaj jeonPause()
! W przeciwnym razie będziesz otrzymywać „aktualizacje”, gdy TwójActivity
nie będzie w ogóle widoczny! W twoim przypadku, jeśli chcesz zobaczyć swój pierwszy tekst ponownie, gdy zostanie ponownie aktywowany, musisz go ustawićonResume()
, a nieonCreate()
!źródło
Pierwsza linia nowego widoku tekstu jest niepotrzebna
t=new TextView(this);
możesz to zrobić
TextView t = (TextView)findViewById(R.id.TextView01);
jeśli chodzi o wątek w tle, który tu śpi, jest przykładem, ale myślę, że istnieje zegar, który byłby lepszy do tego. tutaj jest link do dobrego przykładu z użyciem licznika czasu http://android-developers.blogspot.com/2007/11/stitch-in-time.html
Thread thr = new Thread(mTask); thr.start(); } Runnable mTask = new Runnable() { public void run() { // just sleep for 30 seconds. try { Thread.sleep(3000); runOnUiThread(done); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }; Runnable done = new Runnable() { public void run() { // t.setText("done"); } };
źródło
@ user264892
Zauważyłem, że używając zmiennej typu String potrzebowałem poprzedzić ciągiem „” lub jawnie rzutować na CharSequence.
Więc zamiast:
String Status = "Asking Server..."; txtStatus.setText(Status);
próbować:
String Status = "Asking Server..."; txtStatus.setText((CharSequence) Status);
lub:
String Status = "Asking Server..."; txtStatus.setText("" + Status);
lub, ponieważ twój ciąg nie jest dynamiczny, jeszcze lepiej:
txtStatus.setText("AskingServer...");
źródło
zgodnie z twoją radą używam handle i runnables do przełączania / zmiany zawartości TextView przy użyciu „timera”. z jakiegoś powodu aplikacja zawsze pomija drugi krok („Krok drugi: smaż jajko”) i wyświetla tylko ostatni (trzeci) krok („Krok trzeci: podaj jajko”).
TextView t; private String sText; private Handler mHandler = new Handler(); private Runnable mWaitRunnable = new Runnable() { public void run() { t.setText(sText); } }; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); mMonster = BitmapFactory.decodeResource(getResources(), R.drawable.monster1); t=new TextView(this); t=(TextView)findViewById(R.id.TextView01); sText = "Step One: unpack egg"; t.setText(sText); sText = "Step Two: fry egg"; mHandler.postDelayed(mWaitRunnable, 3000); sText = "Step three: serve egg"; mHandler.postDelayed(mWaitRunnable, 4000); ... }
źródło
:) Używasz wątku w niewłaściwy sposób. Po prostu wykonaj następujące czynności:
private void runthread() { splashTread = new Thread() { @Override public void run() { try { synchronized(this){ //wait 5 sec wait(_splashTime); } } catch(InterruptedException e) {} finally { //call the handler to set the text } } }; splashTread.start(); }
Otóż to.
źródło
ustawienie tekstu na sam textview dwukrotnie powoduje nadpisanie pierwszego napisanego tekstu. Więc za drugim razem, kiedy używamy settext, po prostu dodajemy nowy ciąg, np
textview.append("Step Two: fry egg");
źródło
@Zordid @Iambda Odpowiedź jest świetna, ale znalazłem to, jeśli wstawię
mHandler.postDelayed(mUpdateUITimerTask, 10 * 1000);
w metodzie run () i
mHandler.postDelayed(mUpdateUITimerTask, 0);
w metodzie onCreate spraw, aby rzecz była aktualizowana.
źródło