简体   繁体   中英

how to keep selected checkboxes in android searchable listview?

I have a simple searchable listview with checkboxes but it can't remember my selections when it's getting filtered. when I filter a value and mark related checkbox then my choice won't be kept after clearing search value...

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical">

    <Button
        android:id="@+id/btnChecked"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:foregroundGravity="center_horizontal"
        android:text="Get checked items"></Button>

    <EditText
        android:id="@+id/searchFilter"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:ems="10"
        android:inputType="textPersonName"
        android:hint="Search Ingredients"
        android:textColor="@color/material_on_surface_emphasis_medium" />

    <ListView
        android:id="@+id/lvMain"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
    </ListView>
</LinearLayout>

MainActivity.java

package com.example.listview;

import android.app.Activity;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
import android.util.SparseBooleanArray;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Filter;
import android.widget.ListView;

public class MainActivity extends Activity implements OnClickListener {

    final String LOG_TAG = "myLogs";

    ListView lvMain;
    String[] names;

    private ArrayAdapter<CharSequence> adapter;



    /** Called when the activity is first created. */
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        EditText theFilter = (EditText) findViewById(R.id.searchFilter);

        lvMain = (ListView) findViewById(R.id.lvMain);
        // here we adjust list elements choice mode
        lvMain.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
        // create adapter using array from resources file
        adapter = ArrayAdapter.createFromResource(
                this, R.array.names,
                android.R.layout.simple_list_item_multiple_choice);
        lvMain.setAdapter(adapter);

        Button btnChecked = (Button) findViewById(R.id.btnChecked);
        btnChecked.setOnClickListener(this);

        // get array from resources file
        names = getResources().getStringArray(R.array.names);

        theFilter.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {

            }

            @Override
            public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {


                (MainActivity.this).adapter.getFilter().filter(charSequence);
                SparseBooleanArray scArray = lvMain.getCheckedItemPositions();




            }

            @Override
            public void afterTextChanged(Editable editable) {


                // Uncheck everything:

                for (int i = 0; i < lvMain.getCount(); i++) {
                    if (lvMain.isItemChecked(i)) {
                        lvMain.setItemChecked(i, true);
                    } else {
                        lvMain.setItemChecked(i, false);
                    }
                }
            }

        });
    }

    public void onClick(View arg0) {
        Log.d(LOG_TAG, "checked: ");
        SparseBooleanArray sbArray = lvMain.getCheckedItemPositions();
        for (int i = 0; i < sbArray.size(); i++) {
            int key = sbArray.keyAt(i);
            if (sbArray.get(key))
                Log.d(LOG_TAG, names[key]);
        }
    }
}

as you can see in below pictures, it can't remember "Petr" and "Ivan" selected wrongly after search...

搜索前

选择过滤值

清除搜索后选择错误

It is because ArrayAdapter does not support this. You need to create a custom adapter that will remember what has been checked so that when it redraws a view it does not take the default value of unchecked.

Create a class that extends from BaseAdapter that works on an ArrayList<Model> instead of string array. In this Model you can have a boolean checked (initially all false). That way when user scrolls around or searches your model will know weather current name is selected.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM