Lipiec 15, 2011
Pierwsze kroki Tutoriale UI
W dzisiejszym artykule zagłębimy się w kolejny element interfejsu użytkownika, jakim jest ListView. Jego zastosowanie jest nadzwyczaj proste – wyświetlić zbiór obiektów jeden pod drugim. I tym też za chwilę się zajmiemy. Poznamy podstawy tworzenia widoku listy, spersonalizujemy jej wygląd i przyjrzymy się mechanizmom z nią związanym.
Standardowo, przed rozpoczęciem powinniśmy stworzyć nowy projekt Androidowy w środowisku Eclipse. W niniejszym artykule będzie on nosił nazwę HelloListView.
Zadaniem naszej aplikacji będzie wyświetlenie listy języków, które po kliknięciu wyświetlą krótką informację o tym jak w danym języku wygląda słowo „Cześć”.
Jako, że w naszym przykładzie źródłem danych będą zwykłe tablice napisów, na miejsce ich przechowywania wybierzemy plik /res/values/strings.xml. Służy on bowiem nie tylko do zapisywania pojedynczych słów/zdań, ale również do przechowywania całych tablic napisów. Element, który przechowuje takie dane to <string-array name=”…”>, wewnątrz którego zawarte są elementy <item>. Każdy <item> to pojedynczy element tablicy. Atrybut name elementu string-array jest nazwą tablicy. Więcej na ten temat możemy poczytać w dokumentacji (link).
Oto cała zawartość pliku strings.xml, który na razie będzie przechowywał dwie tablice napisów – listę języków (tablica languages) oraz listę odmian słowa „cześć” (hello_phrases).
Dodanie elementu ListView do naszego UI skutkuje dodaniem poniższych kilku linijek kodu:
Jak widać, nie ma tu nic nietypowego, dlatego od razu przejdziemy do kodu źródłowego naszej aplikacji.
Rozpoczynamy jak zwykle od dodania elementu layoutu do klasy Aktywności, w której będzie on wykorzystany:
Następnym krokiem będzie pobranie danych, które zapisaliśmy w pliku strings.xml. Odbywa się to poprzez obiekt Resources, który wewnątrz klasy Aktywności można pobrać za pomocą getResources(). Metoda ta zawraca obiekt dający nam dostęp do wszystkich zasobów folderu /res/ naszej aplikacji.
Poszczególne elementy zasobów naszej aplikacji pobieramy za pomocą metod get…(int). Zwracają one element, na którego ID wskazują pola statyczne automatycznie generowanej klasy R. My jak widać korzystamy jedynie z metody getStringArray(int), której działanie jest chyba oczywiste.
Aby element ListView wyświetlił przekazane mu dane, musimy skorzystać z wzorca Adapter, który w tym wypadku powinien dziedziczyć z klasy BaseAdapter. Android domyślnie posiada dwie implementacje adapterów – CursorAdapter oraz ArrayAdapter. My w dzisiejszym artykule wykorzystamy ten drugi, który służy do „adaptowania” danych będących tablicami (CursorAdapter służy do obsługi danych bazodanowych).
Za pomocą metody setAdapter() stworzyliśmy nowy obiekt ArrayAdapter. W tym wypadku skorzystaliśmy z konstruktora, któremu oprócz kontekstu aplikacji przekazujemy:
Listę wszystkich dostępnych konstruktorów ArrayAdapter możemy znaleźć w dokumentacji (link).
Na koniec dodamy jeszcze obsługę kliknięć na poszczególne elementy listy. Nie jest to nic trudnego, bowiem na obiekcie ListView możemy ustawić listener nasłuchujący kliknięć na jego elementach:
Interfejs OnItemClickListener() dostarcza nam metody onItemClick(), której argumenty pozwalają dokładnie określić na jaki element właśnie kliknęliśmy.
Jak widać, w naszej aplikacji skorzystaliśmy z obiektu Toast, który zgodnie z wybraną pozycją, wyświetli nam tekst z tablicy helloPhrases, przechowującej odmiany zwrotu „Cześć”.
Kompletny kod źródłowy naszej aplikacji aktualnie składa się z:
MainActivity.java
/res/layout/main.xml
/res/values/strings.xml
Jeśli wszystko zrobiliśmy tak jak należy, po uruchomieniu naszej aplikacji powinniśmy ujrzeć coś takiego:
Oprócz dostarczonych przez system ArrayAdapter oraz CursorAdapter, Android pozwala nam na tworzenie i wykorzystywanie własnych adapterów danych. Dzięki temu mamy możliwość wypełniania ListView w sposób całkowicie zdefiniowany przez nas, co daje naprawdę ogromne możliwości. I tym też teraz się zajmiemy.
W poprzednim przykładzie wykorzystaliśmy jeden z gotowych stylów pojedynczych elementów listy, który zapisany jest pod stałą android.R.layout.simple_list_item_1. Teraz spróbujemy zbudować coś nieco bardziej skomplikowanego.
Zaczniemy od dodania nowego pliku z layoutem do /res/layout/. Nasz wygląd będzie zawierał dwa pola tekstowe i będzie wyglądał mniej więcej tak:
Oto cały kod źródłowy (plik: /res/layout/custom_list_item.xml):
Zaznaczyłem w nim kolejną ciekawostkę. Jak widać bowiem, oprócz napisów, Android pozwala nam również na przechowywanie innych wartości wewnątrz folderu /res/values/. Do ciekawszych należą m.in. wielkości (Dimension), identyfikatory (stąd ciąg …@+id/…), itp. Kompletną listę można znaleźć w dokumentacji (link).
My wykorzystujemy kolory, które zapisane są jako /res/values/colors.xml. Kod źródłowy pliku jest krótki i wymowny :
Kiedy zdefiniowaliśmy wygląd pojedynczych elementów naszej listy, pozostało nam już tylko napisanie naszego własnego adaptera dostarczanych danych.
Na razie pójdziemy na łatwiznę, przez co typem jaki przyjmuje nasz adapter będzie tablica stringów. Nic jednak nie stoi na przeszkodzie, by nasz adapter obsługiwał dane z klas modelowych. Wydaje mi się, że po zapoznaniu się z poniższym kodem nikt nie będzie miał wątpliwości w jaki sposób to zrobić.
Pierwszą rzeczą, którą powinniśmy zrobić jest stworzenie nowej klasy dziedziczącej po ArrayAdapter. W naszym przypadku ustawiamy od razu typ danych na String.
Jak widać w wywołaniu konstruktora nadklasy, jako jeden z argumentów przekazujemy wygląd stworzony przez nas (poprzez wartość R.layout.custom_list_item).
Należy również zwrócić uwagę na to, że zamiast obiektu kontekstu przekazywany jest obiekt Aktywności. Uprości nam to nieco kod, który napiszemy za chwilę.
Przechodzimy teraz do rzeczy najważniejszej, czyli implementacji metody zwracającej gotowy element listy.
Metoda getView(…), zaimplementowana powyżej odpowiedzialna jest za zwrócenie obiektu View, który znajduje się na konkretnej pozycji naszej listy. Innymi słowy zwraca ona „widok” poszczególnych elementów listy.
W zasadzie w tym momencie moglibyśmy zakończyć ten artykuł gdyby nie mały szczegół…
W związku z naszym przykładem punkt ten nie będzie miał większego znaczenia. Jednak należy pamiętać, że w realnych aplikacjach element ListView bardzo często wyświetla po kilkadziesiąt/kilkaset elementów o dużo bardziej skomplikowanej budowie. Dlatego też należy zaznajomić się z kilkoma kwestiami, które pozwolą zwiększyć wydajność naszej listy niemal trzykrotnie (przy dużych zbiorach danych).
Pierwszym wydajnościowym problemem naszego przykładu jest tworzenie nowego obiektu Javowego dla każdego elementu naszej listy. Jest to nierozsądne dlatego, że obiekt ten wykorzystywany jest tylko w momencie przekazania widoku elementu do wyświetlenia. Co się dzieje później? Działa Garbage Collector po czym kolejny obiekt listy jest tworzony. I tak w kółko.
Można jednak proces ten nieco przyspieszyć. Odbywa się to dzięki „recyklingowi” obiektów listy, który pozwala na wykorzystanie jednego obiektu do wyświetlenia wszystkich elementów listy. Jak to wygląda w praktyce? Tak:
Jednym z parametrów metody getView(…) jest obiekt convertView (typu View). Jest on właśnie tym odzyskanym obiektem widoku, który możemy wykorzystać do ponownego wyświetlenia.
Zatem, jeśli obiekt ten jest nullem, widok musimy stworzyć we własnym zakresie. Jeżeli jednak obiekt już istnieje, możemy go z powodzeniem wykorzystać do wyświetlenia następnych elementów listy.
Drugim wydajnościowym problemem, którym powinniśmy się zająć jest niepotrzebne wielokrotne wywoływanie metody findViewById(…). Jest ona bowiem bardzo zasobożerna, a jak widać wykorzystujemy ją dwukrotnie przy każdym wywołaniu metody getView(…) (czyli przy każdym elemencie naszej listy).
Powinniśmy zatem zastanowić się co zrobić aby ograniczyć ilość wywołań metody findViewById(…) do niezbędnego minimum (czyli najlepiej do wywołania tylko w momencie tworzenia nowego obiektu widoku).
Z pomocą przychodzi nam tutaj wzorzec ViewHolder, którego implementacja wygląda w ten sposób:
Oto co zrobiliśmy:
I to wszystko w temacie optymalizacji. Tym sposobem udało nam się przyspieszyć element ListView niemal trzykrotnie.
Oto efekty naszej pracy z niestandardowym adapterem listy:
MainActivity.java
LanguagesArrayAdapter.java
main.xml
custom_list_item.xml
Cały projekt dostępny jest na naszym githubie – HelloListView.
[…] ListView, pierwsze kroki […]
[…] widoku, jednokrotne wykonanie findViewById()). Artykuł z tym związany można przeczytać pod tym […]
Zaloguj się lub skorzystaj z profilu:
Możesz również zostawić komentarz bez rejestracji, korzystając z poniższego formularza:
Musisz być zalogowany aby móc pisać komentarze.
ListView, pierwsze kroki
Powiązane linki
Przygotowanie
Podstawy ListView
Własny adapter danych dla ListView
Tablica napisów
UI
Kod źródłowy aplikacji
Działanie i kompletny kod aplikacji
Wygląd pojedynczego elementu listy
Kod adaptera
Optymalizacja
Screeny
Kompletny kod źródłowy
Komentarze (2)
Prześlij komentarz
Pobieranie danych z /res/values/strings.xml
Inicjalizacja ListView
Obsługa kliknięć na konkretny element listy
Tworzenie obiektów
Eliminacja czasochłonnych metod
- layout pojedynczego elementu listy (android.R.layout jest polem, w którym przechowywane są domyślne layouty, dostarczone wraz z systemem Android),
- tablicę napisów, którą wcześniej pobraliśmy z zasobów naszej aplikacji.
- linijki 20-23 – Stworzyliśmy nową zagnieżdżoną klasę statyczną (pod tym adresem można znaleźć bardzo konkretny opis czym jest taka konstrukcja), która będzie nam służyła do przechowywania poszczególnych elementów UI.
- linijki 32-35 – za pomocą metod findViewById(…) (które wywoływane są tylko raz – w momencie tworzenia nowego obiektu widoku), pobieramy elementy UI do ViewHoldera. Obiekt ten przekazujemy przez setTag(…) do naszego widoku. Metoda ta pozwala nam na dołączanie „załączników” do obiektu widoku.
- linijka 37 – kiedy „odzyskujemy” obiekt widoku, wystarczy, że pobierzemy z niego wstawiony przez nas „załącznik” w postaci ViewHoldera.
- linijki 39,40 – operujemy na elementach UI, na które wskazuje nasz ViewHolder.
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="hello">Hello World, MainActivity!</string>
<string name="app_name">HelloListView</string>
<string name="app_header">Multilingual \"Hello\"</string>
<string name="hint">Tap language name to show its \"Hello\" phrase.</string>
<string-array name="languages">
<item>Albanian</item>
<item>English</item>
<item>Arabic</item>
<item>Bulgarian</item>
<item>Chinese</item>
<item>Czech</item>
<item>Danish</item>
<item>Esperanto</item>
<item>Estonian</item>
<item>Filipino</item>
<item>Finnish</item>
<item>French</item>
<item>Greek</item>
<item>Spanish</item>
<item>Dutch</item>
<item>Icelandic</item>
<item>Irish</item>
<item>Japanese</item>
<item>Korean</item>
<item>Latin</item>
<item>German</item>
<item>Norwegian</item>
<item>Portuguese</item>
<item>Polish</item>
<item>Russian</item>
<item>Romanian</item>
<item>Serbian</item>
<item>Swedish</item>
<item>Slovak</item>
<item>Slovenian</item>
<item>Turkish</item>
<item>Ukrainian</item>
<item>Hungarian</item>
<item>Italian</item>
</string-array>
<string-array name="hello_phrases">
<item>Tungjatjeta</item>
<item>Hello</item>
<item>Marhaba</item>
<item>Zdrawejte</item>
<item>Neih hou</item>
<item>Nazdar</item>
<item>Goddag</item>
<item>Saluton</item>
<item>Tervist</item>
<item>Huy</item>
<item>Paivaa</item>
<item>Salut</item>
<item>Geia siou</item>
<item>Hola</item>
<item>Hallo</item>
<item>Godan</item>
<item>Haileo</item>
<item>Konnichi wa</item>
<item>Annyong</item>
<item>Salve</item>
<item>Gruess dich</item>
<item>Goddag</item>
<item>Oi</item>
<item>Cześć</item>
<item>Priwiet</item>
<item>Buna</item>
<item>Zdravo</item>
<item>Hejsan</item>
<item>Ahoj</item>
<item>Zhivjo</item>
<item>Selam</item>
<item>Prywit</item>
<item>Szervusz</item>
<item>Ciao</item>
</string-array>
</resources><ListView android:layout_height="fill_parent" android:layout_width="fill_parent" android:id="@+id/lvLanguages"></ListView>
...
public class MainActivity extends Activity {
private ListView lvLanguages;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
lvLanguages = (ListView) findViewById(R.id.lvLanguages);
}
}...
public class MainActivity extends Activity {
private ListView lvLanguages;
private String[] languages;
private String[] helloPhrases;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
lvLanguages = (ListView) findViewById(R.id.lvLanguages);
initResources();
}
private void initResources() {
Resources res = getResources();
languages = res.getStringArray(R.array.languages);
helloPhrases = res.getStringArray(R.array.hello_phrases);
}
}...
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
lvLanguages = (ListView) findViewById(R.id.lvLanguages);
initResources();
initLanguagesListView();
}
private void initResources() {
Resources res = getResources();
languages = res.getStringArray(R.array.languages);
helloPhrases = res.getStringArray(R.array.hello_phrases);
}
private void initLanguagesListView() {
lvLanguages.setAdapter(new ArrayAdapter<String>(
getApplicationContext(),
android.R.layout.simple_list_item_1,
languages));
}
}...
private void initLanguagesListView() {
lvLanguages.setAdapter(new ArrayAdapter<String>(
getApplicationContext(),
android.R.layout.simple_list_item_1,
languages));
lvLanguages.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View v, int pos, long id) {
Toast.makeText(getApplicationContext(),
helloPhrases[pos],
Toast.LENGTH_SHORT).show();
}
});
}package pl.froger.hellolistview;
import android.app.Activity;
import android.content.res.Resources;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.Toast;
public class MainActivity extends Activity {
private ListView lvLanguages;
private String[] languages;
private String[] helloPhrases;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
lvLanguages = (ListView) findViewById(R.id.lvLanguages);
initResources();
initLanguagesListView();
}
private void initResources() {
Resources res = getResources();
languages = res.getStringArray(R.array.languages);
helloPhrases = res.getStringArray(R.array.hello_phrases);
}
private void initLanguagesListView() {
lvLanguages.setAdapter(new ArrayAdapter<String>(
getApplicationContext(),
android.R.layout.simple_list_item_1,
languages));
lvLanguages.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View v, int pos, long id) {
Toast.makeText(getApplicationContext(),
helloPhrases[pos],
Toast.LENGTH_SHORT).show();
}
});
}
}<?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="wrap_content"> <TextView android:textAppearance="?android:attr/textAppearanceLarge" android:id="@+id/tvTitle" android:text="@string/app_header" android:layout_width="fill_parent" android:gravity="center" android:layout_height="wrap_content"></TextView> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/tvHint" android:text="@string/hint"></TextView> <ListView android:layout_height="fill_parent" android:layout_width="fill_parent" android:id="@+id/lvLanguages"></ListView> </LinearLayout>
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="hello">Hello World, MainActivity!</string>
<string name="app_name">HelloListView</string>
<string name="app_header">Multilingual \"Hello\"</string>
<string name="hint">Tap language name to show its \"Hello\" phrase.</string>
<string-array name="languages">
<item>Albanian</item>
<item>English</item>
<item>Arabic</item>
<item>Bulgarian</item>
<item>Chinese</item>
<item>Czech</item>
<item>Danish</item>
<item>Esperanto</item>
<item>Estonian</item>
<item>Filipino</item>
<item>Finnish</item>
<item>French</item>
<item>Greek</item>
<item>Spanish</item>
<item>Dutch</item>
<item>Icelandic</item>
<item>Irish</item>
<item>Japanese</item>
<item>Korean</item>
<item>Latin</item>
<item>German</item>
<item>Norwegian</item>
<item>Portuguese</item>
<item>Polish</item>
<item>Russian</item>
<item>Romanian</item>
<item>Serbian</item>
<item>Swedish</item>
<item>Slovak</item>
<item>Slovenian</item>
<item>Turkish</item>
<item>Ukrainian</item>
<item>Hungarian</item>
<item>Italian</item>
</string-array>
<string-array name="hello_phrases">
<item>Tungjatjeta</item>
<item>Hello</item>
<item>Marhaba</item>
<item>Zdrawejte</item>
<item>Neih hou</item>
<item>Nazdar</item>
<item>Goddag</item>
<item>Saluton</item>
<item>Tervist</item>
<item>Huy</item>
<item>Paivaa</item>
<item>Salut</item>
<item>Geia siou</item>
<item>Hola</item>
<item>Hallo</item>
<item>Godan</item>
<item>Haileo</item>
<item>Konnichi wa</item>
<item>Annyong</item>
<item>Salve</item>
<item>Gruess dich</item>
<item>Goddag</item>
<item>Oi</item>
<item>Cześć</item>
<item>Priwiet</item>
<item>Buna</item>
<item>Zdravo</item>
<item>Hejsan</item>
<item>Ahoj</item>
<item>Zhivjo</item>
<item>Selam</item>
<item>Prywit</item>
<item>Szervusz</item>
<item>Ciao</item>
</string-array>
</resources><?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="horizontal" android:padding="15dp"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="0" android:height="20dp" android:width="20dp" android:gravity="center" android:background="@color/item_number_bg_color" android:textColor="@color/item_number_font_color" android:id="@+id/tvItemNumber"></TextView> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/tvLanguage" android:text="---" android:layout_marginLeft="20dp"></TextView> </LinearLayout>
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="item_number_bg_color">#ECECEC</color>
<color name="item_number_font_color">#000000</color>
</resources>...
public class LanguagesArrayAdapter extends ArrayAdapter<String> {
private Activity context;
private String[] languages;
public LanguagesArrayAdapter(Activity context, String[] languages) {
super(context, R.layout.custom_list_item, languages);
this.context = context;
this.languages = languages;
}
}...
public class LanguagesArrayAdapter extends ArrayAdapter<String> {
private Activity context;
private String[] languages;
public LanguagesArrayAdapter(Activity context, String[] languages) {
super(context, R.layout.custom_list_item, languages);
this.context = context;
this.languages = languages;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater layoutInflater = context.getLayoutInflater();
View rowView = layoutInflater.inflate(R.layout.custom_list_item, null, true);
TextView tvLanguage = (TextView) rowView.findViewById(R.id.tvLanguage);
TextView tvItemNumber = (TextView) rowView.findViewById(R.id.tvItemNumber);
tvItemNumber.setText(Integer.toString(position));
tvLanguage.setText(languages[position]);
return rowView;
}
} ...
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View rowView = convertView;
if(rowView == null){
LayoutInflater layoutInflater = context.getLayoutInflater();
rowView = layoutInflater.inflate(R.layout.custom_list_item, null, true);
}
TextView tvLanguage = (TextView) rowView.findViewById(R.id.tvLanguage);
TextView tvItemNumber = (TextView) rowView.findViewById(R.id.tvItemNumber);
tvItemNumber.setText(Integer.toString(position));
tvLanguage.setText(languages[position]);
return rowView;
}...
public class LanguagesArrayAdapter extends ArrayAdapter<String> {
private Activity context;
private String[] languages;
public LanguagesArrayAdapter(Activity context, String[] languages) {
super(context, R.layout.custom_list_item, languages);
this.context = context;
this.languages = languages;
}
static class ViewHolder {
public TextView tvLanguage;
public TextView tvItemNumber;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder viewHolder;
View rowView = convertView;
if(rowView == null) {
LayoutInflater layoutInflater = context.getLayoutInflater();
rowView = layoutInflater.inflate(R.layout.custom_list_item, null, true);
viewHolder = new ViewHolder();
viewHolder.tvLanguage = (TextView) rowView.findViewById(R.id.tvLanguage);
viewHolder.tvItemNumber = (TextView) rowView.findViewById(R.id.tvItemNumber);
rowView.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) rowView.getTag();
}
viewHolder.tvItemNumber.setText(Integer.toString(position));
viewHolder.tvLanguage.setText(languages[position]);
return rowView;
}
}package pl.froger.hellolistview;
import android.app.Activity;
import android.content.res.Resources;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ListView;
import android.widget.Toast;
public class MainActivity extends Activity {
private ListView lvLanguages;
private String[] languages;
private String[] helloPhrases;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
lvLanguages = (ListView) findViewById(R.id.lvLanguages);
initResources();
initLanguagesListView();
}
private void initResources() {
Resources res = getResources();
languages = res.getStringArray(R.array.languages);
helloPhrases = res.getStringArray(R.array.hello_phrases);
}
private void initLanguagesListView() {
LanguagesArrayAdapter adapter = new LanguagesArrayAdapter(this, languages);
lvLanguages.setAdapter(adapter);
lvLanguages.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View v, int pos, long id) {
Toast.makeText(getApplicationContext(),
helloPhrases[pos],
Toast.LENGTH_SHORT).show();
}
});
}
}package pl.froger.hellolistview;
import android.app.Activity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.TextView;
public class LanguagesArrayAdapter extends ArrayAdapter<String> {
private Activity context;
private String[] languages;
public LanguagesArrayAdapter(Activity context, String[] languages) {
super(context, R.layout.custom_list_item, languages);
this.context = context;
this.languages = languages;
}
static class ViewHolder {
public TextView tvLanguage;
public TextView tvItemNumber;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder viewHolder;
View rowView = convertView;
if(rowView == null) {
LayoutInflater layoutInflater = context.getLayoutInflater();
rowView = layoutInflater.inflate(R.layout.custom_list_item, null, true);
viewHolder = new ViewHolder();
viewHolder.tvLanguage = (TextView) rowView.findViewById(R.id.tvLanguage);
viewHolder.tvItemNumber = (TextView) rowView.findViewById(R.id.tvItemNumber);
rowView.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) rowView.getTag();
}
viewHolder.tvItemNumber.setText(Integer.toString(position));
viewHolder.tvLanguage.setText(languages[position]);
return rowView;
}
}<?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="wrap_content"> <TextView android:textAppearance="?android:attr/textAppearanceLarge" android:id="@+id/tvTitle" android:text="@string/app_header" android:layout_width="fill_parent" android:gravity="center" android:layout_height="wrap_content"></TextView> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/tvHint" android:text="@string/hint"></TextView> <ListView android:layout_height="fill_parent" android:layout_width="fill_parent" android:id="@+id/lvLanguages"></ListView> </LinearLayout>
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="horizontal" android:padding="15dp"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="0" android:height="20dp" android:width="20dp" android:gravity="center" android:background="@color/item_number_bg_color" android:textColor="@color/item_number_font_color" android:id="@+id/tvItemNumber"></TextView> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/tvLanguage" android:text="---" android:layout_marginLeft="20dp"></TextView> </LinearLayout>
28 lipca 2011 o 00:00
29 sierpnia 2011 o 07:48