Lekcja 2.3. Tworzenie prostego interfejsu u┼╝ytkownika

> Dodaj do ulubionych

Budowa graficznego interfejsu u┼╝ytkownika aplikacji Android opiera si─Ö na hierarchii obiekt├│w View i ViewGroup. Obiekty View s─ů zazwyczaj widocznymi elementami interfejsu, np. przyciskami i polami tekstowymi, natomiast obiekty ViewGroup to niewidoczne kontenery okre┼Ťlaj─ůce spos├│b rozmieszczenia element├│w widok├│w potomnych, np. w siatce albo pionowej li┼Ťcie.

Dost─Öpna jest sk┼éadnia XML odpowiadaj─ůca podklasom klas View i ViewGroup, dzi─Öki czemu interfejs u┼╝ytkownika mo┼╝na zdefiniowa─ç przy u┼╝yciu hierarchii element├│w XML.

Alternatywne układy

Mo┼╝liwo┼Ť─ç definiowania uk┼éadu interfejsu u┼╝ytkownika przy u┼╝yciu XML-a zamiast kodu programistycznego jest korzystne z kilku powod├│w, z kt├│rych najwa┼╝niejszym jest mo┼╝liwo┼Ť─ç tworzenia r├│┼╝nych uk┼éad├│w dla ekran├│w o r├│┼╝nych rozmiarach. Mo┼╝na na przyk┼éad utworzy─ç dwie wersje uk┼éadu i nakaza─ç systemowi stosowanie jednego na ÔÇ×ma┼éychÔÇŁ ekranach, a drugiego ÔÇö na ÔÇ×du┼╝ychÔÇŁ. Wi─Öcej informacji na ten temat znajduje si─Ö w lekcji o obs┼éudze r├│┼╝nych urz─ůdze┼ä.

Rysunek 1. Ilustracja drzewiastej struktury obiekt├│w klasy ViewGroup zawieraj─ůcych obiekty klasy View
Rysunek 1. Ilustracja drzewiastej struktury obiekt├│w klasy ViewGroup zawieraj─ůcych obiekty klasy View

W tej lekcji dowiesz si─Ö, jak utworzy─ç przy u┼╝yciu XML-a uk┼éad zawieraj─ůcy pole tekstowe i przycisk. W nast─Öpnej lekcji dowiesz si─Ö, jak reagowa─ç na naci┼Ťni─Öcie tego przycisku poprzez wys┼éanie zawarto┼Ťci pola tekstowego do innej aktywno┼Ťci.

Tworzenie układu liniowego

Otw├│rz plik activity_main.xml znajduj─ůcy si─Ö w katalogu res/layout/.

Domy┼Ťlnie dodany do projektu szablon BlankActivity zawiera plik activity_main.xml, kt├│ry z kolei zawiera widok g┼é├│wny RelativeLayout i widok potomny TextView.

Najpierw usu┼ä element <TextView>, a nast─Öpnie nazw─Ö elementu <RelativeLayout> zmie┼ä na <LinearLayout>. P├│┼║niej dodaj atrybut android:orientation i przypisz mu warto┼Ť─ç "horizontal". Teraz ca┼éy kod powinien wygl─ůda─ç nast─Öpuj─ůco:

<?xml version="1.0" encoding="utf-8"?>
<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" >
</LinearLayout>

LinearLayout to grupa widok├│w (podklasa klasy ViewGroup) rozmieszczaj─ůca widoki potomne w pionie lub poziomie, zgodnie z ustawieniem atrybutu android:orientation. Widoki potomne widoku LinearLayout na ekranie s─ů wy┼Ťwietlane w kolejno┼Ťci zdefiniowania w pliku XML.

Dwa pozosta┼ée atrybuty, android:layout_width i android:layout_height, s─ů wymagane we wszystkich widokach i okre┼Ťlaj─ů ich wymiary.

Poniewa┼╝ LinearLayout to g┼é├│wny widok uk┼éadu, powinien on wype┼énia─ç ca┼éy obszar dost─Öpny aplikacji na ekranie . Aby tak by┼éo, nale┼╝y szeroko┼Ť─ç i wysoko┼Ť─ç ustawi─ç na "match_parent". Warto┼Ť─ç ta oznacza, ┼╝e widok powinien rozci─ůga─ç si─Ö w poziomie i pionie na ca┼é─ů szeroko┼Ť─ç i wysoko┼Ť─ç widoku nadrz─Ödnego.

Wi─Öcej informacji na temat w┼éasno┼Ťci uk┼éad├│w mo┼╝na znale┼║─ç w poradniku dotycz─ůcym Uk┼éad├│w.

