我有一个列表,其中每行包含一个复选框和一个textview,我也有一个按钮,应该检查/取消选中列表中的所有复选框,但是,我无法使用复选框OUTSIDE来实现这一点。屏幕,只有可见的一个。如果我理解得很好,那就是因为屏幕外的项目不存在,它们会在滚动时被回收以创建新行,在尝试检查/访问屏幕外的复选框时会导致空指针/退出索引错误。 / p>
我用谷歌搜索解决方案但到目前为止没有任何工作。
我该如何解决这个问题?
这是适配器:
public class AlumnoArrayAdapter<T> extends BaseAdapter{
Context mContext;
LayoutInflater mInflater;
ArrayList<T> mList;
ArrayList<Alumno> alumno;
boolean verEstadisticas;
SparseBooleanArray mSparseBooleanArray;
public AlumnoArrayAdapter(Context context, ArrayList<T> list, ArrayList<Alumno> alumno, boolean verEstadisticas) {
//TODO Auto-generated constructor stub
this.alumno = alumno;
this.verEstadisticas = verEstadisticas;
this.mContext = context;
mInflater = LayoutInflater.from(mContext);
mSparseBooleanArray = new SparseBooleanArray();
mList = new ArrayList<T>();
this.mList = list;
}
public ArrayList<T> getCheckedItems() {
ArrayList<T> mTempArry = new ArrayList<T>();
for(int i=0;i<mList.size();i++) {
if(mSparseBooleanArray.get(i)) {
mTempArry.add(mList.get(i));
}
}
return mTempArry;
}
public int getCount() {
return mList.size();
}
public Object getItem(int position) {
return mList.get(position);
}
public long getItemId(int position) {
return position;
}
public View getView(final int position, View convertView, ViewGroup parent) {
if(convertView == null) {
convertView = mInflater.inflate(R.layout.row, null);
}
TextView tvTitle = (TextView) convertView.findViewById(R.id.tvTitle);
tvTitle.setText(mList.get(position).toString());
CheckBox mCheckBox = (CheckBox) convertView.findViewById(R.id.chkEnable);
mCheckBox.setTag((Integer) position);
mCheckBox.setChecked(mSparseBooleanArray.get(position));
mCheckBox.setOnCheckedChangeListener(mCheckedChangeListener);
if(verEstadisticas){
mCheckBox.setVisibility(View.GONE);
}
mCheckBox.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
CheckBox cb = (CheckBox) v;
Integer position = (Integer) cb.getTag();
alumno.get(position).setChecked(cb.isChecked());
}
});
return convertView;
}
OnCheckedChangeListener mCheckedChangeListener = new OnCheckedChangeListener() {
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
mSparseBooleanArray.put((Integer) buttonView.getTag(), isChecked);
}
};
}
如果需要更多代码,请告诉我们。
感谢任何可能的帮助。
提前致谢!
编辑:有一个解决方案!,修改后的适配器:
public class AlumnoArrayAdapter<T> extends BaseAdapter{
Context mContext;
LayoutInflater mInflater;
ArrayList<T> mList;
ArrayList<Alumno> alumno;
boolean verEstadisticas;
SparseBooleanArray mSparseBooleanArray;
boolean checarTodo = false;
public AlumnoArrayAdapter(Context context, ArrayList<T> list, ArrayList<Alumno> alumno, boolean verEstadisticas) {
//TODO Auto-generated constructor stub
this.alumno = alumno;
this.verEstadisticas = verEstadisticas;
this.mContext = context;
mInflater = LayoutInflater.from(mContext);
mSparseBooleanArray = new SparseBooleanArray();
mList = new ArrayList<T>();
this.mList = list;
}
public ArrayList<T> getCheckedItems() {
ArrayList<T> mTempArry = new ArrayList<T>();
for(int i=0;i<mList.size();i++) {
if(mSparseBooleanArray.get(i)) {
mTempArry.add(mList.get(i));
}
}
return mTempArry;
}
public int getCount() {
return mList.size();
}
public Object getItem(int position) {
return mList.get(position);
}
public long getItemId(int position) {
return position;
}
public void checkAll(){
for(int x = 0; x < alumno.size(); x++){
alumno.get(x).setChecked(!alumno.get(x).isChecked());
}
}
public View getView(final int position, View convertView, ViewGroup parent) {
if(convertView == null) {
convertView = mInflater.inflate(R.layout.row, null);
}
TextView tvTitle = (TextView) convertView.findViewById(R.id.tvTitle);
tvTitle.setText(mList.get(position).toString());
CheckBox mCheckBox = (CheckBox) convertView.findViewById(R.id.chkEnable);
mCheckBox.setTag((Integer) position);
mCheckBox.setChecked(alumno.get(position).isChecked());
if(verEstadisticas){
mCheckBox.setVisibility(View.GONE);
}
mCheckBox.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
CheckBox cb = (CheckBox) v;
//Alumno Alumno = (Alumno) cb.getTag();
Integer position = (Integer) cb.getTag();
alumno.get(position).setChecked(cb.isChecked());
}
});
return convertView;
}
}
答案 0 :(得分:3)
您可以尝试以下方法:
我希望这一步有所帮助。
答案 1 :(得分:1)
您需要操纵基础数据结构中的“已检查”信息。正如您所说,GUI对象仅用于表示底层数据的可视化表单。使用GUI对象作为保存应用程序状态信息的唯一方法是很诱人的,但不是一个好主意。
答案 2 :(得分:1)
检查此代码。尝试采用适配器。它不一样。但很少有修改肯定会奏效。
class CustomAdapter extends ArrayAdapter<ContactPerson>{
private ArrayList<ContactPerson> contactList;
public CustomAdapter(Context context, int textViewResourceId,
ArrayList<ContactPerson> contactList) {
super(context, textViewResourceId, contactList);
// TODO Auto-generated constructor stub
this.contactList = new ArrayList<ContactPerson>();
this.contactList.addAll(contactList);
}
private class ViewHolder{
TextView ContactName;
CheckBox contactCheck;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
ViewHolder holder = null;
Log.v("Convert View", String.valueOf(position));
if(convertView==null){
LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.checkbox_item, null);
holder = new ViewHolder();
holder.ContactName = (TextView) convertView.findViewById(R.id.contact_name);
holder.contactCheck = (CheckBox) convertView.findViewById(R.id.contact_check);
convertView.setTag(holder);
holder.contactCheck.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
CheckBox cb = (CheckBox) v;
ContactPerson contact = (ContactPerson) cb.getTag();
// Log.i("clicked users", contact.getName());
contact.setSelected(cb.isChecked());
}
});
}
else{
holder = (ViewHolder) convertView.getTag();
}
ContactPerson contacts = contactList.get(position);
holder.ContactName.setText("("+contacts.getName()+")");
holder.contactCheck.setChecked(contacts.isSelected());
holder.contactCheck.setTag(contacts);
holder.ContactName.setText(contacts.getName());
return convertView;
}
}
private void checkButtonClick(){
Button nextButton = (Button) findViewById(R.id.selected_done);
nextButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
StringBuffer display = new StringBuffer();
display.append("the selected contacts are");
ArrayList<ContactPerson> finalContactList = contactAdapter.contactList;
for(int i=0;i<finalContactList.size();i++){
ContactPerson selected = finalContactList.get(i);
if(selected.isSelected()){
display.append("\n"+selected.getName()+"\t"+selected.getPhoneNumber());
}
}
Toast.makeText(getApplicationContext(), display, Toast.LENGTH_LONG).show();
}
});
}
答案 3 :(得分:1)
我会使用内置的listview函数来标记已检查的项目:setItemChecked,并结合行的自定义可检查视图。有关创建可检查视图的完美演练(有关处理复选框子项的部分),请参阅Here。为了完整起见,这是一个可检查视图的示例:
public class ExampleListItemView extends RelativeLayout implements Checkable {
private static final int[] CHECKED_STATE_SET = { android.R.attr.state_checked };
public ExampleListItemView(Context context) {
super(context);
}
public ExampleListItemView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public ExampleListItemView(Context context, AttributeSet attrs,
int defStyle) {
super(context, attrs, defStyle);
}
TextView txtExample;
CheckBox cbExample;
private boolean isChecked = false;
@Override
protected void onFinishInflate() {
super.onFinishInflate();
txtExample = (TextView) findViewById(R.id.txtExample);
cbExample = (CheckBox) findViewById(R.id.cbExample);
isChecked = false;
}
public void setText(String text){
txtExample.setText(text);
}
@Override
public boolean isChecked() {
return isChecked;
}
@Override
public void setChecked(boolean checked) {
if (isChecked != checked) {
cbExample.setChecked(checked);
isChecked = checked;
refreshDrawableState();
}
}
@Override
public void toggle() {
setChecked(!isChecked);
}
@Override
public int[] onCreateDrawableState(int extraSpace) {
final int[] drawableState = super.onCreateDrawableState(extraSpace + 1);
if (isChecked()) {
mergeDrawableStates(drawableState, CHECKED_STATE_SET);
}
return drawableState;
}
相关的xml布局:
<?xml version="1.0" encoding="utf-8"?>
<com.example.ExampleListItemView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
ndroid:addStatesFromChildren="true" >
<CheckBox android:id="@+id/cbExample" />
<TextView
android:id="@+id/txtExample"
android:layout_toRightOf="@id/cbExample" />
</com.example.ExampleListItemView>
然后你会得到类似的东西:
for(int i = 0; i < adapter.getCount(); i++){
listView.setItemChecked(i, true);
}
SparseBooleanArray checked = listView.getCheckedItemPositions();