Складний список із кнопками
Раніше були розглянуті кастомні адаптери, які дозволяють виводити в списки складні дані. Тепер перейдемо до наступного кроку і розглянемо, як ми можемо додавати в списки інші елементи, наприклад, кнопки, та обробляти їх події.
Для цього спершу визначимо наступний клас Product:
package com.example.listapp;
public class Product {
private final String name;
private int count;
private final String unit;
Product(String name, String unit){
this.name = name;
this.count=0;
this.unit = unit;
}
public String getUnit() {
return this.unit;
}
public void setCount(int count) {
this.count = count;
}
public int getCount() {
return count;
}
public String getName(){
return this.name;
}
}
Цей клас зберігає назву, кількість продукту, а також одиницю вимірювання. Об'єкти цього класу будуть виводитися в список.
Для цього в папку res/layout додаємо новий файл list_item.xml:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="16dp" >
<TextView
android:id="@+id/nameView"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:textSize="18sp"
app:layout_constraintHorizontal_weight="2"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toLeftOf="@+id/countView"
app:layout_constraintTop_toTopOf="parent"/>
<TextView
android:id="@+id/countView"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:textSize="18sp"
app:layout_constraintHorizontal_weight="2"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toRightOf="@+id/nameView"
app:layout_constraintRight_toLeftOf="@+id/addButton"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="@+id/addButton"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="+"
app:layout_constraintHorizontal_weight="1"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toRightOf="@+id/countView"
app:layout_constraintRight_toLeftOf="@+id/removeButton"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="@+id/removeButton"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="-"
app:layout_constraintHorizontal_weight="1"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toRightOf="@+id/addButton"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>
Тут визначені два текстових поля для виведення назви і кількості продукту, а також дві кнопки для додавання і видалення одиниці продукту.
Тепер додамо клас адаптера, який називатимемо ProductAdapter:
package com.example.listapp;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.TextView;
import java.util.ArrayList;
class ProductAdapter extends ArrayAdapter<Product> {
private final LayoutInflater inflater;
private final int layout;
private final ArrayList<Product> productList;
ProductAdapter(Context context, int resource, ArrayList<Product> products) {
super(context, resource, products);
this.productList = products;
this.layout = resource;
this.inflater = LayoutInflater.from(context);
}
public View getView(int position, View convertView, ViewGroup parent) {
final ViewHolder viewHolder;
if(convertView==null){
convertView = inflater.inflate(this.layout, parent, false);
viewHolder = new ViewHolder(convertView);
convertView.setTag(viewHolder);
}
else{
viewHolder = (ViewHolder) convertView.getTag();
}
final Product product = productList.get(position);
viewHolder.nameView.setText(product.getName());
viewHolder.countView.setText(product.getCount() + " " + product.getUnit());
viewHolder.removeButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
int count = product.getCount()-1;
if(count<0) count=0;
product.setCount(count);
viewHolder.countView.setText(count + " " + product.getUnit());
}
});
viewHolder.addButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
int count = product.getCount()+1;
product.setCount(count);
viewHolder.countView.setText(count + " " + product.getUnit());
}
});
return convertView;
}
private static class ViewHolder {
final Button addButton, removeButton;
final TextView nameView, countView;
ViewHolder(View view){
addButton = view.findViewById(R.id.addButton);
removeButton = view.findViewById(R.id.removeButton);
nameView = view.findViewById(R.id.nameView);
countView = view.findViewById(R.id.countView);
}
}
}
Для кожної кнопки тут визначено обробник натискання, в якому ми зменшуємо або збільшуємо кількість продукту на одиницю, а потім переустановлюємо текст у відповідному текстовому полі.
Далі у файлі activity_main.xml визначимо елемент ListView:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ListView
android:id="@+id/productList"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
І змінюємо клас MainActivity:
package com.example.listapp;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.ListView;
import java.util.ArrayList;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ArrayList<Product> products = new ArrayList<Product>();
products.add(new Product("Картофель", "кг."));
products.add(new Product("Чай", "шт."));
products.add(new Product("Яйца", "шт."));
products.add(new Product("Молоко", "л."));
products.add(new Product("Макароны", "кг."));
ListView productList = findViewById(R.id.productList);
ProductAdapter adapter = new ProductAdapter(this, R.layout.list_item, products);
productList.setAdapter(adapter);
}
}
В результаті вийде наступний проект:

І після запуску програми ми зможемо керувати кількістю продуктів через кнопки:
