2 komentarze

Podstawowe elementy UI – Button, EditText, TextView, Toast, LinearLayout

Lipiec 8, 2011 Pierwsze kroki Tutoriale UI

Kiedy mamy już ogólne pojęcie o budowie aplikacji w systemie Android, możemy zacząć zagłębiać się w podstawowe komponenty z jakich możemy je budować. W niniejszym artykule skupimy się na kilku podstawowych elementach interfejsu użytkownika:

  • TextView – pole tekstowe,
  • EditText – pole tekstowe formularza,
  • Button,
  • LinearLayout – jeden z możliwych układów elementów UI naszego okna,
  • Toast – „dymek” wyświetlający niewielką ilość informacji (najczęściej tekstowych).

Przygotowania

Przed przeczytaniem tego artykuły powinniśmy stworzyć nowy projekt Androidowy w Eclipse. Opis jak to zrobić można znaleźć pod tym adresem. Dla ułatwienia zakładam, że projekt będzie nosił nazwę HelloUI, natomiast główna (i jedyna) Aktywność – HelloUIActivity.

Oprócz tego przygotujmy zestaw napisów, z których będziemy korzystać w naszym layoucie.

Plik /res/values/strings.xml:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="hello">Hello World, HelloUIActivity!</string>
    <string name="app_name">HelloUI</string>
    <string name="editText_hint">Type any text here</string>
    <string name="button_showToast">Show text in toast</string>
    <string name="button_changeTextView">Set text to TextView</string>
</resources>

UI Aplikacji

Pierwszą rzeczą, którą się zajmiemy, będzie stworzenie layoutu zawierającego wszystkie wymienione wyżej elementy (oprócz komponentu Toast, który zostanie stworzony bezpośrednio w kodzie źródłowym). Przechodzimy zatem do edycji pliku main.xml (/res/layout/), nad którym możemy pracować w edytorze graficznym oraz tekstowym.

Oto efekt, jaki powinniśmy osiągnąć (podgląd w edytorze graficznym):

Graphical Layout

 Właściwości elementów można edytować zarówno w edytorze tekstowym (dodawanie atrybutów do poszczególnych elementów), jak i graficznym (zakładka Properties, którą można wyświetlić przez Window->Show View->Properties).

Oto kod źródłowy naszego layoutu:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
	xmlns:android="http://schemas.android.com/apk/res/android"
	android:orientation="vertical"
	android:layout_width="fill_parent"
	android:layout_height="fill_parent">
	<EditText
		android:layout_height="wrap_content"
		android:id="@+id/etMainField"
		android:layout_width="fill_parent"
		android:hint="@string/editText_hint">
		<requestFocus></requestFocus>
	</EditText>
	<LinearLayout
		android:layout_height="wrap_content"
		android:orientation="horizontal"
		android:layout_width="fill_parent">
		<Button
			android:layout_height="wrap_content"
			android:id="@+id/btnShowInToast"
			android:text="@string/button_showToast"
			android:layout_weight="1"
			android:layout_width="fill_parent"></Button>
		<Button
			android:layout_height="wrap_content"
			android:id="@+id/btnShowInTextView"
			android:text="@string/button_changeTextView"
			android:layout_weight="1"
			android:layout_width="fill_parent"></Button>
	</LinearLayout>
	<TextView
		android:layout_height="wrap_content"
		android:text="TextView"
		android:layout_width="wrap_content"
		android:id="@+id/tvMainTextView"></TextView>
</LinearLayout>

Postaram się pokrótce przedstawić każdy z użytych tutaj elementów.

LinearLayout

W naszym interfejsie użyty został dwukrotnie. Układ tego typu, jak sama nazwa wskazuje, ustawia poszczególne elementy liniowo – jeden pod drugim lub jeden obok drugiego. O tym w jaki sposób układane będą elementy decyduje atrybut  android:orientation. Dzięki niemu, wewnętrzny LinearLayout pozwolił nam na umieszczenie przycisków obok siebie, a nie jeden pod drugim.

<LinearLayout
	xmlns:android="http://schemas.android.com/apk/res/android"
	android:orientation="vertical"
	android:layout_width="fill_parent"
	android:layout_height="fill_parent">
	...
</LinearLayout>
...
	<LinearLayout
		android:layout_height="wrap_content"
		android:orientation="horizontal"
		android:layout_width="fill_parent">
		...
	</LinearLayout>
...

Atrybuty android:layout_height oraz android:layout_width oznaczają w jaki sposób dany element ma być „rozciągany”. Wartość fill_parent (w nowszych wersjach zastąpiona przez match_parent) sprawia, że element wypełnia całe dostępne „wnętrze” elementu nadrzędnego, natomiast wartość wrap_content rozciąga element tak, by pomieścił całą swoją zawartość.

