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 上做出这些决定。这将解释您将错误归咎于过滤器。
尝试一下,因为这不是一个困难的修复。
我有一个 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 上做出这些决定。这将解释您将错误归咎于过滤器。
尝试一下,因为这不是一个困难的修复。