Style - wylaczone z elementu XML grupy podelementow formatujacych
(w Eclipse i Android Studio zapisywane w predefiniowanym pliku res/values/styles.xml)
Temat - styl stosowany do calej aktywnosci
Częściowo na podstawie: http://stackoverflow.com/questions/5442183/using-the-animated-circle-in-an-imageview-while-loading-stuff
Aplikacja będzie pokazywała pierścień (ikona oczekiwania).
1. Tworzymy aplikację z empty activity o nazwie MainActivity.
2. W pliku activity_main.xml dodajemy panel z paskiem postępu:
3. Style StylTlaPierscienia i StylPierscienia określające wygląd panelu i umieszczonego
w jego centrum pierścienia zdefiniowane są w pliku res/values/styles.xml.
W pliku tym jest już predefiniowany temat aktywności.
4. W pliku res/values/strings.xml dodaję wartość łańcucha init:
Trwa inicjowanie widoku
5. Uruchamiamy program. Pierścień na półprzezroczystym zielonym tle kręci się
w nieskończoność.
W najprostszym scenariuszu inicjacja interfejsu mogłaby się odbywać metodzie onCreate
(plik MainActivity.java), po czym panel z pierścieniem byłby ukrywany (zob. kod poniżej).
To jednak nie zadziała, bo żeby powstał panel z pierścieniem metoda onCreate musi
zakończyć swoje działanie. A na jej końcu panel jest ukrywany. W efekcie nigdy go nie
zobaczymy.
package pl.umk.fizyka.pierscien;
import...
public class MainActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//inicjacja w watku UI blokuje tworzenie panela pierscienia
try
{
Thread.sleep(5000); //zamiast tego powinno byc inicjowanie widoku
Toast.makeText(MainActivity.this, "Inicjacja zakończona", Toast.LENGTH_SHORT).show();
}
catch(InterruptedException exc)
{
Toast.makeText(MainActivity.this, "Inicjacja przerwana", Toast.LENGTH_SHORT).show();
}
finally
{
View panelPierscienia = findViewById(R.id.panelPierscienia);
panelPierscienia.setVisibility(View.GONE);
Toast.makeText(MainActivity.this, "Panel pierściania ukryty", Toast.LENGTH_SHORT).show();
}
}
}
-------------------
Wstęp do wątków
[Zasadniczo aplikacje Androida są jednowątkowe (dotyczy to także usług uruchamianych
w ramach aplikacji).]
6. Rozwiązaniem jest utworzenie dodatkowego wątku, który będzie tworzony w MainActivity.onCreate,
ale będzie wykonywany niezależnie od wątku interfejsu (ang. UI thread). Zmieniamy wobec tego
zawartość tej metody:
[Uwaga! Próba wywołania toastu, czy w ogóle dostępu do kontrolek z wątku innego niż wątek UI
spowoduje błąd (spróbować). Należy używać runOnUiThread. Stąd metoda pokazToast.]
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//inicjacja asynchroniczna w osobnym watku
//klopot: zmiane interfejsu trzeba robic w watku UI
Thread t = new Thread()
{
public void pokazToast(final String komunikat)
{
runOnUiThread(
new Runnable()
{
public void run()
{
Toast.makeText(MainActivity.this, komunikat, Toast.LENGTH_SHORT).show();
}
});
}
public void run()
{
try
{
Thread.sleep(5000); //zamiast tego powinno byc inicjowanie widoku
pokazToast("Działanie wątku zakończone");
}
catch(InterruptedException exc)
{
pokazToast("Działanie wątku przerwane");
}
finally
{
runOnUiThread(
new Runnable()
{
public void run()
{
View panelPierscienia = findViewById(R.id.panelPierscienia);
panelPierscienia.setVisibility(View.GONE);
Toast.makeText(MainActivity.this, "Panel pierściania ukryty", Toast.LENGTH_SHORT).show();
}
});
}
}
};
t.start();
}
Teraz panel widoczny jest przez 5 sekund (tyle trwa Thread.sleep, który symuluje polecenia
inicjujące UI), a potem jest ukrywany.
Więcej w: http://www.xoriant.com/blog/mobile-application-development/android-async-task.html