ListView- lista rozwijalna

Kontrolka ListView umożliwia wykorzystanie różnych elementów wyświetlanych w grupie zorganizowanej w wielu wierszach. Wykorzystanie kontrolki ListView wymaga zastosowania adaptera list.

Adapter listy automatycznie wstawia elementy do listy. Adapter może pobierać dane z tablicy, bazy danych lub danych zapisanych w postaci ciągów w pliku typu XML. Podczas pobierania danych generuje widoki dla każdego elementu listy.

Widok elementu listy to osobny widok (layout). W najprostszym wariancie zawiera tylko kontrolkę TextView, która jest wymagana w widoku elementu listy. Konstrukcyjnie widok elementu listy może być dodatkowo wyposażony w różne inne kontrolki niż TextView. W takim przypadku należy przygotować osobną klasę obsługującą adapter listy niestandardowego widoku. Przykład niestandardowego widoku ListView

Android Studio Kotlin ListView

Układ widoku

Przygotowanie projektu rozpoczniemy od układu głównego widoku. Widok oparty jest na układzie LinearLayout z opcją wyrównania pionowego (vertical). W układzie tym umieść kontrolkę ListView oraz cztery kontrolki Button.

Kotlin layout ListView

W przedstawionym układzie ListView ma przypisaną linie widoku o zielonkawym kolorze i szerokości 2dp. Patrz na poniższy fragment pliku activity_main.xml

Wskazówka:


<ListView
    android:id="@+id/listView"
    android:layout_width="match_parent"
    android:layout_height="259dp"
    android:layout_marginBottom="20dp"
    android:divider="#7cc82a"
    android:dividerHeight="2dp" />

Kontrolka ListView może zawierać nagłówek i stopkę. Elementy te można dodać dynamicznie w trakcie działania programu.

Prosta lista widoku

W tym rozwiązaniu elementy listy pobierzemy ze statycznej tablicy łańcuchów znaków. Korzystając z elastyczności języka Kotlin nie musimy jawnie deklarować typu tablicy. Jeżeli skorzystamy z metody arrayOf kompilator sam określi typ przechowywanych wartości w tablicy.

W głównym pliku projektu MainActivity.kt definiujemy tablicę danych oraz zmienne na identyfikator nagłówka i stopki.

UWAGA. Identyfikator elementu występującego w projekcie aplikacji mobilnej w systemie Android jest liczbą szesnastkową i musi być unikatowy. W tym celu należy posłużyć się metodą generującą identyfikator: generateViewId(). Metoda ta należy do klasy View. Można też zastosować identyfikator oparty na unikatowym tagu elementu.

Wskazówka:


class MainActivity : AppCompatActivity() {
    val idNaglowek= View.generateViewId()
    val idStopka= View.generateViewId()
    val TagNaglowek= "moj_naglowek"
    val tabKrajeUE=arrayOf("Austria", "Belgia", "Bułgaria",
                 "Chorwacja", "Cypr", "Czechy", "Dania",
                 "Estonia", "Finlandia", "Francja", "Grecja",
                 "Hiszpania", "Holandia", "Irlandia", "Litwa",
                 "Luksemburg", "Łotwa", "Malta", "Niemcy",
                 "Polska", "Portugalia", "Rumunia", "Słowacja",
                 "Słowenia", "Szwecja", "Węgry", "Włochy")

    override fun onCreate(savedInstanceState: Bundle?) {

Dodajemy funkcję ładującą te dane do kontrolki ListView. W kodzie funkcji zwróć uwagę na adapter pośredniczący przy ładowaniu danych do kontrolki ListView. Adapter jest oparty na klasie ArrayAdapter, której konstruktor może zawierać kilka parametrów. W tym przypadku użyto parametr:

Wskazówka:


fun ListaProsta(){
    val listView=findViewById<ListView>(R.id.listView)

    val staryNaglowek=listView.findViewById<TextView>(idNaglowek)
    if(staryNaglowek!=null)listView.removeHeaderView(staryNaglowek)
    //val starynaglowek=listView.findViewWithTag<TextView>(TagNaglowek)
    //if(starynaglowek!=null)listView.removeHeaderView(starynaglowek)

    val naglowek=TextView(this)
    naglowek.setTextSize(22f)
    naglowek.setText("Lista prosta pobrana z tablicy")
    naglowek.setBackgroundColor(Color.parseColor("#FFEFA910"))
    naglowek.id=idNaglowek
    naglowek.tag=TagNaglowek
    listView.addHeaderView(naglowek)
    val moj_adapter= ArrayAdapter<String>(this,
        android.R.layout.simple_list_item_1,
        tabKrajeUE)
    listView.adapter=moj_adapter
}

Metoda addHeaderView() klasy ListView dodaje nagłowek, a metoda addFooterView() dodaje stopkę. Argumentami tych metod są kontrolki typu TextView, tworzące tekst nagłówka lub stopki.

Wywołanie utworzonej funkcji wykonamy w słuchaczu zdarzeń kliknięć kontrolki Button

Wskazówka:


override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)

