Android - ListView - 如果我筛选具有复选框的列表,它会在数组中获取不同的值

Android - ListView - if i filter list having checkboxes it gets me different values in array

我有一个 ListView,它有大约 7 个项目,其中 2 个是这样检查的:

我将在列表中再检查一项已过滤的项目:

现在我将清除过滤器,结果将是这样的:

但是当我将这些项目添加到数组时,由于过滤器选项,它存储了错误的值。

谁能帮我解决这个问题?

编辑:

这是我的实际代码 -

public class ContactSelector extends Activity {

//EditText - Filter
EditText inputSearch;

ImageView iv;

ArrayList<String> mycontactsNameList = new ArrayList<String>();
ArrayList<String> fullContactList = new ArrayList<String>();
ArrayList<String> fullContactNumberList = new ArrayList<String>();
ArrayList<String> mycontactsNumberList = new ArrayList<String>();
ArrayList<String> mycontactsImageList = new ArrayList<String>();
ArrayList<String> checked = new ArrayList<String>();

//List Adapter
ArrayAdapter<mItems> listAdapter;

private ListView mainListView;
private mItems[] itemss;

//Here these are String of Array to save checked items
private String[] nameschecked = new String[0];
private String[] numberschecked = new String[0];

/** Called when the activity is first created. */
@SuppressWarnings("deprecation")
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.contact_selector);

    mainListView = (ListView) findViewById(R.id.list_view);
    inputSearch = (EditText) findViewById(R.id.inputSearch);


    //HERE IS THE LOGIC TO ADD CHECKED ITEMS TO STRING OF ARRAY - nameschecked, numberschecked
    mainListView
            .setOnItemClickListener(new AdapterView.OnItemClickListener() {
                @Override
                public void onItemClick(AdapterView<?> parent, View item,
                        int position, long id) {
                    mItems planet = listAdapter.getItem(position);
                    planet.toggleChecked();
                    SelectViewHolder viewHolder = (SelectViewHolder) item
                            .getTag();
                    viewHolder.getCheckBox().setChecked(planet.isChecked());
                    if(nameschecked[position] == "" || nameschecked[position] == null){
                        Toast.makeText(getApplicationContext(), "Empty Currently!", Toast.LENGTH_SHORT).show();
                    }
                    else {
                        Toast.makeText(getApplicationContext(), "Previous Data::"+nameschecked[position].toString(), Toast.LENGTH_SHORT).show();
                    }
                    if (planet.isChecked()) {
                        nameschecked[position] = viewHolder.getTextView()
                                .getText().toString();
                        numberschecked[position] = viewHolder
                                .getNumberView().getText().toString();
                        Toast.makeText(getApplicationContext(), "Selected Item--"+nameschecked[position].toString(), Toast.LENGTH_SHORT).show();
                    } else {
                        nameschecked[position] = "";
                        numberschecked[position] = "";

                        if(nameschecked[position] == ""){
                            Toast.makeText(getApplicationContext(), "Cleared!", Toast.LENGTH_SHORT).show();
                        }
                    }

                }
            });

    itemss = (mItems[]) getLastNonConfigurationInstance();

    ArrayList<mItems> listArray = new ArrayList<mItems>();

    /**
     * Enabling Search Filter
     * */

     //SEARCH FILTER
    inputSearch.addTextChangedListener(new TextWatcher() {

        public void onTextChanged(CharSequence cs, int arg1, int arg2,
                int arg3) {
            ContactSelector.this.listAdapter.getFilter().filter(cs);
        }

        public void beforeTextChanged(CharSequence arg0, int arg1,
                int arg2, int arg3) {

        }

        public void afterTextChanged(Editable arg0) {

        }
    });

    try {
        Uri uri = ContactsContract.CommonDataKinds.Phone.CONTENT_URI;
        String[] projection = new String[] {
                ContactsContract.CommonDataKinds.Phone._ID,
                ContactsContract.CommonDataKinds.Phone.CONTACT_ID,
                ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME,
                ContactsContract.CommonDataKinds.Phone.NUMBER,
                ContactsContract.CommonDataKinds.Phone.STARRED,
                ContactsContract.CommonDataKinds.Phone.TYPE,
                ContactsContract.CommonDataKinds.Phone.PHOTO_URI,
                ContactsContract.CommonDataKinds.Phone.PHOTO_ID,
                ContactsContract.CommonDataKinds.Phone.PHOTO_FILE_ID,
                ContactsContract.CommonDataKinds.Phone.PHOTO_THUMBNAIL_URI,
                ContactsContract.CommonDataKinds.Phone.TIMES_CONTACTED };
        String sortOrder = ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME
                + " COLLATE LOCALIZED ASC";

        Cursor cursor = UILApplication.getAppContext().getContentResolver()
                .query(uri, projection, null, null, sortOrder);

        cursor.moveToFirst();

        //SAVING CONTACTS DATA TO TEMP ARRAY
        while (!cursor.isLast()) {

            try {
                System.out
                        .println("*******contact***2*****diplay name*******"
                                + cursor.getString(2));
                mycontactsNameList.add(cursor.getString(2).toString());
            } catch (Exception e) {
                mycontactsNameList.add("");
                System.out.println("error 2");
                e.printStackTrace();
            }

            try {
                System.out.println("*******contact***3****number********"
                        + cursor.getString(3));
                mycontactsNumberList.add(cursor.getString(3).toString());
            } catch (Exception e) {
                mycontactsNumberList.add("");
                System.out.println("error 3");
                e.printStackTrace();
            }

            try {
                System.out.println("*******contact***4****image********"
                        + cursor.getString(1));
                mycontactsImageList.add(cursor.getString(1).toString());
            } catch (Exception e) {
                mycontactsImageList.add("");
                System.out.println("error 4");
            }

            cursor.moveToNext();
        }
    } catch (Exception e) {
        System.out.println("err for read cont:::");
        e.printStackTrace();
    }

    //CLEAR ACTUAL ARRAY TO AVOID DUPLICATES AND REFRESH LIST
    fullContactList.clear();
    fullContactNumberList.clear();
    fullImageList.clear();

    //ADD ALL TEMP ARRAY TO ACTUAL ARRAY
    fullContactList.addAll(mycontactsNameList);
    fullContactNumberList.addAll(mycontactsNumberList);
    fullImageList.addAll(mycontactsImageList);

    //SET SIZE OF nameschecked and numberschecked SO THAT WE CAN ADD CHECKED DATA TO SPECIFIC POSITION
    nameschecked = new String[fullContactList.size()];
    numberschecked = new String[fullContactList.size()];

    //ADD ACTUAL ARRAY TO ARRAYLIST
    for (int i = 0; i < fullContactList.size(); i++) {
        listArray.add(new mItems(fullContactList.get(i),
                fullContactNumberList.get(i), fullImageList.get(i)));
    }

    //ADD ARRAY LIST TO ADAPTER AND SET ADAPTER TO LISTVIEW
    listAdapter = new SelectArrayAdapter(this, listArray);
    mainListView.setAdapter(listAdapter);

}

