Podstawowe layouty
Spis treści
Jak już zapewne sami zaważyliście pliki z layoutem można otwierać na co najmniej dwa sposoby. Pierwszym, edytorem wizualnym, posługiwaliśmy sie ostatnio. Pora na drugi. Otwórzmy sobie nasz plik z poprzedniej lekcji wybierając tryb xml.
Powinniśmy zobaczyć coś takiego:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<TextView
android:id="@+id/nazwa"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/javastart"
android:textAppearance="?android:attr/textAppearanceLarge" />
<TextView
android:id="@+id/imie_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/imie" />
<EditText
android:id="@+id/imie"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="textPersonName" >
<requestFocus />
</EditText>
<TextView
android:id="@+id/textView3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/plec" />
<RadioGroup
android:id="@+id/plec"
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
<RadioButton
android:id="@+id/radio0"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:checked="true"
android:text="@string/kobieta" />
<RadioButton
android:id="@+id/radio1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/mezczyzna" />
</RadioGroup>
<TextView
android:id="@+id/textView4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/ocena" />
<RatingBar
android:id="@+id/ocena"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:numStars="5" />
<Button
android:id="@+id/przycisk"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:text="@string/ok" />
</LinearLayout>
Jak widać każdemu elementowi przypada kawałek odpowiadającemu mu kodu. Jest to dosyć czytelne, ponieważ dokładnie widać gdzie zaczyna się definiowanie parametrów danego elementu.
Niektórzy nie używają w ogóle trybu wizualnego, twierdząc, ze generuje on zbędny kod. Osobiście sie z nimi nie zgadzam. Kreator umożliwia w bardzo łatwy sposób stworzenie pożądanego layoutu.
Dzisiaj pokusimy sie o bardziej zaawansowany widok. W celu jego zrealizowania potrzebne będzie nam zrozumienie layoutów. Jeśli przejdziemy z powrotem do widoku wizualnego, to w wigetach możemy zauważyć zakładkę layout.
Samo przeciąganie layoutu na ekran właściwie nic nie daje, ponieważ jest to tylko pojemnik na właściwą zawartość. Zależnie od wybranego layoutu wrzucone w niego elementy będą układać sie z góry na dół, od prawej od lewej, albo będą zachowywały się zależnie od innego elementu. Ich istotna właściwością jest to, ze można wrzucać jeden layout do drugiego.
Linear Layout (Horizontal)
Elementy w tym layoucie będą się układać od lewej do prawej.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal" >
<Button
android:id="@+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button" />
<Button
android:id="@+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button" />
<Button
android:id="@+id/button3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button" />
<Button
android:id="@+id/button4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button" />
<Button
android:id="@+id/button5"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button" />
</LinearLayout>
Linear Layout (Vertical)
Elementy w tym layoucie będą się układać z góry na dół.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
.
.
.
</LinearLayout>
Jak widać, jedyna zmiana to dodatkowy atrybut android:orientation="vertical" dla LinearLayout.
Relative layout
Tutaj sprawa jest ciekawsza. Elementy układają się zależnie od innych elementów. Przyjrzyjmy się temu dokładniej.
Najpierw ustalmy RelativeLayout na całym ekranie - najlepiej skopiować poniższy kod.
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent" >
</RelativeLayout>
Przy przeciąganiu elementu pojawiają się strzałki wskazujące względem jakiego innego elementu zostanie on ustawiony. Ustawmy sobie kilka przycisków.
Zajrzyjmy teraz do tego co zostało wygenerowane w pliku XML.
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<Button
android:id="@+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_marginLeft="92dp"
android:layout_marginTop="81dp"
android:text="Button" />
<Button
android:id="@+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="@+id/button1"
android:layout_below="@+id/button1"
android:layout_marginTop="130dp"
android:text="Button" />
<Button
android:id="@+id/button3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/button1"
android:layout_marginLeft="48dp"
android:layout_marginTop="60dp"
android:layout_toRightOf="@+id/button2"
android:text="Button" />
</RelativeLayout>
Pojawiają się nowe atrybuty.
Te z informacją o odległości (zauważcie, że stosowanie jest dp, a nie px - informacja na ten temat na końcu artykułu)
android:layout_marginLeft // dodatkowa odległość po lewej stronie
android:layout_marginTop // dodatkowa odległość od góry
No i atrybuty relacyjne, wskazujące od których elementów zależą
android:layout_alignParentLeft // zależne od lewej strony kontenera (layoutu) w którym się znajduje
android:layout_alignParentTop // zależne od prawej strony kontenera (layoutu) w którym się znajduje
android:layout_below // znajduje się pod wskazanym elementem
android:layout_toRightOf // znajduje się po prawej stronie wskazanego elementu
Spróbuj teraz przemieścić pierwszy przycisk. Efekt - wszystko się przesunęło. Niestety nie ma na to lekarstwa i najlepszym sposobem zarządzania RelativeLayoutem jest wpisywanie go z poziomu XML.
Frame Layout
Używany dużo rzadziej niż inne layouty. Służy głównie do przechowywania tylko jednego widoku, który ma być widoczny nad innym.
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<ImageView
android:id="@+id/imageView1"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:scaleType="centerCrop"
android:src="@drawable/tlo" />
<TextView
android:id="@+id/textView1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="top"
android:text="Text na górze"
android:textAppearance="?android:attr/textAppearanceLarge"
android:textColor="#ff0000"
android:textStyle="bold" />
<TextView
android:id="@+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:text="Tekst na dole"
android:textAppearance="?android:attr/textAppearanceLarge"
android:textColor="#ff0000" />
</FrameLayout>
Tutaj nowym elementem może być ImageView. Jest to kontrolka służąca do wyświetlania grafik. Przed jej użyciem należy umieścić swój obrazek w forderze /res/drawable, a następnie wystarczy przeciągnąć kontrolkę ImageView na ekran, a system sam zapyta nas jakiej grafiki chcemy użyć. Wybieramy odpowiednią i gotowe.
Dodatkowe informacje
Przy projektowaniu ekranu należy zwrócić szczególną uwagę na to, że użytkownicy naszej aplikacji będą korzystali z niej na szerokiej gamie urządzeń z rożnymi rozdzielczościami. Dlatego właśnie w Androidzie nie stosujemy pikseli (px) tylko dp (Density-independent pixel).
Jego wielkość jest zależna od wielkości ekranu, co zapewnia nam, ze aplikacja będzie wyglądała niemal identycznie na wszystkich urządzeniach.
Pozostaje jeszcze kwestia zmiany orientacji ekranu. Tutaj sprawa nie jest taka prosta. Ja z reguły radze sobie w taki sposób, ze blokuje możliwość obrotu ekranu. Jest to podejście bardzo nieeleganckie. Optymalnym rozwiązaniem byłoby stworzenie osobnych layoutu dla orientacji pionowej i poziomej. Następnie wystarczy tylko przechwycić wydarzenie zmiany orientacji i wczytać alternatywny layout. Nie jestem jeszcze do końca przekonany co do takie podejścia. Postaram sie douczyć i w najbliższym czasie napisać o tym osobny artykuł.
Dyskusja i komentarze
Masz pytania do tego wpisu? Może chcesz się podzielić spostrzeżeniami? Zapraszamy dyskusji na naszej grupie na Facebooku.
Poniżej znajdziesz archiwalne wpisy z czasów, gdy strona była jeszcze hobbystycznym blogiem.
Mateusz
" /res/drawabke" wkradła się literówka. Poza tym świetny artykuł :)
Marcin Kunert
Hej Mateusz, dzięki za info. Widzę, że uważnie czytałeś. Poprawiłem :)
Tomek
Świetne artykuły, jest jakaś konkretna częstotliwość z jaką je wrzucasz? Czy piszesz po prostu w wolnych chwilach?
Marcin Kunert
W wolnych chwilach, których ostatnio coraz mniej. Spróbuję się zmobilizować i coś niebawem dodać.
Lolo
Można jakoś napisać aplikację by nie miała okna ale, żeby można było np. wyświetlać toasty?