    val bt1=findViewById<Button>(R.id.button1)
    bt1.setOnClickListener{ ListaProsta() }

}

Uruchamiamy projekt i sprawdzamy efekt działania.

Kotlin layout ListView addHeaderView() addFooterView()

Listę można przewijać z góry na dół i odwrotnie.

Prosta lista widoku pobrana z plików zasobu XML

Metoda pobierania danych zapisanych bezpośrednio w kodzie programu nie jest wygodna w przypadku możliwości zmiany zawartości elementów listy. Lepszym sposobem jest pobieranie danych zapisanych na przykład w pliku zasobów XML.

Przejdź do pliku strings.xml lub utwórz nowy, a w nim dodaj prostą tablicę łańcuchów znaków (typ String). UWAGA. Taka tablica musi posiadać niepowtarzalną nazwę, po której jest identyfikowana w projekcie.

Wskazówka:


<resources>
    <string name="app_name">Lista widoku</string>
    <!--tablica krajów UE-->
    <string-array name="KrajeUE">
        <item>Austria</item>
        <item>Włochy</item>
        <item>Węgry</item>
        <item>Szwecja</item>
        <item>Słowenia</item>
        <item>Słowacja</item>
        <item>Rumunia</item>
        <item>Portugalia</item>
        <item>Polska</item>
    </string-array>
</resources>

Kraje zostały celowo wprowadzane bez porządku alfabetycznego. Tablica zostanie posortowana od A do Z przed załadowaniem do adaptera ListView. Patrz poniższy kod

Wskazówka:


val tabUE=resources.getStringArray(R.array.KrajeUE)
tabUE.sort()

Pierwsza linijka kodu odpowiedzialna jest za pobranie tablicy z pliku zasobów, druga za jej posortowanie.

Dodajemy funkcję ładującą tablicę pobraną z pliku zasobów do adaptera ListView. Kod funkcji nieznacznie się różni od poprzedniej.

Wskazówka:


fun ListaProstaPobrana_z_Zasobow(){
    val listView=findViewById<ListView>(R.id.listView)

    val staryNaglowek=listView.findViewById<TextView>(idNaglowek)
    if(staryNaglowek!=null)listView.removeHeaderView(staryNaglowek)

    val naglowek=TextView(this)
    naglowek.setTextSize(22f)
    naglowek.setText("Lista prosta pobrana z zasobów")
    naglowek.id=idNaglowek
    naglowek.setBackgroundColor(Color.parseColor("#FFc7241f"))
    listView.addHeaderView(naglowek)
    val tabUE=resources.getStringArray(R.array.KrajeUE)
    tabUE.sort()
    val moj_adapter= ArrayAdapter<String>(this,
        android.R.layout.simple_list_item_1,
        tabUE)
    listView.adapter=moj_adapter
}

Funkcję wywołamy w słuchaczu kliknięcia w drugiej kontrolce typu Button.

Wskazówka:


override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)

    val bt1=findViewById<Button>(R.id.button1)
    bt1.setOnClickListener{ ListaProsta() }

    val bt2=findViewById<Button>(R.id.button2)
    bt2.setOnClickListener{ ListaProstaPobrana_z_Zasobow() }

}

Sprawdzamy działanie aplikacji.

Kotlin layout ListView

Wczytane elementy listy powinny być posortowane w porządku alfabetycznym od A do Z.

