Android:Listview不保存复选框的状态

时间:2013-08-19 18:40:32

标签: android android-listview android-view

我检查所有类似问题的主题,但我仍然坚持死点。我有一个列表视图与联系人列表,但当我向下滚动并向上滚动列表视图时,不保存我的选择状态。所有复选框都设置为false。当我调试时,我看到,当我滚动listview时,我的onClickListener认为复选框已签名并重置此项。我做所有事情,其他数组与位置布尔等,我仍然不知道该怎么做:(我将非常感谢任何帮助:)

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        readContacts();
        Contact_Database dbhandler = new Contact_Database(
                getApplicationContext(), null, null, 1);
        numbers.addAll( dbhandler.getAllNumbers());
        System.out.println("onCreate");
        ListView lv = getListView();
        registerForContextMenu(lv);
        lv.setTextFilterEnabled(true);
        lv.clearChoices();
        MyAdapter adapter = (new MyAdapter(this, R.layout.contact_list_sms, contacts));
        adapter.notifyDataSetChanged();
        lv.setAdapter(adapter);

    }

    /**
     * When I destroy intent i send request to database, faster!
     */

    @Override
    protected void onDestroy() {
        super.onDestroy();
        for (int i = 0; i < numbers.size(); ++i)
            System.out.println("@@@@" + numbers.get(i));

        swap_contacts();

    }

class MyAdapter extends ArrayAdapter<Contact> {

        LayoutInflater inflat;

        public MyAdapter(Context context, int textViewResourceId,
                ArrayList<Contact> objects) {
            super(context, textViewResourceId, objects);
            inflat = LayoutInflater.from(context);
            System.out.println("LOLLLLL");
            notifyDataSetChanged();

        }

        @Override
        public int getItemViewType(int position) {
            return (position == this.getCount() - 1) ? 1 : 0;
        }

        @Override
        public int getViewTypeCount() {
            return 2;
        }

        // if that contact exist in database? numbers, in onCreate method
        // i init this with saved position from databse
        private boolean exist(String x) {
            for (int i = 0; i < numbers.size(); i++)
                if (numbers.get(i).compareTo(x) == 0)
                    return true;
            return false;
        }

        @SuppressLint("NewApi")
        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            System.out.println("ROWS !!! ->" + numbers.size());
            ViewHolder holder = null;
            if (convertView == null) {
                holder = new ViewHolder();
                convertView = inflat.inflate(R.layout.contact_row, null);
                holder.textView1 = (TextView) convertView
                        .findViewById(R.id.name);
                holder.textView2 = (TextView) convertView
                        .findViewById(R.id.number);
                holder.on_off = (CheckBox) convertView
                        .findViewById(R.id.enable);
                convertView.setTag(holder);
            } else {
                holder = (ViewHolder) convertView.getTag();
            }
            Contact it = contacts.get(position);
            Log.v("XXX", holder.toString());
            if (it != null) {
                holder.textView1.setText(contacts.get(position).name);
                holder.textView2.setText(contacts.get(position).phone);
                // update state of checbox from database
                if (exist(contacts.get(position).phone))
                    holder.on_off.setChecked(true);
                else
                    holder.on_off.setChecked(false);
            }

            final int element_position = position;

            holder.on_off
                    .setOnCheckedChangeListener(new OnCheckedChangeListener() {
                        // update list when we click on it
                        @Override
                        public void onCheckedChanged(CompoundButton buttonView,
                                boolean isChecked) {
                            String nr_telefonu = contacts.get(element_position).phone;
                            if (isChecked) {
                                numbers.add(nr_telefonu);
                            } else {
                                numbers.remove(nr_telefonu);
                            }
                        }
                    });
            return convertView;
        }


        @Override
        public Contact getItem(int position) {
            return contacts.get(position);
        }

        private class ViewHolder {
            TextView textView1, textView2;
            CheckBox on_off;

            public String toString() {
                return "-";
            }
        }
    }

3 个答案:

答案 0 :(得分:2)

列表在滚动时不保存状态,因为每次为行项创建新对象。所以你需要在Pojo类(Setter和getter)的帮助下显式保存CheckBox的状态。

