|
|
Kierunek
Informatyka
|
|||
|
|
||||
Instrukcja
do ćwiczeń laboratoryjnych nr:
|
12
|
Nazwa przedmiotu:
|
||
Temat: Prezentacja danych w formie list dynamicznych RecyclerView
|
Tryb studiów:
stacjonarne |
|||
|
Czas trwanie
ćw. 2x45
min |
||||
|
Autor materiałów:
dr Marcin Skuba |
||||
1. Treści programowe:
Tworzenie
list dynamicznych przeznaczonych do przechowywania serii danych.
2. Cel zajęć:
Celem zajęć jest
zapoznanie studentów z mechanizmami tworzenia list dynamicznych RecyclerView.
3. Materiały dydaktyczne
Lista rozwijana RecyclerView jest następca
klasy ListView. Została ulepszona i zoptymalizowana pod kątem wydajności.
Lepiej radzi sobie z dużą ilością danych.
PRZYKŁAD 1.
Poniżej przedstawiono prosty
przykład aplikacji wykorzystujący listę RecyclerView.
Jest to przykład, od którego należy zacząć analizę działania mechanizmu
listy.

Layout główny zawierający listę RecyclerView (activity_main.xml):
<?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:id="@+id/main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="10dp"
android:orientation="vertical"
tools:context=".MainActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Lista RecyclerView"
android:textStyle="bold"/>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/my_recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="10dp"/>
</LinearLayout>
Layout z jedną pozycją
listy (recyclerview_row.xml) zawierający tylko
jedno pole tekstowe textView:
<?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="wrap_content"
android:orientation="horizontal"
android:padding="10dp">
<TextView
android:id="@+id/textView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="18dp"
android:textColor="#f00"
/>
</LinearLayout>
Klasa
MyRectclerViewAdapter.java definiująca adapter jako klasę pomocniczą do
zarządzania listą:
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import java.util.List;
import androidx.recyclerview.widget.RecyclerView;
class MyRecyclerViewAdapter extends RecyclerView.Adapter<MyRecyclerViewAdapter.ViewHolder>
{
private List<String> mData;
private LayoutInflater mInflater;
private ItemClickListener mClickListener;
// dane
są przekazywane do konstruktora
MyRecyclerViewAdapter(Context context,
List<String> data) {
this.mInflater = LayoutInflater.from(context);
this.mData = data;
}
// w
razie potrzeby wypełnia układ wiersza xml
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent,
int viewType) {
View view = mInflater.inflate(R.layout.recyclerview_row, parent,
false);
return
new ViewHolder(view);
}
// wiąże
dane z TextView w każdym wierszu
@Override
public void onBindViewHolder(ViewHolder holder,
int position) {
String text
= mData.get(position);
holder.myTextView.setText(text);
}
//
Zwraca informację, ile elementów jest w liście.
// Dzięki temu RecyclerView
wie, jak długi ma być suwak przewijania.
@Override
public int getItemCount() {
return
mData.size();
}
//
Pozwala łatwo wyciągnąć dane z konkretnego miejsca listy.
String getItem(int id) {
return
mData.get(id);
}
//
umożliwia przechwytywanie zdarzeń związanych z kliknięciami
void setClickListener(ItemClickListener itemClickListener)
{
this.mClickListener = itemClickListener;
}
//
działanie nadrzędne wdroży tę metodę, aby reagować na zdarzenia związane z
kliknięciem
public interface ItemClickListener {
void onItemClick(View view, int position);
}
//
Przechowuje i przetwarza widoki po ich przewinięciu poza ekran.
// Zamiast ciągle szukać przycisku
czy tekstu za pomocą findViewById
// (co jest wolne), adapter szuka ich
raz, zapisuje w ViewHolderze i szybko do nich wraca
podczas przewijania.
// Implementuje też OnClickListener, aby wykrywać kliknięcia w dany wiersz.
public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
TextView
myTextView;
ViewHolder(View itemView) {
super(itemView);
myTextView = itemView.findViewById(R.id.textView);
itemView.setOnClickListener(this);
}
@Override
public
void onClick(View
view) {
if (mClickListener != null) mClickListener.onItemClick(view, getBindingAdapterPosition());
}
}
}
Główna klasa Aktywności MainActivity.java:
import android.os.Bundle;
import android.view.View;
import android.widget.Toast;
import androidx.activity.EdgeToEdge;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.graphics.Insets;
import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsCompat;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import java.util.ArrayList;
public class MainActivity extends AppCompatActivity implements MyRecyclerViewAdapter.ItemClickListener{
MyRecyclerViewAdapter
adapter;
@Override
protected void
onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
EdgeToEdge.enable(this);
setContentView(R.layout.activity_main);
ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main), (v, insets)
-> {
Insets
systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars());
v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom);
return insets;
});
//
dane do wypełnienia RecyclerView
ArrayList<String> dane
= new ArrayList<>();
dane.add("Piersza");
dane.add("Druga");
dane.add("Trzecia");
dane.add("Czwarta");
dane.add("Piąta");
//
konfiguracja RecyclerView
RecyclerView recyclerView = findViewById(R.id.my_recycler_view);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
adapter
= new MyRecyclerViewAdapter(this, dane);
adapter.setClickListener(this);
recyclerView.setAdapter(adapter);
}
@Override
public void onItemClick(View view, int position) {
Toast.makeText(this, "Wybrano pozycję:
" + adapter.getItem(position) + " nr: " + position, Toast.LENGTH_SHORT).show();
}
}
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
PRZYKŁAD 2.
Kolejny przykład
przedstawia listę złożoną z dwóch obiektów w postaci pola tekstowego (TextView) i obiektu graficznego (ImageView).
Dane dotyczące
przedmiotu zgrupowane są w klasie Przedmiot i zawierają dwie zmienne. Zmienna
tekstowa przechowuje wartość tekstową wyświetlaną później w liście oraz
zmienną całkowitą przechowującą identyfikator obrazka.