Więcej informacji o LinearLayout można znaleźć w oficjalnej dokumentacji (link).

EditText

Pole tekstowe pozwalające na wprowadzanie danych. Na razie w naszej aplikacji wykorzystaliśmy bardzo podstawową funkcjonalność tego elementu, aczkolwiek warto nadmienić, że posiada ono m.in. takie możliwości jak ustawianie jakie dane takie pole powinno przyjmować (dzięki czemu np. możemy sprawić, że zamiast pełnej klawiatury, wyświetli się tylko numeryczna).

...
	<EditText
		android:layout_height="wrap_content"
		android:id="@+id/etMainField"
		android:layout_width="fill_parent"
		android:hint="@string/editText_hint">
		<requestFocus></requestFocus>
	</EditText>
...

Atrybut android:hint ustawia podpowiedź do naszego pola testowego (wyświetlana jest tylko wtedy, gdy pole nie posiada żadnych wpisanych danych). Element <requestFocus> sprawia, że po odpaleniu naszej aplikacji, pole tekstowe będzie podświetlone.

Button

...
		<Button
			android:layout_height="wrap_content"
			android:id="@+id/btnShowInToast"
			android:text="@string/button_showToast"
			android:layout_weight="1"
			android:layout_width="fill_parent"></Button>
		<Button
			android:layout_height="wrap_content"
			android:id="@+id/btnShowInTextView"
			android:text="@string/button_changeTextView"
			android:layout_weight="1"
			android:layout_width="fill_parent"></Button>
...

W wypadku przycisków w naszym przykładzie, wartym uwagi jest tylko jeden parametr. Jest nim android:layout_weight, który określa jaką „wagę” ma dany element. Jeżeli wykorzystamy go razem z atrybutami android:layout_width/android:layout_height ustawionymi na fill_parent nasze elementy wypełnią całą dostępną przestrzeń zgodnie ze swoją wagą. I tak, gdy jeden element ma wagę równą 1 i drugi również 1, wypełnią one dostępną przestrzeń po równo. Dla wagi 1:2, wypełnią przestrzeń w takich właśnie proporcjach (1/3 dla pierwszego elementu, 2/3 dla drugiego).

TextView

...
	<TextView
		android:layout_height="wrap_content"
		android:text="TextView"
		android:layout_width="wrap_content"
		android:id="@+id/tvMainTextView"></TextView>
...

W tym wypadku chyba nie ma nic wartego większej uwagi. :)

Warto jednak zwrócić uwagę na to, że każdy (oprócz LinearLayout) posiada swój identyfikator, który ustawiamy przez atrybut android:id=”@+id/…”. To właśnie dzięki temu atrybutowi będziemy mogli odwoływać się do naszych elementów bezpośrednio z kodu źródłowego naszej aplikacji.

Kod źródłowy aplikacji

Kiedy już mamy przygotowany interfejs naszej aplikacji, pozostało nam tylko w jakiś sposób go oprogramować. Otwieramy zatem plik z klasą naszej głównej Aktywności i bierzemy się do pracy.

Najpierw dodajemy prywatne pola, które będą przechowywały elementy naszego layoutu:

...
public class HelloUIActivity extends Activity {
	private Button btnShowInToast;
	private Button btnShowInTextView;
	private EditText etMainEditText;
	private TextView tvMainTextView;

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
	}
}

Następnie, wewnątrz onCreate(), za pomocą metody findViewById(int) oraz rzutowania, z klasy R pobieramy elementy naszego layoutu.

	...
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
		btnShowInToast = (Button) findViewById(R.id.btnShowInToast);
		btnShowInTextView = (Button) findViewById(R.id.btnShowInTextView);
		etMainEditText = (EditText) findViewById(R.id.etMainField);
		tvMainTextView = (TextView) findViewById(R.id.tvMainTextView);
	}

Teraz pozostaje tylko przypisać przyciskom odpowiednie akcje. Robimy to za pomocą metody setOnClickListener(OnClickListener), wywoływanej na obiekcie przycisku.

	...
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
		btnShowInToast = (Button) findViewById(R.id.btnShowInToast);
		btnShowInTextView = (Button) findViewById(R.id.btnShowInTextView);
		etMainEditText = (EditText) findViewById(R.id.etMainField);
		tvMainTextView = (TextView) findViewById(R.id.tvMainTextView);
		initBtnOnClickListeners();
	}

	private void initBtnOnClickListeners() {
		btnShowInToast.setOnClickListener(new OnClickListener() {
			public void onClick(View v) {
				showToastWithText(etMainEditText.getText());
			}
		});
		btnShowInTextView.setOnClickListener(new OnClickListener() {
			public void onClick(View v) {
				changeTextInTextView(etMainEditText.getText());
			}
		});
	}