Dodawanie pola tekstowego

Aby utworzy─ç pole tekstowe, nale┼╝y w elemencie <LinearLayout> utworzy─ç element <EditText>.

Jak w przypadku ka┼╝dego obiektu klasy View, w┼éasno┼Ťci obiektu EditText nale┼╝y zdefiniowa─ç przy u┼╝yciu odpowiednich atrybut├│w XML. Poni┼╝ej przedstawione jest poprawne umiejscowienie tego kodu w elemencie <LinearLayout>:

    <EditText android:id="@+id/edit_message"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:hint="@string/edit_message" />

Opis atrybut├│w:

android:id

Unikalny identyfikator dla widoku, przy u┼╝yciu kt├│rego mo┼╝na odnosi─ç si─Ö do tego obiektu w kodzie aplikacji, np. aby odczyta─ç ten obiekt i nim manipulowa─ç (przeczytasz o tym w nast─Öpnej lekcji).

Znak @ jest wymagany zawsze, gdy odnosimy si─Ö do obiektu zasobu wewn─ůtrz pliku XML. Po nim powinny znajdowa─ç si─Ö typ zasobu (w tym przypadku id), uko┼Ťnik oraz nazwa zasobu (edit_message).

Znak + przed typem zasobu jest wymagany tylko przy pierwszej definicji identyfikatora zasobu. Podczas kompilacji programu, narz─Ödzia SDK u┼╝ywaj─ů tego identyfikatora do utworzenia nowego identyfikatora zasobu w pliku gen/R.java projektu, kt├│ry odnosi si─Ö do elementu EditText. Po zadeklarowaniu identyfikatora zasobu w ten spos├│b, w kolejnych odniesieniach do niego nie trzeba ju┼╝ u┼╝ywa─ç znaku plusa. Znak plus jest wymagany tylko, gdy okre┼Ťlany jest identyfikator nowego zasobu i nie jest potrzebny dla konkretnych zasob├│w, takich jak ┼éa┼äcuchy i uk┼éady. Wi─Öcej informacji na temat obiekt├│w zasob├│w znajduje si─Ö w bocznej ramce.

android:layout_width i android:layout_height
Zamiast okre┼Ťla─ç konkretne warto┼Ťci szeroko┼Ťci i wysoko┼Ťci, za pomoc─ů warto┼Ťci "wrap_content" mo┼╝na sprawi─ç, ┼╝e widok b─Ödzie dopasowywa┼é si─Ö rozmiarem do tre┼Ťci. Gdyby zamiast tego u┼╝yto warto┼Ťci "match_parent", w├│wczas element EditText wype┼énia┼éby ekran, poniewa┼╝ by┼éby dopasowany rozmiarem do wymiar├│w rodzica, kt├│rym jest LinearLayout. Wi─Öcej informacji na temat w┼éasno┼Ťci uk┼éad├│w mo┼╝na znale┼║─ç w poradniku dotycz─ůcym uk┼éad├│w.
android:hint

Jest to domy┼Ťlny tekst wy┼Ťwietlany, gdy pole tekstowe jest puste. Zamiast konkretnego tekstu mo┼╝na wpisa─ç warto┼Ť─ç "@string/edit_message" odnosz─ůc─ů si─Ö do zasobu ┼éa┼äcuchowego znajduj─ůcego si─Ö w osobnym pliku. Poniewa┼╝ odwo┼éanie jest do konkretnego zasobu (nie identyfikatora), nie trzeba dodawa─ç znaku plus. Poniewa┼╝ jednak wskazany zas├│b ┼éa┼äcuchowy nie jest jeszcze zdefiniowany, zostanie wy┼Ťwietlone powiadomienie o b┼é─Ödzie. Wkr├│tce to naprawimy definiuj─ůc ten ┼éa┼äcuch.

Dodawanie zasobów łańcuchowych

Tekst dodawany do interfejsu u┼╝ytkownika zawsze powinien by─ç definiowany w postaci zasob├│w ┼éa┼äcuchowych. Dzi─Öki temu wszystkimi tekstami u┼╝ywanymi w interfejsie mo┼╝na zarz─ůdza─ç w jednym miejscu, co u┼éatwia prac─Ö i modyfikowanie programu. Ponadto umieszczenie ┼éa┼äcuch├│w tekstowych na zewn─ůtrz aplikacji umo┼╝liwia jej lokalizacj─Ö w r├│┼╝nych j─Özykach polegaj─ůc─ů na podaniu alternatywnych definicji dla ka┼╝dego zasobu ┼éa┼äcuchowego.