Obsługa kliknięcia w element listy

Elementy przechowywane w kontrolce ListView są indeksowane na tych samych zasadach co w każdej kolekcji zaczynając od 0 (zera) a kończąc na indeksie o jeden mniejszym niż rozmiar kolekcji.

Obsługa kliknięcia w dowolny element wymaga wykorzystania słuchacza kliknięć w itemy (elementy) listy. Zapewnia to metoda setOnItemClickListener().

Ta metoda (w języku Kotlin) w standardowym użyciu posiada cztery parametry. Pierwszy to właściciel (ojciec) obiektu, drugi to układ widoku, trzeci to pozycja z listy, czwarty to wyrażenie lambda przekazujące te parametry do obsługi kliknięcia w element listy.

Fakt kliknięcia w dowolny element listy zarejestrujemy jako wyświetlenie okna dialogowego (AlertDialog), do którego przekażemy treść i indeks elementu.

Wskazówka:


fun ObslugaKlikniecia(){
    //załaduj listę
    ListaProstaPobrana_z_Zasobow()
    //obsłuz klikniecie w załadowany element listy
    val listView=findViewById<ListView>(R.id.listView)
    listView.setOnItemClickListener { parent, view, position, id ->
        val elementListy=parent.getItemAtPosition(position)
        val oknoKomunikatu=AlertDialog.Builder(this)
        oknoKomunikatu.setTitle("Kliknięto w element listy")
        oknoKomunikatu.setMessage(elementListy.toString()+"\nindeks: "+id.toString())
        oknoKomunikatu.setPositiveButton("Zamknij",null)
        oknoKomunikatu.show()
    }
}

Wywołanie funkcji podepniemy pod słuchacza kliknięć trzeciej kontrolki Button.

Wskazówka:


override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)

    val bt1=findViewById<Button>(R.id.button1)
    bt1.setOnClickListener{ ListaProsta() }

    val bt2=findViewById<Button>(R.id.button2)
    bt2.setOnClickListener{ ListaProstaPobrana_z_Zasobow() }

    val bt3=findViewById<Button>(R.id.button3)
    bt3.setOnClickListener{ ObslugaKlikniecia() }
}

Uruchamiamy aplikacje i sprawdzamy jej działanie.

Kotlin layout listView.setOnItemClickListener

Kliknięcie w element listy wywołuje powyższy komunikat.

Niestandardowy ListView

Szeroką modyfikacje kontrolki ListView daje możliwość wykorzystania niestandardowego układu ListView, który jest przygotowany w postaci osobnego widoku (layout) dla pojedynczego elementu (item) listy.

W podanym przykładzie pojedynczy element listy będzie zawierać obrazek (flaga kraju), nazwę kraju oraz powierzchnię kraju.

Kotlin niestandardowy layout listView

Tworzenie nowej listy rozpoczniemy od przygotowania pliku XML widoku układu elementu. Do projektu dodaj nowy plik XML i nadaj mu nazwę: item_layout_list.xml. Do układu dodaj LinearLayout w widoku poziomym (horyzontalnym). Dodaj jeden element ImageView na obraz flagi. Dodaj kolejny LinearLayout, ale w układzie pionowym (vertical). Osadź w tym układzie dwie kontrolki typu TextView, w których wyświetli się nazwa państwa oraz jego powierzchnia.

Kotlin niestandardowy layout listView

Proponowany układ przedstawia poniższy kod

Wskazówka:


<?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="10dp">
    <ImageView
        android:id="@+id/ikonaFlagi"
        android:src="@color/zielonkawy"
        android:layout_width="128dp"
        android:layout_height="96dp" />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        android:padding="10dp">

        <TextView
            android:id="@+id/textViewKraj"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="Nazwa kraju"
            android:textSize="24sp" />

        <TextView
            android:id="@+id/textViewPow"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="Indeks kraju"
            android:textSize="20sp" />
    </LinearLayout>

</LinearLayout>

Przejdź do widoku hierarchii projektu i skopiuj do katalogu res/ drawable pliki graficzne obrazów flag państwowych. Przypisz im niepowtarzalne nazwy

Kotlin niestandardowy layout listView