OnClickListener jest interfejsem posiadającym jedną metodę – onClick(View). Wywoływana jest ona w momencie kliknięcia na element interfejsu, a argumentem jest element, na który kliknęliśmy.

Na koniec jeszcze niewielkie metody, które wywoływane są przez nasze przyciski:

	...
	private void showToastWithText(CharSequence toastText) {
		Toast.makeText(getApplicationContext(), toastText, Toast.LENGTH_LONG)
			 .show();
	}

	protected void changeTextInTextView(CharSequence text) {
		tvMainTextView.setText(text);
	}

Toast

Ostatnim elementem UI, o którym dziś wspomnę jest Toast. Za jego pomocą możemy wyświetlać niewielkie wiadomości, w postaci „dymku” wyświetlanego na naszym urządzeniu.

	...
	private void showToastWithText(CharSequence toastText) {
		Toast.makeText(getApplicationContext(), toastText, Toast.LENGTH_LONG)
			 .show();
	}

Jak widać, wyświetlenie go w podstawowej wersji nie jest niczym skomplikowanym. Wystarczy skorzystać ze statycznej metody makeText(Context, CharSequence, int), która przyjmuje argumenty:

  • kontekst aplikacji (aktywność zwraca go poprzez getApplicationContext()),
  • tekst, który należy wyświetlić (przedstawiany za pomocą obiektu CharSequence),
  • czas, przez jaki wyświetlany ma być nasz „dymek” (możemy wykorzystać dwa pola statyczne klasy Toast – Toast.LENGTH_LONG oraz Toast.LENGHT_SHORT).

makeText(…) zwraca nam gotowy obiekt Toast, na którym wystarczy wywołać metodę show(), która wyświetli nam go na ekranie.

Screeny

Kompletny kod źródłowy aplikacji

main.xml

package pl.froger.helloui;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

public class HelloUIActivity extends Activity {
	private Button btnShowInToast;
	private Button btnShowInTextView;
	private EditText etMainEditText;
	private TextView tvMainTextView;

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
		btnShowInToast = (Button) findViewById(R.id.btnShowInToast);
		btnShowInTextView = (Button) findViewById(R.id.btnShowInTextView);
		etMainEditText = (EditText) findViewById(R.id.etMainField);
		tvMainTextView = (TextView) findViewById(R.id.tvMainTextView);
		initBtnOnClickListeners();
	}

	private void initBtnOnClickListeners() {
		btnShowInToast.setOnClickListener(new OnClickListener() {
			public void onClick(View v) {
				showToastWithText(etMainEditText.getText());
			}
		});
		btnShowInTextView.setOnClickListener(new OnClickListener() {
			public void onClick(View v) {
				changeTextInTextView(etMainEditText.getText());
			}
		});
	}

	private void showToastWithText(CharSequence toastText) {
		Toast.makeText(getApplicationContext(), toastText, Toast.LENGTH_LONG)
			 .show();
	}

	protected void changeTextInTextView(CharSequence text) {
		tvMainTextView.setText(text);
	}
}

HelloUIActivity.java

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
	xmlns:android="http://schemas.android.com/apk/res/android"
	android:orientation="vertical"
	android:layout_width="fill_parent"
	android:layout_height="fill_parent">
	<EditText
		android:layout_height="wrap_content"
		android:id="@+id/etMainField"
		android:layout_width="fill_parent"
		android:hint="@string/editText_hint">
		<requestFocus></requestFocus>
	</EditText>
	<LinearLayout
		android:layout_height="wrap_content"
		android:orientation="horizontal"
		android:layout_width="fill_parent">
		<Button
			android:layout_height="wrap_content"
			android:id="@+id/btnShowInToast"
			android:text="@string/button_showToast"
			android:layout_weight="1"
			android:layout_width="fill_parent"></Button>
		<Button
			android:layout_height="wrap_content"
			android:id="@+id/btnShowInTextView"
			android:text="@string/button_changeTextView"
			android:layout_weight="1"
			android:layout_width="fill_parent"></Button>
	</LinearLayout>
	<TextView
		android:layout_height="wrap_content"
		android:text="TextView"
		android:layout_width="wrap_content"
		android:id="@+id/tvMainTextView"></TextView>
</LinearLayout>

Cały projekt dostępny jest na naszym githubie – HelloUI.

Komentarze (2) Subskrybuj

 

  1. [...] Podstawowe elementy UI – Button, EditText, TextView, Toast, LinearLayout [...]

  2. [...] Podstawowe elementy UI – Button, EditText, TextView, Toast, LinearLayout [...]

Prześlij komentarz

Zaloguj się lub skorzystaj z profilu:

[rpxlogin redirect="http://www.android4devs.pl" prompt="" style="large"]

Możesz również zostawić komentarz bez rejestracji, korzystając z poniższego formularza:

Musisz być zalogowany aby móc pisać komentarze.