/** Holds data. - GETTER AND SETTER*/
private static class mItems {
    private String name = "";
    private boolean checked = false;
    private String number = "";
    private String image = "";

    public mItems(String name, String number, String image) {
        this.name = name;
        this.number = number;
        this.image = image;
    }

    public String getName() {
        return name;
    }

    public String getNumber() {
        return number;
    }

    public String getImage() {
        return image;
    }

    public boolean isChecked() {
        return checked;
    }

    public void setChecked(boolean checked) {
        this.checked = checked;
    }

    public String toString() {
        return name;
    }

    public void toggleChecked() {
        checked = !checked;
    }
}

private static class SelectViewHolder {
    private CheckBox checkBox;
    private TextView textView, number;
    private ImageView image;

    public SelectViewHolder(TextView textView, TextView number,
            CheckBox checkBox, ImageView image) {
        this.checkBox = checkBox;
        this.textView = textView;
        this.image = image;
        this.number = number;
    }

    public CheckBox getCheckBox() {
        return checkBox;
    }

    public TextView getTextView() {
        return textView;
    }

    public TextView getNumberView() {
        return number;
    }

    public ImageView getImageView() {
        return image;
    }
}

/** Custom adapter for displaying an array of Planet objects. */
private static class SelectArrayAdapter extends ArrayAdapter<mItems> {
    private LayoutInflater inflater;

    public SelectArrayAdapter(Context context, List<mItems> planetList) {
        super(context, R.layout.row, R.id.rowTextView, planetList);
        // Cache the LayoutInflate to avoid asking for a new one each time.
        inflater = LayoutInflater.from(context);
    }

    @SuppressLint("InflateParams")
    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        // Planet to display
        mItems planet = (mItems) this.getItem(position);

        // The child views in each row.
        CheckBox checkBox;
        TextView name, number;
        ImageView iv1;

        // Create a new row view
        if (convertView == null) {
            convertView = inflater.inflate(R.layout.row, null);

            // Find the child views.
            name = (TextView) convertView.findViewById(R.id.rowTextView);
            number = (TextView) convertView.findViewById(R.id.rowNumber);
            iv1 = (ImageView) convertView.findViewById(R.id.cimageView);

            checkBox = (CheckBox) convertView.findViewById(R.id.CheckBox01);
            // Optimization: Tag the row with it's child views, so we don't
            // have to
            // call findViewById() later when we reuse the row.
            convertView.setTag(new SelectViewHolder(name, number, checkBox,
                    iv1));
            // If CheckBox is toggled, update the planet it is tagged with.
            checkBox.setOnClickListener(new View.OnClickListener() {
                public void onClick(View v) {
                    CheckBox cb = (CheckBox) v;
                    mItems planet = (mItems) cb.getTag();
                    planet.setChecked(cb.isChecked());
                    Toast.makeText(getContext(),
                            "Number: " + planet.getNumber(),
                            Toast.LENGTH_SHORT).show();
                }
            });
        }
        // Reuse existing row view
        else {
            SelectViewHolder viewHolder = (SelectViewHolder) convertView
                    .getTag();
            checkBox = viewHolder.getCheckBox();
            name = viewHolder.getTextView();
            number = viewHolder.getNumberView();
            iv1 = viewHolder.getImageView();
        }
        checkBox.setTag(planet);
        checkBox.setChecked(planet.isChecked());
        name.setText(planet.getName());
        number.setText(planet.getNumber());
        if (!planet.getImage().equals("")) {
            iv1.setImageBitmap(decodeFile(planet.getImage()));
        } else {
            iv1.setImageResource(R.drawable.ic_launcher);
        }

        return convertView;
    }
}

public Object onRetainNonConfigurationInstance() {
    return itemss;
}

}

在此代码中,我添加了注释以检查该代码段的作用。

这是从 phone 获取所有联系人并显示在列表中的简单代码。

我select一些联系人并创建了一个保存在数据库中的组。

它工作得很好,但这里的问题是如果我过滤列表并且 select 一些联系人一切都出错了。

我认为在 if (convertView == null) 块下放置 checkBox.setOnClickListener 是不明智的。通常当视图(行项目)不可见时 convertView 为 null 但可能仍然为 null 只是因为虽然您已经看到该项目但视图未被回收,并且 Android 使用虚拟内存在 Listview 上做出这些决定。这将解释您将错误归咎于过滤器。 尝试一下,因为这不是一个困难的修复。