openplanning

Android ListView với Checkbox sử dụng ArrayAdapter

  1. Ví dụ
  2. Phụ lục: Thiết kế giao diện

1. Ví dụ

Android xây dựng sẵn một Layout đơn giản mà ListItem làm bởi một CheckedTextView. Trong ví dụ này tôi sẽ hướng dẫn bạn sử dụng ArrayAdapterandroid.R.layout.simple_list_item_checked. (Hoặc android.R.layout.simple_list_item_multiple_choice)
Tạo mới một Android project:
  • ListViewSimpleListItemChecked
  • Name: ListViewSimpleListItemChecked
  • Package name: org.o7planning.listviewsimplelistitemchecked
Thiết kế giao diện:
Nếu bạn quan tâm tới các bước để thiết kế giao diện ứng dụng này xin hãy xem phần phụ lục phía cuối bài viết.
activity_main.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"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <ListView
        android:id="@+id/listView"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:layout_marginStart="16dp"
        android:layout_marginLeft="16dp"
        android:layout_marginTop="16dp"
        android:layout_marginEnd="16dp"
        android:layout_marginRight="16dp"
        android:layout_marginBottom="16dp"
        app:layout_constraintBottom_toTopOf="@+id/button"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <Button
        android:id="@+id/button"
        android:layout_width="0dp"
        android:layout_height="46dp"
        android:layout_marginStart="16dp"
        android:layout_marginLeft="16dp"
        android:layout_marginEnd="16dp"
        android:layout_marginRight="16dp"
        android:layout_marginBottom="16dp"
        android:text="Print Selected Items"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
UserAccount.java
package org.o7planning.listviewsimplelistitemchecked;

import java.io.Serializable;

public class UserAccount implements Serializable {

    private String userName;
    private String userType;

    private boolean active;

    public UserAccount(String userName, String userType)  {
        this.userName= userName;
        this.userType = userType;
        this.active= true;
    }

    public UserAccount(String userName, String userType, boolean active)  {
        this.userName= userName;
        this.userType = userType;
        this.active= active;
    }

    public String getUserType() {
        return userType;
    }

    public void setUserType(String userType) {
        this.userType = userType;
    }

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public boolean isActive() {
        return active;
    }

    public void setActive(boolean active) {
        this.active = active;
    }

    @Override
    public String toString() {
        return this.userName +" ("+ this.userType+")";
    }

}
MainActivity.java
package org.o7planning.listviewsimplelistitemchecked;

import android.os.Bundle;
import android.util.Log;
import android.util.SparseBooleanArray;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.CheckedTextView;
import android.widget.ListView;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;

public class MainActivity extends AppCompatActivity {

    public static final String TAG = "ListViewExample";

    private ListView listView;
    private Button button;

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

        this.listView = (ListView)findViewById(R.id.listView);
        this.button = (Button)findViewById(R.id.button);

        // CHOICE_MODE_NONE: (Default)
        // (listView.setItemChecked(..) doest not work with CHOICE_MODE_NONE).
        // CHOICE_MODE_SINGLE:
        // CHOICE_MODE_MULTIPLE:
        // CHOICE_MODE_MULTIPLE_MODAL:
        this.listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);

        this.listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {

            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                Log.i(TAG, "onItemClick: " +position);
                CheckedTextView v = (CheckedTextView) view;
                boolean currentCheck = v.isChecked();
                UserAccount user = (UserAccount) listView.getItemAtPosition(position);
                user.setActive(!currentCheck);
            }
        });
        //

        this.button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                printSelectedItems();
            }
        });

         this.initListViewData();
    }

    private void initListViewData()  {
        UserAccount tom = new UserAccount("Tom","admin");
        UserAccount jerry = new UserAccount("Jerry","user");
        UserAccount donald = new UserAccount("Donald","guest", false);

        UserAccount[] users = new UserAccount[]{tom,jerry, donald};

        // android.R.layout.simple_list_item_checked:
        // ListItem is very simple (Only one CheckedTextView).
        ArrayAdapter<UserAccount> arrayAdapter
                = new ArrayAdapter<UserAccount>(this, android.R.layout.simple_list_item_checked , users);

        this.listView.setAdapter(arrayAdapter);

        for(int i=0;i< users.length; i++ )  {
            this.listView.setItemChecked(i,users[i].isActive());
        }
    }

    // When user click "Print Selected Items".
    public void printSelectedItems()  {

        SparseBooleanArray sp = listView.getCheckedItemPositions();

        StringBuilder sb= new StringBuilder();

        for(int i=0;i<sp.size();i++){
            if(sp.valueAt(i)==true){
                UserAccount user= (UserAccount) listView.getItemAtPosition(i);
                // Or:
                // String s = ((CheckedTextView) listView.getChildAt(i)).getText().toString();
                //
                String s= user.getUserName();
                sb = sb.append(" "+s);
            }
        }
        Toast.makeText(this, "Selected items are: "+sb.toString(), Toast.LENGTH_LONG).show();
    }

}
Chạy ví dụ:
Android cũng cung cấp cho bạn một Layout tương tự với simple_list_item_checked đó là simple_list_item_multiple_choice.

Sự khác biệt duy nhất tuyệt đối giữa hai Layout trên là kiểu dáng của checkbox khi nó được lựa chọn. Cái thứ nhất android.R.layout.simple_list_item_multiple_choice được cho là phù hợp hơn với ListView đa lựa chọn, trong khi đó android.R.layout.simple_list_item_checked là phù hợp hơn cho các kịch bản touch-and-go (Chạm và thực thi điều gì đó, chẳng hạn mở một Activity khác). Cũng cần nói thêm, tất cả mọi thứ là tương đối với nhau và tùy vào thói quen của mỗi người, và hơn nữa tùy thuộc vào loại nào phù hợp với thiết kế hiện tại của bạn để sử dụng.

2. Phụ lục: Thiết kế giao diện

Kéo thả các thành phần vào giao diện:
Sét đặt giàng buộc (constraint) cho các thành phần trên giao diện:
Sét đặt ID, Text cho các thành phần trên giao diện.

Các hướng dẫn lập trình Android

Show More