W pliku zasobów XML przygotujemy tablicę tablic zawartości pojedynczego itemu. W pliku strings.xml dodaj informację o wybranych krajach zorganizowaną jak poniżej

Wskazówka:


<array name="KrajeFlagi">
    <item>@array/polska</item>
    <item>@array/austria</item>
    <item>@array/belgia</item>
    <item>@array/portugalia</item>
</array>

<array name="polska">
    <item name="nazwa" type="string">Polska</item>
    <item name="flaga" type="int">@drawable/pl</item>
    <item name="pow" type="string">322 575 km?</item>
</array>
<array name="austria">
    <item name="nazwa" type="string">Austria</item>
    <item name="flaga" type="int">@drawable/austria</item>
    <item name="pow" type="string">83 871 km?</item>
</array>
<array name="belgia">
    <item name="nazwa" type="string">Belgia</item>
    <item name="flaga" type="int">@drawable/belgia</item>
    <item name="pow" type="string">30 688 km?</item>
</array>
<array name="portugalia">
    <item name="nazwa" type="string">Portugalia</item>
    <item name="flaga" type="int">@drawable/portugalia</item>
    <item name="pow" type="string">92 152 km?</item>
</array>

Do projektu dodaj nową klasę (zapisaną w języku Kotlin), która będzie odpowiedzialna za adapter niestandardowej ListView. Klase nazwij MojAdapterListy. W hierarchii projektu pojawi się plik o nazwie utworzonej klasy.

add Kotlin class

Zawartość pliku utworzonej klasy MojAdapterListy, która bazuje na klasie ArrayAdapter

Wskazówka:


import android.content.Context
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ArrayAdapter
import android.widget.ImageView
import android.widget.TextView

class MojAdapterListy(context: Context, val zasobWidoku: Int, val itemy: List<PrzekazywneDane>) :
    ArrayAdapter<PrzekazywneDane>(context, zasobWidoku, itemy) {
    //obsłuz ładowany układ widoku itemu
    override fun getView(position: Int, convertView: View?, parent: ViewGroup): View {
        val layout:LayoutInflater=LayoutInflater.from(context)
        val view:View=layout.inflate(zasobWidoku,null)
        val img:ImageView=view.findViewById(R.id.ikonaFlagi)
        val txtKraj:TextView=view.findViewById(R.id.textViewKraj)
        val txtPow:TextView=view.findViewById(R.id.textViewPow)
        val dane:PrzekazywneDane=itemy[position]

        img.setImageDrawable(context.resources.getDrawable(dane.obrazFlagi))
        txtKraj.text=dane.nazwa
        txtPow.text=dane.pow

        return view
    }
}
//klas posredniczaca w przekazywaniu danych do itemów adaptera
class PrzekazywneDane(val nazwa:String, val obrazFlagi:Int, val pow:String)

UWAGA. Przy tworzeniu niestandardowych widoków list można skorzystać z podpowiedzi naprawy błędów, która w tym przypadku ułatwi konstrukcję adaptera tworzonej listy

ArrayAdapter ListView Android Studio

Po załadowaniu podpowiedzi parametry funkcji tworzącej zmienimy na zmienne typu val, patrz poniżej

Wskazówka:


class MojAdapterListy(context: Context, val zasobWidoku: Int, val itemy: List<PrzekazywneDane>) :
    ArrayAdapter<PrzekazywneDane>(context, zasobWidoku, itemy)

Sercem utworzonej klasy jest nadpisana funkcja getView (override fun getView). Jej zadaniem odczytanie z plików zasobów widoku (layout) pojedynczego elementu listy i załadowanie do adaptera ListView. Następnie odszukanie kontrolek niestandardowego widoku, odczytanie danych z itemów i przesłanie ich do odpowiedniej kontrolki.

Dane do utworzonej klasy adaptera niestandardowej ListView są przekazane w formie kolekcji jako lista bazująca na utworzonym typie klasy danych o nazwie Przekazywanedane. O tym należy pamiętać przy implementacji funkcji wczytującej dane z plików zasobu XML.

Przechodzimy do głównego pliku projektu i piszemy funkcję wczytującą dane do niestandardowego układu ListView.

UWAGA. Przed nazwa funkcji występuje dyrektywa @SuppressLint("ResourceType") nakazuje ignorowanie ostrzeżeń adnotacji indeksów dodawanych elementów. Tu linie tabBufor.getString(0).toString() itd.

W podanej funkcji dane odczytane są na podstawie tablicy tablic (w zasobach to R.array.KrajeFlagi). Każdy element tej tablicy jest tablicą, do której kod odwołuje sie jako tymczasowej buforowej tablicy

Wskazówka:


val tabBufor=resources.obtainTypedArray(tabKrajeFlagi.getResourceId(i,0))

Z której to pobierane są właściwe dane.

Wskazówka:


@SuppressLint("ResourceType")
fun LadujNiestandardowaListe(){
    val listView=findViewById<ListView>(R.id.listView)
    Naglowek(listView,"Lista niestandardowa- kraje i flagi","#FF94EF8E")
    var listaKrajow = mutableListOf<PrzekazywneDane>()
    val tabKrajeFlagi=resources.obtainTypedArray(R.array.KrajeFlagi)
    for (i in 0.. tabKrajeFlagi.length()-1){
        val tabBufor=resources.obtainTypedArray(tabKrajeFlagi.getResourceId(i,0))
        listaKrajow.add(
            PrzekazywneDane(
                tabBufor.getString(0).toString(),
                tabBufor.getResourceId(1, R.drawable.pl),
                tabBufor.getString(2).toString()
                )
            )
    }
    listView.adapter=MojAdapterListy(this,R.layout.item_layout_list,listaKrajow)
    Stopka(listView,"Lista zawiera "+listaKrajow.count().toString()+" elementów","#FF94EF8E")
}

W podanym rozwiązaniu są dwie funkcje związane z nagłówkiem i stopką ListView. Ich kod bazuje na wcześniejszym rozwiązaniu i został wprowadzony w celu uproszczenia przedstawionej treści funkcji ładującej niestandardowy układ ListView.

Wskazówka:


fun Naglowek(listView:ListView, tytul:String,kolor:String){
    val staryNaglowek=listView.findViewById<TextView>(idNaglowek)
    if(staryNaglowek!=null)listView.removeHeaderView(staryNaglowek)
    val naglowek=TextView(this)
    naglowek.setTextSize(22f)
    naglowek.setText(tytul)
    naglowek.setBackgroundColor(Color.parseColor(kolor))
    naglowek.id=idNaglowek
    listView.addHeaderView(naglowek)
}
fun Stopka(listView:ListView, tytul:String,kolor:String){
    val staraStopka=listView.findViewById<TextView>(idStopka)
    if(staraStopka!=null)listView.removeFooterView(staraStopka)
    val stopka=TextView(this)
    stopka.setTextSize(14f)
    stopka.setText(tytul)
    stopka.setBackgroundColor(Color.parseColor(kolor))
    stopka.id=idStopka
    listView.addFooterView(stopka)
}

Uruchom aplikację i sprawdź jej działanie.

Kotlin ArrayAdapter ListView Android Studio

Powyżej widok na prawidłowo działającą aplikację.

Pełny kod pliku MainActivity.kt

Wskazówka:


import android.annotation.SuppressLint
import android.graphics.Color
import android.os.Bundle
import android.view.View
import android.widget.ArrayAdapter
import android.widget.Button
import android.widget.ListView
import android.widget.TextView
import androidx.appcompat.app.AlertDialog
import androidx.appcompat.app.AppCompatActivity

class MainActivity : AppCompatActivity() {
    val idNaglowek= View.generateViewId()
    val idStopka= View.generateViewId()
    val TagNaglowek= "moj_naglowek"
    val tabKrajeUE=arrayOf("Austria", "Belgia", "Bułgaria",
                 "Chorwacja", "Cypr", "Czechy", "Dania",
                 "Estonia", "Finlandia", "Francja", "Grecja",
                 "Hiszpania", "Holandia", "Irlandia", "Litwa",
                 "Luksemburg", "Łotwa", "Malta", "Niemcy",
                 "Polska", "Portugalia", "Rumunia", "Słowacja",
                 "Słowenia", "Szwecja", "Węgry", "Włochy")

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val bt1=findViewById<Button>(R.id.button1)
        bt1.setOnClickListener{ ListaProsta() }