Domy┼Ťlnie tw├│j projekt Android zawiera plik zasob├│w ┼éa┼äcuchowych o nazwie res/values/strings.xml. Otw├│rz go i usu┼ä z niego element <string> o nazwie hello_world. Nast─Öpnie dodaj nowy element <string> o nazwie edit_message i w jego tre┼Ťci wpisz tekst Wpisz wiadomo┼Ť─ç.

Dodatkowo, skoro ju┼╝ jeste┼Ť w tym pliku, wpisz ┼éa┼äcuch Wy┼Ťlij dla przycisku o nazwie button_send, kt├│ry wkr├│tce dodasz do projektu.

Teraz plik strings.xml powinien zawiera─ç nast─Öpuj─ůcy kod:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="app_name">My First App</string>
    <string name="edit_message">Enter a message</string>
    <string name="button_send">Send</string>
    <string name="menu_settings">Settings</string>
    <string name="title_activity_main">MainActivity</string>
</resources>

Wi─Öcej informacji na temat sposob├│w wykorzystania zasob├│w ┼éa┼äcuchowych do lokalizacji program├│w znajdziesz w lekcji o obs┼éudze r├│┼╝nych urz─ůdze┼ä.

Dodawanie przycisk├│w

Teraz w uk┼éadzie bezpo┼Ťrednio za elementem <EditText> dodaj element <Button>:

<Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/button_send" />

Wysoko┼Ť─ç i szeroko┼Ť─ç s─ů ustawione na wrap_content, dzi─Öki czemu przycisk dopasowuje si─Ö rozmiarem do znajduj─ůcego si─Ö na nim tekstu. Przycisk ten nie musi mie─ç atrybutu android:id, poniewa┼╝ nie b─Ödziemy si─Ö do niego odwo┼éywa─ç z kodu aktywno┼Ťci.

Tworzenie p├│l tekstowych o szeroko┼Ťci ekranu

Aktualnie elementy EditText i Button dopasowuj─ů si─Ö rozmiarami do znajduj─ůcej si─Ö w nich tre┼Ťci, jak wida─ç na rysunku 2.

Rysunek 2. Elementy EditText i Button maj─ů szeroko┼Ťci ustawione na wrap_content
Rysunek 2. Elementy EditText i Button maj─ů szeroko┼Ťci ustawione na wrap_content

Rozwi─ůzanie to jest dobre dla przycisku, ale nie dla pola tekstowego, w kt├│rym u┼╝ytkownik mo┼╝e wpisywa─ç teksty o r├│┼╝nej d┼éugo┼Ťci. Dlatego lepiej by by┼éo wype┼éni─ç nieu┼╝ywan─ů cze┼Ť─ç ekranu tym polem. Mo┼╝na to zrobi─ç w uk┼éadzie LinearLayout przy u┼╝yciu w┼éasno┼Ťci wagi, kt├│r─ů definiuje si─Ö za pomoc─ů atrybutu android:layout_weight.

Warto┼Ť─ç ta jest liczb─ů okre┼Ťlaj─ůc─ů, ile miejsca ma zaj─ů─ç ka┼╝dy z widok├│w wzgl─Ödem ilo┼Ťci miejsca zaj─Ötego przez widoki siostrzane. Jest to co┼Ť podobnego do przepis├│w na drinki: „2 cz─Ö┼Ťci w├│dki, 1 cz─Ö┼Ť─ç likieru kawowego” oznacza, ┼╝e 2/3 drinka stanowi w├│dka. Je┼Ťli na przyk┼éad jednemu widokowi zostanie przypisana waga 2, a drugiemu 1, to suma ich wyniesie 3, a zatem pierwszy widok b─Ödzie zajmowa┼é 2/3 dost─Öpnej przestrzeni, natomiast drugi — reszt─Ö. Je┼Ťli dodamy do tego trzeci widok i nadamy mu wag─Ö 1, w├│wczas pierwszy widok (o wadze 2) b─Ödzie zajmowa┼é 1/2 dost─Öpnej przestrzeni, natomiast pozosta┼ée dwa widoki po 1/4.

Domy┼Ťlnie ka┼╝dy widok ma wag─Ö 0, a wi─Öc je┼Ťli przypisze si─Ö wag─Ö wy┼╝sz─ů od 0 tylko jednemu widokowi, zajmie on ca┼é─ů przestrze┼ä, jaka pozostanie dost─Öpna po przydzieleniu ka┼╝demu widokowi miejsca, kt├│re jest przez niego wymagane. Aby zatem wype┼éni─ç pozostaj─ůc─ů woln─ů przestrze┼ä elementem EditText w naszym uk┼éadzie, nadajemy mu wag─Ö 1, a wag─Ö przycisku pozostawiamy bez zmian.

