Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> Android

Lấy tất cả item đã check trong ListView trên Android

Giới thiệu

Ví dụ này minh họa cách hiển thị ListView với CheckBox trên mỗi item, sử dụng BaseAdapter tùy chỉnh (CustomAdapter) và model Model để lưu trạng thái check, cùng nút bấm "Chọn tất cả"/"Bỏ chọn tất cả".

Bước 1: Tạo dự án mới

Tạo project Android Studio: File → New Project.

Bước 2: Layout chính (res/layout/activity_main.xml)

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="https://schemas.android.com/apk/res/android"
    xmlns:tools="https://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="MainActivity">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:orientation="horizontal">

        <Button
            android:id="@+id/viewCheckedItem"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Chọn tất cả" />

        <Button
            android:id="@+id/deSelect"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Bỏ chọn tất cả" />

    </LinearLayout>

    <ListView
        android:id="@+id/listView"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_marginTop="30dp"
        android:layout_weight="1">
    </ListView>

</LinearLayout>

Bước 3: Item layout (res/layout/listitem.xml)

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="https://schemas.android.com/apk/res/android"
    android:orientation="horizontal"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <CheckBox
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/checkBox" />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/playerNameList"
        android:layout_marginStart="20dp"
        android:textSize="20sp" />

</LinearLayout>

Bước 4: Model - Model.java

class Model {
    private boolean isSelected;
    private String player;

    String getPlayer() { return player; }
    void setPlayer(String player) { this.player = player; }
    boolean getSelected() { return isSelected; }
    void setSelected(boolean selected) { isSelected = selected; }
}

Bước 5: CustomAdapter - BaseAdapter với ViewHolder

Sử dụng pattern ViewHolder để tối ưu hiệu năng. CheckBox click cập nhật model và hiển thị Toast.

import android.annotation.SuppressLint;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.CheckBox;
import android.widget.TextView;
import android.widget.Toast;
import java.util.ArrayList;
import java.util.Objects;

class CustomAdapter extends BaseAdapter {
    private Context context;
    private static ArrayList modelArrayList;

    CustomAdapter(Context context, ArrayList modelArrayList) {
        this.context = context;
        CustomAdapter.modelArrayList = modelArrayList;
    }

    @Override public int getViewTypeCount() { return getCount(); }
    @Override public int getItemViewType(int position) { return position; }
    @Override public int getCount() { return modelArrayList.size(); }
    @Override public Object getItem(int position) { return modelArrayList.get(position); }
    @Override public long getItemId(int position) { return 0; }

    @SuppressLint("InflateParams")
    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        ViewHolder holder;
        if (convertView == null) {
            holder = new ViewHolder();
            LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            convertView = Objects.requireNonNull(inflater).inflate(R.layout.listitem, null, true);
            holder.checkBox = convertView.findViewById(R.id.checkBox);
            holder.tvPlayer = convertView.findViewById(R.id.playerNameList);
            convertView.setTag(holder);
        } else {
            holder = (ViewHolder) convertView.getTag();
        }

        holder.checkBox.setText("Checkbox " + position);
        holder.tvPlayer.setText(modelArrayList.get(position).getPlayer());
        holder.checkBox.setChecked(modelArrayList.get(position).getSelected());
        holder.checkBox.setTag(R.integer.btnPlusView, convertView);
        holder.checkBox.setTag(position);

        holder.checkBox.setOnClickListener(v -> {
            Integer pos = (Integer) holder.checkBox.getTag();
            Toast.makeText(context, "Checkbox " + pos + " clicked!", Toast.LENGTH_SHORT).show();
            Model model = modelArrayList.get(pos);
            model.setSelected(!model.getSelected());
        });

        return convertView;
    }

    private static class ViewHolder {
        CheckBox checkBox;
        TextView tvPlayer;
    }
}

Bước 6: strings.xml - Định nghĩa integer tag

<resources>
    <string name="app_name">Sample</string>
    <integer name="btnPlusView">1</integer>
    <integer name="btnPlusPos">2</integer>
</resources>

Bước 7: MainActivity - Khởi tạo dữ liệu và xử lý nút chọn/bỏ chọn

import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.ListView;
import android.widget.Toast;
import java.util.ArrayList;

public class MainActivity extends AppCompatActivity {
    private ListView listView;
    private ArrayList modelArrayList;
    private CustomAdapter customAdapter;
    Button btnSelect, btnDeselect;

    public static String[] playerList = new String[]{
        "Sơn Tùng M-TP - Việt Nam", "Cristiano Ronaldo - Bồ Đào Nha",
        "Lionel Messi - Argentina", "Neymar Jr - Brazil",
        "Eden Hazard - Bỉ", "Gianluigi Buffon - Ý",
        "James Rodríguez - Colombia", "Sadio Mané - Senegal",
        "Toni Kroos - Đức"
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        listView = findViewById(R.id.listView);
        btnSelect = findViewById(R.id.viewCheckedItem);
        btnDeselect = findViewById(R.id.deSelect);

        modelArrayList = getModel(false);
        customAdapter = new CustomAdapter(this, modelArrayList);
        listView.setAdapter(customAdapter);

        btnSelect.setOnClickListener(v -> {
            modelArrayList = getModel(true);
            customAdapter = new CustomAdapter(this, modelArrayList);
            listView.setAdapter(customAdapter);
            Toast.makeText(getApplicationContext(), "Đã chọn tất cả", Toast.LENGTH_SHORT).show();
        });

        btnDeselect.setOnClickListener(v -> {
            modelArrayList = getModel(false);
            customAdapter = new CustomAdapter(this, modelArrayList);
            listView.setAdapter(customAdapter);
            Toast.makeText(getApplicationContext(), "Đã bỏ chọn tất cả", Toast.LENGTH_SHORT).show();
        });
    }

    private ArrayList getModel(boolean isSelect) {
        ArrayList list = new ArrayList<>();
        for (int i = 0; i < 9; i++) {
            Model model = new Model();
            model.setSelected(isSelect);
            model.setPlayer(playerList[i]);
            list.add(model);
        }
        return list;
    }
}

Bước 8: Manifest

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="https://schemas.android.com/apk/res/android" package="app.com.sample">
    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
</manifest>

Chạy ứng dụng

Chạy app, ListView hiển thị 9 cầu thủ với CheckBox. Click CheckBox đơn lẻ hoặc bấm "Chọn tất cả"/"Bỏ chọn tất cả" để cập nhật toàn bộ.

Lấy danh sách item đã check

// Ví dụ: nút "Xem đã chọn"
Button btnGetChecked = findViewById(R.id.btnGetChecked);
btnGetChecked.setOnClickListener(v -> {
    StringBuilder sb = new StringBuilder("Đã chọn:\n");
    for (Model m : modelArrayList) {
        if (m.getSelected()) sb.append("- ").append(m.getPlayer()).append("\n");
    }
    Toast.makeText(this, sb.toString(), Toast.LENGTH_LONG).show();
});

Khuyến nghị: Dùng RecyclerView + CheckBox

ListView đã cũ. RecyclerView với ListAdapter và DiffUtil hiệu năng tốt hơn, hỗ trợ animation, dễ dàng thêm header/footer, swipe actions.