        val bt2=findViewById<Button>(R.id.button2)
        bt2.setOnClickListener{ ListaProstaPobrana_z_Zasobow() }

        val bt3=findViewById<Button>(R.id.button3)
        bt3.setOnClickListener{ ObslugaKlikniecia() }

        val bt4=findViewById<Button>(R.id.button4)
        bt4.setOnClickListener{ LadujNiestandardowaListe() }
    }
    fun ListaProsta(){
        val listView=findViewById<ListView>(R.id.listView)

        val staryNaglowek=listView.findViewById<TextView>(idNaglowek)
        if(staryNaglowek!=null)listView.removeHeaderView(staryNaglowek)
        //val starynaglowek=listView.findViewWithTag<TextView>(TagNaglowek)
        //if(starynaglowek!=null)listView.removeHeaderView(starynaglowek)

        val naglowek=TextView(this)
        naglowek.setTextSize(22f)
        naglowek.setText("Lista prosta pobrana z tablicy")
        naglowek.setBackgroundColor(Color.parseColor("#FFEFA910"))
        naglowek.id=idNaglowek
        naglowek.tag=TagNaglowek
        listView.addHeaderView(naglowek)
        val moj_adapter= ArrayAdapter<String>(this,
            android.R.layout.simple_list_item_1,
            tabKrajeUE)
        listView.adapter=moj_adapter
    }

    fun ListaProstaPobrana_z_Zasobow(){
        val listView=findViewById<ListView>(R.id.listView)

        val staryNaglowek=listView.findViewById<TextView>(idNaglowek)
        if(staryNaglowek!=null)listView.removeHeaderView(staryNaglowek)

        val naglowek=TextView(this)
        naglowek.setTextSize(22f)
        naglowek.setText("Lista prosta pobrana z zasobów")
        naglowek.id=idNaglowek
        naglowek.setBackgroundColor(Color.parseColor("#FFc7241f"))
        listView.addHeaderView(naglowek)
        val tabUE=resources.getStringArray(R.array.KrajeUE)
        tabUE.sort()
        val moj_adapter= ArrayAdapter<String>(this,
            android.R.layout.simple_list_item_1,
            tabUE)
        listView.adapter=moj_adapter
    }

    fun ObslugaKlikniecia(){
        //załaduj listę
        ListaProstaPobrana_z_Zasobow()
        //obsłuz klikniecie w załadowany element listy
        val listView=findViewById<ListView>(R.id.listView)
        listView.setOnItemClickListener { parent, view, position, id ->
            val elementListy=parent.getItemAtPosition(position)
            val oknoKomunikatu=AlertDialog.Builder(this)
            oknoKomunikatu.setTitle("Kliknięto w element listy")
            oknoKomunikatu.setMessage(elementListy.toString()+"\nindeks: "+id.toString())
            oknoKomunikatu.setPositiveButton("Zamknij",null)
            oknoKomunikatu.show()
        }
    }

    fun Naglowek(listView:ListView, tytul:String,kolor:String){
        val staryNaglowek=listView.findViewById<TextView>(idNaglowek)
        if(staryNaglowek!=null)listView.removeHeaderView(staryNaglowek)
        val naglowek=TextView(this)
        naglowek.setTextSize(22f)
        naglowek.setText(tytul)
        naglowek.setBackgroundColor(Color.parseColor(kolor))
        naglowek.id=idNaglowek
        listView.addHeaderView(naglowek)
    }
    fun Stopka(listView:ListView, tytul:String,kolor:String){
        val staraStopka=listView.findViewById<TextView>(idStopka)
        if(staraStopka!=null)listView.removeFooterView(staraStopka)
        val stopka=TextView(this)
        stopka.setTextSize(14f)
        stopka.setText(tytul)
        stopka.setBackgroundColor(Color.parseColor(kolor))
        stopka.id=idStopka
        listView.addFooterView(stopka)
    }
    @SuppressLint("ResourceType")
    fun LadujNiestandardowaListe(){
        val listView=findViewById<ListView>(R.id.listView)
        Naglowek(listView,"Lista niestandardowa- kraje i flagi","#FF94EF8E")
        var listaKrajow = mutableListOf<PrzekazywneDane>()
        val tabKrajeFlagi=resources.obtainTypedArray(R.array.KrajeFlagi)
        for (i in 0.. tabKrajeFlagi.length()-1){
            val tabBufor=resources.obtainTypedArray(tabKrajeFlagi.getResourceId(i,0))
            listaKrajow.add(
                PrzekazywneDane(
                    tabBufor.getString(0).toString(),
                    tabBufor.getResourceId(1, R.drawable.pl),
                    tabBufor.getString(2).toString()
                    )
                )
        }
        listView.adapter=MojAdapterListy(this,R.layout.item_layout_list,listaKrajow)
        Stopka(listView,"Lista zawiera "+listaKrajow.count().toString()+" elementów","#FF94EF8E")
    }
}

Pełny kod pliku MojAdapterListy.kt

Wskazówka:


import android.content.Context
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ArrayAdapter
import android.widget.ImageView
import android.widget.TextView

class MojAdapterListy(context: Context, val zasobWidoku: Int, val itemy: List<PrzekazywneDane>) :
    ArrayAdapter<PrzekazywneDane>(context, zasobWidoku, itemy) {
    //obsłuz ładowany układ widoku itemu
    override fun getView(position: Int, convertView: View?, parent: ViewGroup): View {
        val layout:LayoutInflater=LayoutInflater.from(context)
        val view:View=layout.inflate(zasobWidoku,null)
        val img:ImageView=view.findViewById(R.id.ikonaFlagi)
        val txtKraj:TextView=view.findViewById(R.id.textViewKraj)
        val txtPow:TextView=view.findViewById(R.id.textViewPow)
        val dane:PrzekazywneDane=itemy[position]

        img.setImageDrawable(context.resources.getDrawable(dane.obrazFlagi))
        txtKraj.text=dane.nazwa
        txtPow.text=dane.pow

        return view
    }
}
//klas posredniczaca w przekazywaniu danych do itemów adaptera
class PrzekazywneDane(val nazwa:String, val obrazFlagi:Int, val pow:String)

Zawartość pliku zasobów string.xml

Wskazówka:


<resources>
    <string name="app_name">Lista widoku</string>
    <!--tablica krajów UE-->
    <string-array name="KrajeUE">
        <item>Austria</item>
        <item>Włochy</item>
        <item>Węgry</item>
        <item>Szwecja</item>
        <item>Słowenia</item>
        <item>Słowacja</item>
        <item>Rumunia</item>
        <item>Portugalia</item>
        <item>Polska</item>
    </string-array>

    <array name="KrajeFlagi">
        <item>@array/polska</item>
        <item>@array/austria</item>
        <item>@array/belgia</item>
        <item>@array/portugalia</item>
    </array>

    <array name="polska">
        <item name="nazwa" type="string">Polska</item>
        <item name="flaga" type="int">@drawable/pl</item>
        <item name="pow" type="string">322 575 km?</item>
    </array>
    <array name="austria">
        <item name="nazwa" type="string">Austria</item>
        <item name="flaga" type="int">@drawable/austria</item>
        <item name="pow" type="string">83 871 km?</item>
    </array>
    <array name="belgia">
        <item name="nazwa" type="string">Belgia</item>
        <item name="flaga" type="int">@drawable/belgia</item>
        <item name="pow" type="string">30 688 km?</item>
    </array>
    <array name="portugalia">
        <item name="nazwa" type="string">Portugalia</item>
        <item name="flaga" type="int">@drawable/portugalia</item>
        <item name="pow" type="string">92 152 km?</item>
    </array>
</resources>
Układ okresowy- kod qr
Układ okresowy

Układ okresowy pierwiastków- darmowa aplikacja na Androida

Pobierz ze sklepu Google Play
Alkomat- wirtualny test kod qr
Alkomat- wirtualny test

Alkomat- darmowa aplikacja na Androida

Pobierz ze sklepu Google Play
Taklarz- olinowanie stałe kod qr
Olinowanie stałe- kalkulator średnic

Olinowanie stałe- darmowa aplikacja na Androida

Pobierz ze sklepu Google Play
przepis na gogfry

Przepis na gofry

zobacz
przepis na bitą śmietanę

Przepis na bitą śmietanę

zobacz