<EditText
        android:layout_weight="1"
        ... />

Aby poprawi─ç wydajno┼Ť─ç uk┼éadu, gdy okre┼Ťli si─Ö wag─Ö, nale┼╝y szeroko┼Ť─ç elementu EditText zmieni─ç na zero (0dp). Ustawienie szeroko┼Ťci na zero sprawia, ┼╝e uk┼éad jest bardziej wydajny, poniewa┼╝ warto┼Ť─ç wrap_content okre┼Ťlaj─ůca szeroko┼Ť─ç zmusza system do obliczania szeroko┼Ťci, co jest niepotrzebne, gdy┼╝ p├│┼║niej i tak waga zmusza go po raz kolejny do obliczenia szeroko┼Ťci elementu maj─ůcego wype┼énia─ç pozostaj─ůc─ů woln─ů przestrze┼ä.

<EditText
        android:layout_weight="1"
        android:layout_width="0dp"
        ... />

Na rysunku 3. przedstawiono efekt przypisania wagi elementowi EditText.

Rysunek 3. Element EditText ma przypisan─ů wag─Ö pozwalaj─ůc─ů mu zaj─ů─ç ca┼é─ů woln─ů przestrze┼ä w widoku LinearLayout
Rysunek 3. Element EditText ma przypisan─ů wag─Ö pozwalaj─ůc─ů mu zaj─ů─ç ca┼é─ů woln─ů przestrze┼ä w widoku LinearLayout

Poniżej przedstawiony jest kod, który powinien znajdować się w pliku układu:

<?xml version="1.0" encoding="utf-8"?>
<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">
    <EditText android:id="@+id/edit_message"
        android:layout_weight="1"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:hint="@string/edit_message" />
    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/button_send" />
</LinearLayout>

Uk┼éad ten jest stosowany przez domy┼Ťln─ů klas─Ö Activity wygenerowan─ů przez narz─Ödzia SDK podczas tworzenia projektu. Dzi─Öki temu mo┼╝na ju┼╝ uruchomi─ç aplikacj─Ö, aby zobaczy─ç, jak dzia┼éa:

  • W Eclipse kliknij przycisk Start na pasku narz─Ödzi.
  • W wierszu polece┼ä przejd┼║ do katalogu g┼é├│wnego projektu i wykonaj nast─Öpuj─ůce polecenie:

    ant debug
    adb install bin/MyFirstApp-debug.apk
    

W nast─Öpnej lekcji nauczysz si─Ö reagowa─ç na zdarzenia naci┼Ťni─Öcia przycisk├│w, odczytywa─ç tekst z p├│l tekstowych, rozpoczyna─ç nowe aktywno┼Ťci i wiele wi─Öcej.

Autor: Google

Źródło: https://developer.android.com/training/basics/firstapp/building-ui.html

Tłumaczenie: Łukasz Piwko

Tre┼Ť─ç tej strony jest dost─Öpna na zasadach licencji CC BY 2.5

2 komentarze do “Lekcja 2.3. Tworzenie prostego interfejsu u┼╝ytkownika”

  1. Witam,
    Mam problem, nie moge uruchomi─ç programu, gdy┼╝ wyskakuje b┼é─ůd w pliku MainActivity.java , konkretnie w linijce:
    .add(R.id.container, new PlaceholderFragment()).commit();

    „container cannot be resolved or is not a field”.

    W innej aplikacji jest ydentyczny kod i wszystklo jest ok.

    Nadmieni─Ö, ┼╝e przed tym, musia┼éam edytowa─ç plik fragment_main.xml, gdy┼╝ wyskakiwa┼é mi b┼é─ůd w linijce:
    android:text=”@string/hello_world” />

    hello_world zamieniłam na edit_message i juz było ok.

    chyba ┼╝e tutaj co┼Ť sknoci┼éam.

    Bardzo bym prosiła o pomoc.

    A tak przy okazji, fajny kurs, pierwszy na jaki natrafi┼é─ům, w kt├│rym wyja┼Ťniane jest wszystko krok po kroku ­čÖé

  2. Uda┼éo mi sie rozwi─ůza─ç problem, w pliku activity_main.xml w wierszu: <EditText android:id="@+id/edit_message" zamiast edit_message wpisa┼éam container i posz┼éo.

    Teraz tylko nie moge uruchomi─ç aplikacji na tablecie, wyskakuje na urz─ůdzeniu info, ┼╝e apliakcja zosta┼éa zatrzymana… ???

Mo┼╝liwo┼Ť─ç komentowania zosta┼éa wy┼é─ůczona.