Plik
activity_main.xml:
<?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:id="@+id/main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="10dp"
android:orientation="vertical"
tools:context=".MainActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Lista RecyclerView"
android:textStyle="bold"/>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/my_recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="10dp"/>
</LinearLayout>
Plik recyclerview_row.xml:
<?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="wrap_content"
android:orientation="horizontal"
android:padding="10dp">
<ImageView
android:id="@+id/imageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="5dp"
/>
<TextView
android:id="@+id/textView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="18dp"
android:textColor="#f00"
/>
</LinearLayout>
Plik Przedmiot.java:
public class
Przedmiot {
private int
icona;
private String nazwa;
public Przedmiot(int icon, String nazwa) {
this.icona = icon;
this.nazwa = nazwa;
}
public int getIcona() {
return
icona;
}
public void setIcona(int icona) {
this.icona = icona;
}
public String getNazwa() {
return
nazwa;
}
public void setNazwa(String nazwa) {
this.nazwa = nazwa;
}
}
Plik MyRecyclerViewAdapter.java
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import java.util.List;
import androidx.recyclerview.widget.RecyclerView;
class MyRecyclerViewAdapter extends RecyclerView.Adapter<MyRecyclerViewAdapter.ViewHolder>
{
private List<Przedmiot> mData;
private LayoutInflater mInflater;
private ItemClickListener mClickListener;
MyRecyclerViewAdapter(Context context,
List<Przedmiot> data) {
this.mInflater = LayoutInflater.from(context);
this.mData = data;
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent,
int viewType) {
View view = mInflater.inflate(R.layout.recyclerview_row, parent,
false);
return
new ViewHolder(view);
}
@Override
public void onBindViewHolder(ViewHolder holder,
int position) {
Przedmiot przedmiot= mData.get(position);
holder.myTextView.setText(przedmiot.getNazwa());
holder.imageView.setImageResource(przedmiot.getIcona());
}
@Override
public int getItemCount() {
return
mData.size();
}
Przedmiot getItem(int id) {
return
mData.get(id);
}
void setClickListener(ItemClickListener itemClickListener)
{
this.mClickListener = itemClickListener;
}
public interface ItemClickListener {
void onItemClick(View view, int position);
}
public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
TextView
myTextView;
ImageView
imageView;
ViewHolder(View itemView) {
super(itemView);
myTextView = itemView.findViewById(R.id.textView);
imageView = itemView.findViewById(R.id.imageView);
itemView.setOnClickListener(this);
}
@Override
public
void onClick(View
view) {
if (mClickListener != null) mClickListener.onItemClick(view, getBindingAdapterPosition());
}
}
}
Plik MainActivity.java:
import android.os.Bundle;
import android.view.View;
import android.widget.Toast;
import androidx.activity.EdgeToEdge;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.graphics.Insets;
import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsCompat;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import java.util.ArrayList;
public class MainActivity extends AppCompatActivity implements MyRecyclerViewAdapter.ItemClickListener{
MyRecyclerViewAdapter
adapter;
@Override
protected void
onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
EdgeToEdge.enable(this);
setContentView(R.layout.activity_main);
ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main), (v, insets)
-> {
Insets
systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars());
v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom);
return insets;
});
ArrayList<Przedmiot>
dane = new ArrayList<>();
dane.add(new Przedmiot(R.drawable.cpp_icon, "C++"));
dane.add(new Przedmiot(R.drawable.java_icon, "Java"));
dane.add(new Przedmiot(R.drawable.android_icon, "Android"));
dane.add(new Przedmiot(R.drawable.math_icon, "Matematyka"));
//
konfiguracja RecyclerView
RecyclerView recyclerView = findViewById(R.id.my_recycler_view);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
adapter
= new MyRecyclerViewAdapter(this, dane);
adapter.setClickListener(this);
recyclerView.setAdapter(adapter);
}
@Override
public void onItemClick(View view, int position) {
Przedmiot przedmiot
= adapter.getItem(position);
Toast.makeText(this, "Wybrano pozycję:
" + przedmiot.getNazwa()
+ " nr: " +
position, Toast.LENGTH_SHORT).show();
}
}
Pliki graficzne (drawable):
4. Zadania
Zadanie 1.
Napisz program, w którym dodaj jeszcze jedno pole tekstowe w
pozycji listy, w którym zapisany będzie opis przedmiotu.
Zadanie 2.
Napisz program według własnego pomysłu, w którym zaprojektuj listę
wyświetlającą wartości tekstowe oraz grafikę.
W jednym wierszy powinno być co najmniej cztery elementy.