Baza Wiedzy

Podstawowe layouty

W tym artykule przyjrzymy sie bliżej podstawowym layoutom:

 

  1. Linear Layout (Horizontal)
  2. Linear Layout (Vertical)
  3. Relative layout
  4. Frame Layout

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ł.

Najlepszy newsletter o Javie w Polsce

Czy chcesz otrzymywać nowości ze świata Javy oraz przykładowe pytania rekrutacyjne? Zapisz się na newsletter i bądź na bieżąco! Otrzymasz także ekskluzywne materiały oraz informacje o nowych kursach i promocjach.

Nikomu nie udostępniamy Twojego maila, a jeśli zechcesz to w każdej chwili możesz się wypisać.

Komentarze do artykułu

Wyłączyliśmy możliwość dodawania komentarzy. Poniżej znajdziesz archiwalne wpisy z czasów gdy strona była jeszcze hobbystycznym blogiem. Zapraszamy natomiast do zadawnia pytań i dyskusji na naszej grupe na facebooku.

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?

JavaStart na YoutubeJavaStart Newsletter