我在片段中有ListView
控件(CoordinatorLayout)。
ListView
的每一行都是TableLayout
,其中包含CheckBox
控件。
如果我检查第一行,则调用片段中的DeleteSelection
方法,然后删除第一行视图。但是新的第一行还有一个复选框仍然被检查!!
我查了十几篇关于ListView的帖子并删除了一些项目,但我仍然无法理解......我变得疯狂了......请帮助。
row.xml
<?xml version="1.0" encoding="utf-8"?>
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TableRow>
<TextView
android:id="@+id/txtCourt"
android:layout_width="match_parent"
android:layout_height="30dp"
android:gravity="center_vertical"
android:paddingLeft="5dp"
android:paddingRight="5dp" />
<CheckBox
android:id="@+id/chkSelect"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingLeft="5dp"
android:paddingRight="5dp"/>
</TableRow>
</TableLayout>
MyFragment.java
public class MyFragment extends Fragment {
private Context mContext;
private ListView listView1;
private List<MyObject> mylist = new ArrayList<>();
在覆盖onViewCreated
方法中,我初始化listview和适配器:
for(int i=1; i<5; i++) {
MyObject res = new MyObject();
res.mytextBla = "bla" + i;
this.mylist.add(res);
}
this.mAdapter = new CustomAdapter(this.mylist, getActivity().getApplicationContext());
this.listview1.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
this.listview1.setAdapter(mAdapter);
再远一点:
public void DeleteSelection() {
SparseBooleanArray arr = mAdapter.getSelectedIds();
for(int i = (arr .size()-1); i >=0; i--) {
if (arr.valueAt(i)) {
MyObject res = mAdapter.getItem(arr.keyAt(i));
this.mylist.remove(res);
}
}
mAdapter.removeSelection();
}
CustomAdapter.java
public class CustomAdapter extends ArrayAdapter<MyObject> {
private SparseBooleanArray mSelectedItemsIds;
private List<MyObject> mylist;
private Context mContext;
public mylistAdapter(List<MyObject> mylist, Context context) {
super(context, R.layout.row, mylist);
this.mylist = mylist;
this.mContext=context;
mSelectedItemsIds = new SparseBooleanArray();
}
public void toggleSelection(int position) {
selectView(position, !mSelectedItemsIds.get(position));
}
@Override
public void remove(MyObject object) {
this.mylist.remove(object);
notifyDataSetChanged();
}
public void removeSelection() {
mSelectedItemsIds.clear(); // = new SparseBooleanArray();
notifyDataSetChanged();
}
public void selectView(int position, boolean value) {
if (value)
mSelectedItemsIds.put(position, value);
else
mSelectedItemsIds.delete(position);
notifyDataSetChanged();
}
public SparseBooleanArray getSelectedIds() {
return mSelectedItemsIds;
}
public void refresh(ArrayList<MyObject> mylist) {
this.mylist = mylist;
this.clear();
this.addAll(mylist);
this.notifyDataSetChanged();
}
// View lookup cache
private static class ViewHolder {
CheckBox chkSelect;
TextView txtBla;
}
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
// Get the data item for this position
MyObject dataModel = getItem(position);
ViewHolder viewHolder; // view lookup cache stored in tag
final View result;
if (convertView == null) {
viewHolder = new ViewHolder();
LayoutInflater inflater = LayoutInflater.from(getContext());
convertView = inflater.inflate(R.layout.row, null); //parent, false);
viewHolder.txtBla = convertView.findViewById(R.id.txtBla);
viewHolder.chkSelect = convertView.findViewById(R.id.chkSelect);
viewHolder.chkSelect.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
toggleSelection(position);
}
});
result = convertView;
convertView.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) convertView.getTag();
result=convertView;
}
viewHolder.txtBla.setText(dataModel.mytextBla);
// Return the completed view to render on screen
return convertView;
}
}
谢谢!
答案 0 :(得分:0)
您的适配器中的getView()
方法实际上并未设置复选框的选中状态。每次重新使用视图时,都应确保正确设置检查状态。像
viewHolder.ckhSelect.setChecked(mSelectedItemIds.get(position));
请注意,这会触发您的OnCheckedChangeListener()
。一个简单的解决方法是将侦听器设置为null
,然后在修改复选框的选中状态后将其重新设置为实际值,但也有其他(更复杂的)方法。