在getView()方法中,您需要检查每个复选框的值。

@Override
        public View getView(int position, View convertView, ViewGroup parent) {
////////////////////

并且在setOnCheckedChangeListener上你需要保存复选框的状态

                  holder.on_off
                    .setOnCheckedChangeListener(new OnCheckedChangeListener() {
                        // update list when we click on it
                        @Override
                        public void onCheckedChanged(CompoundButton buttonView,
                                boolean isChecked) {
                        // need to save the state

有关详细信息,请参阅以下博客

http://amitandroid.blogspot.in/2013/03/android-listview-with-checkbox-and.html

您可以根据自己的要求进行更改。

答案 1 :(得分:0)

感谢您的回答:)我为每个复选框按钮创建一个带状态的数组stan。明天我将尝试重建我所有的课程,就像博客上的列表一样,这可能对我有帮助。

但是当我这样做时: 保存状态:

holder.on_off
                    .setOnCheckedChangeListener(new OnCheckedChangeListener() {
                        // update list when we click on it
                        // this.setChecked(stan[position]);
                        @Override
                        public void onCheckedChanged(CompoundButton buttonView,
                                boolean isChecked) {
                            String nr_telefonu = p.get(element_position).phone;
                            buttonView.setChecked(stan[element_position]);

                            stan[element_position] = isChecked;
                        }
                    });

刷新按钮状态

if (it != null) {
                holder.textView1.setText(contacts.get(position).name);
                holder.textView2.setText(contacts.get(position).phone);
                // update state of checbox from database

                    holder.on_off.setChecked(stan[position]);
            }

我仍然站在死点,没有任何改变

答案 2 :(得分:0)

我已经在下面找到了解决这个问题的方法,我花了很多时间找到它并且对我有用!

&#13;
&#13;
public class RowAdapter extends ArrayAdapter<Rows> {

	Context context; 
    int layoutResourceId;    
    ArrayList<Rows> data;
    boolean[] checkBoxState;
    RowHolder rowHolder;
	
	
	public RowAdapter(Context context, int layoutResourceId, ArrayList<Rows> data) {
		super(context, layoutResourceId, data);
		
		this.layoutResourceId = layoutResourceId;
		this.context = context;
		this.data = data;
		
		checkBoxState = new boolean[data.size()];
	}
	

	@Override
    public View getView(final int position, View convertView, ViewGroup parent) {
        View row = convertView;
        RowHolder holder = null;
        
        
        if(row == null)
        {
            	
            LayoutInflater inflater = ((Activity)context).getLayoutInflater();
            row = inflater.inflate(layoutResourceId, parent, false);
            holder = new RowHolder();

holder.textView1 = (TextView)row.findViewById(R.id.textView1);
            holder.textView2 = (TextView)row.findViewById(R.id.textView2);
            holder.textView3 = (TextView)row.findViewById(R.id.textView3);
            holder.textView4 = (TextView)row.findViewById(R.id.textView4);
            holder.checkBox=(CheckBox) row.findViewById(R.id.checkBox1);
         
            
            row.setTag(holder);
        }
        else{
        
        	holder = (RowHolder)row.getTag();
            }
    
        
        Rows rows = data.get(position);
        holder.textView1.setText(rows.address);
        holder.textView2.setText(rows.tenancy);
        holder.textView3.setText(rows.location);
        holder.textView4.setText(rows.name);
        
        holder.checkBox.setChecked(checkBoxState[position]);

holder.checkBox.setOnClickListener(new View.OnClickListener() {
            
        	   public void onClick(View v) {
        	    if(((CheckBox)v).isChecked())
        	     checkBoxState[position]=true;
        	    else
        	     checkBoxState[position]=false;
        	      
        	    }
        	   });
       
        
        return row;
    }
    
    static class RowHolder
    {
    	TextView textView1;
        TextView textView2;
        TextView textView3;
        TextView textView4;
        CheckBox checkBox;
    }
    
  

    
    
}
        
&#13;
&#13;
&#13;